Skip to content

Commit c304680

Browse files
committed
gh-122728: Fix SystemError in PyEval_GetLocals()
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().
1 parent fbfab4f commit c304680

File tree

4 files changed

+20
-1
lines changed

4 files changed

+20
-1
lines changed

Lib/test/test_capi/test_misc.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,16 @@ def genf(): yield
11571157
gen = genf()
11581158
self.assertEqual(_testcapi.gen_get_code(gen), gen.gi_code)
11591159

1160+
def test_pyeval_getlocals(self):
1161+
# Test PyEval_GetLocals()
1162+
x = 1
1163+
y = 2
1164+
local_vars = _testcapi.pyeval_getlocals()
1165+
self.assertEqual(local_vars,
1166+
{'self': self,
1167+
'x': 1,
1168+
'y': 2})
1169+
11601170

11611171
@requires_limited_api
11621172
class TestHeapTypeRelative(unittest.TestCase):
Lines changed: 2 additions & 0 deletions
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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3341,6 +3341,12 @@ test_critical_sections(PyObject *module, PyObject *Py_UNUSED(args))
33413341
Py_RETURN_NONE;
33423342
}
33433343

3344+
static PyObject *
3345+
pyeval_getlocals(PyObject *module, PyObject *Py_UNUSED(args))
3346+
{
3347+
return Py_XNewRef(PyEval_GetLocals());
3348+
}
3349+
33443350
static PyMethodDef TestMethods[] = {
33453351
{"set_errno", set_errno, METH_VARARGS},
33463352
{"test_config", test_config, METH_NOARGS},
@@ -3483,6 +3489,7 @@ static PyMethodDef TestMethods[] = {
34833489
{"test_weakref_capi", test_weakref_capi, METH_NOARGS},
34843490
{"function_set_warning", function_set_warning, METH_NOARGS},
34853491
{"test_critical_sections", test_critical_sections, METH_NOARGS},
3492+
{"pyeval_getlocals", pyeval_getlocals, METH_NOARGS},
34863493
{NULL, NULL} /* sentinel */
34873494
};
34883495

Python/ceval.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2499,7 +2499,7 @@ PyEval_GetLocals(void)
24992499
PyFrameObject *f = _PyFrame_GetFrameObject(current_frame);
25002500
PyObject *ret = f->f_locals_cache;
25012501
if (ret == NULL) {
2502-
PyObject *ret = PyDict_New();
2502+
ret = PyDict_New();
25032503
if (ret == NULL) {
25042504
Py_DECREF(locals);
25052505
return NULL;

0 commit comments

Comments
 (0)