-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
[mypyc] Support Python 3.12 type alias syntax (PEP 695) #17384
Conversation
Inferring TypeVar as the type broke various tests. Use more complete stubs. Previously some of these tests were quite unrealistic.
According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅ |
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.
LG, but I have one question.
@@ -411,7 +411,9 @@ def analyze_ref_expr(self, e: RefExpr, lvalue: bool = False) -> Type: | |||
result = self.alias_type_in_runtime_context( | |||
node, ctx=e, alias_definition=e.is_alias_rvalue or lvalue | |||
) | |||
elif isinstance(node, (TypeVarExpr, ParamSpecExpr, TypeVarTupleExpr)): | |||
elif isinstance(node, TypeVarExpr): | |||
return self.named_type("typing.TypeVar") |
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.
Will this cause crashes on Python versions where TypeVar
is not a proper class? And/or if it is imported from typing_extensions
(e.g. by people who want the type variables with defaults)?
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.
TypeVar has been a class since at least 3.6, for what it's worth: https://github.com/python/cpython/blob/8d999cbf4adea053be6dbb612b9844635c4dfb8e/Lib/typing.py#L453.
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.
TypeVar
is defined unconditionally as a class in typeshed:
@final
class TypeVar:
@property
def __name__(self) -> str: ...
@property
def __bound__(self) -> Any | None: ...
...
Also on the oldest supported Python version (3.8) TypeVar
is a class:
Python 3.8.10 (v3.8.10:3d8993a744, May 3 2021, 09:09:08)
[Clang 12.0.5 (clang-1205.0.22.9)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from typing import TypeVar
>>> TypeVar
<class 'typing.TypeVar'>
But this won't be right if TypeVar
is imported from typing_extensions
. It probably won't usually make a difference, but it's possible to imagine runtime introspection use cases where mypy could get confused. But this wasn't properly supported before (when the type was object
), so it doesn't seem like a major issue. I may fix this in a follow-up PR if it's easy enough.
if python_3_12_type_alias: | ||
with self.allow_unbound_tvars_set(): | ||
rvalue.accept(self) |
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 should have been fixed by #17404. Can you try it out?
Yeah it is. Deleted my earlier comment, before I saw yours. Sorry for the noice. -- |
The main tricky bit is supporting uses of type alias objects at runtime. Python evaluates values of type aliases lazily, but there's no way to do this using public APIs, so we directly modify the
TypeAliasType
object that is used to represent a type alias at runtime in C. Unfortunately, this is fragile and will need to be updated each time CPython updates the internal representation ofTypeAliasType
objects.Wrap the target of the type alias within a lambda expression, so that we can easily create the lazy compute function in mypyc. This also reflects how this is implemented in CPython.
Improve test stubs to avoid various false positives or confusing errors in tests when type checking runtime operations on types. This also makes some exisisting tests more realistic.
Follow-up to #17357.