I'm trying to run some expressions using a custom dict as globals.
class Namespace(dict):
def __getitem__(self, key):
if key == "y":
return 10
else:
return super(Namespace, self).__getitem__(key)
def run_with_dict(d):
print(eval("x + y", d))
print(eval("[ (p * y) for p in ['foo', 'bar'] ]", d))
print(eval("{ p: (p * y) for p in ['foo', 'bar'] }", d))
custom = Namespace()
custom["x"] = 2
regular = {"x": 2, "y": 10}
run_with_dict(regular)
run_with_dict(custom)
When running it in CPython 2.7, it fails only on the map comprehension:
12
['foofoofoofoofoofoofoofoofoofoo', 'barbarbarbarbarbarbarbarbarbar']
{'foo': 'foofoofoofoofoofoofoofoofoofoo', 'bar': 'barbarbarbarbarbarbarbarbarbar'}
12
['foofoofoofoofoofoofoofoofoofoo', 'barbarbarbarbarbarbarbarbarbar']
Traceback (most recent call last):
File "<stdin>", line 22, in <module>
File "<stdin>", line 15, in run_with_dict
File "<string>", line 1, in <module>
File "<string>", line 1, in <dictcomp>
NameError: global name 'y' is not defined
But when it's run with PyPy 2.7, it works fine. It also works fine in any Python 3.
What implementation difference could explain that? Is this a bug in CPython 2.7 or is it undefined behavior? Is there anything I could do to make it work in both implementations?