Skip to content

Commit 6bd5992

Browse files
authored
[3.14] gh-129849: Add tests for Py_tp_bases (GH-143208) (#146225)
(cherry picked from commit 6f8867a)
1 parent 73e74ee commit 6bd5992

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

Lib/test/test_capi/test_misc.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,18 @@ def genf(): yield
915915
gen = genf()
916916
self.assertEqual(_testcapi.gen_get_code(gen), gen.gi_code)
917917

918+
def test_tp_bases_slot(self):
919+
cls = _testcapi.HeapCTypeWithBasesSlot
920+
self.assertEqual(cls.__bases__, (int,))
921+
self.assertEqual(cls.__base__, int)
922+
923+
def test_tp_bases_slot_none(self):
924+
self.assertRaisesRegex(
925+
SystemError,
926+
"Py_tp_bases is not a tuple",
927+
_testcapi.create_heapctype_with_none_bases_slot
928+
)
929+
918930

919931
@requires_limited_api
920932
class TestHeapTypeRelative(unittest.TestCase):

Modules/_testcapi/heaptype.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,24 @@ pytype_getmodulebydef(PyObject *self, PyObject *type)
528528
return Py_XNewRef(mod);
529529
}
530530

531+
static PyType_Slot HeapCTypeWithBasesSlotNone_slots[] = {
532+
{Py_tp_bases, NULL}, /* filled out with Py_None in runtime */
533+
{0, 0},
534+
};
535+
536+
static PyType_Spec HeapCTypeWithBasesSlotNone_spec = {
537+
.name = "_testcapi.HeapCTypeWithBasesSlotNone",
538+
.basicsize = sizeof(PyObject),
539+
.flags = Py_TPFLAGS_DEFAULT,
540+
.slots = HeapCTypeWithBasesSlotNone_slots
541+
};
542+
543+
static PyObject *
544+
create_heapctype_with_none_bases_slot(PyObject *self, PyObject *Py_UNUSED(ignored))
545+
{
546+
HeapCTypeWithBasesSlotNone_slots[0].pfunc = Py_None;
547+
return PyType_FromSpec(&HeapCTypeWithBasesSlotNone_spec);
548+
}
531549

532550
static PyMethodDef TestMethods[] = {
533551
{"pytype_fromspec_meta", pytype_fromspec_meta, METH_O},
@@ -546,6 +564,8 @@ static PyMethodDef TestMethods[] = {
546564
{"get_tp_token", get_tp_token, METH_O},
547565
{"pytype_getbasebytoken", pytype_getbasebytoken, METH_VARARGS},
548566
{"pytype_getmodulebydef", pytype_getmodulebydef, METH_O},
567+
{"create_heapctype_with_none_bases_slot",
568+
create_heapctype_with_none_bases_slot, METH_NOARGS},
549569
{NULL},
550570
};
551571

@@ -879,6 +899,18 @@ static PyType_Spec HeapCTypeMetaclassNullNew_spec = {
879899
.slots = empty_type_slots
880900
};
881901

902+
static PyType_Slot HeapCTypeWithBasesSlot_slots[] = {
903+
{Py_tp_bases, NULL}, /* filled out in module init function */
904+
{0, 0},
905+
};
906+
907+
static PyType_Spec HeapCTypeWithBasesSlot_spec = {
908+
.name = "_testcapi.HeapCTypeWithBasesSlot",
909+
.basicsize = sizeof(PyLongObject),
910+
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
911+
.slots = HeapCTypeWithBasesSlot_slots
912+
};
913+
882914

883915
typedef struct {
884916
PyObject_HEAD
@@ -1419,6 +1451,18 @@ _PyTestCapi_Init_Heaptype(PyObject *m) {
14191451
&PyType_Type, m, &HeapCTypeMetaclassNullNew_spec, (PyObject *) &PyType_Type);
14201452
ADD("HeapCTypeMetaclassNullNew", HeapCTypeMetaclassNullNew);
14211453

1454+
PyObject *bases = PyTuple_Pack(1, &PyLong_Type);
1455+
if (bases == NULL) {
1456+
return -1;
1457+
}
1458+
HeapCTypeWithBasesSlot_slots[0].pfunc = bases;
1459+
PyObject *HeapCTypeWithBasesSlot = PyType_FromSpec(&HeapCTypeWithBasesSlot_spec);
1460+
Py_DECREF(bases);
1461+
if (HeapCTypeWithBasesSlot == NULL) {
1462+
return -1;
1463+
}
1464+
ADD("HeapCTypeWithBasesSlot", HeapCTypeWithBasesSlot);
1465+
14221466
ADD("Py_TP_USE_SPEC", PyLong_FromVoidPtr(Py_TP_USE_SPEC));
14231467

14241468
PyObject *HeapCCollection = PyType_FromMetaclass(

0 commit comments

Comments
 (0)