@@ -3284,6 +3284,66 @@ test_weakref_capi(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
32843284 _Py_COMP_DIAG_POP
32853285}
32863286
3287+ struct simpletracer_data {
3288+ int count ;
3289+ void * addresses [10 ];
3290+ };
3291+
3292+ static int _simpletracer (PyObject * obj , PyRefTracerEvent event , void * data ) {
3293+ struct simpletracer_data * the_data = (struct simpletracer_data * )data ;
3294+ the_data -> count ++ ;
3295+ assert (the_data -> count < 10 );
3296+ the_data -> addresses [the_data -> count ] = obj ;
3297+ return 0 ;
3298+ }
3299+
3300+ static PyObject *
3301+ test_reftracer (PyObject * ob , PyObject * Py_UNUSED (ignored ))
3302+ {
3303+ struct simpletracer_data tracer_data = {0 };
3304+ void * the_data = (void * )& tracer_data ;
3305+ // Install a simple tracer function
3306+ PyRefTracer_SetTracer (_simpletracer , the_data );
3307+
3308+ // Check that the tracer was correctly installed
3309+ void * data ;
3310+ if (PyRefTracer_GetTracer (& data ) != _simpletracer || data != the_data ) {
3311+ PyErr_SetString (PyExc_ValueError , "The reftracer not correctly installed" );
3312+ PyRefTracer_SetTracer (NULL , NULL );
3313+ return NULL ;
3314+ }
3315+ // Create a bunch of objects
3316+
3317+ PyObject * obj = PyList_New (0 );
3318+ if (obj == NULL ) {
3319+ return NULL ;
3320+ }
3321+ PyObject * obj2 = PyDict_New ();
3322+ if (obj2 == NULL ) {
3323+ Py_DECREF (obj );
3324+ return NULL ;
3325+ }
3326+
3327+ // Remove the tracer
3328+ PyRefTracer_SetTracer (NULL , NULL );
3329+
3330+ Py_DECREF (obj );
3331+ Py_DECREF (obj2 );
3332+
3333+ // Check that the tracer was removed
3334+ if (PyRefTracer_GetTracer (& data ) != NULL || data != NULL ) {
3335+ PyErr_SetString (PyExc_ValueError , "The reftracer was not correctly removed" );
3336+ return NULL ;
3337+ }
3338+
3339+ // Check that the objects were traced and are inside the list
3340+ if (tracer_data .count != 2 || tracer_data .addresses [1 ] != obj || tracer_data .addresses [2 ] != obj2 ) {
3341+ PyErr_SetString (PyExc_ValueError , "The objects were not correctly traced" );
3342+ return NULL ;
3343+ }
3344+
3345+ Py_RETURN_NONE ;
3346+ }
32873347
32883348static PyMethodDef TestMethods [] = {
32893349 {"set_errno" , set_errno , METH_VARARGS },
@@ -3320,6 +3380,7 @@ static PyMethodDef TestMethods[] = {
33203380 {"test_get_type_name" , test_get_type_name , METH_NOARGS },
33213381 {"test_get_type_qualname" , test_get_type_qualname , METH_NOARGS },
33223382 {"test_get_type_dict" , test_get_type_dict , METH_NOARGS },
3383+ {"test_reftracer" , test_reftracer , METH_NOARGS },
33233384 {"_test_thread_state" , test_thread_state , METH_VARARGS },
33243385#ifndef MS_WINDOWS
33253386 {"_spawn_pthread_waiter" , spawn_pthread_waiter , METH_NOARGS },
0 commit comments