This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author congma
Recipients bruno.loff, congma, docs@python, terry.reedy
Date 2021-03-27.13:15:48
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1616850948.17.0.158809129462.issue43605@roundup.psfhosted.org>
In-reply-to
Content
Some more context: Issue 37646. The demo in that one was "eval inside list-comprehension-scope", while this one is the other way around.

Perhaps another example may better illustrate the interplay between eval and the execution environment:

```
def f():
    x = 1
    def g():
        return eval("x")
    return g
enc = f()
enc()
```

We get ``NameError: name 'x' is not defined``.

The reason is that, during compilation the compiler doesn't and cannot care about what the string "x" means as an argument to eval(). To the compiler it's just a string constant passed to a function, and it's not much different from
```
        return print("x")
```
The compiler decides that the enclosed function g() has no locals in its block. And since there's no global with the name ``x`` either, when the dynamic expression is evaluated in eval() in that environment, the name doesn't resolve, because "eval() doesn't have access to the enclosing scope".

But the following is different:

```
def f():
    x = 1
    def g():
        x  # <----- 
        return eval("x")
    return g
enc = f()
enc()  # return value: 1
```

The marked line introduces name ``x`` as a local by virtue of merely having it in an expression-statement. Inside the function block of g(), we can imagine that the name resolution "goes up one level" into the enclosing block of f() where it is bound to the int object. When eval() is called there, the name does resolve.

I'm trying to think up a mental model but I'm afraid I can't find a simple one, except "once compiled, it's compiled, and eval() must learn to work with the already-compiled code". A much more in-depth description of name binding and execution in CPython is given here:

https://tenthousandmeters.com/blog/python-behind-the-scenes-5-how-variables-are-implemented-in-cpython/

especially in the section "``LOAD_DEREF`` and ``STORE_DEREF``".
History
Date User Action Args
2021-03-27 13:15:48congmasetrecipients: + congma, terry.reedy, docs@python, bruno.loff
2021-03-27 13:15:48congmasetmessageid: <1616850948.17.0.158809129462.issue43605@roundup.psfhosted.org>
2021-03-27 13:15:48congmalinkissue43605 messages
2021-03-27 13:15:48congmacreate