| -- Test cases for simple expressions. |
| -- |
| -- See also: |
| -- * check-functions.test contains test cases for calls. |
| -- * check-varargs.test contains test cases for *args. |
| -- * check-dynamic.test contains test cases related to 'Any' type. |
| -- * check-generics.test contains test cases for generic values. |
| |
| |
| -- None expression |
| -- --------------- |
| |
| |
| [case testNoneAsRvalue] |
| import typing |
| a: A |
| class A: pass |
| [out] |
| |
| [case testNoneAsArgument] |
| # flags: --no-strict-optional |
| import typing |
| def f(x: 'A', y: 'B') -> None: pass |
| f(None, None) |
| class A: pass |
| class B(A): pass |
| [out] |
| |
| |
| -- Simple expressions |
| -- ------------------ |
| |
| |
| [case testIntLiteral] |
| a = 0 |
| b: A |
| if int(): |
| b = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "A") |
| if int(): |
| a = 1 |
| class A: |
| pass |
| |
| [case testStrLiteral] |
| a = '' |
| b: A |
| if int(): |
| b = 'x' # E: Incompatible types in assignment (expression has type "str", variable has type "A") |
| if int(): |
| a = 'x' |
| if int(): |
| a = r"x" |
| if int(): |
| a = """foo""" |
| class A: |
| pass |
| |
| [case testFloatLiteral] |
| a = 0.0 |
| b: A |
| if str(): |
| b = 1.1 # E: Incompatible types in assignment (expression has type "float", variable has type "A") |
| if str(): |
| a = 1.1 |
| class A: |
| pass |
| [builtins fixtures/dict.pyi] |
| |
| [case testComplexLiteral] |
| a = 0.0j |
| b: A |
| if str(): |
| b = 1.1j # E: Incompatible types in assignment (expression has type "complex", variable has type "A") |
| if str(): |
| a = 1.1j |
| class A: |
| pass |
| [builtins fixtures/dict.pyi] |
| |
| [case testBytesLiteral] |
| b: bytes |
| a: A |
| if str(): |
| b = b'foo' |
| if str(): |
| b = br"foo" |
| if str(): |
| b = b'''foo''' |
| if str(): |
| a = b'foo' # E: Incompatible types in assignment (expression has type "bytes", variable has type "A") |
| class A: pass |
| [builtins fixtures/dict.pyi] |
| |
| [case testUnicodeLiteralInPython3] |
| s: str |
| if int(): |
| s = u'foo' |
| b: bytes |
| if int(): |
| b = u'foo' # E: Incompatible types in assignment (expression has type "str", variable has type "bytes") |
| [builtins fixtures/primitives.pyi] |
| |
| |
| -- Binary operators |
| -- ---------------- |
| |
| |
| [case testAdd] |
| a: A |
| b: B |
| c: C |
| if int(): |
| c = a + c # E: Unsupported operand types for + ("A" and "C") |
| if int(): |
| a = a + b # E: Incompatible types in assignment (expression has type "C", variable has type "A") |
| if int(): |
| c = b + a # E: Unsupported left operand type for + ("B") |
| if int(): |
| c = a + b |
| |
| class A: |
| def __add__(self, x: 'B') -> 'C': |
| pass |
| class B: |
| pass |
| class C: |
| pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testSub] |
| a: A |
| b: B |
| c: C |
| if int(): |
| c = a - c # E: Unsupported operand types for - ("A" and "C") |
| if int(): |
| a = a - b # E: Incompatible types in assignment (expression has type "C", variable has type "A") |
| if int(): |
| c = b - a # E: Unsupported left operand type for - ("B") |
| if int(): |
| c = a - b |
| |
| class A: |
| def __sub__(self, x: 'B') -> 'C': |
| pass |
| class B: |
| pass |
| class C: |
| pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testMul] |
| a: A |
| b: B |
| c: C |
| if int(): |
| c = a * c # E: Unsupported operand types for * ("A" and "C") |
| if int(): |
| a = a * b # E: Incompatible types in assignment (expression has type "C", variable has type "A") |
| if int(): |
| c = b * a # E: Unsupported left operand type for * ("B") |
| if int(): |
| c = a * b |
| |
| class A: |
| def __mul__(self, x: 'B') -> 'C': |
| pass |
| class B: |
| pass |
| class C: |
| pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testMatMul] |
| a: A |
| b: B |
| c: C |
| if int(): |
| c = a @ c # E: Unsupported operand types for @ ("A" and "C") |
| if int(): |
| a = a @ b # E: Incompatible types in assignment (expression has type "C", variable has type "A") |
| if int(): |
| c = b @ a # E: Unsupported left operand type for @ ("B") |
| if int(): |
| c = a @ b |
| |
| class A: |
| def __matmul__(self, x: 'B') -> 'C': |
| pass |
| class B: |
| pass |
| class C: |
| pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testDiv] |
| a: A |
| b: B |
| c: C |
| if int(): |
| c = a / c # E: Unsupported operand types for / ("A" and "C") |
| a = a / b # E: Incompatible types in assignment (expression has type "C", variable has type "A") |
| if int(): |
| c = b / a # E: Unsupported left operand type for / ("B") |
| if int(): |
| c = a / b |
| |
| class A: |
| def __truediv__(self, x: 'B') -> 'C': |
| pass |
| class B: |
| pass |
| class C: |
| pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testIntDiv] |
| a: A |
| b: B |
| c: C |
| if int(): |
| c = a // c # E: Unsupported operand types for // ("A" and "C") |
| a = a // b # E: Incompatible types in assignment (expression has type "C", variable has type "A") |
| if int(): |
| c = b // a # E: Unsupported left operand type for // ("B") |
| if int(): |
| c = a // b |
| |
| class A: |
| def __floordiv__(self, x: 'B') -> 'C': |
| pass |
| class B: |
| pass |
| class C: |
| pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testMod] |
| a: A |
| b: B |
| c: C |
| if int(): |
| c = a % c # E: Unsupported operand types for % ("A" and "C") |
| if int(): |
| a = a % b # E: Incompatible types in assignment (expression has type "C", variable has type "A") |
| if int(): |
| c = b % a # E: Unsupported left operand type for % ("B") |
| if int(): |
| c = a % b |
| |
| class A: |
| def __mod__(self, x: 'B') -> 'C': |
| pass |
| class B: |
| pass |
| class C: |
| pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testPow] |
| a: A |
| b: B |
| c: C |
| if int(): |
| c = a ** c # E: Unsupported operand types for ** ("A" and "C") |
| if int(): |
| a = a ** b # E: Incompatible types in assignment (expression has type "C", variable has type "A") |
| if int(): |
| c = b ** a # E: Unsupported left operand type for ** ("B") |
| if int(): |
| c = a ** b |
| |
| class A: |
| def __pow__(self, x: 'B') -> 'C': |
| pass |
| class B: |
| pass |
| class C: |
| pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testMiscBinaryOperators] |
| a: A |
| b: B |
| b = a & a # Fail |
| b = a | b # Fail |
| b = a ^ a # Fail |
| b = a << b # Fail |
| b = a >> a # Fail |
| |
| b = a & b |
| b = a | a |
| b = a ^ b |
| b = a << a |
| b = a >> b |
| class A: |
| def __and__(self, x: 'B') -> 'B': pass |
| def __or__(self, x: 'A') -> 'B': pass |
| def __xor__(self, x: 'B') -> 'B': pass |
| def __lshift__(self, x: 'A') -> 'B': pass |
| def __rshift__(self, x: 'B') -> 'B': pass |
| class B: pass |
| [builtins fixtures/tuple.pyi] |
| [out] |
| main:3: error: Unsupported operand types for & ("A" and "A") |
| main:4: error: Unsupported operand types for | ("A" and "B") |
| main:5: error: Unsupported operand types for ^ ("A" and "A") |
| main:6: error: Unsupported operand types for << ("A" and "B") |
| main:7: error: Unsupported operand types for >> ("A" and "A") |
| |
| [case testBooleanAndOr] |
| a: A |
| b: bool |
| if int(): |
| b = b and b |
| if int(): |
| b = b or b |
| if int(): |
| b = b and a # E: Incompatible types in assignment (expression has type "Union[Literal[False], A]", variable has type "bool") |
| if int(): |
| b = a and b # E: Incompatible types in assignment (expression has type "Union[A, bool]", variable has type "bool") |
| if int(): |
| b = b or a # E: Incompatible types in assignment (expression has type "Union[Literal[True], A]", variable has type "bool") |
| if int(): |
| b = a or b # E: Incompatible types in assignment (expression has type "Union[A, bool]", variable has type "bool") |
| class A: pass |
| |
| [builtins fixtures/bool.pyi] |
| |
| [case testRestrictedTypeAnd] |
| |
| b: bool |
| i: str |
| j = not b and i |
| if j: |
| reveal_type(j) # N: Revealed type is "builtins.str" |
| [builtins fixtures/bool.pyi] |
| |
| [case testRestrictedTypeOr] |
| |
| b: bool |
| i: str |
| j = b or i |
| if not j: |
| reveal_type(j) # N: Revealed type is "builtins.str" |
| [builtins fixtures/bool.pyi] |
| |
| [case testAndOr] |
| |
| s = "" |
| b = bool() |
| reveal_type(s and b or b) # N: Revealed type is "builtins.bool" |
| [builtins fixtures/bool.pyi] |
| |
| [case testRestrictedBoolAndOrWithGenerics] |
| from typing import List |
| |
| def f(a: List[str], b: bool) -> bool: |
| x = a and b |
| y: bool |
| return reveal_type(x or y) # N: Revealed type is "builtins.bool" |
| [builtins fixtures/list.pyi] |
| |
| [case testNonBooleanOr] |
| c: C |
| d: D |
| b: bool |
| if int(): |
| c = c or c |
| if int(): |
| c = c or d |
| if int(): |
| c = d or c |
| if int(): |
| b = c or c # E: Incompatible types in assignment (expression has type "C", variable has type "bool") |
| if int(): |
| d = c or d # E: Incompatible types in assignment (expression has type "C", variable has type "D") |
| if int(): |
| d = d or c # E: Incompatible types in assignment (expression has type "C", variable has type "D") |
| class C: pass |
| class D(C): pass |
| [builtins fixtures/bool.pyi] |
| |
| [case testInOperator] |
| from typing import Iterator, Iterable, Any |
| a: A |
| b: B |
| c: bool |
| d: D |
| e: Any |
| if int(): |
| c = c in a # E: Unsupported operand types for in ("bool" and "A") |
| if int(): |
| a = b in a # E: Incompatible types in assignment (expression has type "bool", variable has type "A") |
| if int(): |
| c = a in b # E: Unsupported right operand type for in ("B") |
| if int(): |
| c = b in d # E: Unsupported operand types for in ("B" and "D") |
| if int(): |
| c = b in a |
| if int(): |
| c = a in d |
| if int(): |
| c = e in d |
| if int(): |
| c = a in e |
| |
| class A: |
| def __contains__(self, x: 'B') -> bool: pass |
| class B: pass |
| class D(Iterable[A]): |
| def __iter__(self) -> Iterator[A]: pass |
| [builtins fixtures/bool.pyi] |
| |
| [case testNotInOperator] |
| from typing import Iterator, Iterable, Any |
| a: A |
| b: B |
| c: bool |
| d: D |
| e: Any |
| if int(): |
| c = c not in a # E: Unsupported operand types for in ("bool" and "A") |
| if int(): |
| a = b not in a # E: Incompatible types in assignment (expression has type "bool", variable has type "A") |
| if int(): |
| c = a not in b # E: Unsupported right operand type for in ("B") |
| if int(): |
| c = b not in d # E: Unsupported operand types for in ("B" and "D") |
| if int(): |
| c = b not in a |
| if int(): |
| c = a not in d |
| if int(): |
| c = e in d |
| if int(): |
| c = a in e |
| |
| class A: |
| def __contains__(self, x: 'B') -> bool: pass |
| class B: pass |
| class D(Iterable[A]): |
| def __iter__(self) -> Iterator[A]: pass |
| [builtins fixtures/bool.pyi] |
| |
| [case testNonBooleanContainsReturnValue] |
| a: A |
| b: bool |
| c: str |
| if int(): |
| b = a not in a |
| if int(): |
| b = a in a |
| if int(): |
| c = a not in a # E: Incompatible types in assignment (expression has type "bool", variable has type "str") |
| if int(): |
| c = a in a # E: Incompatible types in assignment (expression has type "bool", variable has type "str") |
| |
| class A: |
| def __contains__(self, x: 'A') -> str: pass |
| [builtins fixtures/bool.pyi] |
| |
| [case testInWithInvalidArgs] |
| a = 1 in ([1] + ['x']) # E: List item 0 has incompatible type "str"; expected "int" |
| [builtins fixtures/list.pyi] |
| |
| [case testEq] |
| a: A |
| b: bool |
| if int(): |
| a = a == b # E: Incompatible types in assignment (expression has type "bool", variable has type "A") |
| if int(): |
| a = a != b # E: Incompatible types in assignment (expression has type "bool", variable has type "A") |
| if int(): |
| b = a == b |
| if int(): |
| b = a != b |
| |
| class A: |
| def __eq__(self, o: object) -> bool: pass |
| def __ne__(self, o: object) -> bool: pass |
| [builtins fixtures/bool.pyi] |
| |
| [case testLtAndGt] |
| a: A |
| b: B |
| bo: bool |
| if int(): |
| a = a < b # E: Incompatible types in assignment (expression has type "bool", variable has type "A") |
| if int(): |
| a = a > b # E: Incompatible types in assignment (expression has type "bool", variable has type "A") |
| if int(): |
| bo = a < b |
| if int(): |
| bo = a > b |
| |
| class A: |
| def __lt__(self, o: 'B') -> bool: pass |
| def __gt__(self, o: 'B') -> bool: pass |
| class B: |
| def __lt__(self, o: 'B') -> bool: pass |
| def __gt__(self, o: 'B') -> bool: pass |
| [builtins fixtures/bool.pyi] |
| |
| [case cmpIgnoredPy3] |
| a: A |
| b: B |
| bo: bool |
| bo = a <= b # E: Unsupported left operand type for <= ("A") |
| |
| class A: |
| def __cmp__(self, o: 'B') -> bool: pass |
| class B: |
| pass |
| [builtins fixtures/bool.pyi] |
| |
| [case testLeAndGe] |
| a: A |
| b: B |
| bo: bool |
| if int(): |
| a = a <= b # E: Incompatible types in assignment (expression has type "bool", variable has type "A") |
| if int(): |
| a = a >= b # E: Incompatible types in assignment (expression has type "bool", variable has type "A") |
| if int(): |
| bo = a <= b |
| if int(): |
| bo = a >= b |
| |
| class A: |
| def __le__(self, o: 'B') -> bool: pass |
| def __ge__(self, o: 'B') -> bool: pass |
| class B: |
| def __le__(self, o: 'B') -> bool: pass |
| def __ge__(self, o: 'B') -> bool: pass |
| [builtins fixtures/bool.pyi] |
| |
| [case testChainedComp] |
| a: A |
| b: B |
| bo: bool |
| a < a < b < b # Fail |
| a < b < b < b |
| a < a > a < b # Fail |
| |
| class A: |
| def __lt__(self, o: 'B') -> bool: pass |
| def __gt__(self, o: 'B') -> bool: pass |
| class B: |
| def __lt__(self, o: 'B') -> bool: pass |
| def __gt__(self, o: 'B') -> bool: pass |
| [builtins fixtures/bool.pyi] |
| [out] |
| main:4: error: Unsupported operand types for < ("A" and "A") |
| main:6: error: Unsupported operand types for < ("A" and "A") |
| main:6: error: Unsupported operand types for > ("A" and "A") |
| |
| |
| [case testChainedCompBoolRes] |
| a: A |
| b: B |
| bo: bool |
| if int(): |
| bo = a < b < b |
| if int(): |
| a = a < b < b # E: Incompatible types in assignment (expression has type "bool", variable has type "A") |
| |
| class A: |
| def __lt__(self, o: 'B') -> bool: pass |
| def __gt__(self, o: 'B') -> bool: pass |
| class B: |
| def __lt__(self, o: 'B') -> bool: pass |
| def __gt__(self, o: 'B') -> bool: pass |
| [builtins fixtures/bool.pyi] |
| |
| |
| [case testChainedCompResTyp] |
| x: X |
| y: Y |
| a: A |
| b: B |
| p: P |
| bo: bool |
| if int(): |
| b = y == y == y |
| if int(): |
| bo = y == y == y # E: Incompatible types in assignment (expression has type "B", variable has type "bool") |
| if int(): |
| a = x < y |
| if int(): |
| a = x < y == y # E: Incompatible types in assignment (expression has type "P", variable has type "A") |
| if int(): |
| p = x < y == y |
| |
| class P: |
| pass |
| class A(P): |
| pass |
| class B(P): |
| pass |
| |
| class X: |
| def __lt__(self, o: 'Y') -> A: pass |
| def __gt__(self, o: 'Y') -> A: pass |
| class Y: |
| def __lt__(self, o: 'Y') -> A: pass |
| def __gt__(self, o: 'Y') -> A: pass |
| def __eq__(self, o: 'Y') -> B: pass # type: ignore |
| [builtins fixtures/bool.pyi] |
| |
| |
| [case testIs] |
| a: A |
| b: bool |
| if int(): |
| a = a is b # E: Incompatible types in assignment (expression has type "bool", variable has type "A") |
| if int(): |
| b = a is b |
| if int(): |
| b = b is a |
| if int(): |
| b = a is None |
| class A: pass |
| [builtins fixtures/bool.pyi] |
| |
| [case testIsNot] |
| a: A |
| b: bool |
| if int(): |
| a = a is not b # E: Incompatible types in assignment (expression has type "bool", variable has type "A") |
| if int(): |
| b = a is not b |
| if int(): |
| b = b is not a |
| if int(): |
| b = a is not None |
| class A: pass |
| [builtins fixtures/bool.pyi] |
| |
| [case testIsRightOperand] |
| |
| 1 is 1() |
| [builtins fixtures/bool.pyi] |
| [out] |
| main:2: error: "int" not callable |
| |
| [case testReverseBinaryOperator] |
| |
| class A: |
| def __add__(self, x: int) -> int: pass |
| class B: |
| def __radd__(self, x: A) -> str: pass |
| s: str |
| n: int |
| if int(): |
| n = A() + 1 |
| if int(): |
| s = A() + B() |
| if int(): |
| n = A() + B() # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| |
| [case testReverseBinaryOperator2] |
| class A: |
| def __add__(self, x: 'A') -> object: pass |
| class B: |
| def __radd__(self, x: A) -> str: pass |
| s: str |
| n: int |
| if int(): |
| s = A() + B() |
| n = A() + B() # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| |
| [case testReverseBinaryOperator3] |
| |
| class N: |
| def __add__(self, x: 'N') -> object: pass |
| class A: |
| def __add__(self, x: N) -> int: pass |
| class B: |
| def __radd__(self, x: N) -> str: pass |
| s: str |
| s = A() + B() # E: Unsupported operand types for + ("A" and "B") |
| |
| [case testBinaryOperatorWithAnyRightOperand] |
| from typing import Any, cast |
| class A: pass |
| A() + cast(Any, 1) |
| |
| [case testReverseComparisonOperator] |
| class C: |
| def __gt__(self, x: 'A') -> object: pass |
| class A: |
| def __lt__(self, x: C) -> int: pass # E: Signatures of "__lt__" of "A" and "__gt__" of "C" are unsafely overlapping |
| class B: |
| def __gt__(self, x: A) -> str: pass |
| s: str |
| n: int |
| if int(): |
| n = A() < C() |
| s = A() < B() |
| if int(): |
| n = A() < B() # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| s = object() < B() # E: Unsupported operand types for > ("B" and "object") |
| |
| [case testReversibleComparisonWithExtraArgument] |
| class C: |
| def __lt__(self, o: object, x: str = "") -> int: ... |
| |
| [case testErrorContextAndBinaryOperators] |
| import typing |
| class A: |
| def __getitem__(self, i: str) -> int: pass |
| def f() -> None: |
| A()[1] # Error |
| class B: |
| A()[1] # Error |
| A()[1] # Error |
| [out] |
| main:5: error: Invalid index type "int" for "A"; expected type "str" |
| main:7: error: Invalid index type "int" for "A"; expected type "str" |
| main:8: error: Invalid index type "int" for "A"; expected type "str" |
| |
| [case testErrorContextAndBinaryOperators2] |
| import m |
| [file m.py] |
| import typing |
| class A: |
| def __getitem__(self, i: str) -> int: pass |
| def f() -> None: |
| A()[1] # Error |
| class B: |
| A()[1] # Error |
| A()[1] # Error |
| [out] |
| tmp/m.py:5: error: Invalid index type "int" for "A"; expected type "str" |
| tmp/m.py:7: error: Invalid index type "int" for "A"; expected type "str" |
| tmp/m.py:8: error: Invalid index type "int" for "A"; expected type "str" |
| |
| |
| [case testDivmod] |
| # flags: --disable-error-code=used-before-def |
| from typing import Tuple, Union, SupportsInt |
| _Decimal = Union[Decimal, int] |
| class Decimal(SupportsInt): |
| def __init__(self, int) -> None: ... |
| def __divmod__(self, other: _Decimal) -> Tuple[Decimal, Decimal]: ... |
| def __rdivmod__(self, other: _Decimal) -> Tuple[Decimal, Decimal]: ... |
| |
| i = 8 |
| f = 8.0 |
| d = Decimal(8) |
| |
| reveal_type(divmod(i, i)) # N: Revealed type is "Tuple[builtins.int, builtins.int]" |
| reveal_type(divmod(f, i)) # N: Revealed type is "Tuple[builtins.float, builtins.float]" |
| reveal_type(divmod(d, i)) # N: Revealed type is "Tuple[__main__.Decimal, __main__.Decimal]" |
| |
| reveal_type(divmod(i, f)) # N: Revealed type is "Tuple[builtins.float, builtins.float]" |
| reveal_type(divmod(f, f)) # N: Revealed type is "Tuple[builtins.float, builtins.float]" |
| divmod(d, f) # E: Unsupported operand types for divmod ("Decimal" and "float") |
| |
| reveal_type(divmod(i, d)) # N: Revealed type is "Tuple[__main__.Decimal, __main__.Decimal]" |
| divmod(f, d) # E: Unsupported operand types for divmod ("float" and "Decimal") |
| reveal_type(divmod(d, d)) # N: Revealed type is "Tuple[__main__.Decimal, __main__.Decimal]" |
| |
| # Now some bad calls |
| divmod() # E: "divmod" expects 2 arguments \ |
| # E: Missing positional arguments "_x", "_y" in call to "divmod" |
| divmod(7) # E: "divmod" expects 2 arguments \ |
| # E: Missing positional argument "_y" in call to "divmod" |
| divmod(7, 8, 9) # E: "divmod" expects 2 arguments \ |
| # E: Too many arguments for "divmod" |
| divmod(_x=7, _y=9) # E: "divmod" must be called with 2 positional arguments |
| |
| divmod('foo', 'foo') # E: Unsupported left operand type for divmod ("str") |
| divmod(i, 'foo') # E: Unsupported operand types for divmod ("int" and "str") |
| divmod(f, 'foo') # E: Unsupported operand types for divmod ("float" and "str") |
| divmod(d, 'foo') # E: Unsupported operand types for divmod ("Decimal" and "str") |
| |
| divmod('foo', i) # E: Unsupported operand types for divmod ("str" and "int") |
| divmod('foo', f) # E: Unsupported operand types for divmod ("str" and "float") |
| divmod('foo', d) # E: Unsupported operand types for divmod ("str" and "Decimal") |
| |
| [builtins fixtures/divmod.pyi] |
| [typing fixtures/typing-medium.pyi] |
| |
| |
| -- Unary operators |
| -- --------------- |
| |
| |
| [case testUnaryMinus] |
| a: A |
| b: B |
| if int(): |
| a = -a # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| if int(): |
| b = -b # E: Unsupported operand type for unary - ("B") |
| if int(): |
| b = -a |
| |
| class A: |
| def __neg__(self) -> 'B': |
| pass |
| class B: |
| pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testUnaryPlus] |
| a: A |
| b: B |
| if int(): |
| a = +a # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| if int(): |
| b = +b # E: Unsupported operand type for unary + ("B") |
| if int(): |
| b = +a |
| |
| class A: |
| def __pos__(self) -> 'B': |
| pass |
| class B: |
| pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testUnaryNot] |
| a: A |
| b: bool |
| if int(): |
| a = not b # E: Incompatible types in assignment (expression has type "bool", variable has type "A") |
| if int(): |
| b = not a |
| if int(): |
| b = not b |
| class A: |
| pass |
| [builtins fixtures/bool.pyi] |
| |
| [case testUnaryBitwiseNeg] |
| a: A |
| b: B |
| if int(): |
| a = ~a # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| if int(): |
| b = ~b # E: Unsupported operand type for ~ ("B") |
| if int(): |
| b = ~a |
| |
| class A: |
| def __invert__(self) -> 'B': |
| pass |
| class B: |
| pass |
| |
| |
| -- Indexing |
| -- -------- |
| [builtins fixtures/tuple.pyi] |
| |
| |
| [case testIndexing] |
| a: A |
| b: B |
| c: C |
| if int(): |
| c = a[c] # E: Invalid index type "C" for "A"; expected type "B" |
| if int(): |
| a = a[b] # E: Incompatible types in assignment (expression has type "C", variable has type "A") |
| if int(): |
| c = b[a] # E: Value of type "B" is not indexable |
| if int(): |
| c = a[b] |
| |
| class A: |
| def __getitem__(self, x: 'B') -> 'C': |
| pass |
| class B: pass |
| class C: pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testIndexingAsLvalue] |
| a: A |
| b: B |
| c: C |
| a[c] = c # Fail |
| a[b] = a # Fail |
| b[a] = c # Fail |
| a[b] = c |
| |
| class A: |
| def __setitem__(self, x: 'B', y: 'C') -> None: |
| pass |
| class B: |
| pass |
| class C: |
| pass |
| [builtins fixtures/tuple.pyi] |
| [out] |
| main:4: error: Invalid index type "C" for "A"; expected type "B" |
| main:5: error: Incompatible types in assignment (expression has type "A", target has type "C") |
| main:6: error: Unsupported target for indexed assignment ("B") |
| |
| [case testOverloadedIndexing] |
| from foo import * |
| [file foo.pyi] |
| from typing import overload |
| a: A |
| b: B |
| c: C |
| a[b] |
| a[c] |
| a[1] # E: No overload variant of "__getitem__" of "A" matches argument type "int" \ |
| # N: Possible overload variants: \ |
| # N: def __getitem__(self, B, /) -> int \ |
| # N: def __getitem__(self, C, /) -> str |
| |
| i: int |
| s: str |
| if int(): |
| i = a[b] |
| if int(): |
| s = a[b] # E: Incompatible types in assignment (expression has type "int", variable has type "str") |
| if int(): |
| i = a[c] # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| if int(): |
| s = a[c] |
| |
| class A: |
| @overload |
| def __getitem__(self, x: 'B') -> int: |
| pass |
| @overload |
| def __getitem__(self, x: 'C') -> str: |
| pass |
| class B: pass |
| class C: pass |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| |
| -- Cast expression |
| -- --------------- |
| |
| |
| [case testCastExpressions] |
| from typing import cast, Any |
| class A: pass |
| class B: pass |
| class C(A): pass |
| a: A |
| b: B |
| c: C |
| |
| if int(): |
| a = cast(A, a()) # E: "A" not callable |
| if int(): |
| a = cast(Any, a()) # E: "A" not callable |
| b = cast(A, a) # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| |
| if int(): |
| a = cast(A, b) |
| if int(): |
| a = cast(A, a) |
| c = cast(C, a) |
| if int(): |
| a = cast(A, c) |
| if int(): |
| a = cast(Any, b) |
| b = cast(Any, a) |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testAnyCast] |
| from typing import cast, Any |
| a: A |
| b: B |
| a = cast(Any, a()) # Fail |
| a = cast(Any, b) |
| b = cast(Any, a) |
| class A: pass |
| class B: pass |
| [builtins fixtures/tuple.pyi] |
| [out] |
| main:4: error: "A" not callable |
| |
| -- assert_type() |
| |
| [case testAssertType] |
| from typing import assert_type, Any |
| from typing_extensions import Literal |
| a: int = 1 |
| returned = assert_type(a, int) |
| reveal_type(returned) # N: Revealed type is "builtins.int" |
| assert_type(a, str) # E: Expression is of type "int", not "str" |
| assert_type(a, Any) # E: Expression is of type "int", not "Any" |
| assert_type(a, Literal[1]) # E: Expression is of type "int", not "Literal[1]" |
| assert_type(42, Literal[42]) |
| assert_type(42, int) # E: Expression is of type "Literal[42]", not "int" |
| [builtins fixtures/tuple.pyi] |
| |
| [case testAssertTypeGeneric] |
| from typing import assert_type, TypeVar, Generic |
| from typing_extensions import Literal |
| T = TypeVar("T") |
| def f(x: T) -> T: return x |
| assert_type(f(1), int) |
| class Gen(Generic[T]): |
| def __new__(cls, obj: T) -> Gen[T]: ... |
| assert_type(Gen(1), Gen[int]) |
| # With type context, it infers Gen[Literal[1]] instead. |
| y: Gen[Literal[1]] = assert_type(Gen(1), Gen[Literal[1]]) |
| |
| [builtins fixtures/tuple.pyi] |
| |
| [case testAssertTypeUncheckedFunction] |
| from typing import assert_type |
| from typing_extensions import Literal |
| def f(): |
| x = 42 |
| assert_type(x, Literal[42]) |
| [out] |
| main:5: error: Expression is of type "Any", not "Literal[42]" |
| main:5: note: "assert_type" expects everything to be "Any" in unchecked functions |
| [builtins fixtures/tuple.pyi] |
| |
| [case testAssertTypeUncheckedFunctionWithUntypedCheck] |
| # flags: --check-untyped-defs |
| from typing import assert_type |
| from typing_extensions import Literal |
| def f(): |
| x = 42 |
| assert_type(x, Literal[42]) |
| [out] |
| main:6: error: Expression is of type "int", not "Literal[42]" |
| [builtins fixtures/tuple.pyi] |
| |
| [case testAssertTypeNoPromoteUnion] |
| from typing import Union, assert_type |
| |
| Scalar = Union[int, bool, bytes, bytearray] |
| |
| |
| def reduce_it(s: Scalar) -> Scalar: |
| return s |
| |
| assert_type(reduce_it(True), Scalar) |
| [builtins fixtures/tuple.pyi] |
| |
| [case testAssertTypeWithDeferredNodes] |
| from typing import Callable, TypeVar, assert_type |
| |
| T = TypeVar("T") |
| |
| def dec(f: Callable[[], T]) -> Callable[[], T]: |
| return f |
| |
| def func() -> None: |
| some = _inner_func() |
| assert_type(some, int) |
| |
| @dec |
| def _inner_func() -> int: |
| return 1 |
| [builtins fixtures/tuple.pyi] |
| |
| -- None return type |
| -- ---------------- |
| |
| |
| [case testNoneReturnTypeBasics] |
| def f() -> None: |
| pass |
| |
| class A: |
| def g(self, x: object) -> None: |
| pass |
| def __call__(self) -> None: |
| pass |
| |
| a: A |
| o: object |
| if int(): |
| a = f() # E: "f" does not return a value |
| if int(): |
| o = a() # E: Function does not return a value |
| if int(): |
| o = A().g(a) # E: "g" of "A" does not return a value |
| if int(): |
| o = A.g(a, a) # E: "g" of "A" does not return a value |
| A().g(f()) # E: "f" does not return a value |
| x: A = f() # E: "f" does not return a value |
| f() |
| A().g(a) |
| [builtins fixtures/tuple.pyi] |
| |
| [case testNoneReturnTypeWithStatements] |
| import typing |
| def f() -> None: pass |
| |
| if f(): # E: "f" does not return a value |
| pass |
| elif f(): # E: "f" does not return a value |
| pass |
| while f(): # E: "f" does not return a value |
| pass |
| def g() -> object: |
| return f() # E: "f" does not return a value |
| raise f() # E: "f" does not return a value |
| [builtins fixtures/exception.pyi] |
| |
| [case testNoneReturnTypeWithExpressions] |
| from typing import cast |
| |
| def f() -> None: pass |
| class A: |
| def __add__(self, x: 'A') -> 'A': pass |
| |
| a: A |
| [f()] # E: "f" does not return a value |
| f() + a # E: "f" does not return a value |
| a + f() # E: "f" does not return a value |
| f() == a # E: "f" does not return a value |
| a != f() # E: "f" does not return a value |
| cast(A, f()) |
| f().foo # E: "f" does not return a value |
| [builtins fixtures/list.pyi] |
| |
| [case testNoneReturnTypeWithExpressions2] |
| import typing |
| |
| def f() -> None: pass |
| class A: |
| def __add__(self, x: 'A') -> 'A': |
| pass |
| |
| a: A |
| b: bool |
| f() in a # E: "f" does not return a value # E: Unsupported right operand type for in ("A") |
| a < f() # E: "f" does not return a value |
| f() <= a # E: "f" does not return a value |
| a in f() # E: "f" does not return a value |
| -f() # E: "f" does not return a value |
| not f() # E: "f" does not return a value |
| f() and b # E: "f" does not return a value |
| b or f() # E: "f" does not return a value |
| [builtins fixtures/bool.pyi] |
| |
| |
| -- Slicing |
| -- ------- |
| |
| |
| [case testGetSlice] |
| a: A |
| b: B |
| if int(): |
| a = a[1:2] # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| if int(): |
| a = a[1:] # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| if int(): |
| a = a[:2] # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| if int(): |
| a = a[:] # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| |
| if int(): |
| b = a[1:2] |
| if int(): |
| b = a[1:] |
| if int(): |
| b = a[:2] |
| if int(): |
| b = a[:] |
| |
| class A: |
| def __getitem__(self, s: slice) -> 'B': pass |
| class B: pass |
| [builtins fixtures/slice.pyi] |
| |
| [case testSlicingWithInvalidBase] |
| |
| a: A |
| a[1:2] # E: Invalid index type "slice" for "A"; expected type "int" |
| a[:] # E: Invalid index type "slice" for "A"; expected type "int" |
| class A: |
| def __getitem__(self, n: int) -> 'A': pass |
| [builtins fixtures/slice.pyi] |
| |
| [case testSlicingWithNonindexable] |
| |
| o: object |
| o[1:2] # E: Value of type "object" is not indexable |
| o[:] # E: Value of type "object" is not indexable |
| [builtins fixtures/slice.pyi] |
| |
| [case testNonIntSliceBounds] |
| from typing import Any |
| a: Any |
| o: object |
| a[o:1] # E: Slice index must be an integer, SupportsIndex or None |
| a[1:o] # E: Slice index must be an integer, SupportsIndex or None |
| a[o:] # E: Slice index must be an integer, SupportsIndex or None |
| a[:o] # E: Slice index must be an integer, SupportsIndex or None |
| [builtins fixtures/slice.pyi] |
| |
| [case testSliceSupportsIndex] |
| import typing_extensions |
| class Index: |
| def __init__(self, value: int) -> None: |
| self.value = value |
| def __index__(self) -> int: |
| return self.value |
| |
| c = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] |
| reveal_type(c[Index(0):Index(5)]) # N: Revealed type is "builtins.list[builtins.int]" |
| [file typing_extensions.pyi] |
| from typing import Protocol |
| class SupportsIndex(Protocol): |
| def __index__(self) -> int: ... |
| [builtins fixtures/slice.pyi] |
| |
| [case testNoneSliceBounds] |
| from typing import Any |
| a: Any |
| a[None:1] |
| a[1:None] |
| a[None:] |
| a[:None] |
| [builtins fixtures/slice.pyi] |
| |
| [case testNoneSliceBoundsWithStrictOptional] |
| from typing import Any |
| a: Any |
| a[None:1] |
| a[1:None] |
| a[None:] |
| a[:None] |
| [builtins fixtures/slice.pyi] |
| |
| |
| -- Lambdas |
| -- ------- |
| |
| |
| [case testTrivialLambda] |
| from typing import Callable |
| f = lambda: 1 # type: Callable[[], int] |
| if int(): |
| f = lambda: ''.x # E: "str" has no attribute "x" |
| if int(): |
| f = lambda: '' \ |
| # E: Incompatible types in assignment (expression has type "Callable[[], str]", variable has type "Callable[[], int]") \ |
| # E: Incompatible return value type (got "str", expected "int") |
| |
| [case testVoidLambda] |
| import typing |
| def void() -> None: |
| pass |
| x = lambda: void() # type: typing.Callable[[], None] |
| |
| [case testNoCrashOnLambdaGenerator] |
| # flags: --no-strict-optional |
| from typing import Iterator, Callable |
| |
| # These should not crash |
| lambda: (yield) |
| |
| gen: Callable[[], Iterator[str]] |
| gen = (lambda: (yield 1)) # E: Incompatible types in "yield" (actual type "int", expected type "str") |
| |
| def fun(cb: Callable[[], Iterator[str]]) -> None: |
| pass |
| fun(lambda: (yield from [1])) # E: Incompatible types in "yield from" (actual type "int", expected type "str") |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testLambdaAndReachability] |
| def f() -> None: |
| aa = [] |
| y = lambda x: 1 |
| aa.append(1) |
| 1() # E: "int" not callable |
| [builtins fixtures/list.pyi] |
| |
| |
| -- List comprehensions |
| -- ------------------- |
| |
| |
| [case testSimpleListComprehension] |
| from typing import List |
| a: List[A] |
| a = [x for x in a] |
| b = [x for x in a] # type: List[B] # E: List comprehension has incompatible type List[A]; expected List[B] |
| class A: pass |
| class B: pass |
| [builtins fixtures/for.pyi] |
| |
| [case testSimpleListComprehensionNestedTuples] |
| from typing import List, Tuple |
| l: List[Tuple[A, Tuple[A, B]]] |
| a = [a2 for a1, (a2, b1) in l] # type: List[A] |
| b = [a2 for a1, (a2, b1) in l] # type: List[B] # E: List comprehension has incompatible type List[A]; expected List[B] |
| class A: pass |
| class B: pass |
| [builtins fixtures/for.pyi] |
| |
| [case testSimpleListComprehensionNestedTuples2] |
| from typing import List, Tuple |
| l: List[Tuple[int, Tuple[int, str]]] |
| a = [f(d) for d, (i, s) in l] |
| b = [f(s) for d, (i, s) in l] # E: Argument 1 to "f" has incompatible type "str"; expected "int" |
| |
| def f(x: int): pass |
| [builtins fixtures/for.pyi] |
| |
| [case testListComprehensionWithNonDirectMapping] |
| from typing import List |
| a: List[A] |
| b: List[B] |
| if int(): |
| b = [f(x) for x in a] |
| if int(): |
| a = [f(x) for x in a] # E: List comprehension has incompatible type List[B]; expected List[A] |
| ([f(x) for x in b]) # E: Argument 1 to "f" has incompatible type "B"; expected "A" |
| class A: pass |
| class B: pass |
| def f(a: A) -> B: pass |
| [builtins fixtures/for.pyi] |
| |
| [case testErrorInListComprehensionCondition] |
| from typing import List |
| a: List[A] |
| a = [x for x in a if x()] # E: "A" not callable |
| class A: pass |
| [builtins fixtures/for.pyi] |
| |
| [case testTypeInferenceOfListComprehension] |
| from typing import List |
| a: List[A] |
| o = [x for x in a] # type: List[object] |
| class A: pass |
| [builtins fixtures/for.pyi] |
| |
| [case testSimpleListComprehensionInClassBody] |
| from typing import List |
| class A: |
| a: List[A] |
| a = [x for x in a] |
| b = [x for x in a] # type: List[B] # E: List comprehension has incompatible type List[A]; expected List[B] |
| class B: pass |
| [builtins fixtures/for.pyi] |
| [out] |
| |
| |
| -- Set comprehension |
| -- ----------------- |
| |
| |
| [case testSimpleSetComprehension] |
| from typing import Set |
| a: Set[A] |
| a = {x for x in a} |
| b = {x for x in a} # type: Set[B] # E: Set comprehension has incompatible type Set[A]; expected Set[B] |
| class A: pass |
| class B: pass |
| [builtins fixtures/set.pyi] |
| |
| |
| -- Dictionary comprehension |
| -- ------------------------ |
| |
| |
| [case testSimpleDictionaryComprehension] |
| from typing import Dict, List, Tuple |
| abd: Dict[A, B] |
| abl: List[Tuple[A, B]] |
| abd = {a: b for a, b in abl} |
| x = {a: b for a, b in abl} # type: Dict[B, A] |
| y = {a: b for a, b in abl} # type: A |
| class A: pass |
| class B: pass |
| [builtins fixtures/dict.pyi] |
| [out] |
| main:5: error: Key expression in dictionary comprehension has incompatible type "A"; expected type "B" |
| main:5: error: Value expression in dictionary comprehension has incompatible type "B"; expected type "A" |
| main:6: error: Incompatible types in assignment (expression has type "Dict[A, B]", variable has type "A") |
| |
| |
| [case testDictionaryComprehensionWithNonDirectMapping] |
| from typing import Dict, List, Tuple |
| abd: Dict[A, B] |
| abl: List[Tuple[A, B]] |
| abd = {a: f(b) for a, b in abl} |
| class A: pass |
| class B: pass |
| class C: pass |
| def f(b: A) -> C: pass |
| [builtins fixtures/dict.pyi] |
| [out] |
| main:4: error: Value expression in dictionary comprehension has incompatible type "C"; expected type "B" |
| main:4: error: Argument 1 to "f" has incompatible type "B"; expected "A" |
| |
| |
| -- Generator expressions |
| -- --------------------- |
| |
| |
| [case testSimpleGeneratorExpression] |
| from typing import Iterator |
| # The implementation is mostly identical to list comprehensions, so only a few |
| # test cases is ok. |
| a: Iterator[int] |
| if int(): |
| a = (x for x in a) |
| b: Iterator[str] |
| if int(): |
| b = (x for x in a) # E: Generator has incompatible item type "int"; expected "str" |
| [builtins fixtures/for.pyi] |
| |
| [case testGeneratorIncompatibleErrorMessage] |
| from typing import Callable, Iterator, List |
| |
| a = [] # type: List[Callable[[], str]] |
| b: Iterator[Callable[[], int]] |
| if int(): |
| b = (x for x in a) # E: Generator has incompatible item type "Callable[[], str]"; expected "Callable[[], int]" |
| [builtins fixtures/list.pyi] |
| |
| -- Conditional expressions |
| -- ----------------------- |
| |
| |
| [case testSimpleConditionalExpression] |
| import typing |
| y = '' |
| x = 1 if y else 2 |
| if int(): |
| x = 3 |
| if int(): |
| x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| |
| [case testConditionalExpressionWithEmptyCondition] |
| import typing |
| def f() -> None: pass |
| x = 1 if f() else 2 # E: "f" does not return a value |
| |
| [case testConditionalExpressionWithSubtyping] |
| import typing |
| class A: pass |
| class B(A): pass |
| x = B() if bool() else A() |
| if int(): |
| x = A() |
| if int(): |
| x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "A") |
| y = A() if bool() else B() |
| if int(): |
| y = A() |
| if int(): |
| y = '' # E: Incompatible types in assignment (expression has type "str", variable has type "A") |
| [builtins fixtures/bool.pyi] |
| |
| [case testConditionalExpressionAndTypeContext] |
| import typing |
| x = [1] if bool() else [] |
| if int(): |
| x = [1] |
| if int(): |
| x = ['x'] # E: List item 0 has incompatible type "str"; expected "int" |
| [builtins fixtures/list.pyi] |
| |
| [case testConditionalExpressionUnion] |
| from typing import Union |
| reveal_type(1 if bool() else 2) # N: Revealed type is "builtins.int" |
| reveal_type(1 if bool() else '') # N: Revealed type is "builtins.object" |
| x: Union[int, str] = reveal_type(1 if bool() else '') \ |
| # N: Revealed type is "Union[Literal[1]?, Literal['']?]" |
| class A: |
| pass |
| class B(A): |
| pass |
| class C: |
| pass |
| class D(A): |
| pass |
| a = A() |
| b = B() |
| c = C() |
| d = D() |
| reveal_type(a if bool() else b) # N: Revealed type is "__main__.A" |
| reveal_type(b if bool() else c) # N: Revealed type is "builtins.object" |
| reveal_type(c if bool() else b) # N: Revealed type is "builtins.object" |
| reveal_type(c if bool() else a) # N: Revealed type is "builtins.object" |
| reveal_type(d if bool() else b) # N: Revealed type is "__main__.A" |
| [builtins fixtures/bool.pyi] |
| |
| [case testConditionalExpressionUnionWithAny] |
| from typing import Union, Any |
| a: Any |
| x: Union[int, str] = reveal_type(a if int() else 1) # N: Revealed type is "Union[Any, Literal[1]?]" |
| reveal_type(a if int() else 1) # N: Revealed type is "Any" |
| |
| [case testConditionalExpressionStatementNoReturn] |
| from typing import List, Union |
| x = [] |
| y = "" |
| x.append(y) if bool() else x.append(y) |
| z = x.append(y) if bool() else x.append(y) # E: "append" of "list" does not return a value |
| [builtins fixtures/list.pyi] |
| |
| -- Special cases |
| -- ------------- |
| |
| |
| [case testOperationsWithNonInstanceTypes] |
| from typing import cast |
| class A: |
| def __add__(self, a: 'A') -> 'A': pass |
| def f() -> None: |
| pass |
| a: A |
| None + a # E: Unsupported left operand type for + ("None") |
| f + a # E: Unsupported left operand type for + ("Callable[[], None]") |
| a + f # E: Unsupported operand types for + ("A" and "Callable[[], None]") |
| cast(A, f) |
| [case testOperatorMethodWithInvalidArgCount] |
| |
| a: A |
| a + a # Fail |
| |
| class A: |
| def __add__(self) -> 'A': |
| pass |
| [out] |
| main:3: error: Too many arguments for "__add__" of "A" |
| |
| [case testOperatorMethodAsVar] |
| from typing import Any |
| class A: |
| def __init__(self, _add: Any) -> None: |
| self.__add__ = _add |
| a: A |
| a + a |
| [out] |
| |
| [case testOperatorMethodAsVar2] |
| |
| class A: |
| def f(self, x: int) -> str: pass |
| __add__ = f |
| s: str |
| s = A() + 1 |
| A() + (A() + 1) |
| [out] |
| main:7: error: Argument 1 has incompatible type "str"; expected "int" |
| |
| [case testIndexedLvalueWithSubtypes] |
| a: A |
| b: B |
| c: C |
| a[c] = c |
| a[b] = c |
| a[c] = b |
| |
| class A: |
| def __setitem__(self, x: 'B', y: 'B') -> None: |
| pass |
| class B: |
| pass |
| class C(B): |
| pass |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| |
| -- Ellipsis |
| -- -------- |
| |
| |
| [case testEllipsis] |
| |
| a: A |
| if str(): |
| a = ... # E: Incompatible types in assignment (expression has type "ellipsis", variable has type "A") |
| b = ... |
| c = ... |
| if str(): |
| b = c |
| ....__class__ |
| ....a # E: "ellipsis" has no attribute "a" |
| |
| class A: pass |
| [builtins fixtures/dict.pyi] |
| [out] |
| |
| |
| -- Yield expression |
| -- ---------------- |
| |
| |
| [case testYieldExpression] |
| def f(x: int) -> None: |
| x = yield f('') |
| x = 1 |
| [builtins fixtures/for.pyi] |
| [out] |
| main:1: error: The return type of a generator function should be "Generator" or one of its supertypes |
| main:2: error: "f" does not return a value |
| main:2: error: Argument 1 to "f" has incompatible type "str"; expected "int" |
| |
| [case testYieldExpressionWithNone] |
| from typing import Iterator |
| def f(x: int) -> Iterator[None]: |
| (yield) |
| [builtins fixtures/for.pyi] |
| [out] |
| |
| |
| -- Yield from expression |
| -- ---------------- |
| |
| |
| [case testYieldFromIteratorHasNoValue] |
| from typing import Iterator |
| def f() -> Iterator[int]: |
| yield 5 |
| def g() -> Iterator[int]: |
| a = yield from f() # E: Function does not return a value |
| |
| [case testYieldFromGeneratorHasValue] |
| from typing import Iterator, Generator |
| def f() -> Generator[int, None, str]: |
| yield 5 |
| return "ham" |
| def g() -> Iterator[int]: |
| a = "string" |
| a = yield from f() |
| [out] |
| |
| [case testYieldFromTupleExpression] |
| from typing import Generator |
| def g() -> Generator[int, None, None]: |
| x = yield from () # E: Function does not return a value |
| x = yield from (0, 1, 2) # E: Function does not return a value |
| x = yield from (0, "ERROR") # E: Incompatible types in "yield from" (actual type "object", expected type "int") \ |
| # E: Function does not return a value |
| x = yield from ("ERROR",) # E: Incompatible types in "yield from" (actual type "str", expected type "int") \ |
| # E: Function does not return a value |
| [builtins fixtures/tuple.pyi] |
| |
| -- dict(...) |
| -- --------- |
| |
| |
| -- Note that the stub used in unit tests does not have all overload |
| -- variants, but it should not matter. |
| |
| [case testDictWithKeywordArgsOnly] |
| from typing import Dict, Any |
| d1 = dict(a=1, b=2) # type: Dict[str, int] |
| d2 = dict(a=1, b='') # type: Dict[str, int] # E: Dict entry 1 has incompatible type "str": "str"; expected "str": "int" |
| d3 = dict(a=1) # type: Dict[int, int] # E: Dict entry 0 has incompatible type "str": "int"; expected "int": "int" |
| d4 = dict(a=1, b=1) |
| d4.xyz # E: "Dict[str, int]" has no attribute "xyz" |
| d5 = dict(a=1, b='') # type: Dict[str, Any] |
| [builtins fixtures/dict.pyi] |
| |
| [case testDictWithoutKeywordArgs] |
| from typing import Dict |
| d = dict() # E: Need type annotation for "d" (hint: "d: Dict[<type>, <type>] = ...") |
| d2 = dict() # type: Dict[int, str] |
| dict(undefined) # E: Name "undefined" is not defined |
| [builtins fixtures/dict.pyi] |
| |
| [case testDictFromList] |
| from typing import Dict |
| d = dict([(1, 'x'), (2, 'y')]) |
| d() # E: "Dict[int, str]" not callable |
| d2 = dict([(1, 'x')]) # type: Dict[str, str] # E: List item 0 has incompatible type "Tuple[int, str]"; expected "Tuple[str, str]" |
| [builtins fixtures/dict.pyi] |
| |
| [case testDictFromIterableAndKeywordArg] |
| from typing import Dict |
| it = [('x', 1)] |
| |
| d = dict(it, x=1) |
| d() # E: "Dict[str, int]" not callable |
| |
| d2 = dict(it, x='') |
| d2() # E: "Dict[str, object]" not callable |
| |
| d3 = dict(it, x='') # type: Dict[str, int] # E: Argument "x" to "dict" has incompatible type "str"; expected "int" |
| [builtins fixtures/dict.pyi] |
| |
| [case testDictFromIterableAndKeywordArg2] |
| it = [(1, 'x')] |
| dict(it, x='y') # E: Keyword argument only valid with "str" key type in call to "dict" |
| [builtins fixtures/dict.pyi] |
| |
| [case testDictFromIterableAndKeywordArg3] |
| d = dict([], x=1) |
| d() # E: "Dict[str, int]" not callable |
| [builtins fixtures/dict.pyi] |
| |
| [case testDictFromIterableAndStarStarArgs] |
| from typing import Dict |
| it = [('x', 1)] |
| |
| kw = {'x': 1} |
| d = dict(it, **kw) |
| d() # E: "Dict[str, int]" not callable |
| |
| kw2 = {'x': ''} |
| d2 = dict(it, **kw2) |
| d2() # E: "Dict[str, object]" not callable |
| |
| d3 = dict(it, **kw2) # type: Dict[str, int] # E: Argument 2 to "dict" has incompatible type "**Dict[str, str]"; expected "int" |
| [builtins fixtures/dict.pyi] |
| |
| [case testDictFromIterableAndStarStarArgs2] |
| it = [(1, 'x')] |
| kw = {'x': 'y'} |
| d = dict(it, **kw) # E: Keyword argument only valid with "str" key type in call to "dict" |
| d() # E: "Dict[int, str]" not callable |
| [builtins fixtures/dict.pyi] |
| |
| [case testUserDefinedClassNamedDict] |
| from typing import Generic, TypeVar |
| T = TypeVar('T') |
| S = TypeVar('S') |
| class dict(Generic[T, S]): |
| def __init__(self, x: T, **kwargs: T) -> None: pass |
| dict(1, y=1) |
| [builtins fixtures/dict.pyi] |
| |
| [case testSpecialSignatureForSubclassOfDict] |
| from typing import TypeVar, Dict, Generic |
| T = TypeVar('T') |
| S = TypeVar('S') |
| class D1(dict): pass # Implicit base class Dict[Any, Any] |
| D1([(1, 2)], x=1) |
| class D2(Dict[T, S], Generic[T, S]): pass |
| da = D2([('x', 2)], x=1) |
| da() # E: "D2[str, int]" not callable |
| D2([(1, 2)], x=1) # E: Keyword argument only valid with "str" key type in call to "dict" |
| db = D2(x=1) |
| db() # E: "D2[str, int]" not callable |
| [builtins fixtures/dict.pyi] |
| |
| [case testSpecialSignatureForSubclassOfDict2] |
| from typing import TypeVar, Dict, Generic |
| T = TypeVar('T') |
| class D(Dict[str, T], Generic[T]): pass |
| D([('x', 1)], x=1) |
| [builtins fixtures/dict.pyi] |
| |
| [case testOverridingSpecialSignatureInSubclassOfDict] |
| from typing import TypeVar, Dict, Generic |
| T = TypeVar('T') |
| S = TypeVar('S') |
| class D(Dict[T, S], Generic[T, S]): |
| def __init__(self, x: S, y: T) -> None: pass |
| d = D(1, y='') |
| d() # E: "D[str, int]" not callable |
| [builtins fixtures/dict.pyi] |
| |
| [case testRevealType] |
| reveal_type(1) # N: Revealed type is "Literal[1]?" |
| |
| [case testRevealLocals] |
| x = 1 |
| y = 2 |
| z = x + y |
| reveal_locals() |
| [out] |
| main:4: note: Revealed local types are: |
| main:4: note: x: builtins.int |
| main:4: note: y: builtins.int |
| main:4: note: z: builtins.int |
| |
| [case testUndefinedRevealType] |
| reveal_type(x) |
| [out] |
| main:1: error: Name "x" is not defined |
| main:1: note: Revealed type is "Any" |
| |
| [case testUserDefinedRevealType] |
| def reveal_type(x: int) -> None: pass |
| reveal_type("foo") # E: Argument 1 to "reveal_type" has incompatible type "str"; expected "int" |
| |
| [case testTypingRevealType] |
| from typing import reveal_type |
| from typing import reveal_type as show_me_the_type |
| |
| reveal_type(1) # N: Revealed type is "Literal[1]?" |
| show_me_the_type(1) # N: Revealed type is "Literal[1]?" |
| |
| [case testTypingExtensionsRevealType] |
| from typing_extensions import reveal_type |
| from typing_extensions import reveal_type as show_me_the_type |
| |
| reveal_type(1) # N: Revealed type is "Literal[1]?" |
| show_me_the_type(1) # N: Revealed type is "Literal[1]?" |
| |
| [builtins fixtures/tuple.pyi] |
| |
| [case testRevealTypeVar] |
| reveal_type = 1 |
| 1 + "foo" # E: Unsupported operand types for + ("int" and "str") |
| |
| [case testRevealForward] |
| def f() -> None: |
| reveal_type(x) |
| x = 1 + int() |
| [out] |
| main:2: note: Revealed type is "builtins.int" |
| |
| [case testRevealUncheckedFunction] |
| def f(): |
| x = 42 |
| reveal_type(x) |
| [out] |
| main:3: note: Revealed type is "Any" |
| main:3: note: 'reveal_type' always outputs 'Any' in unchecked functions |
| |
| [case testRevealCheckUntypedDefs] |
| # flags: --check-untyped-defs |
| def f(): |
| x = 42 |
| reveal_type(x) |
| [out] |
| main:4: note: Revealed type is "builtins.int" |
| |
| [case testRevealTypedDef] |
| def f() -> None: |
| x = 42 |
| reveal_type(x) |
| [out] |
| main:3: note: Revealed type is "builtins.int" |
| |
| [case testLambdaTypedContext] |
| def f() -> None: |
| lambda: 'a'.missing() # E: "str" has no attribute "missing" |
| |
| [case testLambdaUnypedContext] |
| def f(): |
| lambda: 'a'.missing() |
| |
| [case testLambdaCheckUnypedContext] |
| # flags: --check-untyped-defs |
| def f(): |
| lambda: 'a'.missing() # E: "str" has no attribute "missing" |
| |
| [case testEqNone] |
| None == None |
| [builtins fixtures/ops.pyi] |
| |
| [case testLtNone] |
| None < None # E: Unsupported left operand type for < ("None") |
| [builtins fixtures/ops.pyi] |
| |
| [case testDictWithStarExpr] |
| |
| b = {'z': 26, *a} # E: invalid syntax |
| [builtins fixtures/dict.pyi] |
| |
| [case testDictWithStarStarExpr] |
| |
| from typing import Dict, Iterable |
| |
| class Thing: |
| def keys(self) -> Iterable[str]: |
| ... |
| def __getitem__(self, key: str) -> int: |
| ... |
| |
| a = {'a': 1} |
| b = {'z': 26, **a} |
| c = {**b} |
| d = {**a, **b, 'c': 3} |
| e = {1: 'a', **a} # E: Cannot infer type argument 1 of <dict> \ |
| # N: Try assigning the literal to a variable annotated as dict[<key>, <val>] |
| f = {**b} # type: Dict[int, int] # E: Unpacked dict entry 0 has incompatible type "Dict[str, int]"; expected "SupportsKeysAndGetItem[int, int]" |
| g = {**Thing()} |
| h = {**a, **Thing()} |
| i = {**Thing()} # type: Dict[int, int] # E: Unpacked dict entry 0 has incompatible type "Thing"; expected "SupportsKeysAndGetItem[int, int]" \ |
| # N: Following member(s) of "Thing" have conflicts: \ |
| # N: Expected: \ |
| # N: def __getitem__(self, int, /) -> int \ |
| # N: Got: \ |
| # N: def __getitem__(self, str, /) -> int \ |
| # N: Expected: \ |
| # N: def keys(self) -> Iterable[int] \ |
| # N: Got: \ |
| # N: def keys(self) -> Iterable[str] |
| j = {1: 'a', **Thing()} # E: Cannot infer type argument 1 of <dict> \ |
| # N: Try assigning the literal to a variable annotated as dict[<key>, <val>] |
| [builtins fixtures/dict.pyi] |
| [typing fixtures/typing-medium.pyi] |
| |
| [case testDictIncompatibleTypeErrorMessage] |
| from typing import Dict, Callable |
| |
| def things() -> int: |
| return 42 |
| |
| stuff: Dict[int, Callable[[], str]] = { |
| 1: things # E: Dict entry 0 has incompatible type "int": "Callable[[], int]"; expected "int": "Callable[[], str]" |
| } |
| [builtins fixtures/dict.pyi] |
| |
| [case testDictIncompatibleKeyVerbosity] |
| from typing import Dict |
| import mod |
| |
| class A: ... |
| class B(A): ... |
| |
| d: Dict[A, B] = {A(): mod.B()} # E: Dict entry 0 has incompatible type "A": "mod.B"; expected "A": "__main__.B" |
| |
| [file mod.py] |
| class B: ... |
| |
| [builtins fixtures/dict.pyi] |
| |
| [case testDictIncompatibleValueVerbosity] |
| from typing import Dict |
| import mod |
| |
| class A: ... |
| class B(A): ... |
| |
| d: Dict[B, A] = {mod.B(): A()} # E: Dict entry 0 has incompatible type "mod.B": "A"; expected "__main__.B": "A" |
| |
| [file mod.py] |
| class B: ... |
| |
| [builtins fixtures/dict.pyi] |
| |
| [case testTypeAnnotationNeededMultipleAssignment] |
| x, y = [], [] # E: Need type annotation for "x" (hint: "x: List[<type>] = ...") \ |
| # E: Need type annotation for "y" (hint: "y: List[<type>] = ...") |
| [builtins fixtures/list.pyi] |
| |
| [case testStrictEqualityEq] |
| # flags: --strict-equality |
| class A: ... |
| class B: ... |
| class C(B): ... |
| |
| A() == B() # E: Non-overlapping equality check (left operand type: "A", right operand type: "B") |
| B() == C() |
| C() == B() |
| A() != B() # E: Non-overlapping equality check (left operand type: "A", right operand type: "B") |
| B() != C() |
| C() != B() |
| [builtins fixtures/bool.pyi] |
| |
| [case testStrictEqualityIs] |
| # flags: --strict-equality |
| class A: ... |
| class B: ... |
| class C(B): ... |
| |
| A() is B() # E: Non-overlapping identity check (left operand type: "A", right operand type: "B") |
| B() is C() |
| C() is B() |
| A() is not B() # E: Non-overlapping identity check (left operand type: "A", right operand type: "B") |
| B() is not C() |
| C() is not B() |
| [builtins fixtures/bool.pyi] |
| |
| [case testStrictEqualityContains] |
| # flags: --strict-equality |
| class A: ... |
| class B: ... |
| class C(B): ... |
| |
| A() in [B()] # E: Non-overlapping container check (element type: "A", container item type: "B") |
| B() in [C()] |
| C() in [B()] |
| A() not in [B()] # E: Non-overlapping container check (element type: "A", container item type: "B") |
| B() not in [C()] |
| C() not in [B()] |
| [builtins fixtures/list.pyi] |
| [typing fixtures/typing-full.pyi] |
| |
| [case testStrictEqualityUnions] |
| # flags: --strict-equality |
| from typing import Container, Union |
| |
| class A: ... |
| class B: ... |
| |
| a: Union[int, str] |
| b: Union[A, B] |
| |
| a == int() |
| b == int() # E: Non-overlapping equality check (left operand type: "Union[A, B]", right operand type: "int") |
| |
| a is int() |
| b is int() # E: Non-overlapping identity check (left operand type: "Union[A, B]", right operand type: "int") |
| |
| ca: Union[Container[int], Container[str]] |
| cb: Union[Container[A], Container[B]] |
| |
| 42 in ca |
| 42 in cb # E: Non-overlapping container check (element type: "int", container item type: "Union[A, B]") |
| [builtins fixtures/bool.pyi] |
| [typing fixtures/typing-full.pyi] |
| |
| [case testStrictEqualityBytesSpecial] |
| # flags: --strict-equality |
| b'abc' in b'abcde' |
| [builtins fixtures/primitives.pyi] |
| [typing fixtures/typing-medium.pyi] |
| |
| [case testStrictEqualityBytesSpecialUnion] |
| # flags: --strict-equality |
| from typing import Union |
| x: Union[bytes, str] |
| |
| b'abc' in x |
| x in b'abc' |
| [builtins fixtures/primitives.pyi] |
| [typing fixtures/typing-medium.pyi] |
| |
| [case testStrictEqualityByteArraySpecial] |
| # flags: --strict-equality |
| b'abc' in bytearray(b'abcde') |
| bytearray(b'abc') in b'abcde' # OK on Python 3 |
| [builtins fixtures/primitives.pyi] |
| [typing fixtures/typing-medium.pyi] |
| |
| [case testStrictEqualityNoPromotePy3] |
| # flags: --strict-equality |
| 'a' == b'a' # E: Non-overlapping equality check (left operand type: "Literal['a']", right operand type: "Literal[b'a']") |
| b'a' in 'abc' # E: Non-overlapping container check (element type: "bytes", container item type: "str") |
| |
| x: str |
| y: bytes |
| x != y # E: Non-overlapping equality check (left operand type: "str", right operand type: "bytes") |
| [builtins fixtures/primitives.pyi] |
| [typing fixtures/typing-full.pyi] |
| |
| [case testStrictEqualityOkPromote] |
| # flags: --strict-equality |
| from typing import Container |
| c: Container[int] |
| |
| 1 == 1.0 # OK |
| 1.0 in c # OK |
| [builtins fixtures/primitives.pyi] |
| [typing fixtures/typing-full.pyi] |
| |
| [case testStrictEqualityAny] |
| # flags: --strict-equality |
| from typing import Any, Container |
| |
| x: Any |
| c: Container[str] |
| x in c |
| x == 42 |
| x is 42 |
| [builtins fixtures/bool.pyi] |
| [typing fixtures/typing-full.pyi] |
| |
| [case testStrictEqualityStrictOptional] |
| # flags: --strict-equality |
| |
| x: str |
| if x is not None: # OK even with strict-optional |
| pass |
| [builtins fixtures/bool.pyi] |
| |
| [case testStrictEqualityNoStrictOptional] |
| # flags: --strict-equality --no-strict-optional |
| |
| x: str |
| if x is not None: # OK without strict-optional |
| pass |
| [builtins fixtures/bool.pyi] |
| |
| [case testStrictEqualityEqNoOptionalOverlap] |
| # flags: --strict-equality |
| from typing import Optional |
| |
| x: Optional[str] |
| y: Optional[int] |
| if x == y: # E: Non-overlapping equality check (left operand type: "Optional[str]", right operand type: "Optional[int]") |
| ... |
| [builtins fixtures/bool.pyi] |
| |
| [case testCustomEqCheckStrictEquality] |
| # flags: --strict-equality |
| class A: |
| def __eq__(self, other: A) -> bool: # type: ignore |
| ... |
| class B: |
| def __eq__(self, other: B) -> bool: # type: ignore |
| ... |
| |
| # Don't report non-overlapping check if there is already and error. |
| A() == B() # E: Unsupported operand types for == ("A" and "B") |
| [builtins fixtures/bool.pyi] |
| |
| [case testStrictEqualitySequenceAndCustomEq] |
| # flags: --strict-equality |
| from typing import Tuple |
| |
| class C: pass |
| class D: |
| def __eq__(self, other): return True |
| |
| a = [C()] |
| b = [D()] |
| a == b |
| b == a |
| t1: Tuple[C, ...] |
| t2: Tuple[D, ...] |
| t1 == t2 |
| t2 == t1 |
| [builtins fixtures/bool.pyi] |
| |
| [case testCustomEqCheckStrictEqualityOKInstance] |
| # flags: --strict-equality |
| class A: |
| def __eq__(self, other: object) -> bool: |
| ... |
| class B: |
| def __eq__(self, other: object) -> bool: |
| ... |
| |
| A() == int() # OK |
| int() != B() # OK |
| [builtins fixtures/bool.pyi] |
| |
| [case testCustomEqCheckStrictEqualityOKUnion] |
| # flags: --strict-equality |
| from typing import Union |
| class A: |
| def __eq__(self, other: object) -> bool: |
| ... |
| |
| x: Union[A, str] |
| x == int() |
| [builtins fixtures/bool.pyi] |
| |
| [case testCustomEqCheckStrictEqualityTuple] |
| # flags: --strict-equality |
| from typing import NamedTuple |
| |
| class Base(NamedTuple): |
| attr: int |
| |
| class Custom(Base): |
| def __eq__(self, other: object) -> bool: ... |
| |
| Base(int()) == int() # E: Non-overlapping equality check (left operand type: "Base", right operand type: "int") |
| Base(int()) == tuple() |
| Custom(int()) == int() |
| [builtins fixtures/bool.pyi] |
| |
| [case testCustomEqCheckStrictEqualityMeta] |
| # flags: --strict-equality |
| class CustomMeta(type): |
| def __eq__(self, other: object) -> bool: ... |
| |
| class Normal: ... |
| class Custom(metaclass=CustomMeta): ... |
| |
| Normal == int() # E: Non-overlapping equality check (left operand type: "Type[Normal]", right operand type: "int") |
| Normal == Normal |
| Custom == int() |
| [builtins fixtures/bool.pyi] |
| |
| [case testCustomContainsCheckStrictEquality] |
| # flags: --strict-equality |
| class A: |
| def __contains__(self, other: A) -> bool: |
| ... |
| |
| # Don't report non-overlapping check if there is already and error. |
| 42 in A() # E: Unsupported operand types for in ("int" and "A") |
| [builtins fixtures/bool.pyi] |
| |
| [case testStrictEqualityTypeVsCallable] |
| # flags: --strict-equality |
| from typing import Type, List |
| class C: ... |
| class D(C): ... |
| class Bad: ... |
| |
| subclasses: List[Type[C]] |
| object in subclasses |
| D in subclasses |
| Bad in subclasses # E: Non-overlapping container check (element type: "Type[Bad]", container item type: "Type[C]") |
| [builtins fixtures/list.pyi] |
| [typing fixtures/typing-full.pyi] |
| |
| [case testStrictEqualityMetaclass] |
| # flags: --strict-equality |
| from typing import List, Type, Any |
| |
| class Meta(type): ... |
| class OtherMeta(type): ... |
| |
| class A(metaclass=Meta): ... |
| class B(metaclass=Meta): ... |
| class C(metaclass=OtherMeta): ... |
| |
| o: Type[object] |
| a: Type[Any] |
| aa: type |
| exp: List[Meta] |
| |
| A in exp |
| B in exp |
| C in exp # E: Non-overlapping container check (element type: "Type[C]", container item type: "Meta") |
| |
| o in exp |
| a in exp |
| aa in exp |
| |
| a in [A, B] |
| aa in [A, B] |
| |
| class AA: ... |
| class BB: ... |
| a in [AA, BB] |
| aa in [AA, BB] |
| [builtins fixtures/list.pyi] |
| [typing fixtures/typing-full.pyi] |
| |
| [case testEmptyListOverlap] |
| # mypy: strict-equality |
| from typing import List |
| |
| x: List[int] |
| x == [] |
| [builtins fixtures/isinstancelist.pyi] |
| |
| [case testCustomEqDecoratedStrictEquality] |
| # flags: --strict-equality |
| from typing import TypeVar, Callable, Any |
| |
| F = TypeVar('F', bound=Callable[..., Any]) |
| |
| def deco(f: F) -> F: ... |
| |
| class Custom: |
| @deco |
| def __eq__(self, other: object) -> bool: ... |
| |
| Custom() == int() |
| [builtins fixtures/bool.pyi] |
| |
| [case testCustomEqVarStrictEquality] |
| # flags: --strict-equality |
| |
| class Custom: |
| def compare(self, other: object) -> bool: ... |
| __eq__ = compare |
| |
| Custom() == int() |
| [builtins fixtures/bool.pyi] |
| |
| [case testStrictEqualityDisabledWithTypeVarRestrictions] |
| # flags: --strict-equality |
| from typing import TypeVar |
| |
| T = TypeVar('T', str, int) |
| |
| def f(x: T) -> T: |
| if x == int(): # OK |
| ... |
| return x |
| [builtins fixtures/bool.pyi] |
| |
| [case testStrictEqualityWithALiteral] |
| # flags: --strict-equality |
| from typing_extensions import Literal, Final |
| |
| def returns_a_or_b() -> Literal['a', 'b']: |
| ... |
| def returns_1_or_2() -> Literal[1, 2]: |
| ... |
| THREE: Final = 3 |
| |
| if returns_a_or_b() == 'c': # E: Non-overlapping equality check (left operand type: "Literal['a', 'b']", right operand type: "Literal['c']") |
| ... |
| if returns_1_or_2() is THREE: # E: Non-overlapping identity check (left operand type: "Literal[1, 2]", right operand type: "Literal[3]") |
| ... |
| [builtins fixtures/bool.pyi] |
| |
| [case testStrictEqualityWithALiteralNewType] |
| # flags: --strict-equality |
| from typing import NewType |
| |
| UserId = NewType('UserId', int) |
| FileId = NewType('FileId', str) |
| |
| u: UserId |
| f: FileId |
| |
| if u == 0: # OK |
| ... |
| if f == 0: # E: Non-overlapping equality check (left operand type: "FileId", right operand type: "Literal[0]") |
| ... |
| [builtins fixtures/bool.pyi] |
| |
| [case testStrictEqualityWithFixedLengthTupleInCheck] |
| # flags: --strict-equality |
| if 1 in ('x', 'y'): # E: Non-overlapping container check (element type: "int", container item type: "str") |
| pass |
| [builtins fixtures/tuple.pyi] |
| [typing fixtures/typing-full.pyi] |
| |
| [case testOverlappingAnyTypeWithoutStrictOptional] |
| # flags: --no-strict-optional --strict-equality |
| from typing import Any, Optional |
| |
| x: Optional[Any] |
| |
| if x in (1, 2): |
| pass |
| [builtins fixtures/tuple.pyi] |
| [typing fixtures/typing-full.pyi] |
| |
| |
| [case testOverlappingClassCallables] |
| # flags: --strict-equality |
| from typing import Any, Callable, Type |
| |
| x: Type[int] |
| y: Callable[[], Any] |
| x == y |
| y == x |
| int == y |
| y == int |
| [builtins fixtures/bool.pyi] |
| |
| [case testStrictEqualityAndEnumWithCustomEq] |
| # flags: --strict-equality |
| from enum import Enum |
| |
| class E1(Enum): |
| X = 0 |
| Y = 1 |
| |
| class E2(Enum): |
| X = 0 |
| Y = 1 |
| |
| def __eq__(self, other: object) -> bool: |
| return bool() |
| |
| E1.X == E1.Y # E: Non-overlapping equality check (left operand type: "Literal[E1.X]", right operand type: "Literal[E1.Y]") |
| E2.X == E2.Y |
| [builtins fixtures/bool.pyi] |
| |
| [case testStrictEqualityWithBytesContains] |
| # flags: --strict-equality |
| data = b"xy" |
| b"x" in data |
| [builtins fixtures/primitives.pyi] |
| [typing fixtures/typing-full.pyi] |
| |
| [case testUnimportedHintAny] |
| def f(x: Any) -> None: # E: Name "Any" is not defined \ |
| # N: Did you forget to import it from "typing"? (Suggestion: "from typing import Any") |
| pass |
| |
| |
| [case testUnimportedHintAnyLower] |
| def f(x: any) -> None: # E: Name "any" is not defined \ |
| # N: Did you forget to import it from "typing"? (Suggestion: "from typing import Any") |
| pass |
| |
| |
| [case testUnimportedHintOptional] |
| def f(x: Optional[str]) -> None: # E: Name "Optional" is not defined \ |
| # N: Did you forget to import it from "typing"? (Suggestion: "from typing import Optional") |
| pass |
| |
| [case testAssertionLazilyWithIsNone] |
| from typing import Optional, List |
| li: Optional[List] = [] |
| assert li is None, li[0] |
| [builtins fixtures/list.pyi] |
| |
| |
| [case testAssertionLazilyWithIsInstance] |
| from typing import Optional, List |
| li: Optional[List] = [] |
| assert not isinstance(li,list), li[0] |
| [builtins fixtures/isinstancelist.pyi] |
| |
| [case testAssertCurrentFrameIsNotUnreachable] |
| def f() -> int: # E: Missing return statement |
| x: int |
| assert isinstance(x, int), '...' |
| [builtins fixtures/isinstance.pyi] |
| |
| [case testTypeVarAsValue] |
| from typing import TypeVar |
| T = TypeVar("T") |
| x: int |
| x + T # E: Unsupported operand types for + ("int" and "object") |
| T() # E: "object" not callable |