New submission from Kevin Shweh <kevin.sh...@gmail.com>:
LOAD_NAME and LOAD_GLOBAL don't treat dict subclasses for globals() the same way. If globals() is a dict subclass, LOAD_GLOBAL will respect overridden __getitem__, but LOAD_NAME will use PyDict_GetItem. This causes global lookup to behave differently in class statements; for example, in the following code, the final exec is the only one where print(y) causes a NameError: class Foo(dict): def __getitem__(self, index): return 5 if index == 'y' else super().__getitem__(index) exec('print(y)', Foo()) exec('global y; print(y)', Foo()) exec(''' class UsesLOAD_NAME: global y print(y)''', Foo()) exec(''' class UsesLOAD_NAME: print(y)''', Foo()) STORE_GLOBAL and DELETE_GLOBAL also go straight for PyDict_SetItem and PyDict_DelItem; I don't know whether those should be considered bugs as well, but the inconsistency between LOAD_NAME and LOAD_GLOBAL definitely seems wrong. (For reference, the change that introduced the inconsistency was made for issue #14385, which was intended to support non-dict __builtins__.) ---------- components: Interpreter Core messages: 337356 nosy: Kevin Shweh priority: normal severity: normal status: open title: LOAD_NAME and LOAD_GLOBAL handle dict subclasses for globals() differently type: behavior versions: Python 3.7, Python 3.8 _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue36220> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com