Message337245
The patch for this issue changed LOAD_GLOBAL to use PyObject_GetItem when globals() is a dict subclass, but LOAD_NAME, STORE_GLOBAL, and DELETE_GLOBAL weren't changed. (LOAD_NAME uses PyObject_GetItem for builtins now, but not for globals.)
This means that global lookup doesn't respect overridden __getitem__ inside a class statement (unless you explicitly declare the name global with a global statement, in which case LOAD_GLOBAL gets used instead of LOAD_NAME).
I don't have a strong opinion on whether STORE_GLOBAL or DELETE_GLOBAL should respect overridden __setitem__ or __delitem__, but the inconsistency between LOAD_GLOBAL and LOAD_NAME seems like a bug that should be fixed.
For reference, in the following code, the first 3 exec calls successfully print 5, and the last exec call fails, due to the LOAD_GLOBAL/LOAD_NAME inconsistency:
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()) |
|
Date |
User |
Action |
Args |
2019-03-05 23:54:37 | Kevin Shweh | set | recipients:
+ Kevin Shweh, mjpieters, pitrou, vstinner, python-dev |
2019-03-05 23:54:37 | Kevin Shweh | set | messageid: <1551830077.25.0.967210781904.issue14385@roundup.psfhosted.org> |
2019-03-05 23:54:37 | Kevin Shweh | link | issue14385 messages |
2019-03-05 23:54:37 | Kevin Shweh | create | |
|