[3.13] gh-130382: add missing _PyReftracerTrack to ceval Py_DECREF (GH-130689) (#131195)

(cherry picked from commit c5abded099)

Co-authored-by: Tomasz Pytel <tompytel@gmail.com>
This commit is contained in:
Sam Gross 2025-03-14 09:52:05 -04:00 committed by GitHub
parent 130fa4c94f
commit 5646f6f739
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 45 additions and 0 deletions

View file

@ -3186,5 +3186,22 @@ def run(self):
py_thread_ids)
class TestCEval(unittest.TestCase):
def test_ceval_decref(self):
code = textwrap.dedent("""
import _testcapi
_testcapi.toggle_reftrace_printer(True)
l1 = []
l2 = []
del l1
del l2
_testcapi.toggle_reftrace_printer(False)
""")
_, out, _ = assert_python_ok("-c", code)
lines = out.decode("utf-8").splitlines()
self.assertEqual(lines.count("CREATE list"), 2)
self.assertEqual(lines.count("DESTROY list"), 2)
if __name__ == "__main__":
unittest.main()

View file

@ -0,0 +1 @@
Fix ``PyRefTracer_DESTROY`` not being sent from :file:`Python/ceval.c` ``Py_DECREF()``.

View file

@ -3421,6 +3421,31 @@ tracemalloc_track_race(PyObject *self, PyObject *args)
#undef NTHREAD
}
static int
_reftrace_printer(PyObject *obj, PyRefTracerEvent event, void *counter_data)
{
if (event == PyRefTracer_CREATE) {
printf("CREATE %s\n", Py_TYPE(obj)->tp_name);
}
else { // PyRefTracer_DESTROY
printf("DESTROY %s\n", Py_TYPE(obj)->tp_name);
}
return 0;
}
// A simple reftrace printer for very simple tests
static PyObject *
toggle_reftrace_printer(PyObject *ob, PyObject *arg)
{
if (arg == Py_True) {
PyRefTracer_SetTracer(_reftrace_printer, NULL);
}
else {
PyRefTracer_SetTracer(NULL, NULL);
}
Py_RETURN_NONE;
}
static PyMethodDef TestMethods[] = {
{"set_errno", set_errno, METH_VARARGS},
{"test_config", test_config, METH_NOARGS},
@ -3564,6 +3589,7 @@ static PyMethodDef TestMethods[] = {
{"test_critical_sections", test_critical_sections, METH_NOARGS},
{"test_atexit", test_atexit, METH_NOARGS},
{"tracemalloc_track_race", tracemalloc_track_race, METH_NOARGS},
{"toggle_reftrace_printer", toggle_reftrace_printer, METH_O},
{NULL, NULL} /* sentinel */
};

View file

@ -70,6 +70,7 @@
} \
_Py_DECREF_STAT_INC(); \
if (--op->ob_refcnt == 0) { \
_PyReftracerTrack(op, PyRefTracer_DESTROY); \
destructor dealloc = Py_TYPE(op)->tp_dealloc; \
(*dealloc)(op); \
} \