New submission from Ilya Polyakovskiy <ilya.polyakovs...@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 <rep...@bugs.python.org>
<https://bugs.python.org/issue31968>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to