blob: c213255997f890b7b1cd69d6d4febc32467f17c2 [file] [log] [blame] [edit]
-- 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