Skip to content

Add failing tests for set-comprehension and forward-ref scope bugs#1

Merged
Shamik-07 merged 1 commit into
Shamik-07:fix/def_declarationfrom
marimo-team:fix/def_declaration-tests
May 11, 2026
Merged

Add failing tests for set-comprehension and forward-ref scope bugs#1
Shamik-07 merged 1 commit into
Shamik-07:fix/def_declarationfrom
marimo-team:fix/def_declaration-tests

Conversation

@manzt
Copy link
Copy Markdown

@manzt manzt commented May 11, 2026

Two failing tests that demonstrate the correctness issues from the review on marimo-team#9379.

1. Set comprehension typo. SCOPE_CREATING_NODES uses "SetComprehension", but the Lezer Python grammar emits SetComprehensionExpression. As a result the comprehension never creates a scope, the for-target isn't collected, and go-to-def on the expression x in {x for x in range(10)} falls back to first-match and lands on an outer x. A dict-comprehension test is included as a positive control — same shape, but it uses the grammar-correct name and passes. The same typo exists pre-existing in reactive-references/analyzer.ts, worth fixing both spots.

2. Global forward reference. POSITION_SENSITIVE_SCOPES includes "global", so a module-level declaration whose position is after the usage is filtered out:

def foo():
    return a

a = 10

Go-to-def on a inside foo filters out a = 10, the lookup returns null, and the fallback first-match lands on the usage itself. Removing "global" from the set keeps class-scope semantics intact while letting nested functions resolve later-declared globals.

Snapshots encode the expected behavior, so the tests fail on the current branch and will go green once both items are addressed.

Three known bugs in the new scope-aware go-to-definition path.

Set comprehensions never create a scope because SCOPE_CREATING_NODES
uses "SetComprehension" but the Lezer Python grammar emits
"SetComprehensionExpression" — go-to-def on the expression `x` in
`{x for x in ...}` falls back to first-match and lands on an outer
`x` instead of the for-target. A dict-comprehension test uses the
grammar-correct name and passes as a positive control.

`getScopeChain` walks straight up the syntax tree and pushes any
ClassDefinition ancestor onto the chain, but in Python a method
body does not see its enclosing class scope. Once a function or
lambda boundary has been crossed walking outward, class scopes must
be skipped. With the current behavior, go-to-def on `x` inside a
method finds the class-body `x` instead of the module-level `x`.

POSITION_SENSITIVE_SCOPES includes "global", so a module-level
declaration whose position is after the usage is filtered out. From
inside a function that forward-references a later top-level name,
the lookup returns null and the fallback first-match lands on the
usage itself. Class-scope semantics need the position filter; module
scope does not.

The utils.test.ts mocks also drop the `as never` casts in favor of
fully-populated CellHandle literals, so a future field addition will
surface as a typecheck error.
@manzt manzt force-pushed the fix/def_declaration-tests branch from f93dd97 to 02fc173 Compare May 11, 2026 19:27
@Shamik-07 Shamik-07 merged commit bf12fd1 into Shamik-07:fix/def_declaration May 11, 2026
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.

2 participants