gh-118921: Add `copy()` method for `FrameLocalsProxy` (#118923)

This commit is contained in:
Tian Gao 2024-05-10 15:53:10 -07:00 committed by GitHub
parent b88889e9ff
commit 35c436186b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 29 additions and 3 deletions

View File

@ -371,6 +371,15 @@ class TestFrameLocals(unittest.TestCase):
f_locals['o'] = f_locals['k'] f_locals['o'] = f_locals['k']
self.assertEqual(o, 'a.b.c') 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 test_update_with_self(self):
def f(): def f():
f_locals = sys._getframe().f_locals f_locals = sys._getframe().f_locals
@ -405,9 +414,6 @@ class TestFrameLocals(unittest.TestCase):
def test_unsupport(self): def test_unsupport(self):
x = 1 x = 1
d = sys._getframe().f_locals d = sys._getframe().f_locals
with self.assertRaises(AttributeError):
d.copy()
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
copy.copy(d) copy.copy(d)

View File

@ -0,0 +1 @@
Add ``copy()`` method for ``FrameLocalsProxy`` which returns a snapshot ``dict`` for local variables.

View File

@ -637,6 +637,23 @@ framelocalsproxy_setdefault(PyObject* self, PyObject *const *args, Py_ssize_t na
return result; 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* static PyObject*
framelocalsproxy_reversed(PyObject *self, void *Py_UNUSED(ignored)) framelocalsproxy_reversed(PyObject *self, void *Py_UNUSED(ignored))
{ {
@ -677,6 +694,8 @@ static PyMethodDef framelocalsproxy_methods[] = {
NULL}, NULL},
{"__reversed__", _PyCFunction_CAST(framelocalsproxy_reversed), METH_NOARGS, {"__reversed__", _PyCFunction_CAST(framelocalsproxy_reversed), METH_NOARGS,
NULL}, NULL},
{"copy", _PyCFunction_CAST(framelocalsproxy_copy), METH_NOARGS,
NULL},
{"keys", _PyCFunction_CAST(framelocalsproxy_keys), METH_NOARGS, {"keys", _PyCFunction_CAST(framelocalsproxy_keys), METH_NOARGS,
NULL}, NULL},
{"values", _PyCFunction_CAST(framelocalsproxy_values), METH_NOARGS, {"values", _PyCFunction_CAST(framelocalsproxy_values), METH_NOARGS,