diff options
author | Petr Viktorin <encukou@gmail.com> | 2020-11-03 21:27:12 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-03 21:27:12 (GMT) |
commit | 57aaaa8d2a43bddffeca4ead5632ce6652945cc0 (patch) | |
tree | 30d87542dadc05d27d170ae279cb80c82855c9fc /Objects | |
parent | a603c3d371cda76bae75836faf068e146eb6ab76 (diff) | |
download | cpython-57aaaa8d2a43bddffeca4ead5632ce6652945cc0.zip cpython-57aaaa8d2a43bddffeca4ead5632ce6652945cc0.tar.gz cpython-57aaaa8d2a43bddffeca4ead5632ce6652945cc0.tar.bz2 |
Add _PyType_GetModuleByDef (GH-22835)
See https://mail.python.org/archives/list/capi-sig@python.org/thread/T3P2QNLNLBRFHWSKYSTPMVEIL2EEKFJU/ for discussion.
https://bugs.python.org/issue42100
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/typeobject.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c index bd1587a..2daf374 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3158,6 +3158,44 @@ PyType_GetModuleState(PyTypeObject *type) return PyModule_GetState(m); } + +/* Get the module of the first superclass where the module has the + * given PyModuleDef. + * Implemented by walking the MRO, is relatively slow. + * + * This is internal API for experimentation within stdlib. Discussion: + * https://mail.python.org/archives/list/capi-sig@python.org/thread/T3P2QNLNLBRFHWSKYSTPMVEIL2EEKFJU/ + */ +PyObject * +_PyType_GetModuleByDef(PyTypeObject *type, struct PyModuleDef *def) +{ + assert(PyType_Check(type)); + assert(type->tp_mro); + int i; + for (i = 0; i < PyTuple_GET_SIZE(type->tp_mro); i++) { + PyObject *super = PyTuple_GET_ITEM(type->tp_mro, i); + if (!PyType_HasFeature((PyTypeObject *)super, Py_TPFLAGS_HEAPTYPE)) { + /* Currently, there's no way for static types to inherit + * from heap types, but to allow that possibility, + * we `continue` rather than `break`. + * We'll just potentially loop a few more times before throwing + * the error. + */ + continue; + } + PyHeapTypeObject *ht = (PyHeapTypeObject*)super; + if (ht->ht_module && PyModule_GetDef(ht->ht_module) == def) { + return ht->ht_module; + } + } + PyErr_Format( + PyExc_TypeError, + "_PyType_GetModuleByDef: No superclass of '%s' has the given module", + type->tp_name); + return NULL; +} + + /* Internal API to look for a name through the MRO, bypassing the method cache. This returns a borrowed reference, and might set an exception. 'error' is set to: -1: error with exception; 1: error without exception; 0: ok */ |