-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New semantic analyzer: Make assignment analysis logic more straightforward #6527
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
Conversation
Conflicts: mypy/newsemanal/semanal.py mypy/newsemanal/typeanal.py
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's a partial code review (mostly various nits). I still haven't looked at everything.
@JukkaL Thanks for review! I implemented the suggestions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the final part of my review. Looks good -- things are much easier to reason about now. Left a bunch of minor comments. Feel free to ignore some if you are short on time (and maybe create follow-up issues if it seems worth it).
@@ -337,7 +339,7 @@ class C(B): pass # E: Cannot subclass NewType | |||
from typing import Protocol, NewType | |||
|
|||
class P(Protocol): | |||
attr: int | |||
attr: int = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I explained offline, there was previously a false negative in this test (the NewType is abstract otherwise).
test-data/unit/check-newsemanal.test
Outdated
@@ -339,14 +339,25 @@ def main() -> None: | |||
x # E: Name 'x' is not defined | |||
|
|||
[case testNewAnalyzerCyclicDefinitions] | |||
gx = gy # E: Cannot determine type of 'gy' | |||
gx = gy # E: Cannot resolve name "gy", possible cyclic definition |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Grammar nit: run-on sentence in error message. Suggestion:
Cannot resolve name "gy" (possible cyclic definition)
[file b.py] | ||
import a | ||
x = a.x # E: Cannot resolve attribute "x", possible cyclic definition \ | ||
# E: Module has no attribute "x" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be easy to get rid of the second error, as it seems redundant and a bit confusing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opened #6551 for this.
return False | ||
|
||
def is_type_ref(self, rv: Expression, bare: bool = False) -> bool: | ||
"""Does this expression refer to a type? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docstring doesn't make it clear whether C[int]
would be considered a type reference. It would be good to be explicit about this. Also, probably worth mentioning that this assumes a type alias context. It's important since some of the error messages generated below only make sense when defining a type alias.
return | ||
if self.analyze_typeddict_assign(s): | ||
|
||
# The r.h.s. is now ready to be classified, first check if it is a special form: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is much cleaner than what we had previously! Thanks for cleaning this up.
mypy/newsemanal/semanal.py
Outdated
@@ -3379,7 +3515,12 @@ def visit_member_expr(self, expr: MemberExpr) -> None: | |||
n = self.rebind_symbol_table_node(n) | |||
if n: | |||
if isinstance(n.node, PlaceholderNode): | |||
self.defer() | |||
if self.final_iteration: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is duplicated above. Maybe move this if statement to a helper method?
@JukkaL Thanks! I implemented all comments except one (for that I opened a follow-up issue). |
…nd fix stale upper bounds and values (#6563) This is a follow up for #6527. Fixes #7037 I think this also essentially concludes #6300 This PR prohibits duplicate type variable definitions, previously the second one was silently winning. Also now the first one wins. Note that it didn't require additional attribute on `TypeVarExpr` as I initially though, it looks like we can simple use `s.rvalue.analyzed` for the purpose of linking assignments to variables. This PR also naturally fixes an issue where stale upper bound or value appears in a class that uses the type variable.
Fixes #6412
Fixes #6453
In this PR:
Var
sNotes:
progress=True
Follow-ups:
Test updates: