Skip to content

[3.15] gh-150700: Fix class-scope inline comprehensions when nested scopes reference __class__ and friends (GH-150735)#151211

Merged
carljm merged 1 commit into
python:3.15from
miss-islington:backport-ce916dc-3.15
Jun 9, 2026
Merged

[3.15] gh-150700: Fix class-scope inline comprehensions when nested scopes reference __class__ and friends (GH-150735)#151211
carljm merged 1 commit into
python:3.15from
miss-islington:backport-ce916dc-3.15

Conversation

@miss-islington

@miss-islington miss-islington commented Jun 9, 2026

Copy link
Copy Markdown
Contributor
  • Fix class-scope inline comprehensions when nested scopes reference __class__ and friends

In inline_comprehension(), when __class__ / __classdict__ /
__conditional_annotations__ appears as FREE in a comprehension's
symbol table because a nested scope captured it (e.g. nested lambdas),
this name is still discarded from comp_free unconditionally.

This prevents drop_class_free() from seeing it, so the appropriate
ste_needs_(...) flag is never set on the enclosing class.
That leads to codegen_make_closure() throwing SystemError when it
couldn't find __class__ / __classdict__ /
__conditional_annotations__ in the class's cellvars.

From now on we just discard from comp_free when no child scope
(e.g. a lambda) still needs the name as FREE. When a child scope does
need it, keep it in comp_free so drop_class_free() can set the
appropriate flag and the class creates the implicit cell.

  • Fix tests

  • Fix typo

  • Fix formatting

  • Add test checking validity of __class__ returned

  • Prefer 'used' to 'deferred'
    (cherry picked from commit ce916dc)

Co-authored-by: Bartosz Sławecki bartosz@ilikepython.com

…opes reference `__class__` and friends (pythonGH-150735)

* Fix class-scope inline comprehensions when nested scopes reference `__class__` and friends

In `inline_comprehension()`, when `__class__` / `__classdict__` /
`__conditional_annotations__` appears as `FREE` in a comprehension's
symbol table because a nested scope captured it (e.g. nested lambdas),
this name is still discarded from `comp_free` unconditionally.

This prevents `drop_class_free()` from seeing it, so the appropriate
`ste_needs_(...)` flag is never set on the enclosing class.
That leads to `codegen_make_closure()` throwing `SystemError` when it
couldn't find `__class__` / `__classdict__` /
`__conditional_annotations__` in the class's cellvars.

From now on we just discard from `comp_free` when no child scope
(e.g. a lambda) still needs the name as `FREE`. When a child scope does
need it, keep it in `comp_free` so `drop_class_free()` can set the
appropriate flag and the class creates the implicit cell.

* Fix tests

* Fix typo

* Fix formatting

* Add test checking validity of `__class__` returned

* Prefer 'used' to 'deferred'
(cherry picked from commit ce916dc)

Co-authored-by: Bartosz Sławecki <bartosz@ilikepython.com>
@carljm carljm merged commit 73e5d44 into python:3.15 Jun 9, 2026
55 checks passed
@miss-islington miss-islington deleted the backport-ce916dc-3.15 branch June 9, 2026 23:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants