Issue37646
Created on 2019-07-21 23:24 by Grzegorz Krasoń, last changed 2022-04-11 14:59 by admin. This issue is now closed.
| Files | ||||
|---|---|---|---|---|
| File name | Uploaded | Description | Edit | |
| demo.py | Grzegorz Krasoń, 2019-07-21 23:24 | |||
| Pull Requests | |||
|---|---|---|---|
| URL | Status | Linked | Edit |
| PR 15117 | merged | rhettinger, 2019-08-04 20:21 | |
| PR 15155 | merged | miss-islington, 2019-08-07 00:57 | |
| Messages (9) | |||
|---|---|---|---|
| msg348271 - (view) | Author: Grzegorz Krasoń (Grzegorz Krasoń) | Date: 2019-07-21 23:24 | |
eval() works in a global scope when invoked in a list comprehension. |
|||
| msg348272 - (view) | Author: Steven D'Aprano (steven.daprano) * ![]() |
Date: 2019-07-22 00:15 | |
What leads you to believe that eval *shouldn't* work in the global scope in a comprehension? If not the global scope, which scope should it be, local or nonlocal? Is the behaviour documented differently? For reference, the current docs for eval are here: https://docs.python.org/3.5/library/functions.html#eval |
|||
| msg348274 - (view) | Author: Raymond Hettinger (rhettinger) * ![]() |
Date: 2019-07-22 00:25 | |
This used to work as you expected in Python 2. In Python 3, list comprehensions create their own inner scope just like generator expressions. Per the eval() docs, "if both dictionaries are omitted, the expression is executed in the environment where eval() is called." In your code example, the inner scope doesn't have a local variable "x", so the global variable "x" is retrieved. That said, I would have expected the inner "x" to be found as a non-local. So yes, this does seem odd an it isn't really true that "the expression is executed in the environment where eval() is called." Instead, it uses the globals() and locals() of the environment where it is called but not the nested scope. Perhaps this should be clarified in the docs if it is in fact the intended behavior. |
|||
| msg348293 - (view) | Author: Grzegorz Krasoń (Grzegorz Krasoń) | Date: 2019-07-22 10:22 | |
Steven, I believed that any `<expression>` replaced by `eval('<expression>')` will not change behaviour of the code. Now I understand that my assumption was incorrect.
Raymond, thanks for helping me understand this.
|
|||
| msg348313 - (view) | Author: Steven D'Aprano (steven.daprano) * ![]() |
Date: 2019-07-23 01:25 | |
I'm not sure we should be so quick to close this. At the very least, I
think the documentation could be improved.
It does seem desirable to have the invariant:
`expression` == `eval("expression")`
apply in any environment. Was the change in behaviour between 2 and 3
intentional, or just a side-effect of the change in implementation?
|
|||
| msg348405 - (view) | Author: Grzegorz Krasoń (Grzegorz Krasoń) | Date: 2019-07-24 20:52 | |
I re-opened the issue. Dear core developers, can we ask you to confirm if described behavior of eval() is expected? |
|||
| msg349001 - (view) | Author: Raymond Hettinger (rhettinger) * ![]() |
Date: 2019-08-04 20:27 | |
After more thought, I think the existing behavior is probably what we want. There may not be a clean way to allow access and updates to non-locals. Even if a way was found, it may tie our hands and preclude other implementation changes down the road. Also, such a feature may be at odds with the current API which allows the execution environment to be retargeted. There is also a risk of introducing new security issues. I've attached a PR to update the eval() docs to reflect the actual behavior. |
|||
| msg349144 - (view) | Author: Raymond Hettinger (rhettinger) * ![]() |
Date: 2019-08-07 00:56 | |
New changeset 610a4823cc0a3c2380ad0dfe64ae483ced4e5304 by Raymond Hettinger in branch 'master': bpo-37646: Document that eval() cannot access nested scopes (GH-15117) https://github.com/python/cpython/commit/610a4823cc0a3c2380ad0dfe64ae483ced4e5304 |
|||
| msg349145 - (view) | Author: Raymond Hettinger (rhettinger) * ![]() |
Date: 2019-08-07 01:08 | |
New changeset 9341dcb4b9520ab92df10d4256e93a50e1e7d19f by Raymond Hettinger (Miss Islington (bot)) in branch '3.8': bpo-37646: Document that eval() cannot access nested scopes (GH-15117) (GH-15155) https://github.com/python/cpython/commit/9341dcb4b9520ab92df10d4256e93a50e1e7d19f |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022-04-11 14:59:18 | admin | set | github: 81827 |
| 2019-08-07 01:08:28 | rhettinger | set | status: open -> closed nosy:
+ docs@python |
| 2019-08-07 01:08:02 | rhettinger | set | messages: + msg349145 |
| 2019-08-07 00:57:14 | miss-islington | set | pull_requests: + pull_request14888 |
| 2019-08-07 00:56:25 | rhettinger | set | messages: + msg349144 |
| 2019-08-04 20:27:54 | rhettinger | set | messages: + msg349001 |
| 2019-08-04 20:21:23 | rhettinger | set | keywords:
+ patch stage: resolved -> patch review pull_requests: + pull_request14858 |
| 2019-07-24 20:52:25 | Grzegorz Krasoń | set | messages: + msg348405 |
| 2019-07-24 20:48:17 | Grzegorz Krasoń | set | status: closed -> open resolution: not a bug -> (no value) |
| 2019-07-23 01:25:24 | steven.daprano | set | messages: + msg348313 |
| 2019-07-22 10:22:13 | Grzegorz Krasoń | set | status: open -> closed resolution: not a bug messages: + msg348293 stage: resolved |
| 2019-07-22 00:25:59 | rhettinger | set | nosy:
+ rhettinger messages: + msg348274 |
| 2019-07-22 00:15:41 | steven.daprano | set | nosy:
+ steven.daprano messages: + msg348272 |
| 2019-07-21 23:24:25 | Grzegorz Krasoń | create | |
