blob: 80b764141e479d6c02720251405cfee230b350d6 [file]
-- Test cases for type variables with values restriction.
[case testCallGenericFunctionWithTypeVarValueRestriction]
from typing import TypeVar
T = TypeVar('T', int, str)
def f(x: T) -> None: pass
f(1)
f('x')
f(object()) # E: Value of type variable "T" of "f" cannot be "object"
[case testCallGenericFunctionWithTypeVarValueRestrictionUsingContext]
from typing import TypeVar, List
T = TypeVar('T', int, str)
def f(x: T) -> List[T]: pass
i = [1]
s = ['x']
o = [object()]
if int():
i = f(1)
s = f('')
o = f(1) \
# E: Incompatible types in assignment (expression has type "List[int]", variable has type "List[object]") \
# N: "List" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance \
# N: Consider using "Sequence" instead, which is covariant
[builtins fixtures/list.pyi]
[case testCallGenericFunctionWithTypeVarValueRestrictionAndAnyArgs]
from typing import TypeVar, Any, cast
T = TypeVar('T', int, str)
def f(x: T) -> None: pass
f(cast(Any, object()))
[out]
[case testCallGenericFunctionWithTypeVarValueRestrictionInDynamicFunc]
from typing import TypeVar, Any
T = TypeVar('T', int, str)
def f(x: T) -> None: pass
def g():
f(object())
[out]
[case testCallGenericFunctionWithTypeVarValueRestrictionUsingSubtype]
from typing import TypeVar
T = TypeVar('T', int, str)
def f(x: T) -> None: pass
class S(str): pass
f(S())
[out]
[case testCheckGenericFunctionBodyWithTypeVarValues]
from typing import TypeVar
class A:
def f(self, x: int) -> A: return self
class B:
def f(self, x: int) -> B: return self
AB = TypeVar('AB', A, B)
def f(x: AB) -> AB:
x = x.f(1)
return x.f(1)
[case testCheckGenericFunctionBodyWithTypeVarValues2]
from typing import TypeVar
class A:
def f(self) -> A: return A()
def g(self) -> B: return B()
class B:
def f(self) -> A: return A()
def g(self) -> B: return B()
AB = TypeVar('AB', A, B)
def f(x: AB) -> AB:
return x.f() # Error
def g(x: AB) -> AB:
return x.g() # Error
[out]
main:10: error: Incompatible return value type (got "A", expected "B")
main:12: error: Incompatible return value type (got "B", expected "A")
[case testTypeInferenceAndTypeVarValues]
from typing import TypeVar
class A:
def f(self) -> A: return self
def g(self) -> B: return B()
class B:
def f(self) -> B: return self
def g(self) -> B: return B()
AB = TypeVar('AB', A, B)
def f(x: AB) -> AB:
y = x
if y:
return y.f()
else:
return y.g() # E: Incompatible return value type (got "B", expected "A")
[out]
[case testTypeDeclaredBasedOnTypeVarWithValues]
from typing import TypeVar
T = TypeVar('T', int, str)
def f(x: T) -> T:
a = None # type: T
b = None # type: T
if 1:
a = x
b = x
a = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int")
b = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "str")
return x
[out]
[case testIsinstanceAndTypeVarValues]
from typing import TypeVar
T = TypeVar('T', int, str)
def f(x: T) -> T:
if isinstance(x, int):
return 2
return x
def g(x: T) -> T:
if isinstance(x, str):
return ''
return x
def h(x: T) -> T:
if isinstance(x, int):
return '' # E: Incompatible return value type (got "str", expected "int")
return x
[builtins fixtures/isinstance.pyi]
[out]
[case testIsinstanceAndTypeVarValues2]
from typing import TypeVar
T = TypeVar('T', int, str)
def f(x: T) -> T:
if isinstance(x, int):
return 2
else:
return ''
def g(x: T) -> T:
if isinstance(x, int):
return '' # E: Incompatible return value type (got "str", expected "int")
else:
return 2 # E: Incompatible return value type (got "int", expected "str")
return x
[builtins fixtures/isinstance.pyi]
[out]
[case testIsinstanceAndTypeVarValues3]
from typing import TypeVar
T = TypeVar('T', int, str)
def f(x: T) -> T:
if isinstance(x, int):
y = 1
else:
y = ''
return y
[builtins fixtures/isinstance.pyi]
[case testIsinstanceAndTypeVarValues4]
from typing import TypeVar
T = TypeVar('T', int, str)
def f(x: T) -> T:
if isinstance(x, int):
y = 1
else:
y = object()
return y # E: Incompatible return value type (got "object", expected "str")
[builtins fixtures/isinstance.pyi]
[out]
[case testIsinstanceAndTypeVarValues5]
from typing import TypeVar
T = TypeVar('T', int, str)
def f(x: T) -> T:
if isinstance(x, int):
y = object()
else:
y = ''
return y # E: Incompatible return value type (got "object", expected "int")
[builtins fixtures/isinstance.pyi]
[out]
[case testIsinstanceWithUserDefinedTypeAndTypeVarValues]
from typing import TypeVar
class A: pass
class B: pass
T = TypeVar('T', A, B)
def f(x: T) -> None:
y = x
if isinstance(x, A):
# This is only checked when x is A, since A and B are not considered overlapping.
x = y
x = A()
else:
x = B()
x = y
x.foo() # E: "B" has no attribute "foo"
S = TypeVar('S', int, str)
def g(x: S) -> None:
y = x
if isinstance(x, int):
x = y
[builtins fixtures/isinstance.pyi]
[out]
[case testIsinstanceWithUserDefinedTypeAndTypeVarValues2]
from typing import TypeVar
class S(str): pass
T = TypeVar('T', S, int)
def f(x: T) -> None:
y = x
if isinstance(x, S):
# This is checked only when type of x is str.
x = y
x = S()
x = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "S")
else:
x = y
x = 1
x = S() # E: Incompatible types in assignment (expression has type "S", variable has type "int")
[builtins fixtures/isinstance.pyi]
[out]
[case testTypeVarValuesAndNestedCalls]
from typing import TypeVar
T = TypeVar('T', int, str)
def f(m: T) -> int: pass
def h(x: int) -> int: pass
def g(a: T) -> None:
h(f(a))
[out]
[case testGenericTypeWithTypevarValues]
from typing import TypeVar, Generic, Any
X = TypeVar('X', int, str)
class A(Generic[X]): pass
a = None # type: A[int]
b = None # type: A[str]
d = None # type: A[object] # E: Value of type variable "X" of "A" cannot be "object"
c = None # type: A[Any]
[case testConstructGenericTypeWithTypevarValuesAndTypeInference]
from typing import TypeVar, Generic, Any, cast
X = TypeVar('X', int, str)
class A(Generic[X]):
def __init__(self, x: X) -> None: pass
A(1)
A('x')
A(cast(Any, object()))
A(object()) # E: Value of type variable "X" of "A" cannot be "object"
[case testGenericTypeWithTypevarValuesAndTypevarArgument]
from typing import TypeVar, Generic
class C: pass
X = TypeVar('X', int, str)
Y = TypeVar('Y', int, C)
Z = TypeVar('Z')
class D(Generic[X]):
def __init__(self, x: X) -> None: pass
def f(x: X) -> None:
a = None # type: D[X]
def g(x: Y) -> None:
a = None # type: D[Y]
def h(x: Z) -> None:
a = None # type: D[Z]
[out]
main:11: error: Invalid type argument value for "D"
main:13: error: Type variable "Z" not valid as type argument value for "D"
[case testGenericTypeWithTypevarValuesAndSubtypePromotion]
from typing import TypeVar, Generic
X = TypeVar('X', int, str)
class S(str): pass
class C(Generic[X]):
def __init__(self, x: X) -> None: pass
x = None # type: C[str]
y = C(S())
if int():
x = y
y = x
c_int = C(1) # type: C[int]
if int():
y = c_int # E: Incompatible types in assignment (expression has type "C[int]", variable has type "C[str]")
[case testGenericTypeBodyWithTypevarValues]
from typing import TypeVar, Generic
class A:
def f(self, x: int) -> None: pass
def g(self, x: int) -> None: pass
def h(self, x: str) -> None: pass
class B:
def f(self, x: int) -> None: pass
def g(self, x: str) -> None: pass
def h(self, x: int) -> None: pass
X = TypeVar('X', A, B)
class C(Generic[X]):
def f(self, x: X) -> None:
x.f(1)
x.g(1) # E: Argument 1 to "g" of "B" has incompatible type "int"; expected "str"
x.h(1) # E: Argument 1 to "h" of "A" has incompatible type "int"; expected "str"
[out]
[case testAttributeInGenericTypeWithTypevarValues1]
from typing import TypeVar, Generic
X = TypeVar('X', int, str)
class C(Generic[X]):
x = None # type: X
def f(self, x: X) -> None:
self.x = x
self.x = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "str")
[out]
[case testAttributeInGenericTypeWithTypevarValues2]
from typing import TypeVar, Generic
X = TypeVar('X', int, str)
class C(Generic[X]):
x = None # type: X
cn = C() # type: C[int]
cn.x = 1
cn.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int")
cs = C() # type: C[str]
cs.x = ''
cs.x = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "str")
[case testAttributeInGenericTypeWithTypevarValues3]
from typing import TypeVar, Generic
X = TypeVar('X', int, str)
class C(Generic[X]):
def f(self, x: X) -> None:
self.x = x # type: X
ci: C[int]
cs: C[str]
reveal_type(ci.x) # N: Revealed type is 'builtins.int*'
reveal_type(cs.x) # N: Revealed type is 'builtins.str*'
[case testAttributeInGenericTypeWithTypevarValuesUsingInference1]
from typing import TypeVar, Generic
X = TypeVar('X', int, str)
class C(Generic[X]):
def f(self, x: X) -> None:
self.x = x # E: Need type annotation for 'x'
ci: C[int]
cs: C[str]
reveal_type(ci.x) # N: Revealed type is 'Any'
reveal_type(cs.x) # N: Revealed type is 'Any'
[case testAttributeInGenericTypeWithTypevarValuesUsingInference2]
from typing import TypeVar, Generic
X = TypeVar('X', int, str)
class C(Generic[X]):
def f(self, x: X) -> None:
self.x = 1
reveal_type(self.x) # N: Revealed type is 'builtins.int'
ci: C[int]
cs: C[str]
reveal_type(ci.x) # N: Revealed type is 'builtins.int'
reveal_type(cs.x) # N: Revealed type is 'builtins.int'
[case testAttributeInGenericTypeWithTypevarValuesUsingInference3]
from typing import TypeVar, Generic
X = TypeVar('X', int, str)
class C(Generic[X]):
x: X
def f(self) -> None:
self.y = self.x # E: Need type annotation for 'y'
ci: C[int]
cs: C[str]
reveal_type(ci.y) # N: Revealed type is 'Any'
reveal_type(cs.y) # N: Revealed type is 'Any'
[case testInferredAttributeInGenericClassBodyWithTypevarValues]
from typing import TypeVar, Generic
X = TypeVar('X', int, str)
class C(Generic[X]):
x = 1
C.x = 1
C.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int")
[case testMultipleClassTypevarsWithValues1]
from typing import TypeVar, Generic
class A:
def f(self, x: int) -> None: pass
class B:
def f(self, x: str) -> None: pass
X = TypeVar('X', A, B)
Y = TypeVar('Y', int, str)
class C(Generic[X, Y]):
def f(self, x: X, y: Y) -> None:
x.f(y)
[out]
main:10: error: Argument 1 to "f" of "A" has incompatible type "str"; expected "int"
main:10: error: Argument 1 to "f" of "B" has incompatible type "int"; expected "str"
[case testMultipleClassTypevarsWithValues2]
from typing import TypeVar, Generic
class A: pass
class B: pass
X = TypeVar('X', A, B)
Y = TypeVar('Y', int, str)
class C(Generic[X, Y]): pass
a = None # type: C[A, int]
b = None # type: C[B, str]
c = None # type: C[int, int] # E: Value of type variable "X" of "C" cannot be "int"
d = None # type: C[A, A] # E: Value of type variable "Y" of "C" cannot be "A"
[case testCallGenericFunctionUsingMultipleTypevarsWithValues]
from typing import TypeVar
class A: pass
class B: pass
X = TypeVar('X', A, B)
Y = TypeVar('Y', int, str)
def f(x: X, y: Y) -> None: pass
f(A(), '')
f(B(), 1)
f(A(), A()) # E: Value of type variable "Y" of "f" cannot be "A"
f(1, 1) # E: Value of type variable "X" of "f" cannot be "int"
[case testGenericFunctionWithNormalAndRestrictedTypevar]
from typing import TypeVar, Generic
X = TypeVar('X')
Y = TypeVar('Y', int, str)
class C(Generic[Y]):
def __init__(self, y: Y) -> None: pass
def f(x: X, y: Y, z: int) -> None:
C(y)
C(x) # Error
if int():
z = x # Error
z = y # Error
y.foo # Error
[out]
main:8: error: Value of type variable "Y" of "C" cannot be "X"
main:10: error: Incompatible types in assignment (expression has type "X", variable has type "int")
main:11: error: Incompatible types in assignment (expression has type "str", variable has type "int")
main:12: error: "int" has no attribute "foo"
main:12: error: "str" has no attribute "foo"
[case testTypeVarWithValueInferredFromObjectReturnTypeContext]
from typing import TypeVar
T = TypeVar('T', int, str)
def c1(x: object) -> None: pass
def c2(x: int) -> None: pass
def c3(x: str) -> None: pass
def g(x: T) -> T: pass
c1(g(''))
c2(g(1))
c3(g(''))
c2(g('')) # E: Argument 1 to "c2" has incompatible type "str"; expected "int"
c3(g(1)) # E: Argument 1 to "c3" has incompatible type "int"; expected "str"
[case testTypeVarWithValueInferredFromObjectReturnTypeContext2]
from typing import TypeVar
T = TypeVar('T', int, str)
class ss(str): pass
def c(x: ss) -> None: pass
def g(x: T) -> T: pass
c(g(''))
c(g(1))
[out]
main:6: error: Argument 1 to "c" has incompatible type "str"; expected "ss"
main:7: error: Argument 1 to "c" has incompatible type "int"; expected "ss"
[case testDefineAttributeInGenericMethodUsingTypeVarWithValues]
from typing import TypeVar
T = TypeVar('T', int, str)
class A:
def f(self, x: T) -> None:
self.x = x # E: Need type annotation for 'x'
self.y = [x] # E: Need type annotation for 'y'
self.z = 1
reveal_type(A().x) # N: Revealed type is 'Any'
reveal_type(A().y) # N: Revealed type is 'Any'
reveal_type(A().z) # N: Revealed type is 'builtins.int'
[builtins fixtures/list.pyi]
-- Special cases
-- -------------
[case testTypevarValuesSpecialCase1]
from typing import TypeVar, Generic
from abc import abstractmethod
T = TypeVar('T', int, str)
class A(Generic[T]):
@abstractmethod
def f(self) -> 'A[T]': pass
class B(A[str]):
@abstractmethod
def f(self) -> 'B': pass
class C(A[str]):
@abstractmethod
def f(self) -> int: # E: Return type "int" of "f" incompatible with return type "A[str]" in supertype "A"
pass
[out]
[case testDefaultArgumentValueInGenericClassWithTypevarValues]
from typing import TypeVar, Generic
T = TypeVar('T', int, str)
class C(Generic[T]):
def f(self, x: int = None) -> None: pass
[case testTypevarValuesWithOverloadedFunctionSpecialCase]
from foo import *
[file foo.pyi]
from typing import TypeVar, overload, Callable
T = TypeVar('T', int, str)
def f(x: T) -> None:
y = m(g, x)
if int():
x = y
y = object() # Error
A = TypeVar('A')
R = TypeVar('R')
def m(f: Callable[[A], R], it: A) -> A: pass
@overload
def g(x: int) -> int: return x
@overload
def g(x: str) -> str: return x
[out]
tmp/foo.pyi:8: error: Incompatible types in assignment (expression has type "object", variable has type "int")
tmp/foo.pyi:8: error: Incompatible types in assignment (expression has type "object", variable has type "str")
[case testGenericFunctionSubtypingWithTypevarValues]
from typing import TypeVar
class A: pass
T = TypeVar('T', int, str)
U = TypeVar('U', str, A, int)
def f(x: T) -> T: pass
def g(x: U) -> U: pass
a = f
if int():
a = f
if int():
a = g
b = g
if int():
b = g
if int():
b = f # E: Incompatible types in assignment (expression has type "Callable[[T], T]", variable has type "Callable[[U], U]")
[case testInnerFunctionWithTypevarValues]
from typing import TypeVar
T = TypeVar('T', int, str)
U = TypeVar('U', int, str)
def outer(x: T) -> T:
def inner(y: T) -> T:
return x
def inner2(y: U) -> U:
return y
inner(x)
inner(3) # E: Argument 1 to "inner" has incompatible type "int"; expected "str"
inner2(x)
inner2(3)
outer(3)
return x
[out]
[case testInnerFunctionMutualRecursionWithTypevarValues]
from typing import TypeVar
T = TypeVar('T', int, str)
def outer(x: T) -> T:
def inner1(y: T) -> T:
return inner2(y)
def inner2(y: T) -> T:
return inner1('a') # E: Argument 1 to "inner1" has incompatible type "str"; expected "int"
return inner1(x)
[out]
[case testClassMemberTypeVarInFunctionBody]
from typing import TypeVar, List
S = TypeVar('S')
class C:
T = TypeVar('T', bound=int)
def f(self, x: T) -> T:
L = List[S]
y: L[C.T] = [x]
C.T # E: Type variable "C.T" cannot be used as an expression
A = C.T # E: Type variable "C.T" cannot be used as an expression
return y[0]
[builtins fixtures/list.pyi]
[case testParameterLessGenericAsRestriction]
from typing import Sequence, Iterable, TypeVar
S = TypeVar('S', Sequence, Iterable)
def my_len(s: S) -> None: pass
def crash() -> None: my_len((0,))
[case testReferenceToDecoratedFunctionAndTypeVarValues]
from typing import TypeVar, Callable
T = TypeVar('T')
S = TypeVar('S', int, str)
def dec(f: Callable[..., T]) -> Callable[..., T]: ...
@dec
def g(s: S) -> Callable[[S], None]: ...
def f(x: S) -> None:
h = g(x)
h(x)