summaryrefslogtreecommitdiffstats
path: root/Objects/typeobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/typeobject.c')
-rw-r--r--Objects/typeobject.c38
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 */