mypy
72a24313 - [mypyc] Fix lambda inside comprehension (#21009)

Commit
103 days ago
[mypyc] Fix lambda inside comprehension (#21009) Fixes https://github.com/mypyc/mypyc/issues/1190 There's a subtle difference between mypyc and CPython when it comes to evaluating comprehensions: - CPython creates an implicit function scope for every comprehension (visible as `MAKE_FUNCTION` etc) - Mypyc inlines comprehensions directly into the enclosing/outer scope This leads to the following bug: When a lambda inside a comprehension tries to capture the loop variable, the closure/env-class machinery fails because there's no scope boundary to chain through. Consider this example with a module level comprehension which currently fails with `UnboundLocalError`: ```Python3 # bug.py d = {name: (lambda: name) for name in ("a", "b")} d["a"]() ``` <br /> Schematically: ```Bash Before (broken): module scope (no env class) └── lambda (needs env class to find 'name') → crash After (fixed): module scope └── comprehension scope (has env class with 'name' attribute) └── lambda (loads 'name' from comprehensions env class) → works ``` <br /> Three failure modes depending on where the comprehension lives: - Module level: UnboundLocalError at runtime -> the lambda can't find the variable - Class level: KeyError compiler crash -> env class setup fails entirely - Function level: Already worked, because the enclosing function provides the env class The fix creates a _lightweight_ synthetic scope (new `FuncInfo` + `env` class) only when a comprehension body contains a lambda, while still inlining the comprehension into the same basic blocks otherwise. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Author
Parents
Loading