Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[red-knot] Do not panic if named expressions show up in assignment position #13711

Merged
merged 3 commits into from
Oct 16, 2024

Conversation

rtpg
Copy link
Contributor

@rtpg rtpg commented Oct 11, 2024

Unfortunately the test I added here still fails (I believe due to scoping issues, still trying to wrap my head around how the scoping is supposed to work), but I believe my changes to the builder are correct: it is not incorrect for there to be current_assignments to juggle, given the existence of named expressions.

Copy link
Contributor

@carljm carljm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!! I had totally failed to consider the possibility of a namedexpr in a LHS subscript expression.

"/src/a.py",
"
x = [0]
x[0 if y := 2 else 1] = 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is invalid syntax. Red-knot isn't resilient to arbitrary invalid syntax yet (though we should become so). We should make a change so that for now red-knot just always fails fast if there are parser errors, rather than hitting panics that are hard to debug and cause confusion; this isn't the first time we've had this scenario.

For this to be valid syntax, the namedexpr has to be parenthesized to fix the binding precedence. If we do this, the test passes:

Suggested change
x[0 if y := 2 else 1] = 1
x[0 if (y := 2) else 1] = 1

Copy link
Contributor

@carljm carljm Oct 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new mdtest framework will already help with this, since it won't hide syntax errors like the current tests do. Currently it will just fail fast on any test with a syntax error in it; once we start working on syntax error resilience we will add features to it to explicitly assert on syntax errors, but tests with accidental syntax errors will still fail with a clear diagnostic.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, great catch, will fix the test. Glad to see these changes are able to be handled.

My current reading is that the semantic index expects everything to be covered so even in the case of syntax errors we would be expected to try and see each symbol anyways... but that might be me buying into the error's premise a bit too much.

Like should the semantic index cover the entire program? If so, it feels like the underlying error is still a problem. If not, then it feels like there's some concept here of not being covered (and some of the philosophy of #13701, of having lookups be Option/Result-y and falling back, could apply).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The panic here with the syntax error isn't exactly due to lack of coverage. It's that we currently assume (reasonably!) that if a name is being defined, there will be a Name node with Store context; that's normally how the AST works. With the malformed syntax, we end up with a Named expression node whose target doesn't contain any Name node with Store context. So we never create any Definition for the Named. But then type inference assumes that every Named node should be associated with a Definition, it tries to look up the Definition and there isn't one.

I agree with you in general that becoming syntax-error-resilient will probably mean making fewer such invariant assumptions, and being more willing to fall back to Unknown when something just doesn't make sense. The loss with doing this unconditionally is that it becomes easier for bugs to go unnoticed and propagate silently. Ideally perhaps we could relax our invariants only when we actually observe invalid nodes in the AST, rather than doing so unconditionally, to preserve a bit more fail-fast when we have bugs. I'm not sure if this will be feasible or not. The truth is that we have a lot to do and syntax-error-resilience hasn't made it to the top of the list yet!

I think this particular panic would be fixed by having infer_named_expr in type inference check if the target of the Named node is a Name with Store context (which it always should be, if syntax is valid -- walrus expressions aren't allowed to have complex left-hand side), and if not, bail out and don't try to look up a Definition at all. But I would kind of like to consider our strategy for syntax-error-resilience a bit more holistically.

cc @dhruvmanila who is intending to take on the syntax-error-resilience at some point.

I hadn't seen #13701 yet. (Note, I generally won't be alerted to the existence of draft PRs unless explicitly pointed to them; they don't show up in reviewer notifications until marked ready for review.) I'll take a look at it soon (may not be til Monday.)

@rtpg rtpg marked this pull request as ready for review October 14, 2024 06:01
@rtpg
Copy link
Contributor Author

rtpg commented Oct 14, 2024

I am a bit mystified by the benchmark/ecosystem failures but I think the code changes here are ready for another review.

@MichaReiser
Copy link
Member

The benchmark fail at

assert_eq!(self.current_assignments.len(), 0);

Indicating that there are assignments that weren't popped correctly or that the assertion needs updating with your changes.

Copy link
Contributor

github-actions bot commented Oct 15, 2024

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

@MichaReiser MichaReiser requested a review from carljm October 15, 2024 09:23
 Named expressions can show up inside of a subscript, for example
Copy link
Contributor

@carljm carljm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, thank you! I will go ahead and move the tests and then merge.

@carljm carljm enabled auto-merge (squash) October 16, 2024 12:38
@carljm carljm merged commit d25673f into astral-sh:main Oct 16, 2024
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
red-knot Multi-file analysis & type inference
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants