Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PEP 572: TargetScopeError->SyntaxError, other SyntaxError adjustments #1140

Merged
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
45 changes: 37 additions & 8 deletions pep-0572.rst
Expand Up @@ -8,7 +8,7 @@ Content-Type: text/x-rst
Created: 28-Feb-2018
Python-Version: 3.8
Post-History: 28-Feb-2018, 02-Mar-2018, 23-Mar-2018, 04-Apr-2018, 17-Apr-2018,
25-Apr-2018, 09-Jul-2018
25-Apr-2018, 09-Jul-2018, 05-Aug-2019
Resolution: https://mail.python.org/pipermail/python-dev/2018-July/154601.html


Expand Down Expand Up @@ -275,16 +275,47 @@ i`` part establishes that ``i`` is local to the comprehension, but the
``i :=`` part insists that ``i`` is not local to the comprehension.
The same reason makes these examples invalid too::

[[(j := j) for i in range(5)] for j in range(5)]
[i := 0 for i, j in stuff]
[i+1 for i in i := stuff]
[[(j := j) for i in range(5)] for j in range(5)] # compiler TargetScopeError
ncoghlan marked this conversation as resolved.
Show resolved Hide resolved
[i := 0 for i, j in stuff] # compiler TargetScopeError
[i+1 for i in (i := stuff)] # compiler TargetScopeError

While it's technically possible to assign consistent semantics to these cases,
it's difficult to determine whether those semantics actually make *sense* in the
absence of real use cases. Accordingly, the reference implementation will ensure
that such cases raise ``TargetScopeError``, a new subclass of ``SyntaxError``
(with the same signature), rather than executing with implementation defined
behaviour.

This restriction applies even if the assignment expression is never executed::

[False and (i := 0) for i, j in stuff] # compiler TargetScopeError
[i for i, j in stuff if True or (j := 1)] # compiler TargetScopeError

For the comprehension body (the part before the first "for" keyword) and the
filter expression (the part after "if" and before any nested "for"), this
restriction applies solely to target names that are also used as iteration
variables in the comprehension. Lambda expressions appearing in these
positions introduce a new explicit function scope, and hence may use assignment
expressions with no additional restrictions.

Due to design constraints in the reference implementation, named expressions
ncoghlan marked this conversation as resolved.
Show resolved Hide resolved
are disallowed entirely as part of comprehension iterable expressions (the part
gvanrossum marked this conversation as resolved.
Show resolved Hide resolved
after "in", and before any subsequent "if" or "for" keyword)::
ncoghlan marked this conversation as resolved.
Show resolved Hide resolved

[i+1 for i in (j := stuff)] # compiler TargetScopeError
[i+1 for i in [j for j in (k := stuff)]] # compiler TargetScopeError
[i+1 for i in (lambda: (j := stuff))()] # compiler TargetScopeError

A further exception applies when an assignment expression occurs in a
comprehension whose containing scope is a class scope. If the rules
above were to result in the target being assigned in that class's
scope, the assignment expression is expressly invalid.
scope, the assignment expression is expressly invalid. This case also raises
the new ``TargetScopeError``::

class Example:
[(j := i) for i in range(5)] # compiler TargetScopeError

(The reason for the latter exception is the implicit function created
(The reason for the latter exception is the implicit function scope created
for comprehensions -- there is currently no runtime mechanism for a
function to refer to a variable in the containing class scope, and we
do not want to add such a mechanism. If this issue ever gets resolved
Expand All @@ -295,8 +326,6 @@ variable defined in the class scope from a comprehension.)
See Appendix B for some examples of how the rules for targets in
comprehensions translate to equivalent code.

The two invalid cases listed above raise ``TargetScopeError``, a
new subclass of ``SyntaxError`` (with the same signature).

Relative precedence of ``:=``
-----------------------------
Expand Down