-
-
Notifications
You must be signed in to change notification settings - Fork 33.2k
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)
# FalseAdmittedly, 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