@@ -1277,6 +1277,85 @@ test_long_api(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
12771277}
12781278
12791279
1280+ // --- HeapCTypeWithManagedDict --------------------------------------------
1281+
1282+ // Py_TPFLAGS_MANAGED_DICT was added to Python 3.11.0a3
1283+ #if PY_VERSION_HEX >= 0x030B00A3
1284+ # define TEST_MANAGED_DICT
1285+
1286+ typedef struct {
1287+ PyObject_HEAD
1288+ } HeapCTypeObject ;
1289+
1290+ static int
1291+ heapmanaged_traverse (PyObject * self , visitproc visit , void * arg )
1292+ {
1293+ Py_VISIT (Py_TYPE (self ));
1294+ return PyObject_VisitManagedDict (self , visit , arg );
1295+ }
1296+
1297+ static int
1298+ heapmanaged_clear (PyObject * self )
1299+ {
1300+ PyObject_ClearManagedDict (self );
1301+ return 0 ;
1302+ }
1303+
1304+ static void
1305+ heapmanaged_dealloc (HeapCTypeObject * self )
1306+ {
1307+ PyTypeObject * tp = Py_TYPE (self );
1308+ PyObject_ClearManagedDict ((PyObject * )self );
1309+ PyObject_GC_UnTrack (self );
1310+ PyObject_GC_Del (self );
1311+ Py_DECREF (tp );
1312+ }
1313+
1314+ static PyType_Slot HeapCTypeWithManagedDict_slots [] = {
1315+ {Py_tp_traverse , _Py_CAST (void * , heapmanaged_traverse )},
1316+ {Py_tp_clear , _Py_CAST (void * , heapmanaged_clear )},
1317+ {Py_tp_dealloc , _Py_CAST (void * , heapmanaged_dealloc )},
1318+ {0 , 0 },
1319+ };
1320+
1321+ static PyType_Spec HeapCTypeWithManagedDict_spec = {
1322+ "test_pythoncapi_compat.HeapCTypeWithManagedDict" ,
1323+ sizeof (PyObject ),
1324+ 0 ,
1325+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_MANAGED_DICT ,
1326+ HeapCTypeWithManagedDict_slots
1327+ };
1328+
1329+ static PyObject *
1330+ test_managed_dict (PyObject * Py_UNUSED (module ), PyObject * Py_UNUSED (args ))
1331+ {
1332+ PyObject * type = PyType_FromSpec (& HeapCTypeWithManagedDict_spec );
1333+ if (type == NULL ) {
1334+ return NULL ;
1335+ }
1336+
1337+ PyObject * obj = PyObject_CallNoArgs (type );
1338+ if (obj == NULL ) {
1339+ Py_DECREF (type );
1340+ return NULL ;
1341+ }
1342+
1343+ // call heapmanaged_traverse()
1344+ PyGC_Collect ();
1345+
1346+ // call heapmanaged_clear()
1347+ Py_DECREF (obj );
1348+ PyGC_Collect ();
1349+
1350+ Py_DECREF (type );
1351+ // Just in case!
1352+ PyGC_Collect ();
1353+
1354+ Py_RETURN_NONE ;
1355+ }
1356+ #endif // PY_VERSION_HEX >= 0x030B00A3
1357+
1358+
12801359static struct PyMethodDef methods [] = {
12811360 {"test_object" , test_object , METH_NOARGS , _Py_NULL },
12821361 {"test_py_is" , test_py_is , METH_NOARGS , _Py_NULL },
@@ -1303,6 +1382,9 @@ static struct PyMethodDef methods[] = {
13031382 {"test_getitem" , test_getitem , METH_NOARGS , _Py_NULL },
13041383 {"test_dict_api" , test_dict_api , METH_NOARGS , _Py_NULL },
13051384 {"test_long_api" , test_long_api , METH_NOARGS , _Py_NULL },
1385+ #ifdef TEST_MANAGED_DICT
1386+ {"test_managed_dict" , test_managed_dict , METH_NOARGS , _Py_NULL },
1387+ #endif
13061388 {_Py_NULL , _Py_NULL , 0 , _Py_NULL }
13071389};
13081390
0 commit comments