2Tests type variable variance inference for generic protocols.
5# Specification: https://typing.readthedocs.io/en/latest/spec/protocol.html#generic-protocols
7from typing import ParamSpec, Protocol, TypeVar
10T2 = TypeVar("T2", bound=int)
11T3 = TypeVar("T3", bytes, str)
12T1_co = TypeVar("T1_co", covariant=True)
13T1_contra = TypeVar("T1_contra", contravariant=True)
15R = TypeVar("R", covariant=True)
17# > Type checkers will warn if the inferred variance is different from the
21class AnotherBox(Protocol[T1]): # E: T should be covariant
Expected a ty diagnostic for this line
22 def content(self) -> T1:
26class Protocol1(Protocol[T1, T2, T3]): # OK
27 def m1(self, p0: T1, p1: T2, p2: T3) -> T1 | T2:
40class Protocol2(Protocol[T1, T2, T3]): # E: T3 should be contravariant
Expected a ty diagnostic for this line
41 def m1(self, p0: T1, p1: T2, p2: T3) -> T1:
51class Protocol3(Protocol[T1_co]):
56class Protocol4(Protocol[T1]): # E: T1 should be contravariant
Expected a ty diagnostic for this line
57 def m1(self, p0: T1) -> None:
61class Protocol5(Protocol[T1_co]): # E[covariant_in_input+]
Expected a ty diagnostic for this line (tag 'covariant_in_input')
62 def m1(self, p0: T1_co) -> None: # E[covariant_in_input+]
Expected a ty diagnostic for this line (tag 'covariant_in_input')
66class Protocol6(Protocol[T1]): # E: T1 should be covariant
Expected a ty diagnostic for this line
71class Protocol7(Protocol[T1_contra]): # E[contravariant_in_output+]
Expected a ty diagnostic for this line (tag 'contravariant_in_output')
72 def m1(self) -> T1_contra: # E[contravariant_in_output+]
Expected a ty diagnostic for this line (tag 'contravariant_in_output')
76class Protocol8(Protocol[T1]): # OK
80 def m2(self, p1: T1) -> None:
84class Callback(Protocol[P, R]): # OK
85 def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R:
89class Protocol9(Protocol[T1_co]): # OK
91 def prop1(self) -> T1_co:
95class Protocol10(Protocol[T1_co]): # OK
96 def m1(self) -> type[T1_co]:
100class Protocol11(Protocol[T1]): # OK
104class Protocol12(Protocol[T1]): # E: T1 should be covariant
Expected a ty diagnostic for this line
105 # __init__ method is exempt from variance calculations.
106 def __init__(self, x: T1) -> None:
110class Protocol13(Protocol[T1_contra]): # OK
111 def m1(self: "Protocol13[T1_contra]", x: T1_contra) -> None:
115 def m2(cls: "type[Protocol13[T1_contra]]") -> None:
119class Protocol14(Protocol[T1]): # OK
120 def m1(self) -> list[T1]: