Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 93ef7aa

Browse filesBrowse files
[3.13] gh-118921: Add copy() method for FrameLocalsProxy (GH-118923) (#118933)
(cherry picked from commit 35c4361) Co-authored-by: Tian Gao <gaogaotiantian@hotmail.com>
1 parent 7dc9e92 commit 93ef7aa
Copy full SHA for 93ef7aa

File tree

3 files changed

+29
-3
lines changed
Filter options

3 files changed

+29
-3
lines changed

‎Lib/test/test_frame.py

Copy file name to clipboardExpand all lines: Lib/test/test_frame.py
+9-3Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,15 @@ def test_local_objects(self):
371371
f_locals['o'] = f_locals['k']
372372
self.assertEqual(o, 'a.b.c')
373373

374+
def test_copy(self):
375+
x = 0
376+
d = sys._getframe().f_locals
377+
d_copy = d.copy()
378+
self.assertIsInstance(d_copy, dict)
379+
self.assertEqual(d_copy['x'], 0)
380+
d_copy['x'] = 1
381+
self.assertEqual(x, 0)
382+
374383
def test_update_with_self(self):
375384
def f():
376385
f_locals = sys._getframe().f_locals
@@ -405,9 +414,6 @@ def test_sizeof(self):
405414
def test_unsupport(self):
406415
x = 1
407416
d = sys._getframe().f_locals
408-
with self.assertRaises(AttributeError):
409-
d.copy()
410-
411417
with self.assertRaises(TypeError):
412418
copy.copy(d)
413419

+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add ``copy()`` method for ``FrameLocalsProxy`` which returns a snapshot ``dict`` for local variables.

‎Objects/frameobject.c

Copy file name to clipboardExpand all lines: Objects/frameobject.c
+19Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,23 @@ framelocalsproxy_setdefault(PyObject* self, PyObject *const *args, Py_ssize_t na
637637
return result;
638638
}
639639

640+
static PyObject*
641+
framelocalsproxy_copy(PyObject *self, PyObject *Py_UNUSED(ignored))
642+
{
643+
PyObject* result = PyDict_New();
644+
645+
if (result == NULL) {
646+
return NULL;
647+
}
648+
649+
if (PyDict_Update(result, self) < 0) {
650+
Py_DECREF(result);
651+
return NULL;
652+
}
653+
654+
return result;
655+
}
656+
640657
static PyObject*
641658
framelocalsproxy_reversed(PyObject *self, void *Py_UNUSED(ignored))
642659
{
@@ -677,6 +694,8 @@ static PyMethodDef framelocalsproxy_methods[] = {
677694
NULL},
678695
{"__reversed__", _PyCFunction_CAST(framelocalsproxy_reversed), METH_NOARGS,
679696
NULL},
697+
{"copy", _PyCFunction_CAST(framelocalsproxy_copy), METH_NOARGS,
698+
NULL},
680699
{"keys", _PyCFunction_CAST(framelocalsproxy_keys), METH_NOARGS,
681700
NULL},
682701
{"values", _PyCFunction_CAST(framelocalsproxy_values), METH_NOARGS,

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.