gh-74929: Implement PEP 667 by gaogaotiantian · Pull Request #115153 · python/cpython (original) (raw)
Okay I resolved most of the comments, and I believe there's one thing left here - comprehensions.
I'm just going to jump to my proposal and see if that makes sense. If not, we can discuss it more.
import sys def f(): x = 1 [print(sys._getframe().f_locals) for a in [0]] print([sys._getframe().f_locals for a in [0]][0]) print(sys._getframe().f_locals) f()
will print
# Inside comprehension, show hidden variable a and locals in the outside frame
{'x': 1, 'a': 0}
# f_locals from inside but read outside, no hidden variable, only locals.
# This does not match the fiction because the variable should "exist" if it's a frame, but in reality it's gone
{'x': 1}
# f_locals outside, just local variables
{'x': 1}
Notice all the values above are proxies.
import sys class C: x = 1 [print(sys._getframe().f_locals) for a in [0]] print([sys._getframe().f_locals for a in [0]][0]) print(sys._getframe().f_locals)
will print (ignore __module__
and __qualname__
)
# This is a proxy without class-level variable
{'a': 0}
# Empty proxy
{}
# A dict with class level variable
{'x': 1}
An alternative would be:
# A dict, but you can't write to variable a to change the local value
{'a': 0, 'x': 1}
# A dict
{'x': 1}
# Still a dict
{'x': 1}
The latter seems more consistent with the function level result, and it makes locals()
backwards compatible, but it creates a horrible exemption where the f_locals
is not "write through".
Maybe we could stick to a simple rule here - f_locals
will always return something that's write through. locals()
always return dict(proxy)
or the dict itself (in class/module level, outside of the comprehension).
However, this will break the backwards compatibility for locals()
in comprehension in class/module level.