diff options
author | Tian Gao <gaogaotiantian@hotmail.com> | 2024-05-10 22:53:10 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-10 22:53:10 (GMT) |
commit | 35c436186b849f8f2f9fb866c59015c9d034d448 (patch) | |
tree | 7546150928886fe4527122625682ecc69dd10835 | |
parent | b88889e9ffd7b2d2bdac75aecbf14e37fd68e337 (diff) | |
download | cpython-35c436186b849f8f2f9fb866c59015c9d034d448.zip cpython-35c436186b849f8f2f9fb866c59015c9d034d448.tar.gz cpython-35c436186b849f8f2f9fb866c59015c9d034d448.tar.bz2 |
gh-118921: Add `copy()` method for `FrameLocalsProxy` (#118923)
-rw-r--r-- | Lib/test/test_frame.py | 12 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2024-05-10-19-54-18.gh-issue-118921.O4ztZG.rst | 1 | ||||
-rw-r--r-- | Objects/frameobject.c | 19 |
3 files changed, 29 insertions, 3 deletions
diff --git a/Lib/test/test_frame.py b/Lib/test/test_frame.py index 2122553..aee8d37 100644 --- a/Lib/test/test_frame.py +++ b/Lib/test/test_frame.py @@ -371,6 +371,15 @@ class TestFrameLocals(unittest.TestCase): 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 @@ -405,9 +414,6 @@ class TestFrameLocals(unittest.TestCase): def test_unsupport(self): x = 1 d = sys._getframe().f_locals - with self.assertRaises(AttributeError): - d.copy() - with self.assertRaises(TypeError): copy.copy(d) diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-10-19-54-18.gh-issue-118921.O4ztZG.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-10-19-54-18.gh-issue-118921.O4ztZG.rst new file mode 100644 index 0000000..39ccf47 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2024-05-10-19-54-18.gh-issue-118921.O4ztZG.rst @@ -0,0 +1 @@ +Add ``copy()`` method for ``FrameLocalsProxy`` which returns a snapshot ``dict`` for local variables. diff --git a/Objects/frameobject.c b/Objects/frameobject.c index d7fcb19..64fded8 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -638,6 +638,23 @@ framelocalsproxy_setdefault(PyObject* self, PyObject *const *args, Py_ssize_t na } 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)) { PyObject *result = framelocalsproxy_keys(self, NULL); @@ -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, |