From 12f4ac3bc848244242d6b8a7ee158b985fd64744 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sun, 23 Jan 2022 00:06:56 +0100 Subject: bpo-46417: Clear symtable identifiers at exit (GH-30809) Add _PySymtable_Fini() function, called by finalize_interp_clear(). Update test_cmd_line.test_showrefcount() to tolerate negative reference count. --- Include/internal/pycore_symtable.h | 2 ++ Lib/test/test_cmd_line.py | 5 ++++- Python/pylifecycle.c | 4 ++++ Python/symtable.c | 17 +++++++++++++++-- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/Include/internal/pycore_symtable.h b/Include/internal/pycore_symtable.h index 28935f4..4ecfab5 100644 --- a/Include/internal/pycore_symtable.h +++ b/Include/internal/pycore_symtable.h @@ -128,6 +128,8 @@ extern struct symtable* _Py_SymtableStringObjectFlags( int start, PyCompilerFlags *flags); +extern void _PySymtable_Fini(void); + #ifdef __cplusplus } #endif diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index 86ee274..fa5f39e 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -119,7 +119,10 @@ class CmdLineTest(unittest.TestCase): rc, out, err = run_python('-X', 'showrefcount', '-c', code) self.assertEqual(out.rstrip(), b"{'showrefcount': True}") if Py_DEBUG: - self.assertRegex(err, br'^\[\d+ refs, \d+ blocks\]') + # bpo-46417: Tolerate negative reference count which can occur + # because of bugs in C extensions. This test is only about checking + # the showrefcount feature. + self.assertRegex(err, br'^\[-?\d+ refs, \d+ blocks\]') else: self.assertEqual(err, b'') diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 92c8ad0..9d10f94 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -23,6 +23,7 @@ #include "pycore_runtime_init.h" // _PyRuntimeState_INIT #include "pycore_sliceobject.h" // _PySlice_Fini() #include "pycore_structseq.h" // _PyStructSequence_InitState() +#include "pycore_symtable.h" // _PySymtable_Fini() #include "pycore_sysmodule.h" // _PySys_ClearAuditHooks() #include "pycore_traceback.h" // _Py_DumpTracebackThreads() #include "pycore_tuple.h" // _PyTuple_InitTypes() @@ -1700,6 +1701,9 @@ finalize_interp_clear(PyThreadState *tstate) int is_main_interp = _Py_IsMainInterpreter(tstate->interp); _PyExc_ClearExceptionGroupType(tstate->interp); + if (is_main_interp) { + _PySymtable_Fini(); + } /* Clear interpreter state and all thread states */ _PyInterpreterState_Clear(tstate); diff --git a/Python/symtable.c b/Python/symtable.c index 01c6ec1..e9bdff3 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -1121,7 +1121,7 @@ static int symtable_add_def(struct symtable *st, PyObject *name, int flag, int lineno, int col_offset, int end_lineno, int end_col_offset) { - return symtable_add_def_helper(st, name, flag, st->st_cur, + return symtable_add_def_helper(st, name, flag, st->st_cur, lineno, col_offset, end_lineno, end_col_offset); } @@ -2134,7 +2134,7 @@ symtable_raise_if_annotation_block(struct symtable *st, const char *name, expr_t static int symtable_raise_if_comprehension_block(struct symtable *st, expr_ty e) { _Py_comprehension_ty type = st->st_cur->ste_comprehension; - PyErr_SetString(PyExc_SyntaxError, + PyErr_SetString(PyExc_SyntaxError, (type == ListComprehension) ? "'yield' inside list comprehension" : (type == SetComprehension) ? "'yield' inside set comprehension" : (type == DictComprehension) ? "'yield' inside dict comprehension" : @@ -2173,3 +2173,16 @@ _Py_SymtableStringObjectFlags(const char *str, PyObject *filename, _PyArena_Free(arena); return st; } + +void +_PySymtable_Fini(void) +{ + Py_CLEAR(top); + Py_CLEAR(lambda); + Py_CLEAR(genexpr); + Py_CLEAR(listcomp); + Py_CLEAR(setcomp); + Py_CLEAR(dictcomp); + Py_CLEAR(__class__); + Py_CLEAR(_annotation); +} -- cgit v0.12