How does eval() change the dict? This is an example: create a dict -> print -> eval -> print
>>> a={'a':'a','b':'b'}
>>> print(a)
{'a': 'a', 'b': 'b'}
>>> eval('a == "a"',a)
True
>>> print(a)
{'a': 'a', '__builtins__': {'bytearray': <class 'bytearray'>, 'IndexError': <class 'IndexError'>, 'all': <built-in function all>, 'help': Type help() for interactive help, or help(object) for help about object., 'vars': <built-in function vars>, 'SyntaxError': <class 'SyntaxError'>, 'UnicodeDecodeError': <class 'UnicodeDecodeError'>, 'memoryview': <class 'memoryview'>, 'isinstance': <built-in function isinstance>, '__build_class__': <built-in function __build_class__>, 'copyright': Copyright (c) 2001-2012 Python Software Foundation.
All Rights Reserved.
...
The second argument to eval()
is the globals used for the expression run by eval()
.
One of things python does when evaluating an expression is ensuring that the python built-ins are available to the evaluated expression, and to do that it adds the __builtins__
entry to that globals namespace.
So, yes, the eval()
call did change your dictionary, and that is expected and normal behaviour. It even says so in the documentation for the function:
If the globals dictionary is present and lacks ‘__builtins__’, the current globals are copied into globals before expression is parsed. This means that expression normally has full access to the standard __builtin__
module and restricted environments are propagated.
If you want to avoid this change, use an empty dict
for the globals, and use a
as the locals
namespace instead:
eval('a == "a"', {}, a)
The answer resides in the doc !
First of all, the second parameter to eval
is the global
dictionary. Than, we see:
If the globals dictionary is present and lacks ‘__builtins__’, the
current globals are copied into globals before expression is parsed.
So yes, your dictionary gets modified by the call to eval
.
Yes it does. The second argument to eval()
is the "globals" dictionary, which explains what you're seeing.