gh-150700: Fix class-scope inline comprehensions when nested scopes reference __class__ and friends#150735
Conversation
…_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.
…th-lambda-raises-syste
|
Updating branch to see if it fixes doc build issue. |
| a ``lambda`` that references ``__class__``, ``__classdict__``, or | ||
| ``__conditional_annotations__``. Patch by Bartosz Sławecki. |
There was a problem hiding this comment.
I would only mention __class__ here, since __classdict__ and __conditional_annotations__ are internal-only.
There was a problem hiding this comment.
Thanks.
I'm of two minds on this. I initially wrote this news entry to indeed include __class__ only, but then I looked up that we already have a precedent news entry that does mention both __classdict__ and __conditional_annotations__. Both aren't of likely special interest to the regular user, but they are of interest to me or others who know it and I liked the transparency. Maybe it's ok to keep it?
There was a problem hiding this comment.
Sure, I'm just being nitpicky. I don't necessarily agree with that precedent, FWIW. The changelog should be for users, not maintainers -- maintainers can read the commit log if they care.
There was a problem hiding this comment.
I do think we should mention all. The changelog can be fairly low-level and should mention changes that are visible to end users, even end users poking into things they probably shouldn't be poking into.
Follow up to GH-120295.
In
inline_comprehension(), when__class__/__classdict__/__conditional_annotations__appears asFREEin a comprehension's symbol table because a nested scope captured it (e.g. nested lambdas), this name is still discarded fromcomp_freeunconditionally. This preventsdrop_class_free()from seeing it, so the appropriateste_needs_(...)flag is never set on the enclosing class. That leads tocodegen_make_closure()throwingSystemErrorwhen it couldn't find__class__/__classdict__/__conditional_annotations__in the class's cellvars.From now on we just discard from
comp_freewhen no child scope (e.g. a lambda) still needs the name asFREE. When a child scope does need it, keep it incomp_freesodrop_class_free()can set the appropriate flag and the class creates the implicit cell.