diff options
author | Tomasz Pytel <tompytel@gmail.com> | 2025-03-13 16:31:49 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-03-13 16:31:49 (GMT) |
commit | c5abded09995f208b21ebaf012185ca5acb0180b (patch) | |
tree | 2b22375cdd0ce4c5ed704222e1f6028b32076d06 | |
parent | 3a91ee97245639c7c4f8852418157d3fc0ec1a82 (diff) | |
download | cpython-c5abded09995f208b21ebaf012185ca5acb0180b.zip cpython-c5abded09995f208b21ebaf012185ca5acb0180b.tar.gz cpython-c5abded09995f208b21ebaf012185ca5acb0180b.tar.bz2 |
gh-130382: add missing `_PyReftracerTrack` to ceval `Py_DECREF` (#130689)
-rw-r--r-- | Lib/test/test_capi/test_misc.py | 17 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core_and_Builtins/2025-02-28-16-13-02.gh-issue-130382.66VTmy.rst | 1 | ||||
-rw-r--r-- | Modules/_testcapimodule.c | 26 | ||||
-rw-r--r-- | Python/ceval.c | 1 |
4 files changed, 45 insertions, 0 deletions
diff --git a/Lib/test/test_capi/test_misc.py b/Lib/test/test_capi/test_misc.py index 6c4cf5b..2e1e8e7 100644 --- a/Lib/test/test_capi/test_misc.py +++ b/Lib/test/test_capi/test_misc.py @@ -2884,5 +2884,22 @@ class TestVersions(unittest.TestCase): self.assertEqual(result, expected) +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() diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-28-16-13-02.gh-issue-130382.66VTmy.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-28-16-13-02.gh-issue-130382.66VTmy.rst new file mode 100644 index 0000000..8b775c8 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-28-16-13-02.gh-issue-130382.66VTmy.rst @@ -0,0 +1 @@ +Fix ``PyRefTracer_DESTROY`` not being sent from :file:`Python/ceval.c` ``Py_DECREF()``. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 9260c76..409dd02 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -2515,6 +2515,31 @@ code_offset_to_line(PyObject* self, PyObject* const* args, Py_ssize_t nargsf) } +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}, @@ -2608,6 +2633,7 @@ static PyMethodDef TestMethods[] = { {"finalize_thread_hang", finalize_thread_hang, METH_O, NULL}, {"test_atexit", test_atexit, METH_NOARGS}, {"code_offset_to_line", _PyCFunction_CAST(code_offset_to_line), METH_FASTCALL}, + {"toggle_reftrace_printer", toggle_reftrace_printer, METH_O}, {NULL, NULL} /* sentinel */ }; diff --git a/Python/ceval.c b/Python/ceval.c index f9089d7..34f4417 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -80,6 +80,7 @@ } \ _Py_DECREF_STAT_INC(); \ if (--op->ob_refcnt == 0) { \ + _PyReftracerTrack(op, PyRefTracer_DESTROY); \ destructor dealloc = Py_TYPE(op)->tp_dealloc; \ (*dealloc)(op); \ } \ |