Skip to content

Commit 9b5df8b

Browse files
committed
Add test for Py_tp_bases
1 parent 5436289 commit 9b5df8b

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

Lib/test/test_capi/test_misc.py

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

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

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

Modules/_testcapi/heaptype.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,24 @@ pytype_getmodulebytoken(PyObject *self, PyObject *args)
543543
return PyType_GetModuleByToken((PyTypeObject *)type, token);
544544
}
545545

546+
static PyType_Slot HeapCTypeWithBasesSlotInvalid_slots[] = {
547+
{Py_tp_bases, Py_None}, /* Not a tuple - should raise SystemError */
548+
{0, 0},
549+
};
550+
551+
static PyType_Spec HeapCTypeWithBasesSlotInvalid_spec = {
552+
.name = "_testcapi.HeapCTypeWithBasesSlotInvalid",
553+
.basicsize = sizeof(PyObject),
554+
.flags = Py_TPFLAGS_DEFAULT,
555+
.slots = HeapCTypeWithBasesSlotInvalid_slots
556+
};
557+
558+
static PyObject *
559+
create_heapctype_with_invalid_bases_slot(PyObject *self, PyObject *Py_UNUSED(ignored))
560+
{
561+
return PyType_FromSpec(&HeapCTypeWithBasesSlotInvalid_spec);
562+
}
563+
546564

547565
static PyMethodDef TestMethods[] = {
548566
{"pytype_fromspec_meta", pytype_fromspec_meta, METH_O},
@@ -562,6 +580,8 @@ static PyMethodDef TestMethods[] = {
562580
{"pytype_getbasebytoken", pytype_getbasebytoken, METH_VARARGS},
563581
{"pytype_getmodulebydef", pytype_getmodulebydef, METH_O},
564582
{"pytype_getmodulebytoken", pytype_getmodulebytoken, METH_VARARGS},
583+
{"create_heapctype_with_invalid_bases_slot",
584+
create_heapctype_with_invalid_bases_slot, METH_NOARGS},
565585
{NULL},
566586
};
567587

@@ -892,6 +912,18 @@ static PyType_Spec HeapCTypeMetaclassNullNew_spec = {
892912
.slots = empty_type_slots
893913
};
894914

915+
static PyType_Slot HeapCTypeWithBasesSlot_slots[] = {
916+
{Py_tp_bases, NULL}, /* filled out in module init function */
917+
{0, 0},
918+
};
919+
920+
static PyType_Spec HeapCTypeWithBasesSlot_spec = {
921+
.name = "_testcapi.HeapCTypeWithBasesSlot",
922+
.basicsize = sizeof(PyLongObject),
923+
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
924+
.slots = HeapCTypeWithBasesSlot_slots
925+
};
926+
895927

896928
typedef struct {
897929
PyObject_HEAD
@@ -1432,6 +1464,15 @@ _PyTestCapi_Init_Heaptype(PyObject *m) {
14321464
&PyType_Type, m, &HeapCTypeMetaclassNullNew_spec, (PyObject *) &PyType_Type);
14331465
ADD("HeapCTypeMetaclassNullNew", HeapCTypeMetaclassNullNew);
14341466

1467+
PyObject *bases = PyTuple_Pack(1, &PyLong_Type);
1468+
if (bases == NULL) {
1469+
return -1;
1470+
}
1471+
HeapCTypeWithBasesSlot_slots[0].pfunc = bases;
1472+
PyObject *HeapCTypeWithBasesSlot = PyType_FromSpec(&HeapCTypeWithBasesSlot_spec);
1473+
Py_DECREF(bases);
1474+
ADD("HeapCTypeWithBasesSlot", HeapCTypeWithBasesSlot);
1475+
14351476
ADD("Py_TP_USE_SPEC", PyLong_FromVoidPtr(Py_TP_USE_SPEC));
14361477

14371478
PyObject *HeapCCollection = PyType_FromMetaclass(

0 commit comments

Comments
 (0)