Skip to content

Commit

Permalink
[3.13] gh-118921: Add copy() method for FrameLocalsProxy (GH-118923
Browse files Browse the repository at this point in the history
…) (#118933)

(cherry picked from commit 35c4361)

Co-authored-by: Tian Gao <gaogaotiantian@hotmail.com>
  • Loading branch information
miss-islington and gaogaotiantian committed May 10, 2024
1 parent 7dc9e92 commit 93ef7aa
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 3 deletions.
12 changes: 9 additions & 3 deletions Lib/test/test_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,15 @@ def test_local_objects(self):
f_locals['o'] = f_locals['k']
self.assertEqual(o, 'a.b.c')

def test_copy(self):
x = 0
d = sys._getframe().f_locals
d_copy = d.copy()
self.assertIsInstance(d_copy, dict)
self.assertEqual(d_copy['x'], 0)
d_copy['x'] = 1
self.assertEqual(x, 0)

def test_update_with_self(self):
def f():
f_locals = sys._getframe().f_locals
Expand Down Expand Up @@ -405,9 +414,6 @@ def test_sizeof(self):
def test_unsupport(self):
x = 1
d = sys._getframe().f_locals
with self.assertRaises(AttributeError):
d.copy()

with self.assertRaises(TypeError):
copy.copy(d)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add ``copy()`` method for ``FrameLocalsProxy`` which returns a snapshot ``dict`` for local variables.
19 changes: 19 additions & 0 deletions Objects/frameobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,23 @@ framelocalsproxy_setdefault(PyObject* self, PyObject *const *args, Py_ssize_t na
return result;
}

static PyObject*
framelocalsproxy_copy(PyObject *self, PyObject *Py_UNUSED(ignored))
{
PyObject* result = PyDict_New();

if (result == NULL) {
return NULL;
}

if (PyDict_Update(result, self) < 0) {
Py_DECREF(result);
return NULL;
}

return result;
}

static PyObject*
framelocalsproxy_reversed(PyObject *self, void *Py_UNUSED(ignored))
{
Expand Down Expand Up @@ -677,6 +694,8 @@ static PyMethodDef framelocalsproxy_methods[] = {
NULL},
{"__reversed__", _PyCFunction_CAST(framelocalsproxy_reversed), METH_NOARGS,
NULL},
{"copy", _PyCFunction_CAST(framelocalsproxy_copy), METH_NOARGS,
NULL},
{"keys", _PyCFunction_CAST(framelocalsproxy_keys), METH_NOARGS,
NULL},
{"values", _PyCFunction_CAST(framelocalsproxy_values), METH_NOARGS,
Expand Down

0 comments on commit 93ef7aa

Please sign in to comment.