diff options
| author | shadchin <[email protected]> | 2022-04-18 12:39:32 +0300 |
|---|---|---|
| committer | shadchin <[email protected]> | 2022-04-18 12:39:32 +0300 |
| commit | d4be68e361f4258cf0848fc70018dfe37a2acc24 (patch) | |
| tree | 153e294cd97ac8b5d7a989612704a0c1f58e8ad4 /contrib/tools/python3/src/Modules/_abc.c | |
| parent | 260c02f5ccf242d9d9b8a873afaf6588c00237d6 (diff) | |
IGNIETFERRO-1816 Update Python 3 from 3.9.12 to 3.10.4
ref:9f96be6d02ee8044fdd6f124b799b270c20ce641
Diffstat (limited to 'contrib/tools/python3/src/Modules/_abc.c')
| -rw-r--r-- | contrib/tools/python3/src/Modules/_abc.c | 84 |
1 files changed, 75 insertions, 9 deletions
diff --git a/contrib/tools/python3/src/Modules/_abc.c b/contrib/tools/python3/src/Modules/_abc.c index 709b52ff96b..8aa68359039 100644 --- a/contrib/tools/python3/src/Modules/_abc.c +++ b/contrib/tools/python3/src/Modules/_abc.c @@ -1,6 +1,7 @@ /* ABCMeta implementation */ #include "Python.h" +#include "pycore_moduleobject.h" // _PyModule_GetState() #include "clinic/_abc.c.h" /*[clinic input] @@ -14,6 +15,7 @@ PyDoc_STRVAR(_abc__doc__, _Py_IDENTIFIER(__abstractmethods__); _Py_IDENTIFIER(__class__); _Py_IDENTIFIER(__dict__); +_Py_IDENTIFIER(__abc_tpflags__); _Py_IDENTIFIER(__bases__); _Py_IDENTIFIER(_abc_impl); _Py_IDENTIFIER(__subclasscheck__); @@ -27,7 +29,7 @@ typedef struct { static inline _abcmodule_state* get_abc_state(PyObject *module) { - void *state = PyModule_GetState(module); + void *state = _PyModule_GetState(module); assert(state != NULL); return (_abcmodule_state *)state; } @@ -416,6 +418,8 @@ error: return ret; } +#define COLLECTION_FLAGS (Py_TPFLAGS_SEQUENCE | Py_TPFLAGS_MAPPING) + /*[clinic input] _abc._abc_init @@ -445,9 +449,64 @@ _abc__abc_init(PyObject *module, PyObject *self) return NULL; } Py_DECREF(data); + /* If __abc_tpflags__ & COLLECTION_FLAGS is set, then set the corresponding bit(s) + * in the new class. + * Used by collections.abc.Sequence and collections.abc.Mapping to indicate + * their special status w.r.t. pattern matching. */ + if (PyType_Check(self)) { + PyTypeObject *cls = (PyTypeObject *)self; + PyObject *flags = _PyDict_GetItemIdWithError(cls->tp_dict, &PyId___abc_tpflags__); + if (flags == NULL) { + if (PyErr_Occurred()) { + return NULL; + } + } + else { + if (PyLong_CheckExact(flags)) { + long val = PyLong_AsLong(flags); + if (val == -1 && PyErr_Occurred()) { + return NULL; + } + if ((val & COLLECTION_FLAGS) == COLLECTION_FLAGS) { + PyErr_SetString(PyExc_TypeError, "__abc_tpflags__ cannot be both Py_TPFLAGS_SEQUENCE and Py_TPFLAGS_MAPPING"); + return NULL; + } + ((PyTypeObject *)self)->tp_flags |= (val & COLLECTION_FLAGS); + } + if (_PyDict_DelItemId(cls->tp_dict, &PyId___abc_tpflags__) < 0) { + return NULL; + } + } + } Py_RETURN_NONE; } +static void +set_collection_flag_recursive(PyTypeObject *child, unsigned long flag) +{ + assert(flag == Py_TPFLAGS_MAPPING || flag == Py_TPFLAGS_SEQUENCE); + if (PyType_HasFeature(child, Py_TPFLAGS_IMMUTABLETYPE) || + (child->tp_flags & COLLECTION_FLAGS) == flag) + { + return; + } + child->tp_flags &= ~COLLECTION_FLAGS; + child->tp_flags |= flag; + PyObject *grandchildren = child->tp_subclasses; + if (grandchildren == NULL) { + return; + } + assert(PyDict_CheckExact(grandchildren)); + Py_ssize_t i = 0; + while (PyDict_Next(grandchildren, &i, NULL, &grandchildren)) { + assert(PyWeakref_CheckRef(grandchildren)); + PyObject *grandchild = PyWeakref_GET_OBJECT(grandchildren); + if (PyType_Check(grandchild)) { + set_collection_flag_recursive((PyTypeObject *)grandchild, flag); + } + } +} + /*[clinic input] _abc._abc_register @@ -498,6 +557,13 @@ _abc__abc_register_impl(PyObject *module, PyObject *self, PyObject *subclass) /* Invalidate negative cache */ get_abc_state(module)->abc_invalidation_counter++; + /* Set Py_TPFLAGS_SEQUENCE or Py_TPFLAGS_MAPPING flag */ + if (PyType_Check(self)) { + unsigned long collection_flag = ((PyTypeObject *)self)->tp_flags & COLLECTION_FLAGS; + if (collection_flag) { + set_collection_flag_recursive((PyTypeObject *)subclass, collection_flag); + } + } Py_INCREF(subclass); return subclass; } @@ -891,14 +957,14 @@ static PyModuleDef_Slot _abcmodule_slots[] = { static struct PyModuleDef _abcmodule = { PyModuleDef_HEAD_INIT, - "_abc", - _abc__doc__, - sizeof(_abcmodule_state), - _abcmodule_methods, - _abcmodule_slots, - _abcmodule_traverse, - _abcmodule_clear, - _abcmodule_free, + .m_name = "_abc", + .m_doc = _abc__doc__, + .m_size = sizeof(_abcmodule_state), + .m_methods = _abcmodule_methods, + .m_slots = _abcmodule_slots, + .m_traverse = _abcmodule_traverse, + .m_clear = _abcmodule_clear, + .m_free = _abcmodule_free, }; PyMODINIT_FUNC |
