8000 GH-120097: Make FrameLocalsProxy a mapping (#120101) · python/cpython@d1c673b · GitHub
[go: up one dir, main page]

Skip to content

Commit d1c673b

Browse files
authored
GH-120097: Make FrameLocalsProxy a mapping (#120101)
* Register FrameLocalsProxy as a subclass of collections.abc.Mapping * Allow FrameLocalsProxy to matching mapping patterns
1 parent 00257c7 commit d1c673b

File tree

4 files changed

+20
-1
lines changed

4 files changed

+20
-1
lines changed

Lib/_collections_abc.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ def _f(): pass
8585
dict_items = type({}.items())
8686
## misc ##
8787
mappingproxy = type(type.__dict__)
88+
def _get_framelocalsproxy():
89+
return type(sys._getframe().f_locals)
90+
framelocalsproxy = _get_framelocalsproxy()
91+
del _get_framelocalsproxy
8892
generator = type((lambda: (yield))())
8993
## coroutine ##
9094
async def _coro(): pass
@@ -836,6 +840,7 @@ def __eq__(self, other):
836840
__reversed__ = None
837841

838842
Mapping.register(mappingproxy)
843+
Mapping.register(framelocalsproxy)
839844

840845

841846
class MappingView(Sized):

Lib/test/test_frame.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
except ImportError:
1212
_testcapi = None
1313

14+
from collections.abc import Mapping
1415
from test import support
1516
from test.support import import_helper, threading_helper
1617
from test.support.script_helper import assert_python_ok
@@ -418,6 +419,17 @@ def test_unsupport(self):
418419
with self.assertRaises(TypeError):
419420
copy.deepcopy(d)
420421

422+
def test_is_mapping(self):
423+
x = 1
424+
d = sys._getframe().f_locals
425+
self.assertIsInstance(d, Mapping)
426+
match d:
427+
case {"x": value}:
428+
self.assertEqual(value, 1)
429+
kind = "mapping"
430+
case _:
431+
kind = "other"
432+
self.assertEqual(kind, "mapping")
421433

422434
class TestFrameCApi(unittest.TestCase):
423435
def test_basic(self):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
``FrameLocalsProxy`` now subclasses ``collections.abc.Mapping`` and can be
2+
matched as a mapping in ``match`` statements

Objects/frameobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ PyTypeObject PyFrameLocalsProxy_Type = {
720720
.tp_as_mapping = &framelocalsproxy_as_mapping,
721721
.tp_getattro = PyObject_GenericGetAttr,
722722
.tp_setattro = PyObject_GenericSetAttr,
723-
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
723+
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_MAPPING,
724724
.tp_traverse = framelocalsproxy_visit,
725725
.tp_clear = framelocalsproxy_tp_clear,
726726
.tp_richcompare = framelocalsproxy_richcompare,

0 commit comments

Comments
 (0)
0