@Jelle pointed out yesterday that the implementation of PEP 709 (inlined comprehensions) caused one additional behavior change that I failed to identify in the PEP text. Consider this code:
class C:
incr = 1
items = [x+incr for x in range(3)]
Before PEP 709, this code would fail with NameError
, because the comprehension was compiled as a nested function, and functions cannot see variables defined in enclosing class scopes.
Since the merge of the PEP 709 implementation, this code succeeds and does what one might expect at first glance; the comprehension is no longer compiled as a nested function, so the incr
variable is now accessible to it.
I think this is more intuitive and useful behavior, and generally consistent with the post-709 situation that list/dict/set comprehensions are no longer compiled as nested functions.
But if we want to make this change in behavior, we should consider it explicitly, and consider the backward-compatibility implications. It is possible for this to change the behavior of currently working code:
incr = 1
class C:
incr = 2
items = [x+incr for x in range(3)]
In Python 3.11, C.items
will be [1, 2, 3]
(because incr
in the comprehension will bypass the class scope and refer to the global). In current main branch (with PEP 709), it will be [2, 3, 4]
instead: the value from the class scope is used.
So there are two questions to consider here:
-
Do we eventually want the behavior where comprehensions in class scopes can access variables in that same class scope?
-
If so, do we need a deprecation path to get there (this seems to me fairly disruptive, and also challenging to implement)? Or can it just be noted prominently in the release notes? And do we want this in 3.12, along with the other changes from PEP 709, or separately in a future release?
Depending on the answers to those questions, there are a number of possible courses of action:
A) Document this behavior change in the release notes for 3.12.
B) Attempt to roll back just this behavior change (for now?), while leaving the rest of PEP 709 as is. (I think this is tricky but probably doable.)
C) Roll back this behavior change (for now?) by just not inlining comprehensions in class scopes at all. This means that other behaviors (tracebacks, what appears in locals()
) will be inconsistent for comprehensions in class scopes vs other scopes.
D) Roll back all of PEP 709 for 3.12 and re-consider it with this behavior change for 3.13.
I expect to take this question to the SC and the 3.12 release manager, but it seems useful to gather opinions here first.