Created
May 15, 2014 20:20
-
-
Save cowlicks/1d7ef6e66a50ffeceab6 to your computer and use it in GitHub Desktop.
Why doesn't eval work here?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| In [11]: def foo(): | |
| ....: return b | |
| ....: | |
| In [12]: eval('foo()', dict({'b':42}, **globals())) | |
| --------------------------------------------------------------------------- | |
| NameError Traceback (most recent call last) | |
| <ipython-input-12-a2089cf14959> in <module>() | |
| ----> 1 eval('foo()', dict({'b':42}, **globals())) | |
| <string> in <module>() | |
| <ipython-input-11-36533771d987> in foo() | |
| 1 def foo(): | |
| ----> 2 return b | |
| 3 | |
| NameError: global name 'b' is not defined |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What happens above is:
foo()and getsfoofrom the eval globals to execute it.foois called. Sofoolooks forbin its loclas, not there, then infoo.__globals__(not in the eval globals).foo.__globals__refers to the namespacefoowas defined in, which does not haveb. SoNameErroris raised.First I tried to fix this by monkeypatching
foo.__globals__. But this is a read only attribute.What I eventually did is deconstruct
fooand rebuild it with a modified globals using the types module. The result is below.Note
eval('new_foo')returns 666 as expected!