diff options
author | Victor Stinner <vstinner@python.org> | 2021-04-13 11:33:31 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-13 11:33:31 (GMT) |
commit | 65f058eb081c9e1fe44115d1ac7966067e3650c7 (patch) | |
tree | 280959d84c71bf4c20018b312b7b14b221473c83 | |
parent | 54db51c9114ac49030832f5134979ca866ffd21c (diff) | |
download | cpython-65f058eb081c9e1fe44115d1ac7966067e3650c7.zip cpython-65f058eb081c9e1fe44115d1ac7966067e3650c7.tar.gz cpython-65f058eb081c9e1fe44115d1ac7966067e3650c7.tar.bz2 |
bpo-43770: Reorder type_ready() (GH-25373)
Add type_ready_create_dict() sub-function.
* Start with type_ready_create_dict().
* Call type_ready_mro() earlier, before type_ready_add_attrs().
* Call type_ready_inherit_special() earlier, in type_ready_inherit().
-rw-r--r-- | Objects/typeobject.c | 104 |
1 files changed, 56 insertions, 48 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 75dd604..9ed77fd 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -5853,7 +5853,7 @@ type_ready_checks(PyTypeObject *type) static int -type_ready_set_base(PyTypeObject *type) +type_ready_set_bases(PyTypeObject *type) { /* Initialize tp_base (defaults to BaseObject unless that's us) */ PyTypeObject *base = type->tp_base; @@ -5887,13 +5887,7 @@ type_ready_set_base(PyTypeObject *type) if (Py_IS_TYPE(type, NULL) && base != NULL) { Py_SET_TYPE(type, Py_TYPE(base)); } - return 0; -} - -static int -type_ready_add_attrs(PyTypeObject *type) -{ /* Initialize tp_bases */ PyObject *bases = type->tp_bases; if (bases == NULL) { @@ -5909,17 +5903,29 @@ type_ready_add_attrs(PyTypeObject *type) } type->tp_bases = bases; } + return 0; +} - /* Initialize tp_dict */ - PyObject *dict = type->tp_dict; + +static int +type_ready_set_dict(PyTypeObject *type) +{ + if (type->tp_dict != NULL) { + return 0; + } + + PyObject *dict = PyDict_New(); if (dict == NULL) { - dict = PyDict_New(); - if (dict == NULL) { - return -1; - } - type->tp_dict = dict; + return -1; } + type->tp_dict = dict; + return 0; +} + +static int +type_ready_add_attrs(PyTypeObject *type) +{ /* Add type-specific descriptors to tp_dict */ if (add_operators(type) < 0) { return -1; @@ -5972,12 +5978,35 @@ type_ready_mro(PyTypeObject *type) } +/* Some more special stuff */ +static void +type_ready_inherit_special(PyTypeObject *type, PyTypeObject *base) +{ + if (type->tp_as_async == NULL) { + type->tp_as_async = base->tp_as_async; + } + if (type->tp_as_number == NULL) { + type->tp_as_number = base->tp_as_number; + } + if (type->tp_as_sequence == NULL) { + type->tp_as_sequence = base->tp_as_sequence; + } + if (type->tp_as_mapping == NULL) { + type->tp_as_mapping = base->tp_as_mapping; + } + if (type->tp_as_buffer == NULL) { + type->tp_as_buffer = base->tp_as_buffer; + } +} + + static int type_ready_inherit(PyTypeObject *type) { /* Inherit special flags from dominant base */ - if (type->tp_base != NULL) { - inherit_special(type, type->tp_base); + PyTypeObject *base = type->tp_base; + if (base != NULL) { + inherit_special(type, base); } /* Initialize tp_dict properly */ @@ -5992,6 +6021,10 @@ type_ready_inherit(PyTypeObject *type) } } + if (base != NULL) { + type_ready_inherit_special(type, base); + } + /* Sanity check for tp_free. */ if (_PyType_IS_GC(type) && (type->tp_flags & Py_TPFLAGS_BASETYPE) && (type->tp_free == NULL || type->tp_free == PyObject_Del)) @@ -6005,6 +6038,7 @@ type_ready_inherit(PyTypeObject *type) type->tp_name); return -1; } + return 0; } @@ -6073,33 +6107,6 @@ type_ready_set_hash(PyTypeObject *type) } -/* Some more special stuff */ -static void -type_ready_inherit_special(PyTypeObject *type) -{ - PyTypeObject *base = type->tp_base; - if (base == NULL) { - return; - } - - if (type->tp_as_async == NULL) { - type->tp_as_async = base->tp_as_async; - } - if (type->tp_as_number == NULL) { - type->tp_as_number = base->tp_as_number; - } - if (type->tp_as_sequence == NULL) { - type->tp_as_sequence = base->tp_as_sequence; - } - if (type->tp_as_mapping == NULL) { - type->tp_as_mapping = base->tp_as_mapping; - } - if (type->tp_as_buffer == NULL) { - type->tp_as_buffer = base->tp_as_buffer; - } -} - - /* Link into each base class's list of subclasses */ static int type_ready_add_subclasses(PyTypeObject *type) @@ -6132,15 +6139,19 @@ type_ready(PyTypeObject *type) _Py_AddToAllObjects((PyObject *)type, 0); #endif - if (type_ready_set_base(type) < 0) { + /* Initialize tp_dict: _PyType_IsReady() tests if tp_dict != NULL */ + if (type_ready_set_dict(type) < 0) { return -1; } - if (type_ready_add_attrs(type) < 0) { + if (type_ready_set_bases(type) < 0) { return -1; } if (type_ready_mro(type) < 0) { return -1; } + if (type_ready_add_attrs(type) < 0) { + return -1; + } if (type_ready_inherit(type) < 0) { return -1; } @@ -6150,9 +6161,6 @@ type_ready(PyTypeObject *type) if (type_ready_set_hash(type) < 0) { return -1; } - - type_ready_inherit_special(type); - if (type_ready_add_subclasses(type) < 0) { return -1; } |