Skip to content

Commit 790db85

Browse files
gh-76785: Add _PyType_GetModuleName() to the Internal C-API (gh-112323)
The new function corresponds to the existing (public) PyType_GetName() and PyType_GetQualName().
1 parent 5c3a129 commit 790db85

File tree

5 files changed

+43
-0
lines changed

5 files changed

+43
-0
lines changed

Include/internal/pycore_typeobject.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,11 @@ extern PyTypeObject _PyBufferWrapper_Type;
143143
extern PyObject* _PySuper_Lookup(PyTypeObject *su_type, PyObject *su_obj,
144144
PyObject *name, int *meth_found);
145145

146+
147+
// This is exported for the _testinternalcapi module.
148+
PyAPI_FUNC(PyObject *) _PyType_GetModuleName(PyTypeObject *);
149+
150+
146151
#ifdef __cplusplus
147152
}
148153
#endif

Lib/test/test_capi/test_misc.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,6 +1098,21 @@ class Data(_testcapi.ObjExtraData):
10981098
del d.extra
10991099
self.assertIsNone(d.extra)
11001100

1101+
def test_get_type_module_name(self):
1102+
from collections import OrderedDict
1103+
ht = _testcapi.get_heaptype_for_name()
1104+
for cls, expected in {
1105+
int: 'builtins',
1106+
OrderedDict: 'collections',
1107+
ht: '_testcapi',
1108+
}.items():
1109+
with self.subTest(repr(cls)):
1110+
modname = _testinternalcapi.get_type_module_name(cls)
1111+
self.assertEqual(modname, expected)
1112+
1113+
ht.__module__ = 'test_module'
1114+
modname = _testinternalcapi.get_type_module_name(ht)
1115+
self.assertEqual(modname, 'test_module')
11011116

11021117
@requires_limited_api
11031118
class TestHeapTypeRelative(unittest.TestCase):

Modules/_testcapimodule.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,12 @@ static PyType_Spec HeapTypeNameType_Spec = {
569569
.slots = HeapTypeNameType_slots,
570570
};
571571

572+
static PyObject *
573+
get_heaptype_for_name(PyObject *self, PyObject *Py_UNUSED(ignored))
574+
{
575+
return PyType_FromSpec(&HeapTypeNameType_Spec);
576+
}
577+
572578
static PyObject *
573579
test_get_type_name(PyObject *self, PyObject *Py_UNUSED(ignored))
574580
{
@@ -3210,6 +3216,7 @@ static PyMethodDef TestMethods[] = {
32103216
{"py_buildvalue_ints", py_buildvalue_ints, METH_VARARGS},
32113217
{"test_buildvalue_N", test_buildvalue_N, METH_NOARGS},
32123218
{"test_get_statictype_slots", test_get_statictype_slots, METH_NOARGS},
3219+
{"get_heaptype_for_name", get_heaptype_for_name, METH_NOARGS},
32133220
{"test_get_type_name", test_get_type_name, METH_NOARGS},
32143221
{"test_get_type_qualname", test_get_type_qualname, METH_NOARGS},
32153222
{"test_get_type_dict", test_get_type_dict, METH_NOARGS},

Modules/_testinternalcapi.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "pycore_pathconfig.h" // _PyPathConfig_ClearGlobal()
2828
#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
2929
#include "pycore_pystate.h" // _PyThreadState_GET()
30+
#include "pycore_typeobject.h" // _PyType_GetModuleName()
3031

3132
#include "interpreteridobject.h" // PyInterpreterID_LookUp()
3233

@@ -1616,6 +1617,14 @@ perf_trampoline_set_persist_after_fork(PyObject *self, PyObject *args)
16161617
}
16171618

16181619

1620+
static PyObject *
1621+
get_type_module_name(PyObject *self, PyObject *type)
1622+
{
1623+
assert(PyType_Check(type));
1624+
return _PyType_GetModuleName((PyTypeObject *)type);
1625+
}
1626+
1627+
16191628
static PyMethodDef module_functions[] = {
16201629
{"get_configs", get_configs, METH_NOARGS},
16211630
{"get_recursion_depth", get_recursion_depth, METH_NOARGS},
@@ -1678,6 +1687,7 @@ static PyMethodDef module_functions[] = {
16781687
{"get_crossinterp_data", get_crossinterp_data, METH_VARARGS},
16791688
{"restore_crossinterp_data", restore_crossinterp_data, METH_VARARGS},
16801689
_TESTINTERNALCAPI_TEST_LONG_NUMBITS_METHODDEF
1690+
{"get_type_module_name", get_type_module_name, METH_O},
16811691
{NULL, NULL} /* sentinel */
16821692
};
16831693

Objects/typeobject.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4540,6 +4540,12 @@ PyType_GetQualName(PyTypeObject *type)
45404540
return type_qualname(type, NULL);
45414541
}
45424542

4543+
PyObject *
4544+
_PyType_GetModuleName(PyTypeObject *type)
4545+
{
4546+
return type_module(type, NULL);
4547+
}
4548+
45434549
void *
45444550
PyType_GetSlot(PyTypeObject *type, int slot)
45454551
{

0 commit comments

Comments
 (0)