gh-133166: Fix missing error emission of PyType_GetModuleByDef (GH-133240)

This commit is contained in:
neonene 2025-05-01 21:32:57 +09:00 committed by GitHub
parent 662dd29456
commit fa52f289a3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 35 additions and 7 deletions

View file

@ -179,6 +179,22 @@ class TypeTests(unittest.TestCase):
_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

View file

@ -0,0 +1,2 @@
Fix regression where :c:func:`PyType_GetModuleByDef` returns NULL without
setting :exc:`TypeError` when a static type is passed.

View file

@ -521,6 +521,13 @@ error:
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},
@ -538,6 +545,7 @@ static PyMethodDef TestMethods[] = {
{"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},
};

View file

@ -5399,7 +5399,7 @@ PyType_GetModuleByDef(PyTypeObject *type, PyModuleDef *def)
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;
@ -5439,13 +5439,15 @@ PyType_GetModuleByDef(PyTypeObject *type, PyModuleDef *def)
}
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;
}