Skip to content

Commit d513f9e

Browse files
authored
[3.13] gh-129849: Add tests for Py_tp_bases (GH-143208) (#146226)
(cherry picked from commit 6f8867a)
1 parent fa2f9a3 commit d513f9e

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

Lib/test/test_capi/test_misc.py

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

1155+
def test_tp_bases_slot(self):
1156+
cls = _testcapi.HeapCTypeWithBasesSlot
1157+
self.assertEqual(cls.__bases__, (int,))
1158+
self.assertEqual(cls.__base__, int)
1159+
1160+
def test_tp_bases_slot_none(self):
1161+
self.assertRaisesRegex(
1162+
SystemError,
1163+
"Py_tp_bases is not a tuple",
1164+
_testcapi.create_heapctype_with_none_bases_slot
1165+
)
1166+
11551167

11561168
@requires_limited_api
11571169
class TestHeapTypeRelative(unittest.TestCase):

Modules/_testcapi/heaptype.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,26 @@ pyobject_getitemdata(PyObject *self, PyObject *o)
410410
}
411411

412412

413+
static PyType_Slot HeapCTypeWithBasesSlotNone_slots[] = {
414+
{Py_tp_bases, NULL}, /* filled out with Py_None in runtime */
415+
{0, 0},
416+
};
417+
418+
static PyType_Spec HeapCTypeWithBasesSlotNone_spec = {
419+
.name = "_testcapi.HeapCTypeWithBasesSlotNone",
420+
.basicsize = sizeof(PyObject),
421+
.flags = Py_TPFLAGS_DEFAULT,
422+
.slots = HeapCTypeWithBasesSlotNone_slots
423+
};
424+
425+
static PyObject *
426+
create_heapctype_with_none_bases_slot(PyObject *self, PyObject *Py_UNUSED(ignored))
427+
{
428+
HeapCTypeWithBasesSlotNone_slots[0].pfunc = Py_None;
429+
return PyType_FromSpec(&HeapCTypeWithBasesSlotNone_spec);
430+
}
431+
432+
413433
static PyMethodDef TestMethods[] = {
414434
{"pytype_fromspec_meta", pytype_fromspec_meta, METH_O},
415435
{"test_type_from_ephemeral_spec", test_type_from_ephemeral_spec, METH_NOARGS},
@@ -423,6 +443,8 @@ static PyMethodDef TestMethods[] = {
423443
{"make_immutable_type_with_base", make_immutable_type_with_base, METH_O},
424444
{"make_type_with_base", make_type_with_base, METH_O},
425445
{"pyobject_getitemdata", pyobject_getitemdata, METH_O},
446+
{"create_heapctype_with_none_bases_slot",
447+
create_heapctype_with_none_bases_slot, METH_NOARGS},
426448
{NULL},
427449
};
428450

@@ -751,6 +773,18 @@ static PyType_Spec HeapCTypeMetaclassNullNew_spec = {
751773
.slots = empty_type_slots
752774
};
753775

776+
static PyType_Slot HeapCTypeWithBasesSlot_slots[] = {
777+
{Py_tp_bases, NULL}, /* filled out in module init function */
778+
{0, 0},
779+
};
780+
781+
static PyType_Spec HeapCTypeWithBasesSlot_spec = {
782+
.name = "_testcapi.HeapCTypeWithBasesSlot",
783+
.basicsize = sizeof(PyLongObject),
784+
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
785+
.slots = HeapCTypeWithBasesSlot_slots
786+
};
787+
754788

755789
typedef struct {
756790
PyObject_HEAD
@@ -1201,6 +1235,18 @@ _PyTestCapi_Init_Heaptype(PyObject *m) {
12011235
&PyType_Type, m, &HeapCTypeMetaclassNullNew_spec, (PyObject *) &PyType_Type);
12021236
ADD("HeapCTypeMetaclassNullNew", HeapCTypeMetaclassNullNew);
12031237

1238+
PyObject *bases = PyTuple_Pack(1, &PyLong_Type);
1239+
if (bases == NULL) {
1240+
return -1;
1241+
}
1242+
HeapCTypeWithBasesSlot_slots[0].pfunc = bases;
1243+
PyObject *HeapCTypeWithBasesSlot = PyType_FromSpec(&HeapCTypeWithBasesSlot_spec);
1244+
Py_DECREF(bases);
1245+
if (HeapCTypeWithBasesSlot == NULL) {
1246+
return -1;
1247+
}
1248+
ADD("HeapCTypeWithBasesSlot", HeapCTypeWithBasesSlot);
1249+
12041250
PyObject *HeapCCollection = PyType_FromMetaclass(
12051251
NULL, m, &HeapCCollection_spec, NULL);
12061252
if (HeapCCollection == NULL) {

0 commit comments

Comments
 (0)