Thank you all. I will accept the PEP as is. I am happy to accept *clarification* updates to the PEP if people care to submit them as PRs to the peps repo (https://github.com/python/peps), and that could even (to some extent) include summaries of discussion we've had, or outright rejected ideas. But even without any of those I think the PEP is very clear so I will not wait very long (maybe a week).

On Mon, Jul 2, 2018 at 8:38 AM Steven D'Aprano <steve@pearwood.info> wrote:
On Wed, Jun 27, 2018 at 07:29:52PM -0500, Tim Peters wrote:
[...]
> For example, if the name is declared "global" in the outer scope, you'll
> get a compile-time error if you try to declare it "nonlocal" in the
> contained scope.  "parentlocal" adjusts its meaning accordingly, becoming a
> synonym for "global" in that specific case.

"Parentlocal" is only a thing if we buy into the paradigm that inside
comprehensions is a separate "local". And *that* is only true under
two circumstances:

- if you are utterly immersed in the implementation of comprehensions
  as invisible, implicit functions;

- or if you start from the premise that comprehensions ought to
  encapsulate not just the loop variable, but anything else as well.


But experimenting with locals() inside comprehensions shows that
comprehension-scope *isn't* a well-defined thing. It already bleeds out
of the comprehension, and so would some (but only some!) assignment
expressions.

Instead, if we start from the premise that comprehensions (like any
other expression) run in the current scope, then there is no need to
invent a term "parentlocal". There's just the usual LEGB scopes, plus
class (which people usually forget).

With no sublocal scopes (a term we never even had prior to this PEP)
assignments inside the comprehension are no more special than
assignments inside any other expression. They bind in the current scope,
same as always, and keep the sensible identity that these two
expressions are exactly equivalent in their visible semantics:

    [x:=0, x:=1, x:=2]

    [x:=i for i in (0, 1, 2)]

including assignments.

What about the loop variable?

They ARE special, which is completely justified by the Zen:

Although practicality beats purity.

We can take a series of ever-more-detailed explanations, starting from
the highest "bird's eye" view and gradually dropping further into the
murky details of the implementation when, and if, required:

- assignment within comprehensions is no different from assignment
  in any other expression, it occurs in the local scope;

- loop variables? they're a special case, for good reason, and are
  encapsulated inside the comprehension;

- how? they're hidden in an implicit, invisible scope, same as .0
  the implicit, invisible iterator object;

- oh, you didn't know about the .0 variable? well forget about it,
  it's an undocumented implementation detail, just like the invisible,
  implicit function used by comprehensions;

- oh, you didn't know about that either? read the source code.


Only the first two levels of explanation are part of Python the
language. The rest is CPython implementation.



--
Steve
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: https://mail.python.org/mailman/options/python-dev/guido%40python.org


--
--Guido van Rossum (python.org/~guido)