Skip to content

Commit ce7f66b

Browse files
tom-pytelseehwan80
authored andcommitted
pythongh-130382: add missing _PyReftracerTrack to ceval Py_DECREF (python#130689)
1 parent 24796ba commit ce7f66b

File tree

4 files changed

+45
-0
lines changed

4 files changed

+45
-0
lines changed

Lib/test/test_capi/test_misc.py

+17
Original file line numberDiff line numberDiff line change
@@ -2884,5 +2884,22 @@ def test_pack_version_ctypes(self):
28842884
self.assertEqual(result, expected)
28852885

28862886

2887+
class TestCEval(unittest.TestCase):
2888+
def test_ceval_decref(self):
2889+
code = textwrap.dedent("""
2890+
import _testcapi
2891+
_testcapi.toggle_reftrace_printer(True)
2892+
l1 = []
2893+
l2 = []
2894+
del l1
2895+
del l2
2896+
_testcapi.toggle_reftrace_printer(False)
2897+
""")
2898+
_, out, _ = assert_python_ok("-c", code)
2899+
lines = out.decode("utf-8").splitlines()
2900+
self.assertEqual(lines.count("CREATE list"), 2)
2901+
self.assertEqual(lines.count("DESTROY list"), 2)
2902+
2903+
28872904
if __name__ == "__main__":
28882905
unittest.main()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix ``PyRefTracer_DESTROY`` not being sent from :file:`Python/ceval.c` ``Py_DECREF()``.

Modules/_testcapimodule.c

+26
Original file line numberDiff line numberDiff line change
@@ -2515,6 +2515,31 @@ code_offset_to_line(PyObject* self, PyObject* const* args, Py_ssize_t nargsf)
25152515
}
25162516

25172517

2518+
static int
2519+
_reftrace_printer(PyObject *obj, PyRefTracerEvent event, void *counter_data)
2520+
{
2521+
if (event == PyRefTracer_CREATE) {
2522+
printf("CREATE %s\n", Py_TYPE(obj)->tp_name);
2523+
}
2524+
else { // PyRefTracer_DESTROY
2525+
printf("DESTROY %s\n", Py_TYPE(obj)->tp_name);
2526+
}
2527+
return 0;
2528+
}
2529+
2530+
// A simple reftrace printer for very simple tests
2531+
static PyObject *
2532+
toggle_reftrace_printer(PyObject *ob, PyObject *arg)
2533+
{
2534+
if (arg == Py_True) {
2535+
PyRefTracer_SetTracer(_reftrace_printer, NULL);
2536+
}
2537+
else {
2538+
PyRefTracer_SetTracer(NULL, NULL);
2539+
}
2540+
Py_RETURN_NONE;
2541+
}
2542+
25182543
static PyMethodDef TestMethods[] = {
25192544
{"set_errno", set_errno, METH_VARARGS},
25202545
{"test_config", test_config, METH_NOARGS},
@@ -2608,6 +2633,7 @@ static PyMethodDef TestMethods[] = {
26082633
{"finalize_thread_hang", finalize_thread_hang, METH_O, NULL},
26092634
{"test_atexit", test_atexit, METH_NOARGS},
26102635
{"code_offset_to_line", _PyCFunction_CAST(code_offset_to_line), METH_FASTCALL},
2636+
{"toggle_reftrace_printer", toggle_reftrace_printer, METH_O},
26112637
{NULL, NULL} /* sentinel */
26122638
};
26132639

Python/ceval.c

+1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
} \
8181
_Py_DECREF_STAT_INC(); \
8282
if (--op->ob_refcnt == 0) { \
83+
_PyReftracerTrack(op, PyRefTracer_DESTROY); \
8384
destructor dealloc = Py_TYPE(op)->tp_dealloc; \
8485
(*dealloc)(op); \
8586
} \

0 commit comments

Comments
 (0)