R
Robert Lehmann
Hi all,
I have noticed there is a slight asymmetry in the way the interpreter
(v3.3.5, reproduced also in v3.5.x) loads and stores globals. While
loading globals from a custom mapping triggers __getitem__ just fine,
writing seems to silently ignore __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__
exec(fun.__code__, Namespace())
# => getitem x
I would have expected "setitem y 1" to show up as well, but to no avail.
Am I doing something wrong? Is this on purpose?
Cheers,
Robert
PS. I found a 3.3.x commit (e3ab8aa
<http://hg.python.org/cpython/rev/e3ab8aa0216c>) which fixed the
LOAD_GLOBAL opcode to support other types than dict, but STORE_GLOBAL seems
to use bare PyDict_SetItem instead of dispatching to PyObject_SetItem.
I have noticed there is a slight asymmetry in the way the interpreter
(v3.3.5, reproduced also in v3.5.x) loads and stores globals. While
loading globals from a custom mapping triggers __getitem__ just fine,
writing seems to silently ignore __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__
exec(fun.__code__, Namespace())
# => getitem x
I would have expected "setitem y 1" to show up as well, but to no avail.
Am I doing something wrong? Is this on purpose?
Cheers,
Robert
PS. I found a 3.3.x commit (e3ab8aa
<http://hg.python.org/cpython/rev/e3ab8aa0216c>) which fixed the
LOAD_GLOBAL opcode to support other types than dict, but STORE_GLOBAL seems
to use bare PyDict_SetItem instead of dispatching to PyObject_SetItem.