@@ -3363,7 +3363,7 @@ test_gc_visit_objects_basic(PyObject *Py_UNUSED(self),
3363
3363
}
3364
3364
state .target = obj ;
3365
3365
state .found = 0 ;
3366
-
3366
+
3367
3367
PyUnstable_GC_VisitObjects (gc_visit_callback_basic , & state );
3368
3368
Py_DECREF (obj );
3369
3369
if (!state .found ) {
@@ -3400,6 +3400,98 @@ test_gc_visit_objects_exit_early(PyObject *Py_UNUSED(self),
3400
3400
Py_RETURN_NONE ;
3401
3401
}
3402
3402
3403
+ typedef struct {
3404
+ PyObject_HEAD
3405
+ } ObjExtraData ;
3406
+
3407
+ static PyObject *
3408
+ obj_extra_data_new (PyTypeObject * type , PyObject * args , PyObject * kwds )
3409
+ {
3410
+ size_t extra_size = sizeof (PyObject * );
3411
+ PyObject * obj = PyUnstable_Object_GC_NewWithExtraData (type , extra_size );
3412
+ if (obj == NULL ) {
3413
+ return PyErr_NoMemory ();
3414
+ }
3415
+ PyObject_GC_Track (obj );
3416
+ return obj ;
3417
+ }
3418
+
3419
+ static PyObject * *
3420
+ obj_extra_data_get_extra_storage (PyObject * self )
3421
+ {
3422
+ return (PyObject * * )((char * )self + Py_TYPE (self )-> tp_basicsize );
3423
+ }
3424
+
3425
+ static PyObject *
3426
+ obj_extra_data_get (PyObject * self , void * Py_UNUSED (ignored ))
3427
+ {
3428
+ PyObject * * extra_storage = obj_extra_data_get_extra_storage (self );
3429
+ PyObject * value = * extra_storage ;
3430
+ if (!value ) {
3431
+ Py_RETURN_NONE ;
3432
+ }
3433
+ return Py_NewRef (value );
3434
+ }
3435
+
3436
+ static int
3437
+ obj_extra_data_set (PyObject * self , PyObject * newval , void * Py_UNUSED (ignored ))
3438
+ {
3439
+ PyObject * * extra_storage = obj_extra_data_get_extra_storage (self );
3440
+ Py_CLEAR (* extra_storage );
3441
+ if (newval ) {
3442
+ * extra_storage = Py_NewRef (newval );
3443
+ }
3444
+ return 0 ;
3445
+ }
3446
+
3447
+ static PyGetSetDef obj_extra_data_getset [] = {
3448
+ {"extra" , (getter )obj_extra_data_get , (setter )obj_extra_data_set , NULL },
3449
+ {NULL }
3450
+ };
3451
+
3452
+ static int
3453
+ obj_extra_data_traverse (PyObject * self , visitproc visit , void * arg )
3454
+ {
3455
+ PyObject * * extra_storage = obj_extra_data_get_extra_storage (self );
3456
+ PyObject * value = * extra_storage ;
3457
+ Py_VISIT (value );
3458
+ return 0 ;
3459
+ }
3460
+
3461
+ static int
3462
+ obj_extra_data_clear (PyObject * self )
3463
+ {
3464
+ PyObject * * extra_storage = obj_extra_data_get_extra_storage (self );
3465
+ Py_CLEAR (* extra_storage );
3466
+ return 0 ;
3467
+ }
3468
+
3469
+ static void
3470
+ obj_extra_data_dealloc (PyObject * self )
3471
+ {
3472
+ PyTypeObject * tp = Py_TYPE (self );
3473
+ PyObject_GC_UnTrack (self );
3474
+ obj_extra_data_clear (self );
3475
+ tp -> tp_free (self );
3476
+ Py_DECREF (tp );
3477
+ }
3478
+
3479
+ static PyType_Slot ObjExtraData_Slots [] = {
3480
+ {Py_tp_getset , obj_extra_data_getset },
3481
+ {Py_tp_dealloc , obj_extra_data_dealloc },
3482
+ {Py_tp_traverse , obj_extra_data_traverse },
3483
+ {Py_tp_clear , obj_extra_data_clear },
3484
+ {Py_tp_new , obj_extra_data_new },
3485
+ {Py_tp_free , PyObject_GC_Del },
3486
+ {0 , NULL },
3487
+ };
3488
+
3489
+ static PyType_Spec ObjExtraData_TypeSpec = {
3490
+ .name = "_testcapi.ObjExtraData" ,
3491
+ .basicsize = sizeof (ObjExtraData ),
3492
+ .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC ,
3493
+ .slots = ObjExtraData_Slots ,
3494
+ };
3403
3495
3404
3496
struct atexit_data {
3405
3497
int called ;
@@ -4124,6 +4216,17 @@ PyInit__testcapi(void)
4124
4216
Py_INCREF (& MethStatic_Type );
4125
4217
PyModule_AddObject (m , "MethStatic" , (PyObject * )& MethStatic_Type );
4126
4218
4219
+ PyObject * ObjExtraData_Type = PyType_FromModuleAndSpec (
4220
+ m , & ObjExtraData_TypeSpec , NULL );
4221
+ if (ObjExtraData_Type == 0 ) {
4222
+ return NULL ;
4223
+ }
4224
+ int ret = PyModule_AddType (m , (PyTypeObject * )ObjExtraData_Type );
4225
+ Py_DECREF (& ObjExtraData_Type );
4226
+ if (ret < 0 ) {
4227
+ return NULL ;
4228
+ }
4229
+
4127
4230
PyModule_AddObject (m , "CHAR_MAX" , PyLong_FromLong (CHAR_MAX ));
4128
4231
PyModule_AddObject (m , "CHAR_MIN" , PyLong_FromLong (CHAR_MIN ));
4129
4232
PyModule_AddObject (m , "UCHAR_MAX" , PyLong_FromLong (UCHAR_MAX ));
0 commit comments