Robert Lehmann
2014-06-18 11:25:50 UTC
[resending w/o Google Groups
<https://groups.google.com/d/msg/python-ideas/PRLbe6ERtx4/0fXq3lI6TjgJ>]
I'm not sure if this is a beaten horse; I could only find vaguely related
discussions on other scoping issues (so please, by all means, point me to
past discussions of what I propose.)
The interpreter currently supports setting a custom type for globals() and
overriding __getitem__. The same is not true for __setitem__:
class Namespace(dict):
def __getitem__(self, key):
print("getitem", key)
def __setitem__(self, key, value):
print("setitem", key, value)
def fun():
global x, y
x # should call globals.__getitem__
y = 1 # should call globals.__setitem__
dis.dis(fun)
# 3 0 LOAD_GLOBAL 0 (x)
# 3 POP_TOP
#
# 4 4 LOAD_CONST 1 (1)
# 7 STORE_GLOBAL 1 (y)
# 10 LOAD_CONST 0 (None)
# 13 RETURN_VALUE
exec(fun.__code__, Namespace())
# => getitem x
# no setitem :-(
I think it is weird why reading global variables goes through the usual
magic methods just fine, while writing does not. The behaviour seems to
have been introduced in Python 3.3.x (commit e3ab8aa
<http://hg.python.org/cpython/rev/e3ab8aa0216c>) to support custom
__builtins__. The documentation is fuzzy on this issue:
If only globals is provided, it must be a dictionary, which will be used
<https://groups.google.com/d/msg/comp.lang.python/lqnYwf3-Pjw/EiaBJO5H3T0J>
were at odds if this was a bug, unspecified/unsupported behaviour, or a
deliberate design decision. If it is just unsupported, I don't think the
asymmetry makes it any better. If it is deliberate, I don't understand why
dispatching on the dictness of globals (PyDict_CheckExact(f_globals)) is
good enough for LOAD_GLOBAL, but not for STORE_GLOBAL in terms of
performance.
I have a patch (+ tests) to the current default branch straightening out
this asymmetry and will happily open a ticket if you think this is indeed a
bug.
Thanks in advance,
Robert
<https://groups.google.com/d/msg/python-ideas/PRLbe6ERtx4/0fXq3lI6TjgJ>]
I'm not sure if this is a beaten horse; I could only find vaguely related
discussions on other scoping issues (so please, by all means, point me to
past discussions of what I propose.)
The interpreter currently supports setting a custom type for globals() and
overriding __getitem__. The same is not true for __setitem__:
class Namespace(dict):
def __getitem__(self, key):
print("getitem", key)
def __setitem__(self, key, value):
print("setitem", key, value)
def fun():
global x, y
x # should call globals.__getitem__
y = 1 # should call globals.__setitem__
dis.dis(fun)
# 3 0 LOAD_GLOBAL 0 (x)
# 3 POP_TOP
#
# 4 4 LOAD_CONST 1 (1)
# 7 STORE_GLOBAL 1 (y)
# 10 LOAD_CONST 0 (None)
# 13 RETURN_VALUE
exec(fun.__code__, Namespace())
# => getitem x
# no setitem :-(
I think it is weird why reading global variables goes through the usual
magic methods just fine, while writing does not. The behaviour seems to
have been introduced in Python 3.3.x (commit e3ab8aa
<http://hg.python.org/cpython/rev/e3ab8aa0216c>) to support custom
__builtins__. The documentation is fuzzy on this issue:
If only globals is provided, it must be a dictionary, which will be used
for both the global and the local variables. If globals and locals are
given, they are used for the global and local variables, respectively. If
provided, locals can be any mapping object.
People at python-listgiven, they are used for the global and local variables, respectively. If
provided, locals can be any mapping object.
<https://groups.google.com/d/msg/comp.lang.python/lqnYwf3-Pjw/EiaBJO5H3T0J>
were at odds if this was a bug, unspecified/unsupported behaviour, or a
deliberate design decision. If it is just unsupported, I don't think the
asymmetry makes it any better. If it is deliberate, I don't understand why
dispatching on the dictness of globals (PyDict_CheckExact(f_globals)) is
good enough for LOAD_GLOBAL, but not for STORE_GLOBAL in terms of
performance.
I have a patch (+ tests) to the current default branch straightening out
this asymmetry and will happily open a ticket if you think this is indeed a
bug.
Thanks in advance,
Robert