Python eval() receives two optional dictionaries: globals and locals. I was finally able to find at least two differences between them.
First difference: global variables survive until after the eval() call, local variables do not. This becomes important, if eval() returns a lambda.
globs = {"a": 42 }
locs = {"b": 10 }
print(eval("a+b", globs, locs)) # prints 52; no visible difference between usage of a and b
f = eval("lambda: a", globs, locs) # global variable 'a' survives the eval call and can be used in a lambda later
print(f()) # prints 42
globs["a"] = 100 # we can even change the value of a, and the lambda will pick it up
print(f()) # prints 100
del globs["a"] # if we delete globs["a"] the lambda will stop working
print(f()) # raises NameError: name 'a' is not defined
g = eval("lambda: b", globs, locs) # this succeeds, but local variable 'b' will not survive beyond the eval call
print(g()) # raises NameError: name 'b' is not defined
Second difference: local variables override global variables with the same name. This, however, is applicable only during the eval() call. If eval() returns a lambda, the global variable will be used when the lambda is invoked.
globs = {"a": 42 }
locs = {"a": 10 }
data = eval("(a, lambda: a)", globs, locs) # returns a tuple of a value and a lambda
print(data[0], data[1]()) # prints "10 42"; lambda returns the value of the global variable
I could not find information about any other differences in the documentation or elsewhere on the Internet, and even those above I found through experiment. So, I am documenting them here for posterity.

Permalink
This is quite cool IMHO!
Permalink
Thank you!