https://github.com/python/cpython/commit/4767a6e31c0550836b2af45d27e374e721f0c4e6
commit: 4767a6e31c0550836b2af45d27e374e721f0c4e6
branch: main
author: Victor Stinner <[email protected]>
committer: vstinner <[email protected]>
date: 2024-08-06T23:01:44+02:00
summary:

gh-122728: Fix SystemError in PyEval_GetLocals() (#122735)

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().

files:
A Misc/NEWS.d/next/C_API/2024-08-06-14-23-11.gh-issue-122728.l-fQ-v.rst
M Lib/test/test_capi/test_misc.py
M Modules/_testcapimodule.c
M Python/ceval.c

diff --git a/Lib/test/test_capi/test_misc.py b/Lib/test/test_capi/test_misc.py
index 5c4547da1bdc53..be6fe0c1fb43de 100644
--- a/Lib/test/test_capi/test_misc.py
+++ b/Lib/test/test_capi/test_misc.py
@@ -1157,6 +1157,19 @@ def genf(): yield
         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
index 00000000000000..a128d6aef34dfc
--- /dev/null
+++ b/Misc/NEWS.d/next/C_API/2024-08-06-14-23-11.gh-issue-122728.l-fQ-v.rst
@@ -0,0 +1,2 @@
+Fix :c:func:`PyEval_GetLocals` to avoid :exc:`SystemError` ("bad argument to
+internal function"). Patch by Victor Stinner.
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 4a371a5ce33ebe..05deb0549fa637 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -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 */
 };
 
diff --git a/Python/ceval.c b/Python/ceval.c
index f1663ee539aeac..c685a95b2ef088 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -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;

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to