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()
#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},
{"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 */
};