Skip to content

Commit

Permalink
pythongh-122728: Fix SystemError in PyEval_GetLocals() (python#122735)
Browse files Browse the repository at this point in the history
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().
  • Loading branch information
vstinner authored Aug 6, 2024
1 parent 5b8a6c5 commit 4767a6e
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 1 deletion.
13 changes: 13 additions & 0 deletions Lib/test/test_capi/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix :c:func:`PyEval_GetLocals` to avoid :exc:`SystemError` ("bad argument to
internal function"). Patch by Victor Stinner.
7 changes: 7 additions & 0 deletions Modules/_testcapimodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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 */
};

Expand Down
2 changes: 1 addition & 1 deletion Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 4767a6e

Please sign in to comment.