Skip to content

Commit 5c161cb

Browse files
[3.13] gh-122728: Fix SystemError in PyEval_GetLocals() (GH-122735) (#122757)
gh-122728: Fix SystemError in PyEval_GetLocals() (GH-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(). (cherry picked from commit 4767a6e) Co-authored-by: Victor Stinner <[email protected]>
1 parent e808146 commit 5c161cb

File tree

4 files changed

+23
-1
lines changed

4 files changed

+23
-1
lines changed

Lib/test/test_capi/test_misc.py

+13
Original file line numberDiff line numberDiff line change
@@ -1180,6 +1180,19 @@ def genf(): yield
11801180
gen = genf()
11811181
self.assertEqual(_testcapi.gen_get_code(gen), gen.gi_code)
11821182

1183+
def test_pyeval_getlocals(self):
1184+
# Test PyEval_GetLocals()
1185+
x = 1
1186+
self.assertEqual(_testcapi.pyeval_getlocals(),
1187+
{'self': self,
1188+
'x': 1})
1189+
1190+
y = 2
1191+
self.assertEqual(_testcapi.pyeval_getlocals(),
1192+
{'self': self,
1193+
'x': 1,
1194+
'y': 2})
1195+
11831196

11841197
@requires_limited_api
11851198
class TestHeapTypeRelative(unittest.TestCase):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix :c:func:`PyEval_GetLocals` to avoid :exc:`SystemError` ("bad argument to
2+
internal function"). Patch by Victor Stinner.

Modules/_testcapimodule.c

+7
Original file line numberDiff line numberDiff line change
@@ -3332,6 +3332,12 @@ test_critical_sections(PyObject *module, PyObject *Py_UNUSED(args))
33323332
Py_RETURN_NONE;
33333333
}
33343334

3335+
static PyObject *
3336+
pyeval_getlocals(PyObject *module, PyObject *Py_UNUSED(args))
3337+
{
3338+
return Py_XNewRef(PyEval_GetLocals());
3339+
}
3340+
33353341
static PyMethodDef TestMethods[] = {
33363342
{"set_errno", set_errno, METH_VARARGS},
33373343
{"test_config", test_config, METH_NOARGS},
@@ -3476,6 +3482,7 @@ static PyMethodDef TestMethods[] = {
34763482
{"test_weakref_capi", test_weakref_capi, METH_NOARGS},
34773483
{"function_set_warning", function_set_warning, METH_NOARGS},
34783484
{"test_critical_sections", test_critical_sections, METH_NOARGS},
3485+
{"pyeval_getlocals", pyeval_getlocals, METH_NOARGS},
34793486
{NULL, NULL} /* sentinel */
34803487
};
34813488

Python/ceval.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -2482,7 +2482,7 @@ PyEval_GetLocals(void)
24822482
PyFrameObject *f = _PyFrame_GetFrameObject(current_frame);
24832483
PyObject *ret = f->f_locals_cache;
24842484
if (ret == NULL) {
2485-
PyObject *ret = PyDict_New();
2485+
ret = PyDict_New();
24862486
if (ret == NULL) {
24872487
Py_DECREF(locals);
24882488
return NULL;

0 commit comments

Comments
 (0)