Message305746
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. |
|
Date |
User |
Action |
Args |
2017-11-07 12:49:16 | Ilya Polyakovskiy | set | recipients:
+ Ilya Polyakovskiy |
2017-11-07 12:49:16 | Ilya Polyakovskiy | set | messageid: <1510058956.93.0.213398074469.issue31968@psf.upfronthosting.co.za> |
2017-11-07 12:49:16 | Ilya Polyakovskiy | link | issue31968 messages |
2017-11-07 12:49:16 | Ilya Polyakovskiy | create | |
|