]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-122728: Fix SystemError in PyEval_GetLocals() (#122735)
authorVictor Stinner <vstinner@python.org>
Tue, 6 Aug 2024 21:01:44 +0000 (23:01 +0200)
committerGitHub <noreply@github.com>
Tue, 6 Aug 2024 21:01:44 +0000 (23:01 +0200)
Fix PyEval_GetLocals() to avoid SystemError ("bad argument to
internal function"). Don't redefine the 'ret' variable in the if
block.

Add an unit test on PyEval_GetLocals().

Lib/test/test_capi/test_misc.py
Misc/NEWS.d/next/C_API/2024-08-06-14-23-11.gh-issue-122728.l-fQ-v.rst [new file with mode: 0644]
Modules/_testcapimodule.c
Python/ceval.c

index 5c4547da1bdc53552714bf5d7f8985d860e51cba..be6fe0c1fb43dec595b87f7990cdd92b5fe86034 100644 (file)
@@ -1157,6 +1157,19 @@ class CAPITest(unittest.TestCase):
         gen = genf()
         self.assertEqual(_testcapi.gen_get_code(gen), gen.gi_code)
 
+    def test_pyeval_getlocals(self):
+        # Test PyEval_GetLocals()
+        x = 1
+        self.assertEqual(_testcapi.pyeval_getlocals(),
+            {'self': self,
+             'x': 1})
+
+        y = 2
+        self.assertEqual(_testcapi.pyeval_getlocals(),
+            {'self': self,
+             'x': 1,
+             'y': 2})
+
 
 @requires_limited_api
 class TestHeapTypeRelative(unittest.TestCase):
diff --git a/Misc/NEWS.d/next/C_API/2024-08-06-14-23-11.gh-issue-122728.l-fQ-v.rst b/Misc/NEWS.d/next/C_API/2024-08-06-14-23-11.gh-issue-122728.l-fQ-v.rst
new file mode 100644 (file)
index 0000000..a128d6a
--- /dev/null
@@ -0,0 +1,2 @@
+Fix :c:func:`PyEval_GetLocals` to avoid :exc:`SystemError` ("bad argument to
+internal function"). Patch by Victor Stinner.
index 4a371a5ce33ebeb9d183a76296d8c833e4d81cae..05deb0549fa637f9f81244e60c444881f608de41 100644 (file)
@@ -3341,6 +3341,12 @@ test_critical_sections(PyObject *module, PyObject *Py_UNUSED(args))
     Py_RETURN_NONE;
 }
 
+static PyObject *
+pyeval_getlocals(PyObject *module, PyObject *Py_UNUSED(args))
+{
+    return Py_XNewRef(PyEval_GetLocals());
+}
+
 static PyMethodDef TestMethods[] = {
     {"set_errno",               set_errno,                       METH_VARARGS},
     {"test_config",             test_config,                     METH_NOARGS},
@@ -3483,6 +3489,7 @@ static PyMethodDef TestMethods[] = {
     {"test_weakref_capi", test_weakref_capi, METH_NOARGS},
     {"function_set_warning", function_set_warning, METH_NOARGS},
     {"test_critical_sections", test_critical_sections, METH_NOARGS},
+    {"pyeval_getlocals", pyeval_getlocals, METH_NOARGS},
     {NULL, NULL} /* sentinel */
 };
 
index f1663ee539aeac1c60976315db30f023e629fac5..c685a95b2ef088ff1089fb9e71abf6ad388deab3 100644 (file)
@@ -2499,7 +2499,7 @@ PyEval_GetLocals(void)
         PyFrameObject *f = _PyFrame_GetFrameObject(current_frame);
         PyObject *ret = f->f_locals_cache;
         if (ret == NULL) {
-            PyObject *ret = PyDict_New();
+            ret = PyDict_New();
             if (ret == NULL) {
                 Py_DECREF(locals);
                 return NULL;