← Back to index

generics_defaults_specialization.py

True Positive
False Positive
False Negative
Optional (detected)
Warning or Info
TP: 1
FP: 0
FN: 1
Optional: 0 / 0
1"""
2Tests for specialization rules associated with type parameters with
3default values.
4"""
5
6# > A generic type alias can be further subscripted following normal subscription
7# > rules. If a type parameter has a default that hasn't been overridden, it should
8# > be treated like it was substituted into the type alias.
9
10from typing import Generic, TypeAlias, assert_type
11from typing_extensions import TypeVar
13T1 = TypeVar("T1")
14T2 = TypeVar("T2")
15DefaultIntT = TypeVar("DefaultIntT", default=int)
16DefaultStrT = TypeVar("DefaultStrT", default=str)
19class SomethingWithNoDefaults(Generic[T1, T2]): ...
22MyAlias: TypeAlias = SomethingWithNoDefaults[int, DefaultStrT] # OK
25def func1(p1: MyAlias, p2: MyAlias[bool]):
26 assert_type(p1, SomethingWithNoDefaults[int, str])
27 assert_type(p2, SomethingWithNoDefaults[int, bool])
30MyAlias[bool, int] # E: too many arguments passed to MyAlias
[invalid-type-arguments] Too many type arguments: expected between 0 and 1, got 2
33# > Generic classes with type parameters that have defaults behave similarly
34# > generic type aliases. That is, subclasses can be further subscripted following
35# > normal subscription rules, non-overridden defaults should be substituted.
38class SubclassMe(Generic[T1, DefaultStrT]):
39 x: DefaultStrT
42class Bar(SubclassMe[int, DefaultStrT]): ...
45assert_type(Bar, type[Bar[str]])
46assert_type(Bar(), Bar[str])
47assert_type(Bar[bool](), Bar[bool])
50class Foo(SubclassMe[float]): ...
53assert_type(Foo().x, str)
55Foo[str] # E: Foo cannot be further subscripted
Expected a ty diagnostic for this line
58class Baz(Generic[DefaultIntT, DefaultStrT]): ...
61class Spam(Baz): ...
64# Spam is <subclass of Baz[int, str]>
65v1: Baz[int, str] = Spam()