Mailing List Archive

[issue37646] eval() in a list comprehension
New submission from Grzegorz Kraso? <grzegorz.krason@gmail.com>:

eval() works in a global scope when invoked in a list comprehension.

----------
components: Interpreter Core
files: demo.py
messages: 348271
nosy: Grzegorz Kraso?
priority: normal
severity: normal
status: open
title: eval() in a list comprehension
type: behavior
versions: Python 3.7
Added file: https://bugs.python.org/file48495/demo.py

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue37646>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com
[issue37646] eval() in a list comprehension [ In reply to ]
Steven D'Aprano <steve+python@pearwood.info> added the comment:

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

----------
nosy: +steven.daprano

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue37646>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com
[issue37646] eval() in a list comprehension [ In reply to ]
Raymond Hettinger <raymond.hettinger@gmail.com> added the comment:

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.

----------
nosy: +rhettinger

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue37646>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com
[issue37646] eval() in a list comprehension [ In reply to ]
Grzegorz Kraso? <grzegorz.krason@gmail.com> added the comment:

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.

----------
resolution: -> not a bug
stage: -> resolved
status: open -> closed

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue37646>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com
[issue37646] eval() in a list comprehension [ In reply to ]
Steven D'Aprano <steve+python@pearwood.info> added the comment:

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?

----------

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue37646>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com
[issue37646] eval() in a list comprehension [ In reply to ]
Change by Grzegorz Kraso? <grzegorz.krason@gmail.com>:


----------
resolution: not a bug ->
status: closed -> open

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue37646>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com
[issue37646] eval() in a list comprehension [ In reply to ]
Grzegorz Kraso? <grzegorz.krason@gmail.com> added the comment:

I re-opened the issue.

Dear core developers, can we ask you to confirm if described behavior of eval() is expected?

----------

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue37646>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com
[issue37646] eval() in a list comprehension [ In reply to ]
Change by Raymond Hettinger <raymond.hettinger@gmail.com>:


----------
keywords: +patch
pull_requests: +14858
stage: resolved -> patch review
pull_request: https://github.com/python/cpython/pull/15117

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue37646>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com
[issue37646] eval() in a list comprehension [ In reply to ]
Raymond Hettinger <raymond.hettinger@gmail.com> added the comment:

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.

----------

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue37646>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com
[issue37646] eval() in a list comprehension [ In reply to ]
Raymond Hettinger <raymond.hettinger@gmail.com> added the comment:


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


----------

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue37646>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com
[issue37646] eval() in a list comprehension [ In reply to ]
Change by miss-islington <mariatta.wijaya+miss-islington@gmail.com>:


----------
pull_requests: +14888
pull_request: https://github.com/python/cpython/pull/15155

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue37646>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com
[issue37646] eval() in a list comprehension [ In reply to ]
Raymond Hettinger <raymond.hettinger@gmail.com> added the comment:


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


----------

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue37646>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com
[issue37646] eval() in a list comprehension [ In reply to ]
Change by Raymond Hettinger <raymond.hettinger@gmail.com>:


----------
assignee: -> docs@python
components: +Documentation -Interpreter Core
nosy: +docs@python
resolution: -> fixed
stage: patch review -> resolved
status: open -> closed

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue37646>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com