This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author Ilya Polyakovskiy
Recipients Ilya Polyakovskiy
Date 2017-11-07.12:49:16
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1510058956.93.0.213398074469.issue31968@psf.upfronthosting.co.za>
In-reply-to
Content
I'm using exec() to run code with globals object inherited from dict. The problem is overloaded __getitem__ doesn't called to load default argument for class methods.
Here the example. Let's assume we create some variable storage for code execution

class Env(dict):
    def __init__(self, external_storage):
        super().__init__()
        self._external_storage = external_storage

    def __setitem__(self, key, value):
        print('__setitem__: {}'.format(key))
        self._external_storage[key] = value

    def __getitem__(self, key):
        print('__getitem__: {}'.format(key))
        return self._external_storage[key]


storage = {}
env = Env(storage)
env['var'] = 2

exec("""
class A:
    def foo(self, x=var):
        print('foo(): {}'.format(x))

a = A()
a.foo()
""", env)

This code will fail with output:
__setitem__: var
Traceback (most recent call last):
  File "inheri-test.py", line 29, in <module>
    """, env)
  File "<string>", line 2, in <module>
  File "<string>", line 3, in A
NameError: name 'var' is not defined


As far as I understand the problem is Python/ceval.c:2120. There is only PyDict_GetItem used to load variable from f_globals, instead of PyObject_GetItem in case of f_globals is not exact dict.
History
Date User Action Args
2017-11-07 12:49:16Ilya Polyakovskiysetrecipients: + Ilya Polyakovskiy
2017-11-07 12:49:16Ilya Polyakovskiysetmessageid: <1510058956.93.0.213398074469.issue31968@psf.upfronthosting.co.za>
2017-11-07 12:49:16Ilya Polyakovskiylinkissue31968 messages
2017-11-07 12:49:16Ilya Polyakovskiycreate