-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Bypass class attribute lookup for PEP 695 typevars #20292
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
base: master
Are you sure you want to change the base?
Conversation
|
According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅ |
sterliakov
left a comment
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.
Nice one! This part definitely should not use lookup, we are only interested in locals, and (except for one bad corner case) only in the most recent locals entry. Traversing further is only needed when we have
class Foo[T]:
class Bar[T]: # Error here, but typevar is still needed
...|
|
||
| def is_defined_type_param(self, name: str) -> bool: | ||
| def get_defined_type_param(self, name: str) -> TypeVarLikeExpr | None: | ||
| for names in self.locals: |
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.
Ough, I spelled that out but didn't realize that this goes in the wrong direction (?). We are typically interested in the most recent locals frame, so shouldn't this be
| for names in self.locals: | |
| for names in reversed(self.locals): |
? It didn't matter when we only requested a boolean "is defined" result, but now could potentially resolve to a wrong symbol. I don't have a testcase for that, but anyway the variable will normally be found in the most recent local frame, so checking it first makes more sense? Upd: no, it cannot resolve to the wrong symbol, we only accept type variables, and type param redefinitions are never added to symtable, but maybe it's still better to avoid the unnecessary work? reversed is fast
| if names is None: | ||
| continue | ||
| if name in names: |
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.
And just to save a bit on branching,
| if names is None: | |
| continue | |
| if name in names: | |
| if names is not None and name in names: |
Fixes #20283
This is a bit gross, but I'm not sure how to better do this. The problem is that we look up class attributes before looking at locals, but then put the type vars in a new locals scope. I guess one idea would be to define the typevars at usage time? But this is less of a change.