[New-bugs-announce] [issue31968] exec(): method's default arguments from dict-inherited globals
Ilya Polyakovskiy
report at bugs.python.org
Tue Nov 7 07:49:16 EST 2017
New submission from Ilya Polyakovskiy <ilya.polyakovskiy at jetbrains.com>:
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.
----------
components: Interpreter Core
messages: 305746
nosy: Ilya Polyakovskiy
priority: normal
severity: normal
status: open
title: exec(): method's default arguments from dict-inherited globals
versions: Python 3.5, Python 3.6
_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue31968>
_______________________________________
More information about the New-bugs-announce
mailing list