Skip to content

Commit fa52f28

Browse files
authored
gh-133166: Fix missing error emission of PyType_GetModuleByDef (GH-133240)
1 parent 662dd29 commit fa52f28

File tree

4 files changed

+35
-7
lines changed

4 files changed

+35
-7
lines changed

Lib/test/test_capi/test_type.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,22 @@ class Z(C1, A2): pass
179179
_testcapi.pytype_getbasebytoken(
180180
'not a type', id(self), True, False)
181181

182+
def test_get_module_by_def(self):
183+
heaptype = _testcapi.create_type_with_token('_testcapi.H', 0)
184+
mod = _testcapi.pytype_getmodulebydef(heaptype)
185+
self.assertIs(mod, _testcapi)
186+
187+
class H1(heaptype): pass
188+
mod = _testcapi.pytype_getmodulebydef(H1)
189+
self.assertIs(mod, _testcapi)
190+
191+
with self.assertRaises(TypeError):
192+
_testcapi.pytype_getmodulebydef(int)
193+
194+
class H2(int): pass
195+
with self.assertRaises(TypeError):
196+
_testcapi.pytype_getmodulebydef(H2)
197+
182198
def test_freeze(self):
183199
# test PyType_Freeze()
184200
type_freeze = _testcapi.type_freeze
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix regression where :c:func:`PyType_GetModuleByDef` returns NULL without
2+
setting :exc:`TypeError` when a static type is passed.

Modules/_testcapi/heaptype.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,13 @@ pytype_getbasebytoken(PyObject *self, PyObject *args)
521521
return NULL;
522522
}
523523

524+
static PyObject *
525+
pytype_getmodulebydef(PyObject *self, PyObject *type)
526+
{
527+
PyObject *mod = PyType_GetModuleByDef((PyTypeObject *)type, _testcapimodule);
528+
return Py_XNewRef(mod);
529+
}
530+
524531

525532
static PyMethodDef TestMethods[] = {
526533
{"pytype_fromspec_meta", pytype_fromspec_meta, METH_O},
@@ -538,6 +545,7 @@ static PyMethodDef TestMethods[] = {
538545
{"create_type_with_token", create_type_with_token, METH_VARARGS},
539546
{"get_tp_token", get_tp_token, METH_O},
540547
{"pytype_getbasebytoken", pytype_getbasebytoken, METH_VARARGS},
548+
{"pytype_getmodulebydef", pytype_getmodulebydef, METH_O},
541549
{NULL},
542550
};
543551

Objects/typeobject.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5399,7 +5399,7 @@ PyType_GetModuleByDef(PyTypeObject *type, PyModuleDef *def)
53995399
if (!_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) {
54005400
// type_ready_mro() ensures that no heap type is
54015401
// contained in a static type MRO.
5402-
return NULL;
5402+
goto error;
54035403
}
54045404
else {
54055405
PyHeapTypeObject *ht = (PyHeapTypeObject*)type;
@@ -5439,13 +5439,15 @@ PyType_GetModuleByDef(PyTypeObject *type, PyModuleDef *def)
54395439
}
54405440
END_TYPE_LOCK();
54415441

5442-
if (res == NULL) {
5443-
PyErr_Format(
5444-
PyExc_TypeError,
5445-
"PyType_GetModuleByDef: No superclass of '%s' has the given module",
5446-
type->tp_name);
5442+
if (res != NULL) {
5443+
return res;
54475444
}
5448-
return res;
5445+
error:
5446+
PyErr_Format(
5447+
PyExc_TypeError,
5448+
"PyType_GetModuleByDef: No superclass of '%s' has the given module",
5449+
type->tp_name);
5450+
return NULL;
54495451
}
54505452

54515453

0 commit comments

Comments
 (0)