| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 57d1855 commit 8ee07dd
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -220,11 +220,12 @@ static inline PyObject **_PyObject_ManagedDictPointer(PyObject *obj) | |||
| 220 | 220 | return ((PyObject **)obj)-3; | |
| 221 | 221 | } | |
| 222 | 222 | ||
| 223 | - PyObject ** _PyObject_DictPointer(PyObject *); | ||
| 224 | - int _PyObject_VisitInstanceAttributes(PyObject *self, visitproc visit, void *arg); | ||
| 225 | - void _PyObject_ClearInstanceAttributes(PyObject *self); | ||
| 226 | - void _PyObject_FreeInstanceAttributes(PyObject *self); | ||
| 227 | - int _PyObject_IsInstanceDictEmpty(PyObject *); | ||
| 223 | + extern PyObject ** _PyObject_DictPointer(PyObject *); | ||
| 224 | + extern int _PyObject_VisitInstanceAttributes(PyObject *self, visitproc visit, void *arg); | ||
| 225 | + extern void _PyObject_ClearInstanceAttributes(PyObject *self); | ||
| 226 | + extern void _PyObject_FreeInstanceAttributes(PyObject *self); | ||
| 227 | + extern int _PyObject_IsInstanceDictEmpty(PyObject *); | ||
| 228 | + extern PyObject* _PyType_GetSubclasses(PyTypeObject *); | ||
| 228 | 229 | ||
| 229 | 230 | #ifdef __cplusplus | |
| 230 | 231 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4,6 +4,7 @@ | |||
| 4 | 4 | #endif | |
| 5 | 5 | ||
| 6 | 6 | #include "Python.h" | |
| 7 | + #include "pycore_object.h" // _PyType_GetSubclasses() | ||
| 7 | 8 | #include "pycore_moduleobject.h" // _PyModule_GetState() | |
| 8 | 9 | #include "clinic/_abc.c.h" | |
| 9 | 10 | ||
@@ -493,21 +494,20 @@ set_collection_flag_recursive(PyTypeObject *child, unsigned long flag) | |||
| 493 | 494 | { | |
| 494 | 495 | return; | |
| 495 | 496 | } | |
| 497 | + | ||
| 496 | 498 | child->tp_flags &= ~COLLECTION_FLAGS; | |
| 497 | 499 | child->tp_flags |= flag; | |
| 498 | - PyObject *grandchildren = child->tp_subclasses; | ||
| 500 | + | ||
| 501 | + PyObject *grandchildren = _PyType_GetSubclasses(child); | ||
| 499 | 502 | if (grandchildren == NULL) { | |
| 500 | 503 | return; | |
| 501 | 504 | } | |
| 502 | - assert(PyDict_CheckExact(grandchildren)); | ||
| 503 | - Py_ssize_t i = 0; | ||
| 504 | - while (PyDict_Next(grandchildren, &i, NULL, &grandchildren)) { | ||
| 505 | - assert(PyWeakref_CheckRef(grandchildren)); | ||
| 506 | - PyObject *grandchild = PyWeakref_GET_OBJECT(grandchildren); | ||
| 507 | - if (PyType_Check(grandchild)) { | ||
| 508 | - set_collection_flag_recursive((PyTypeObject *)grandchild, flag); | ||
| 509 | - } | ||
| 505 | + | ||
| 506 | + for (Py_ssize_t i = 0; i < PyList_GET_SIZE(grandchildren); i++) { | ||
| 507 | + PyObject *grandchild = PyList_GET_ITEM(grandchildren, i); | ||
| 508 | + set_collection_flag_recursive((PyTypeObject *)grandchild, flag); | ||
| 510 | 509 | } | |
| 510 | + Py_DECREF(grandchildren); | ||
| 511 | 511 | } | |
| 512 | 512 | ||
| 513 | 513 | /*[clinic input] | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -687,27 +687,28 @@ static int recurse_down_subclasses(PyTypeObject *type, PyObject *name, | |||
| 687 | 687 | static int | |
| 688 | 688 | mro_hierarchy(PyTypeObject *type, PyObject *temp) | |
| 689 | 689 | { | |
| 690 | - int res; | ||
| 691 | - PyObject *new_mro, *old_mro; | ||
| 692 | - PyObject *tuple; | ||
| 693 | - PyObject *subclasses; | ||
| 694 | - Py_ssize_t i, n; | ||
| 695 | - | ||
| 696 | - res = mro_internal(type, &old_mro); | ||
| 697 | - if (res <= 0) | ||
| 690 | + PyObject *old_mro; | ||
| 691 | + int res = mro_internal(type, &old_mro); | ||
| 692 | + if (res <= 0) { | ||
| 698 | 693 | /* error / reentrance */ | |
| 699 | 694 | return res; | |
| 700 | - new_mro = type->tp_mro; | ||
| 695 | + } | ||
| 696 | + PyObject *new_mro = type->tp_mro; | ||
| 701 | 697 | ||
| 702 | - if (old_mro != NULL) | ||
| 698 | + PyObject *tuple; | ||
| 699 | + if (old_mro != NULL) { | ||
| 703 | 700 | tuple = PyTuple_Pack(3, type, new_mro, old_mro); | |
| 704 | - else | ||
| 701 | + } | ||
| 702 | + else { | ||
| 705 | 703 | tuple = PyTuple_Pack(2, type, new_mro); | |
| 704 | + } | ||
| 706 | 705 | ||
| 707 | - if (tuple != NULL) | ||
| 706 | + if (tuple != NULL) { | ||
| 708 | 707 | res = PyList_Append(temp, tuple); | |
| 709 | - else | ||
| 708 | + } | ||
| 709 | + else { | ||
| 710 | 710 | res = -1; | |
| 711 | + } | ||
| 711 | 712 | Py_XDECREF(tuple); | |
| 712 | 713 | ||
| 713 | 714 | if (res < 0) { | |
@@ -727,15 +728,18 @@ mro_hierarchy(PyTypeObject *type, PyObject *temp) | |||
| 727 | 728 | Finally, this makes things simple avoiding the need to deal | |
| 728 | 729 | with dictionary iterators and weak references. | |
| 729 | 730 | */ | |
| 730 | - subclasses = type___subclasses___impl(type); | ||
| 731 | - if (subclasses == NULL) | ||
| 731 | + PyObject *subclasses = _PyType_GetSubclasses(type); | ||
| 732 | + if (subclasses == NULL) { | ||
| 732 | 733 | return -1; | |
| 733 | - n = PyList_GET_SIZE(subclasses); | ||
| 734 | - for (i = 0; i < n; i++) { | ||
| 734 | + } | ||
| 735 | + | ||
| 736 | + Py_ssize_t n = PyList_GET_SIZE(subclasses); | ||
| 737 | + for (Py_ssize_t i = 0; i < n; i++) { | ||
| 735 | 738 | PyTypeObject *subclass = _PyType_CAST(PyList_GET_ITEM(subclasses, i)); | |
| 736 | 739 | res = mro_hierarchy(subclass, temp); | |
| 737 | - if (res < 0) | ||
| 740 | + if (res < 0) { | ||
| 738 | 741 | break; | |
| 742 | + } | ||
| 739 | 743 | } | |
| 740 | 744 | Py_DECREF(subclasses); | |
| 741 | 745 | ||
@@ -4124,6 +4128,42 @@ type_dealloc(PyTypeObject *type) | |||
| 4124 | 4128 | Py_TYPE(type)->tp_free((PyObject *)type); | |
| 4125 | 4129 | } | |
| 4126 | 4130 | ||
| 4131 | + | ||
| 4132 | + PyObject* | ||
| 4133 | + _PyType_GetSubclasses(PyTypeObject *self) | ||
| 4134 | + { | ||
| 4135 | + PyObject *list = PyList_New(0); | ||
| 4136 | + if (list == NULL) { | ||
| 4137 | + return NULL; | ||
| 4138 | + } | ||
| 4139 | + | ||
| 4140 | + // Hold a strong reference to tp_subclasses while iterating on it | ||
| 4141 | + PyObject *dict = Py_XNewRef(self->tp_subclasses); | ||
| 4142 | + if (dict == NULL) { | ||
| 4143 | + return list; | ||
| 4144 | + } | ||
| 4145 | + assert(PyDict_CheckExact(dict)); | ||
| 4146 | + | ||
| 4147 | + Py_ssize_t i = 0; | ||
| 4148 | + PyObject *ref; // borrowed ref | ||
| 4149 | + while (PyDict_Next(dict, &i, NULL, &ref)) { | ||
| 4150 | + assert(PyWeakref_CheckRef(ref)); | ||
| 4151 | + PyObject *obj = PyWeakref_GET_OBJECT(ref); // borrowed ref | ||
| 4152 | + if (obj == Py_None) { | ||
| 4153 | + continue; | ||
| 4154 | + } | ||
| 4155 | + assert(PyType_Check(obj)); | ||
| 4156 | + if (PyList_Append(list, obj) < 0) { | ||
| 4157 | + Py_CLEAR(list); | ||
| 4158 | + goto done; | ||
| 4159 | + } | ||
| 4160 | + } | ||
| 4161 | + done: | ||
| 4162 | + Py_DECREF(dict); | ||
| 4163 | + return list; | ||
| 4164 | + } | ||
| 4165 | + | ||
| 4166 | + | ||
| 4127 | 4167 | /*[clinic input] | |
| 4128 | 4168 | type.__subclasses__ | |
| 4129 | 4169 | ||
@@ -4134,28 +4174,7 @@ static PyObject * | |||
| 4134 | 4174 | type___subclasses___impl(PyTypeObject *self) | |
| 4135 | 4175 | /*[clinic end generated code: output=eb5eb54485942819 input=5af66132436f9a7b]*/ | |
| 4136 | 4176 | { | |
| 4137 | - PyObject *list, *raw, *ref; | ||
| 4138 | - Py_ssize_t i; | ||
| 4139 | - | ||
| 4140 | - list = PyList_New(0); | ||
| 4141 | - if (list == NULL) | ||
| 4142 | - return NULL; | ||
| 4143 | - raw = self->tp_subclasses; | ||
| 4144 | - if (raw == NULL) | ||
| 4145 | - return list; | ||
| 4146 | - assert(PyDict_CheckExact(raw)); | ||
| 4147 | - i = 0; | ||
| 4148 | - while (PyDict_Next(raw, &i, NULL, &ref)) { | ||
| 4149 | - assert(PyWeakref_CheckRef(ref)); | ||
| 4150 | - ref = PyWeakref_GET_OBJECT(ref); | ||
| 4151 | - if (ref != Py_None) { | ||
| 4152 | - if (PyList_Append(list, ref) < 0) { | ||
| 4153 | - Py_DECREF(list); | ||
| 4154 | - return NULL; | ||
| 4155 | - } | ||
| 4156 | - } | ||
| 4157 | - } | ||
| 4158 | - return list; | ||
| 4177 | + return _PyType_GetSubclasses(self); | ||
| 4159 | 4178 | } | |
| 4160 | 4179 | ||
| 4161 | 4180 | static PyObject * | |
@@ -4165,6 +4184,7 @@ type_prepare(PyObject *self, PyObject *const *args, Py_ssize_t nargs, | |||
| 4165 | 4184 | return PyDict_New(); | |
| 4166 | 4185 | } | |
| 4167 | 4186 | ||
| 4187 | + | ||
| 4168 | 4188 | /* | |
| 4169 | 4189 | Merge the __dict__ of aclass into dict, and recursively also all | |
| 4170 | 4190 | the __dict__s of aclass's base classes. The order of merging isn't | |
| Back | FazBrowse Home | New Git URL |
0 commit comments