https://github.com/python/cpython/commit/6f8867a6765d3e6effdc09a22691830aa887c3d0
commit: 6f8867a6765d3e6effdc09a22691830aa887c3d0
branch: main
author: AN Long <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2026-03-16T13:59:55+05:30
summary:
gh-129849: Add tests for `Py_tp_bases` (#143208)
files:
M Lib/test/test_capi/test_misc.py
M Modules/_testcapi/heaptype.c
diff --git a/Lib/test/test_capi/test_misc.py b/Lib/test/test_capi/test_misc.py
index 3997acbdf84695..db06719919535f 100644
--- a/Lib/test/test_capi/test_misc.py
+++ b/Lib/test/test_capi/test_misc.py
@@ -916,6 +916,18 @@ def genf(): yield
gen = genf()
self.assertEqual(_testcapi.gen_get_code(gen), gen.gi_code)
+ def test_tp_bases_slot(self):
+ cls = _testcapi.HeapCTypeWithBasesSlot
+ self.assertEqual(cls.__bases__, (int,))
+ self.assertEqual(cls.__base__, int)
+
+ def test_tp_bases_slot_none(self):
+ self.assertRaisesRegex(
+ SystemError,
+ "Py_tp_bases is not a tuple",
+ _testcapi.create_heapctype_with_none_bases_slot
+ )
+
@requires_limited_api
class TestHeapTypeRelative(unittest.TestCase):
diff --git a/Modules/_testcapi/heaptype.c b/Modules/_testcapi/heaptype.c
index 4fdcc850a339b4..eb9458a066f430 100644
--- a/Modules/_testcapi/heaptype.c
+++ b/Modules/_testcapi/heaptype.c
@@ -543,6 +543,25 @@ pytype_getmodulebytoken(PyObject *self, PyObject *args)
return PyType_GetModuleByToken((PyTypeObject *)type, token);
}
+static PyType_Slot HeapCTypeWithBasesSlotNone_slots[] = {
+ {Py_tp_bases, NULL}, /* filled out with Py_None in runtime */
+ {0, 0},
+};
+
+static PyType_Spec HeapCTypeWithBasesSlotNone_spec = {
+ .name = "_testcapi.HeapCTypeWithBasesSlotNone",
+ .basicsize = sizeof(PyObject),
+ .flags = Py_TPFLAGS_DEFAULT,
+ .slots = HeapCTypeWithBasesSlotNone_slots
+};
+
+static PyObject *
+create_heapctype_with_none_bases_slot(PyObject *self, PyObject
*Py_UNUSED(ignored))
+{
+ HeapCTypeWithBasesSlotNone_slots[0].pfunc = Py_None;
+ return PyType_FromSpec(&HeapCTypeWithBasesSlotNone_spec);
+}
+
static PyMethodDef TestMethods[] = {
{"pytype_fromspec_meta", pytype_fromspec_meta, METH_O},
@@ -562,6 +581,8 @@ static PyMethodDef TestMethods[] = {
{"pytype_getbasebytoken", pytype_getbasebytoken, METH_VARARGS},
{"pytype_getmodulebydef", pytype_getmodulebydef, METH_O},
{"pytype_getmodulebytoken", pytype_getmodulebytoken, METH_VARARGS},
+ {"create_heapctype_with_none_bases_slot",
+ create_heapctype_with_none_bases_slot, METH_NOARGS},
{NULL},
};
@@ -892,6 +913,18 @@ static PyType_Spec HeapCTypeMetaclassNullNew_spec = {
.slots = empty_type_slots
};
+static PyType_Slot HeapCTypeWithBasesSlot_slots[] = {
+ {Py_tp_bases, NULL}, /* filled out in module init function */
+ {0, 0},
+};
+
+static PyType_Spec HeapCTypeWithBasesSlot_spec = {
+ .name = "_testcapi.HeapCTypeWithBasesSlot",
+ .basicsize = sizeof(PyLongObject),
+ .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ .slots = HeapCTypeWithBasesSlot_slots
+};
+
typedef struct {
PyObject_HEAD
@@ -1432,6 +1465,18 @@ _PyTestCapi_Init_Heaptype(PyObject *m) {
&PyType_Type, m, &HeapCTypeMetaclassNullNew_spec, (PyObject *)
&PyType_Type);
ADD("HeapCTypeMetaclassNullNew", HeapCTypeMetaclassNullNew);
+ PyObject *bases = PyTuple_Pack(1, &PyLong_Type);
+ if (bases == NULL) {
+ return -1;
+ }
+ HeapCTypeWithBasesSlot_slots[0].pfunc = bases;
+ PyObject *HeapCTypeWithBasesSlot =
PyType_FromSpec(&HeapCTypeWithBasesSlot_spec);
+ Py_DECREF(bases);
+ if (HeapCTypeWithBasesSlot == NULL) {
+ return -1;
+ }
+ ADD("HeapCTypeWithBasesSlot", HeapCTypeWithBasesSlot);
+
ADD("Py_TP_USE_SPEC", PyLong_FromVoidPtr(Py_TP_USE_SPEC));
PyObject *HeapCCollection = PyType_FromMetaclass(
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]