← Back to index

aliases_implicit.py

True Positive
False Positive
False Negative
Optional (detected)
Warning or Info
TP: 17
FP: 1
FN: 5
Optional: 0 / 0
1"""
2Tests traditional implicit type aliases.
3"""
4
5# Specification: https://typing.readthedocs.io/en/latest/spec/aliases.html
6
7from collections.abc import Iterable
8from typing import Any, Callable, Concatenate, ParamSpec, TypeVar, Union, assert_type
9
10TFloat = TypeVar("TFloat", bound=float)
11Vector = Iterable[tuple[TFloat, TFloat]]
14def in_product(v: Vector[TFloat]) -> Iterable[TFloat]:
15 return [x for x, _ in v]
18def dilate(v: Vector[float], scale: float) -> Vector[float]:
19 return ((x * scale, y * scale) for x, y in v)
22# > Type aliases may be as complex as type hints in annotations – anything
23# > that is acceptable as a type hint is acceptable in a type alias.
25S = TypeVar("S")
26T = TypeVar("T")
27P = ParamSpec("P")
28R = TypeVar("R")
30GoodTypeAlias1 = Union[int, str]
31GoodTypeAlias2 = int | None
32GoodTypeAlias3 = list[GoodTypeAlias2]
33GoodTypeAlias4 = list[T]
34GoodTypeAlias5 = tuple[T, ...] | list[T]
35GoodTypeAlias6 = tuple[int, int, S, T]
36GoodTypeAlias7 = Callable[..., int]
37GoodTypeAlias8 = Callable[[int, T], T]
38GoodTypeAlias9 = Callable[Concatenate[int, P], R]
39GoodTypeAlias10 = Any
40GoodTypeAlias11 = GoodTypeAlias1 | GoodTypeAlias2 | list[GoodTypeAlias4[int]]
41GoodTypeAlias12 = list[TFloat]
42GoodTypeAlias13 = Callable[P, None]
45def good_type_aliases(
46 p1: GoodTypeAlias1,
47 p2: GoodTypeAlias2,
48 p3: GoodTypeAlias3,
49 p4: GoodTypeAlias4[int],
50 p5: GoodTypeAlias5[str],
51 p6: GoodTypeAlias6[int, str],
52 p7: GoodTypeAlias7,
53 p8: GoodTypeAlias8[str],
54 p9: GoodTypeAlias9[[str, str], None],
55 p10: GoodTypeAlias10,
56 p11: GoodTypeAlias11,
57 p12: GoodTypeAlias12[bool],
58 p13: GoodTypeAlias13
59):
60 assert_type(p1, int | str)
61 assert_type(p2, int | None)
62 assert_type(p3, list[int | None])
63 assert_type(p4, list[int])
64 assert_type(p5, tuple[str, ...] | list[str])
65 assert_type(p6, tuple[int, int, int, str])
66 assert_type(p7, Callable[..., int])
67 assert_type(p8, Callable[[int, str], str])
68 assert_type(p9, Callable[[int, str, str], None])
Unexpected error [type-assertion-failure] Type `(int, str, str, /) -> None` does not match asserted type `Unknown`
69 assert_type(p10, Any)
70 assert_type(p11, int | str | None | list[list[int]])
71 assert_type(p12, list[bool])
72 assert_type(p13, Callable[..., None])
75def good_type_aliases_used_badly(
76 p1: GoodTypeAlias2[int], # E: type alias is not generic
[not-subscriptable] Cannot subscript non-generic type
77 p2: GoodTypeAlias3[int], # E: type alias is already specialized
[not-subscriptable] Cannot subscript non-generic type: `<class 'list[int | None]'>` is already specialized
78 p3: GoodTypeAlias4[int, int], # E: too many type arguments
[invalid-type-arguments] Too many type arguments: expected 1, got 2
79 p4: GoodTypeAlias8[int, int], # E: too many type arguments
[invalid-type-arguments] Too many type arguments: expected 1, got 2
80 p5: GoodTypeAlias9[int, int], # E: bad type argument for ParamSpec
[invalid-type-arguments] Type argument for `ParamSpec` must be either a list of types, `ParamSpec`, `Concatenate`, or `...`
81 p6: GoodTypeAlias12[str], # E: type argument doesn't match bound
[invalid-type-arguments] Type `str` is not assignable to upper bound `int | float` of type variable `TFloat@GoodTypeAlias12`
82):
83 pass
86var1 = 3
88# The following should not be considered type aliases.
89BadTypeAlias1 = eval("".join(map(chr, [105, 110, 116])))
90BadTypeAlias2 = [int, str]
91BadTypeAlias3 = ((int, str),)
92BadTypeAlias4 = [int for i in range(1)]
93BadTypeAlias5 = {"a": "b"}
94BadTypeAlias6 = (lambda: int)()
95BadTypeAlias7 = [int][0]
96BadTypeAlias8 = int if 1 < 3 else str
97BadTypeAlias9 = var1
98BadTypeAlias10 = True
99BadTypeAlias11 = 1
100BadTypeAlias12 = list or set
101BadTypeAlias13 = f"int"
102BadTypeAlias14 = "int | str"
105def bad_type_aliases(
106 p1: BadTypeAlias1, # E: Invalid type annotation
Expected a ty diagnostic for this line
107 p2: BadTypeAlias2, # E: Invalid type annotation
[invalid-type-form] Variable of type `list[Unknown | <class 'int'> | <class 'str'>]` is not allowed in a type expression
108 p3: BadTypeAlias3, # E: Invalid type annotation
[invalid-type-form] Variable of type `tuple[tuple[<class 'int'>, <class 'str'>]]` is not allowed in a type expression
109 p4: BadTypeAlias4, # E: Invalid type annotation
[invalid-type-form] Variable of type `list[Unknown | <class 'int'>]` is not allowed in a type expression
110 p5: BadTypeAlias5, # E: Invalid type annotation
[invalid-type-form] Variable of type `dict[Unknown | str, Unknown | str]` is not allowed in a type expression
111 p6: BadTypeAlias6, # E: Invalid type annotation
Expected a ty diagnostic for this line
112 p7: BadTypeAlias7, # E: Invalid type annotation
Expected a ty diagnostic for this line
113 p8: BadTypeAlias8, # E: Invalid type annotation
Expected a ty diagnostic for this line
114 p9: BadTypeAlias9, # E: Invalid type annotation
[invalid-type-form] Variable of type `Literal[3]` is not allowed in a type expression
115 p10: BadTypeAlias10, # E: Invalid type annotation
[invalid-type-form] Variable of type `Literal[True]` is not allowed in a type expression
116 p11: BadTypeAlias11, # E: Invalid type annotation
[invalid-type-form] Variable of type `Literal[1]` is not allowed in a type expression
117 p12: BadTypeAlias12, # E: Invalid type annotation
Expected a ty diagnostic for this line
118 p13: BadTypeAlias13, # E: Invalid type annotation
[invalid-type-form] Variable of type `Literal["int"]` is not allowed in a type expression
119 p14: BadTypeAlias14, # E: Invalid type annotation
[invalid-type-form] Variable of type `Literal["int | str"]` is not allowed in a type expression
120):
121 pass
124ListAlias = list
125ListOrSetAlias = list | set
127x1: list[str] = ListAlias() # OK
128assert_type(x1, list[str])
130x2 = ListAlias[int]() # OK
131assert_type(x2, list[int])
133x3 = ListOrSetAlias() # E: cannot instantiate union
[call-non-callable] Object of type `UnionType` is not callable
135x4: ListOrSetAlias[int] # E: already specialized
[not-subscriptable] Cannot subscript non-generic type