[mypyc] Support Python 3.12 type alias syntax (PEP 695)#17384
[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. ✅ |
ilevkivskyi
left a comment
There was a problem hiding this comment.
LG, but I have one question.
| ) | ||
| elif isinstance(node, (TypeVarExpr, ParamSpecExpr, TypeVarTupleExpr)): | ||
| elif isinstance(node, TypeVarExpr): | ||
| return self.named_type("typing.TypeVar") |
There was a problem hiding this comment.
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.
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.
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.
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
TypeAliasTypeobject 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 ofTypeAliasTypeobjects.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.