]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-46417: Clear symtable identifiers at exit (GH-30809)
authorVictor Stinner <vstinner@python.org>
Sat, 22 Jan 2022 23:06:56 +0000 (00:06 +0100)
committerGitHub <noreply@github.com>
Sat, 22 Jan 2022 23:06:56 +0000 (00:06 +0100)
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
Lib/test/test_cmd_line.py
Python/pylifecycle.c
Python/symtable.c

index 28935f4ed55012aa226783e495067605b102c3b1..4ecfab5585032a820cc5a20a1204931337082298 100644 (file)
@@ -128,6 +128,8 @@ extern struct symtable* _Py_SymtableStringObjectFlags(
     int start,
     PyCompilerFlags *flags);
 
+extern void _PySymtable_Fini(void);
+
 #ifdef __cplusplus
 }
 #endif
index 86ee27485c964217b5a4ff363ad40d4258edfa7d..fa5f39ea5fa972e5524a85ded2909ebcab4d520f 100644 (file)
@@ -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'')
 
index 92c8ad079c5fb1a58391a5c09589026075cc66ec..9d10f94efa732efeef22703dbcf270da8bd32dd1 100644 (file)
@@ -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);
index 01c6ec1318d632c8a199e121560d4c6856aae583..e9bdff3eba10972c1a041ff9d37144b8cbbcfcfb 100644 (file)
@@ -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);
+}