Kevin Shweh <kevin.sh...@gmail.com> added the comment:

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())

----------
nosy: +Kevin Shweh

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue14385>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to