From cee09fedbf2a29067e3e4975dcbec29fb79bfc34 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Fri, 10 May 2024 15:53:10 -0700 Subject: [PATCH] gh-118921: Add `copy()` method for `FrameLocalsProxy` (GH-118923) (cherry picked from commit 35c436186b849f8f2f9fb866c59015c9d034d448) Co-authored-by: Tian Gao --- Lib/test/test_frame.py | 12 +++++++++--- ...-05-10-19-54-18.gh-issue-118921.O4ztZG.rst | 1 + Objects/frameobject.c | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-10-19-54-18.gh-issue-118921.O4ztZG.rst diff --git a/Lib/test/test_frame.py b/Lib/test/test_frame.py index 212255374bddd1..aee8d374b22710 100644 --- a/Lib/test/test_frame.py +++ b/Lib/test/test_frame.py @@ -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 @@ -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) 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 00000000000000..39ccf472067cfd --- /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 d7fcb1925d286c..64fded85de1468 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -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)) { @@ -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, pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy