Repository navigation
Respect global declarations and real assignment targets in shadowing and rebinding - #363
Merged
Merged
Conversation
…and rebinding Three cases removed imports that are used: - A function or class body between the use and a shadowing function that declares the name global makes the use refer to the module binding. _is_shadowed now stops there instead of treating the outer local as the binding. - _is_rebound treated any store in a top-level assignment as rebinding the name, including comprehension variables and walrus targets inside lambdas, which are local to their own scope. Only the statement's own (possibly unpacked) targets count now. - A store parsed from a type comment has no enclosing statement; walking up to it crashed the run with AttributeError. It is no longer counted as a rebinding. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019P9bvuGwAyVCNUdsAYPB1V
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #350 / #359, from the second review of
claude/integration.Problems (all removed a used import; the result raised
NameError)globalin an inner scope was ignored.f's localjsonas the binding. The same happened withglobalin a class body, and with the use in a function nested inside theglobalone.n = sum(1 for sep in xs),len([0 for sep in items])andf = lambda: (sep := "x")were all treated as reassigningsep, so a later bare use ofsepno longer counted.AttributeError, because the parsed type comment has no enclosing statement.Fix
_is_shadowedwalks function and class bodies between the use and the import. It returns "not shadowed" at the first one that declares the nameglobal.nonlocalkeeps walking, which matches CPython's resolution. Class bodies still never provide a binding for the functions inside them._collect_declarations(replaces_collect_local_bindings) returns both the local and theglobalnames of a body, and is cached per node._is_unconditional_assignmentonly accepts the statement's own targets, possibly unpacked throughTuple/List/Starred. Comprehension variables and walrus targets under a lambda are not targets._statement()returnsNonewhen there is no enclosing statement.I considered moving the whole analysis to
symtable. It would answer local/global/free per scope, but it can't tell which enclosing function binds a free name, or where in the flow a rebinding happens. Mapping its tables back to AST nodes is also version-dependent (PEP 709 inlining, and 3.13+ annotation scopes). The targeted rules above follow the same resolution order as CPython.Tests
Six new
scope/cases, all failing before this change:global_in_inner_function,global_in_class_body,global_in_enclosing_function,comprehension_target_is_not_rebinding,genexp_and_lambda_walrus_are_not_rebinding,type_comment_store. Full suite passes on 3.9 / 3.12 / 3.14 (283 passed), and pre-commit passes.🤖 Generated with Claude Code
https://claude.ai/code/session_019P9bvuGwAyVCNUdsAYPB1V
Generated by Claude Code