[ty] Generic types aliases (implicit and PEP 613)#21553
Conversation
Diagnostic diff on typing conformance testsChanges were detected when running ty on typing conformance tests--- old-output.txt 2025-11-28 19:17:48.980568399 +0000
+++ new-output.txt 2025-11-28 19:17:52.680561701 +0000
@@ -4,21 +4,26 @@
_directives_deprecated_library.py:41:25: error[invalid-return-type] Function always implicitly returns `None`, which is not assignable to return type `int | float`
_directives_deprecated_library.py:45:24: error[invalid-return-type] Function always implicitly returns `None`, which is not assignable to return type `str`
aliases_explicit.py:41:24: error[invalid-type-form] List literals are not allowed in this context in a type expression: Did you mean `tuple[str, str]`?
-aliases_explicit.py:52:5: error[type-assertion-failure] Type `list[int]` does not match asserted type `@Todo(specialized generic alias in type expression)`
-aliases_explicit.py:53:5: error[type-assertion-failure] Type `tuple[str, ...] | list[str]` does not match asserted type `@Todo(Generic specialization of types.UnionType)`
-aliases_explicit.py:54:5: error[type-assertion-failure] Type `tuple[int, int, int, str]` does not match asserted type `@Todo(specialized generic alias in type expression)`
-aliases_explicit.py:56:5: error[type-assertion-failure] Type `(int, str, /) -> str` does not match asserted type `@Todo(Generic specialization of typing.Callable)`
-aliases_explicit.py:57:5: error[type-assertion-failure] Type `(int, str, str, /) -> None` does not match asserted type `@Todo(Generic specialization of typing.Callable)`
-aliases_explicit.py:59:5: error[type-assertion-failure] Type `int | str | None | list[list[int]]` does not match asserted type `int | str | None | list[@Todo(specialized generic alias in type expression)]`
+aliases_explicit.py:41:36: error[invalid-type-arguments] Too many type arguments: expected 1, got 2
+aliases_explicit.py:57:5: error[type-assertion-failure] Type `(int, str, str, /) -> None` does not match asserted type `(...) -> Unknown`
+aliases_explicit.py:60:5: error[type-assertion-failure] Type `(...) -> None` does not match asserted type `@Todo(Callable[..] specialized with ParamSpec)`
+aliases_explicit.py:67:24: error[invalid-type-arguments] Too many type arguments: expected 0, got 1
+aliases_explicit.py:68:24: error[invalid-type-arguments] Too many type arguments: expected 0, got 1
+aliases_explicit.py:69:29: error[invalid-type-arguments] Too many type arguments: expected 1, got 2
+aliases_explicit.py:70:29: error[invalid-type-arguments] Too many type arguments: expected 1, got 2
+aliases_explicit.py:71:29: error[invalid-type-arguments] Too many type arguments: expected 1, got 2
aliases_explicit.py:101:6: error[call-non-callable] Object of type `UnionType` is not callable
+aliases_explicit.py:102:20: error[invalid-type-arguments] Too many type arguments: expected 0, got 1
aliases_implicit.py:54:24: error[invalid-type-form] List literals are not allowed in this context in a type expression: Did you mean `tuple[str, str]`?
-aliases_implicit.py:63:5: error[type-assertion-failure] Type `list[int]` does not match asserted type `@Todo(specialized generic alias in type expression)`
-aliases_implicit.py:64:5: error[type-assertion-failure] Type `tuple[str, ...] | list[str]` does not match asserted type `@Todo(Generic specialization of types.UnionType)`
-aliases_implicit.py:65:5: error[type-assertion-failure] Type `tuple[int, int, int, str]` does not match asserted type `@Todo(specialized generic alias in type expression)`
-aliases_implicit.py:67:5: error[type-assertion-failure] Type `(int, str, /) -> str` does not match asserted type `@Todo(Generic specialization of typing.Callable)`
-aliases_implicit.py:68:5: error[type-assertion-failure] Type `(int, str, str, /) -> None` does not match asserted type `@Todo(Generic specialization of typing.Callable)`
-aliases_implicit.py:70:5: error[type-assertion-failure] Type `int | str | None | list[list[int]]` does not match asserted type `int | str | None | list[@Todo(specialized generic alias in type expression)]`
-aliases_implicit.py:71:5: error[type-assertion-failure] Type `list[bool]` does not match asserted type `@Todo(specialized generic alias in type expression)`
+aliases_implicit.py:54:36: error[invalid-type-arguments] Too many type arguments: expected 1, got 2
+aliases_implicit.py:68:5: error[type-assertion-failure] Type `(int, str, str, /) -> None` does not match asserted type `(...) -> Unknown`
+aliases_implicit.py:72:5: error[type-assertion-failure] Type `(...) -> None` does not match asserted type `@Todo(Callable[..] specialized with ParamSpec)`
+aliases_implicit.py:76:24: error[invalid-type-arguments] Too many type arguments: expected 0, got 1
+aliases_implicit.py:77:24: error[invalid-type-arguments] Too many type arguments: expected 0, got 1
+aliases_implicit.py:78:29: error[invalid-type-arguments] Too many type arguments: expected 1, got 2
+aliases_implicit.py:79:29: error[invalid-type-arguments] Too many type arguments: expected 1, got 2
+aliases_implicit.py:80:29: error[invalid-type-arguments] Too many type arguments: expected 1, got 2
+aliases_implicit.py:81:25: error[invalid-type-arguments] Type `str` is not assignable to upper bound `int | float` of type variable `TFloat@GoodTypeAlias12`
aliases_implicit.py:107:9: error[invalid-type-form] Variable of type `list[Unknown | <class 'int'> | <class 'str'>]` is not allowed in a type expression
aliases_implicit.py:108:9: error[invalid-type-form] Variable of type `tuple[tuple[<class 'int'>, <class 'str'>]]` is not allowed in a type expression
aliases_implicit.py:109:9: error[invalid-type-form] Variable of type `list[<class 'int'> | Unknown]` is not allowed in a type expression
@@ -29,6 +34,7 @@
aliases_implicit.py:118:10: error[invalid-type-form] Variable of type `Literal["int"]` is not allowed in a type expression
aliases_implicit.py:119:10: error[invalid-type-form] Variable of type `Literal["int | str"]` is not allowed in a type expression
aliases_implicit.py:133:6: error[call-non-callable] Object of type `UnionType` is not callable
+aliases_implicit.py:135:20: error[invalid-type-arguments] Too many type arguments: expected 0, got 1
aliases_newtype.py:11:8: error[invalid-argument-type] Argument is incorrect: Expected `int`, found `Literal["user"]`
aliases_newtype.py:12:14: error[invalid-assignment] Object of type `Literal[42]` is not assignable to `UserId`
aliases_newtype.py:18:11: error[invalid-assignment] Object of type `<NewType pseudo-class 'UserId'>` is not assignable to `type`
@@ -75,7 +81,6 @@
aliases_type_statement.py:88:1: error[cyclic-type-alias-definition] Cyclic definition of `RecursiveTypeAlias6`
aliases_type_statement.py:89:1: error[cyclic-type-alias-definition] Cyclic definition of `RecursiveTypeAlias7`
aliases_typealiastype.py:32:7: error[unresolved-attribute] Object of type `typing.TypeAliasType` has no attribute `other_attrib`
-aliases_typealiastype.py:39:26: error[invalid-type-form] List literals are not allowed in this context in a type expression: Did you mean `tuple[int, str]`?
aliases_typealiastype.py:52:40: error[invalid-type-form] Function calls are not allowed in type expressions
aliases_typealiastype.py:53:40: error[invalid-type-form] List literals are not allowed in this context in a type expression: Did you mean `tuple[int, str]`?
aliases_typealiastype.py:54:42: error[invalid-type-form] Tuple literals are not allowed in this context in a type expression
@@ -92,9 +97,6 @@
aliases_typealiastype.py:63:42: error[invalid-type-form] Boolean operations are not allowed in type expressions
aliases_typealiastype.py:64:42: error[invalid-type-form] F-strings are not allowed in type expressions
aliases_typealiastype.py:66:47: error[unresolved-reference] Name `BadAlias21` used when not defined
-aliases_variance.py:18:24: error[non-subscriptable] Cannot subscript object of type `<class 'ClassA[typing.TypeVar]'>` with no `__class_getitem__` method
-aliases_variance.py:28:16: error[non-subscriptable] Cannot subscript object of type `<class 'ClassA[typing.TypeVar]'>` with no `__class_getitem__` method
-aliases_variance.py:44:16: error[non-subscriptable] Cannot subscript object of type `<class 'ClassB[typing.TypeVar, typing.TypeVar]'>` with no `__class_getitem__` method
annotations_forward_refs.py:47:10: error[invalid-type-form] Invalid subscript of object of type `list[Unknown | <class 'int'>]` in type expression
annotations_forward_refs.py:49:10: error[invalid-type-form] Variable of type `Literal[1]` is not allowed in a type expression
annotations_forward_refs.py:54:11: error[fstring-type-annotation] Type expressions cannot use f-strings
@@ -139,6 +141,10 @@
callables_annotation.py:58:5: error[invalid-type-form] Special form `typing.Callable` expected exactly two arguments (parameter types and return type)
callables_annotation.py:58:14: error[invalid-type-form] The first argument to `Callable` must be either a list of types, ParamSpec, Concatenate, or `...`
callables_annotation.py:157:20: error[invalid-assignment] Object of type `Proto7` is not assignable to `Proto6`
+callables_annotation.py:172:19: error[invalid-type-arguments] Too many type arguments: expected 0, got 1
+callables_annotation.py:175:19: error[invalid-type-arguments] Too many type arguments: expected 0, got 1
+callables_annotation.py:188:25: error[invalid-type-arguments] Too many type arguments: expected 0, got 1
+callables_annotation.py:189:25: error[invalid-type-arguments] Too many type arguments: expected 0, got 1
callables_kwargs.py:24:5: error[type-assertion-failure] Type `int` does not match asserted type `@Todo(`Unpack[]` special form)`
callables_kwargs.py:32:9: error[type-assertion-failure] Type `str` does not match asserted type `@Todo(`Unpack[]` special form)`
callables_kwargs.py:35:5: error[type-assertion-failure] Type `str` does not match asserted type `@Todo(`Unpack[]` special form)`
@@ -467,9 +473,8 @@
generics_defaults_referential.py:37:10: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `int`, found `Literal[""]`
generics_defaults_referential.py:94:1: error[type-assertion-failure] Type `type[Bar[Any, list[Any]]]` does not match asserted type `<class 'Bar'>`
generics_defaults_referential.py:95:1: error[type-assertion-failure] Type `type[Bar[int, list[int]]]` does not match asserted type `<class 'Bar[int, list[int]]'>`
-generics_defaults_specialization.py:26:5: error[type-assertion-failure] Type `SomethingWithNoDefaults[int, str]` does not match asserted type `SomethingWithNoDefaults[int, typing.TypeVar]`
-generics_defaults_specialization.py:27:5: error[type-assertion-failure] Type `SomethingWithNoDefaults[int, bool]` does not match asserted type `@Todo(specialized generic alias in type expression)`
-generics_defaults_specialization.py:30:1: error[non-subscriptable] Cannot subscript object of type `<class 'SomethingWithNoDefaults[int, typing.TypeVar]'>` with no `__class_getitem__` method
+generics_defaults_specialization.py:26:5: error[type-assertion-failure] Type `SomethingWithNoDefaults[int, str]` does not match asserted type `SomethingWithNoDefaults[int, DefaultStrT]`
+generics_defaults_specialization.py:30:15: error[invalid-type-arguments] Too many type arguments: expected between 0 and 1, got 2
generics_defaults_specialization.py:45:1: error[type-assertion-failure] Type `type[Bar[str]]` does not match asserted type `<class 'Bar'>`
generics_paramspec_basic.py:10:1: error[invalid-paramspec] The name of a `ParamSpec` (`NotIt`) must match the name of the variable it is assigned to (`WrongName`)
generics_paramspec_basic.py:23:20: error[invalid-return-type] Function always implicitly returns `None`, which is not assignable to return type `P@func1`
@@ -617,27 +622,41 @@
generics_typevartuple_concat.py:52:1: error[type-assertion-failure] Type `tuple[int, bool, str]` does not match asserted type `tuple[@Todo(PEP 646), ...]`
generics_typevartuple_overloads.py:16:13: error[invalid-argument-type] `@Todo(starred expression)` is not a valid argument to `Generic`
generics_typevartuple_specialization.py:16:13: error[invalid-argument-type] `@Todo(starred expression)` is not a valid argument to `Generic`
-generics_typevartuple_specialization.py:46:5: error[type-assertion-failure] Type `tuple[int, int | float, bool]` does not match asserted type `@Todo(specialized generic alias in type expression)`
-generics_typevartuple_specialization.py:47:5: error[type-assertion-failure] Type `tuple[str, @Todo(specialized non-generic class)]` does not match asserted type `@Todo(specialized generic alias in type expression)`
-generics_typevartuple_specialization.py:50:23: error[invalid-type-form] Tuple literals are not allowed in this context in a type expression: Did you mean `tuple[()]`?
-generics_typevartuple_specialization.py:50:42: error[invalid-type-form] Tuple literals are not allowed in this context in a type expression: Did you mean `tuple[()]`?
-generics_typevartuple_specialization.py:51:5: error[type-assertion-failure] Type `tuple[int]` does not match asserted type `@Todo(specialized generic alias in type expression)`
-generics_typevartuple_specialization.py:52:5: error[type-assertion-failure] Type `tuple[str, @Todo(specialized non-generic class)]` does not match asserted type `@Todo(specialized generic alias in type expression)`
+generics_typevartuple_specialization.py:45:23: error[invalid-type-arguments] Too many type arguments: expected 0, got 2
+generics_typevartuple_specialization.py:45:51: error[invalid-type-arguments] Too many type arguments: expected 0, got 1
+generics_typevartuple_specialization.py:46:5: error[type-assertion-failure] Type `tuple[int, int | float, bool]` does not match asserted type `tuple[@Todo(PEP 646), ...]`
+generics_typevartuple_specialization.py:51:5: error[type-assertion-failure] Type `tuple[int]` does not match asserted type `tuple[@Todo(PEP 646), ...]`
generics_typevartuple_specialization.py:52:37: error[invalid-type-form] Tuple literals are not allowed in this context in a type expression: Did you mean `tuple[()]`?
generics_typevartuple_specialization.py:59:14: error[invalid-argument-type] `@Todo(starred expression)` is not a valid argument to `Generic`
-generics_typevartuple_specialization.py:93:5: error[type-assertion-failure] Type `tuple[str, int]` does not match asserted type `@Todo(specialized generic alias in type expression)`
-generics_typevartuple_specialization.py:94:5: error[type-assertion-failure] Type `tuple[int | float]` does not match asserted type `@Todo(specialized generic alias in type expression)`
+generics_typevartuple_specialization.py:92:28: error[invalid-type-arguments] Too many type arguments: expected 0, got 2
+generics_typevartuple_specialization.py:92:56: error[invalid-type-arguments] Too many type arguments: expected 0, got 1
+generics_typevartuple_specialization.py:93:5: error[type-assertion-failure] Type `tuple[str, int]` does not match asserted type `tuple[@Todo(PEP 646), ...]`
+generics_typevartuple_specialization.py:94:5: error[type-assertion-failure] Type `tuple[int | float]` does not match asserted type `tuple[@Todo(PEP 646), ...]`
generics_typevartuple_specialization.py:95:5: error[type-assertion-failure] Type `tuple[Any, *tuple[Any, ...]]` does not match asserted type `tuple[@Todo(PEP 646), ...]`
+generics_typevartuple_specialization.py:102:32: error[invalid-type-arguments] Too many type arguments: expected 0, got 2
+generics_typevartuple_specialization.py:103:33: error[invalid-type-arguments] Too many type arguments: expected 0, got 1
+generics_typevartuple_specialization.py:127:9: error[invalid-type-arguments] Too many type arguments: expected 0, got 1
+generics_typevartuple_specialization.py:130:18: error[invalid-type-arguments] Too many type arguments: expected 0, got 3
generics_typevartuple_specialization.py:130:35: error[invalid-return-type] Function always implicitly returns `None`, which is not assignable to return type `tuple[tuple[@Todo(PEP 646), ...], T1@func7, T2@func7]`
+generics_typevartuple_specialization.py:134:18: error[invalid-type-arguments] Too many type arguments: expected 0, got 2
+generics_typevartuple_specialization.py:134:37: error[invalid-type-arguments] Too many type arguments: expected 0, got 3
+generics_typevartuple_specialization.py:134:63: error[invalid-type-arguments] Too many type arguments: expected 0, got 4
generics_typevartuple_specialization.py:135:5: error[type-assertion-failure] Type `tuple[tuple[()], str, bool]` does not match asserted type `tuple[tuple[@Todo(PEP 646), ...], Unknown, Unknown]`
generics_typevartuple_specialization.py:136:5: error[type-assertion-failure] Type `tuple[tuple[str], bool, int | float]` does not match asserted type `tuple[tuple[@Todo(PEP 646), ...], Unknown, Unknown]`
generics_typevartuple_specialization.py:137:5: error[type-assertion-failure] Type `tuple[tuple[str, bool], int | float, int]` does not match asserted type `tuple[tuple[@Todo(PEP 646), ...], Unknown, Unknown]`
+generics_typevartuple_specialization.py:143:18: error[invalid-type-arguments] Too many type arguments: expected 0, got 4
generics_typevartuple_specialization.py:143:39: error[invalid-return-type] Function always implicitly returns `None`, which is not assignable to return type `tuple[tuple[@Todo(PEP 646), ...], T1@func9, T2@func9, T3@func9]`
+generics_typevartuple_specialization.py:147:19: error[invalid-type-arguments] Too many type arguments: expected 0, got 3
+generics_typevartuple_specialization.py:147:45: error[invalid-type-arguments] Too many type arguments: expected 0, got 4
generics_typevartuple_specialization.py:148:5: error[type-assertion-failure] Type `tuple[tuple[()], str, bool, int | float]` does not match asserted type `tuple[tuple[@Todo(PEP 646), ...], Unknown, Unknown, Unknown]`
generics_typevartuple_specialization.py:149:5: error[type-assertion-failure] Type `tuple[tuple[bool], str, int | float, int]` does not match asserted type `tuple[tuple[@Todo(PEP 646), ...], Unknown, Unknown, Unknown]`
-generics_typevartuple_specialization.py:157:5: error[type-assertion-failure] Type `tuple[*tuple[int, ...], int]` does not match asserted type `@Todo(Support for `typing.GenericAlias` instances in type expressions)`
-generics_typevartuple_specialization.py:158:5: error[type-assertion-failure] Type `tuple[*tuple[int, ...], str]` does not match asserted type `@Todo(specialized generic alias in type expression)`
-generics_typevartuple_specialization.py:159:5: error[type-assertion-failure] Type `tuple[*tuple[int, ...], str]` does not match asserted type `@Todo(specialized generic alias in type expression)`
+generics_typevartuple_specialization.py:153:12: error[invalid-type-arguments] Too many type arguments: expected 0, got 1
+generics_typevartuple_specialization.py:156:28: error[invalid-type-arguments] Too many type arguments: expected 0, got 2
+generics_typevartuple_specialization.py:156:59: error[invalid-type-arguments] Too many type arguments: expected 0, got 2
+generics_typevartuple_specialization.py:157:5: error[type-assertion-failure] Type `tuple[*tuple[int, ...], int]` does not match asserted type `tuple[@Todo(PEP 646), ...]`
+generics_typevartuple_specialization.py:158:5: error[type-assertion-failure] Type `tuple[*tuple[int, ...], str]` does not match asserted type `tuple[@Todo(PEP 646), ...]`
+generics_typevartuple_specialization.py:159:5: error[type-assertion-failure] Type `tuple[*tuple[int, ...], str]` does not match asserted type `tuple[@Todo(PEP 646), ...]`
+generics_typevartuple_specialization.py:163:13: error[invalid-type-arguments] Too many type arguments: expected 0, got 1
generics_typevartuple_unpack.py:17:13: error[invalid-argument-type] `@Todo(starred expression)` is not a valid argument to `Generic`
generics_upper_bound.py:37:1: error[type-assertion-failure] Type `list[int]` does not match asserted type `list[Unknown | int]`
generics_upper_bound.py:38:1: error[type-assertion-failure] Type `set[int]` does not match asserted type `set[Unknown | int]`
@@ -648,20 +667,6 @@
generics_variance.py:14:6: error[invalid-legacy-type-variable] A `TypeVar` cannot be both covariant and contravariant
generics_variance.py:26:27: error[invalid-return-type] Function always implicitly returns `None`, which is not assignable to return type `Iterator[T_co@ImmutableList]`
generics_variance.py:57:28: error[invalid-return-type] Function always implicitly returns `None`, which is not assignable to return type `B_co@func`
-generics_variance.py:175:25: error[non-subscriptable] Cannot subscript object of type `<class 'Contra[typing.TypeVar]'>` with no `__class_getitem__` method
-generics_variance.py:175:35: error[non-subscriptable] Cannot subscript object of type `<class 'Co[typing.TypeVar]'>` with no `__class_getitem__` method
-generics_variance.py:179:29: error[non-subscriptable] Cannot subscript object of type `<class 'Contra[typing.TypeVar]'>` with no `__class_getitem__` method
-generics_variance.py:179:39: error[non-subscriptable] Cannot subscript object of type `<class 'Contra[typing.TypeVar]'>` with no `__class_getitem__` method
-generics_variance.py:183:21: error[non-subscriptable] Cannot subscript object of type `<class 'Co[typing.TypeVar]'>` with no `__class_getitem__` method
-generics_variance.py:183:27: error[non-subscriptable] Cannot subscript object of type `<class 'Co[typing.TypeVar]'>` with no `__class_getitem__` method
-generics_variance.py:187:25: error[non-subscriptable] Cannot subscript object of type `<class 'Co[typing.TypeVar]'>` with no `__class_getitem__` method
-generics_variance.py:187:31: error[non-subscriptable] Cannot subscript object of type `<class 'Contra[typing.TypeVar]'>` with no `__class_getitem__` method
-generics_variance.py:191:33: error[non-subscriptable] Cannot subscript object of type `<class 'Contra[typing.TypeVar]'>` with no `__class_getitem__` method
-generics_variance.py:191:43: error[non-subscriptable] Cannot subscript object of type `<class 'Co[typing.TypeVar]'>` with no `__class_getitem__` method
-generics_variance.py:191:49: error[non-subscriptable] Cannot subscript object of type `<class 'Contra[typing.TypeVar]'>` with no `__class_getitem__` method
-generics_variance.py:196:5: error[non-subscriptable] Cannot subscript object of type `<class 'Contra[typing.TypeVar]'>` with no `__class_getitem__` method
-generics_variance.py:196:15: error[non-subscriptable] Cannot subscript object of type `<class 'Contra[typing.TypeVar]'>` with no `__class_getitem__` method
-generics_variance.py:196:25: error[non-subscriptable] Cannot subscript object of type `<class 'Contra[typing.TypeVar]'>` with no `__class_getitem__` method
generics_variance_inference.py:19:26: error[invalid-return-type] Function always implicitly returns `None`, which is not assignable to return type `T3@ClassA`
generics_variance_inference.py:24:33: error[invalid-assignment] Object of type `ClassA[int | float, int, int]` is not assignable to `ClassA[int, int, int]`
generics_variance_inference.py:25:37: error[invalid-assignment] Object of type `ClassA[int | float, int, int]` is not assignable to `ClassA[int | float, int | float, int]`
@@ -930,10 +935,6 @@
specialtypes_type.py:139:5: error[type-assertion-failure] Type `type[Any]` does not match asserted type `type`
specialtypes_type.py:143:1: error[unresolved-attribute] Object of type `typing.Type` has no attribute `unknown`
specialtypes_type.py:145:1: error[unresolved-attribute] Class `type` has no attribute `unknown`
-specialtypes_type.py:152:16: error[invalid-type-form] `typing.TypeVar` is not a generic class
-specialtypes_type.py:156:16: error[invalid-type-form] `typing.TypeVar` is not a generic class
-specialtypes_type.py:160:1: error[type-assertion-failure] Type `int` does not match asserted type `Unknown`
-specialtypes_type.py:161:1: error[type-assertion-failure] Type `int` does not match asserted type `Unknown`
specialtypes_type.py:169:21: error[invalid-assignment] Object of type `type` is not assignable to `type[int]`
specialtypes_type.py:175:16: error[invalid-return-type] Return type does not match returned value: expected `type[T@ClassA]`, found `type`
tuples_type_compat.py:15:27: error[invalid-assignment] Object of type `tuple[int | float, int | float | complex]` is not assignable to `tuple[int, int]`
@@ -1038,4 +1039,4 @@
typeddicts_usage.py:28:17: error[missing-typed-dict-key] Missing required key 'name' in TypedDict `Movie` constructor
typeddicts_usage.py:28:18: error[invalid-key] Unknown key "title" for TypedDict `Movie`: Unknown key "title"
typeddicts_usage.py:40:24: error[invalid-type-form] The special form `typing.TypedDict` is not allowed in type expressions
-Found 1040 diagnostics
+Found 1041 diagnostics
|
| reveal_type(a) # revealed: int | ||
| reveal_type(b) # revealed: int |
There was a problem hiding this comment.
We now understand the _FutureLike type alias.
|
| Lint rule | Added | Removed | Changed |
|---|---|---|---|
type-assertion-failure |
416 | 510 | 1,474 |
invalid-argument-type |
818 | 347 | 153 |
invalid-type-arguments |
628 | 55 | 4 |
no-matching-overload |
637 | 13 | 0 |
unsupported-operator |
376 | 10 | 19 |
unused-ignore-comment |
11 | 393 | 0 |
possibly-missing-attribute |
156 | 51 | 96 |
invalid-return-type |
254 | 10 | 13 |
unresolved-attribute |
85 | 90 | 37 |
invalid-assignment |
109 | 12 | 23 |
non-subscriptable |
32 | 29 | 8 |
invalid-type-form |
1 | 35 | 2 |
invalid-context-manager |
0 | 0 | 32 |
not-iterable |
22 | 0 | 6 |
invalid-await |
22 | 2 | 3 |
invalid-method-override |
18 | 0 | 2 |
invalid-parameter-default |
9 | 0 | 3 |
call-non-callable |
1 | 7 | 1 |
redundant-cast |
3 | 0 | 0 |
invalid-raise |
2 | 0 | 0 |
too-many-positional-arguments |
0 | 2 | 0 |
unresolved-reference |
0 | 2 | 0 |
unsupported-base |
0 | 2 | 0 |
parameter-already-assigned |
0 | 1 | 0 |
| Total | 3,600 | 1,571 | 1,876 |
8c80d76 to
812d07b
Compare
CodSpeed Performance ReportMerging #21553 will degrade performances by 77.43%Comparing Summary
Benchmarks breakdown
|
|
0a44b07 to
d85469e
Compare
e951039 to
6aaa9d7
Compare
6aaa9d7 to
d2456eb
Compare
422f31e to
495dfe3
Compare
There was a problem hiding this comment.
Just a review of the tests so far. A couple more tests you could add (possibly in a followup). I haven't checked whether or not these pass on your branch, just some pathological cases I thought of while reading your tests:
from typing import TypeAlias, TypeVar
T = TypeVar("T")
U = TypeVar("U")
TotallyStringifiedPEP613: TypeAlias = "dict[T, U]"
TotallyStringifiedPartiallySpecialized: TypeAlias = "TotallyStringifiedPEP613[U, int]"
def f(x: "TotallyStringifiedPartiallySpecialized[str]"):
reveal_type(x) # revealed: dict[str, int](Edit David: Added. This one still resolves to a @Todo type that was introduced for this precise case)
and
from typing import TypeVar
T = TypeVar("T")
U = TypeVar("U")
V = TypeVar("V")
X = tuple[T, *tuple[U, ...], V]
Y = X[T, tuple[int, str, U], bytes]
def g(obj: Y[bool, range]):
reveal_type(obj) # revealed: tuple[bool, *tuple[tuple[int, str, range], ...], bytes](Edit David: Added. This one passes!)
| ListOrTupleLegacy = Union[list[T], tuple[T, ...]] | ||
| MyCallable = Callable[P, T] | ||
| AnnotatedType = Annotated[T, "tag"] | ||
| TransparentAlias = T |
There was a problem hiding this comment.
Pyrefly and pyright accept TransparentAlias as a valid type alias, but mypy does not. I think we could consider adding a TODO here for us to reject it too when it appears in a type expression. TransparentAlias[int] fails at runtime, just like T[int] fails at runtime. And there's no reason to use TransparentAlias[int] rather than just int.
There was a problem hiding this comment.
TransparentAlias[int]fails at runtime, just likeT[int]fails at runtime
Ok, but it's sort-of reasonable to have it in a type annotation? I spent extra effort to support it after Carl mentioned it, but we can also remove that special handling again, I guess.
There was a problem hiding this comment.
I'd personally lean towards rejecting it because i can't see any use case for it — it probably indicates that the user is confused about Python typing in some way?
But i don't have a strong opinion; don't let this slow you down when it comes to getting the PR in, if you and/or Carl disagree
There was a problem hiding this comment.
I'd personally lean towards rejecting it because i can't see any use case for it — it probably indicates that the user is confused about Python typing in some way?
Maybe. But it seems like an artificial restriction to me? If MyAlias = T | None and MyAlias = Annotated[T, "bla"] are fine, then why should MyAlias = T be forbidden? A PEP 695 type alias type MyAlias[T] = T is (hopefully) also allowed.
| DictStrTo = MyDict[str, U] | ||
|
|
||
| reveal_type(DictStrTo) # revealed: GenericAlias | ||
| reveal_type(DictStrTo) # revealed: <class 'dict[str, U@DictStrTo]'> | ||
|
|
||
| def _( | ||
| # TODO: No error here | ||
| # error: [invalid-type-form] "Invalid subscript of object of type `GenericAlias` in type expression" | ||
| dict_str_to_int: DictStrTo[int], | ||
| ): | ||
| # TODO: This should be `dict[str, int]` | ||
| reveal_type(dict_str_to_int) # revealed: Unknown | ||
| reveal_type(dict_str_to_int) # revealed: dict[str, int] |
There was a problem hiding this comment.
great work, this is fantastic!
| // Infer slice as a value expression to avoid false-positive | ||
| // `invalid-type-form` diagnostics, when we have e.g. | ||
| // `MyCallable[[int, str], None]` but `MyCallable` is dynamic. | ||
| self.infer_expression(slice, TypeContext::default()); |
There was a problem hiding this comment.
I think there are probably lots more error cases in type-expression parsing where we should do similarly
Summary
Add support for generic PEP 613 type aliases and generic implicit type aliases:
closes astral-sh/ty#1643
closes astral-sh/ty#1629
closes astral-sh/ty#1596
closes astral-sh/ty#573
closes astral-sh/ty#221
Typing conformance
New true negatives ✔️
These require
ParamSpecNew true positives ✔️
New true negatives ✔️
These require
ParamSpecNew true positives ✔️
These require
ParamSpecandConcatenate.Favorable diagnostic change ✔️
-generics_defaults_specialization.py:27:5: error[type-assertion-failure] Type `SomethingWithNoDefaults[int, bool]` does not match asserted type `@Todo(specialized generic alias in type expression)`New true negative ✔️
Correct new diagnostic ✔️
One of these should apparently be an error, but not of this kind, so this is good ✔️
Good, those were false positives. ✔️
I skipped the analysis for everything involving
TypeVarTuple.Ecosystem impact
Full report with detailed diff
Previous iterations of this PR showed all kinds of problems. In it's current state, I do not see any large systematic problems, but it is hard to tell with 5k diagnostic changes.
Performance
colour-science/colour, related to this large file with many assignments of hard-coded arrays (lists of lists) tonp.NDArraytypes that we now understand. We now take ~2 seconds to check this file, so definitely not great, but maybe acceptable for now.Test Plan
Updated and new Markdown tests