-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
Description
Bug report
Update
Turns out it is correctly registered as a subclass of Mapping of Python 3.13.2 (at least) - which was the original report - but then it should be exposed in types
.
Bug description:
Although the FrameLocalsProxy object created when retrieving the .f_locals
attribute
from a frame is a complete mutable mapping, and created so it could be a drop-in,
backwards compatible replacement for the plain dict that was retrieved from
there prior to Python 3.13, it can't be tested as a Mapping in either
dynamic or static checking.
In practical terms, if I have a function that will support receiving a mapping, and into which I would pass a FrameLocalsProxy, static checkers would fail.
this is testable on the repl:
import sys
from collections.abc import Mapping, MutableMapping
FrameLocalsProxy = (lambda: type(sys._getframe().f_locals)()
def gen():
yield
running_gen = gen()
next(running_gen)
f_locals = running_gen.gi_frame.f_locals
isinstance(f_locals, FrameLocalsProxy)
# True
isinstance(f_locals, Mapping)
# False
isinstance(f_locals, MutableMapping)
# False
Admittedly, it can't conform with MutableMapping
since it doesn't make sense to try to delete items from such a proxy - although values can be replaced and added. In accord, it lacks clear
and popitem
methods -
Therefore one trying to accurately trying to static type a method that could receive a FrameLocalsProxy one intends to modify will have to resort to protocols. But that doesn't need to be the case for Mapping
, since it is fully conformant.
Also, otherwise code which wants to test in runtime if an object is a mapping should be able to know that with an isinstance check.
I am willing to contribute this change if it is judged correct.
CPython versions tested on:
3.13
Operating systems tested on:
Linux