_testcapi.pytype_getbasebytoken(
'not a type', id(self), True, False)
+ def test_get_module_by_def(self):
+ heaptype = _testcapi.create_type_with_token('_testcapi.H', 0)
+ mod = _testcapi.pytype_getmodulebydef(heaptype)
+ self.assertIs(mod, _testcapi)
+
+ class H1(heaptype): pass
+ mod = _testcapi.pytype_getmodulebydef(H1)
+ self.assertIs(mod, _testcapi)
+
+ with self.assertRaises(TypeError):
+ _testcapi.pytype_getmodulebydef(int)
+
+ class H2(int): pass
+ with self.assertRaises(TypeError):
+ _testcapi.pytype_getmodulebydef(H2)
+
def test_freeze(self):
# test PyType_Freeze()
type_freeze = _testcapi.type_freeze
--- /dev/null
+Fix regression where :c:func:`PyType_GetModuleByDef` returns NULL without
+setting :exc:`TypeError` when a static type is passed.
return NULL;
}
+static PyObject *
+pytype_getmodulebydef(PyObject *self, PyObject *type)
+{
+ PyObject *mod = PyType_GetModuleByDef((PyTypeObject *)type, _testcapimodule);
+ return Py_XNewRef(mod);
+}
+
static PyMethodDef TestMethods[] = {
{"pytype_fromspec_meta", pytype_fromspec_meta, METH_O},
{"create_type_with_token", create_type_with_token, METH_VARARGS},
{"get_tp_token", get_tp_token, METH_O},
{"pytype_getbasebytoken", pytype_getbasebytoken, METH_VARARGS},
+ {"pytype_getmodulebydef", pytype_getmodulebydef, METH_O},
{NULL},
};
if (!_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) {
// type_ready_mro() ensures that no heap type is
// contained in a static type MRO.
- return NULL;
+ goto error;
}
else {
PyHeapTypeObject *ht = (PyHeapTypeObject*)type;
}
END_TYPE_LOCK();
- if (res == NULL) {
- PyErr_Format(
- PyExc_TypeError,
- "PyType_GetModuleByDef: No superclass of '%s' has the given module",
- type->tp_name);
+ if (res != NULL) {
+ return res;
}
- return res;
+error:
+ PyErr_Format(
+ PyExc_TypeError,
+ "PyType_GetModuleByDef: No superclass of '%s' has the given module",
+ type->tp_name);
+ return NULL;
}