blob: c434c0642db29b1e3cef2a83c8e3776cfaac98bc [file] [log] [blame]
-- 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 = None # type: A
class A: pass
[out]
[case testNoneAsArgument]
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 = None # type: 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 = None # type: 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 = None # type: 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
[file builtins.py]
class object:
def __init__(self): pass
class type: pass
class function: pass
class float: pass
class str: pass
[case testComplexLiteral]
a = 0.0j
b = None # type: 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
[file builtins.py]
class object:
def __init__(self): pass
class type: pass
class function: pass
class complex: pass
class str: pass
[case testBytesLiteral]
b, a = None, None # type: (bytes, 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
[file builtins.py]
class object:
def __init__(self): pass
class type: pass
class tuple: pass
class function: pass
class bytes: pass
class str: pass
[case testUnicodeLiteralInPython3]
s = None # type: str
if int():
s = u'foo'
b = None # type: 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, b, c = None, None, None # type: (A, B, 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, b, c = None, None, None # type: (A, B, 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, b, c = None, None, None # type: (A, B, 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, b, c = None, None, None # type: (A, B, 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, b, c = None, None, None # type: (A, B, 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, b, c = None, None, None # type: (A, B, 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, b, c = None, None, None # type: (A, B, 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, b, c = None, None, None # type: (A, B, 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, b = None, None # type: (A, 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, b = None, None # type: (A, 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[bool, 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[bool, 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 = None # type: bool
i = None # type: str
j = not b and i
if j:
reveal_type(j) # N: Revealed type is 'builtins.str'
[builtins fixtures/bool.pyi]
[case testRestrictedTypeOr]
b = None # type: bool
i = None # type: 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, d, b = None, None, None # type: (C, D, 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, b, c, d, e = None, None, None, None, None # type: (A, B, bool, D, 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, b, c, d, e = None, None, None, None, None # type: (A, B, bool, D, 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, b, c = None, None, None # type: (A, bool, int)
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 "int")
if int():
c = a in a # E: Incompatible types in assignment (expression has type "bool", variable has type "int")
class A:
def __contains__(self, x: 'A') -> int: 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, b = None, None # type: (A, 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, b, bo = None, None, None # type: (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():
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 testCmp_python2]
a, b, c, bo = None, None, None, None # type: (A, B, C, bool)
bo = a == a # E: Unsupported operand types for == ("A" and "A")
bo = a != a # E: Unsupported operand types for comparison ("A" and "A")
bo = a < b
bo = a > b
bo = b <= b
bo = b <= c
bo = b >= c # E: Unsupported operand types for comparison ("C" and "B")
bo = a >= b
bo = c >= b
bo = c <= b # E: Unsupported operand types for comparison ("B" and "C")
bo = a == c
bo = b == c # E: Unsupported operand types for == ("C" and "B")
class A:
def __cmp__(self, o):
# type: ('B') -> bool
pass
def __eq__(self, o):
# type: ('int') -> bool
pass
class B:
def __cmp__(self, o):
# type: ('B') -> bool
pass
def __le__(self, o):
# type: ('C') -> bool
pass
class C:
def __cmp__(self, o):
# type: ('A') -> bool
pass
def __eq__(self, o):
# type: ('int') -> bool
pass
[builtins_py2 fixtures/bool_py2.pyi]
[case testDiv_python2]
10 / 'no' # E: Unsupported operand types for / ("int" and "str")
'no' / 10 # E: Unsupported operand types for / ("str" and "int")
[builtins_py2 fixtures/ops.pyi]
[case cmpIgnoredPy3]
a, b, bo = None, None, None # type: (A, B, 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, b, bo = None, None, None # type: (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():
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, b, bo = None, None, None # type: (A, B, 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:3: error: Unsupported operand types for < ("A" and "A")
main:5: error: Unsupported operand types for < ("A" and "A")
main:5: error: Unsupported operand types for > ("A" and "A")
[case testChainedCompBoolRes]
a, b, bo = None, None, None # type: (A, B, 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, y = None, None # type: (X, Y)
a, b, p, bo = None, None, None, None # type: (A, B, P, 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, b = None, None # type: (A, 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, b = None, None # type: (A, 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 = None # type: str
n = None # type: 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 = None # type: str
n = None # type: 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 = None # type: 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 = None # type: str
n = None # type: 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]
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, b = None, None # type: (A, 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, b = None, None # type: (A, 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, b = None, None # type: (A, 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, b = None, None # type: (A, 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, b, c = None, None, None # type: (A, B, 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, b, c = None, None, None # type: (A, B, 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:3: error: Invalid index type "C" for "A"; expected type "B"
main:4: error: Incompatible types in assignment (expression has type "A", target has type "C")
main:5: error: Unsupported target for indexed assignment ("B")
[case testOverloadedIndexing]
from foo import *
[file foo.pyi]
from typing import overload
a, b, c = None, None, None # type: (A, B, 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, s = None, None # type: (int, 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, b, c = None, None, None # type: (A, B, 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, b = None, None # type: (A, 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:3: error: "A" not callable
-- None return type
-- ----------------
[case testNoneReturnTypeBasics]
a, o = None, None # type: (A, 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)
def f() -> None:
pass
class A:
def g(self, x: object) -> None:
pass
def __call__(self) -> None:
pass
[builtins fixtures/tuple.pyi]
[case testNoneReturnTypeWithStatements]
import typing
if f(): # Fail
pass
elif f(): # Fail
pass
while f(): # Fail
pass
def g() -> object:
return f() # Fail
raise f() # Fail
def f() -> None: pass
[builtins fixtures/exception.pyi]
[out]
main:2: error: "f" does not return a value
main:4: error: "f" does not return a value
main:6: error: "f" does not return a value
main:9: error: "f" does not return a value
main:10: error: "f" does not return a value
[case testNoneReturnTypeWithExpressions]
from typing import cast
a = None # type: 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
def f() -> None: pass
class A:
def __add__(self, x: 'A') -> 'A': pass
[builtins fixtures/list.pyi]
[case testNoneReturnTypeWithExpressions2]
import typing
a, b = None, None # type: (A, 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
def f() -> None: pass
class A:
def __add__(self, x: 'A') -> 'A':
pass
[builtins fixtures/bool.pyi]
-- Slicing
-- -------
[case testGetSlice]
a, b = None, None # type: (A, 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 = None # type: 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 = None # type: 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, o = None, None # type: (Any, object)
a[o:1] # E: Slice index must be an integer or None
a[1:o] # E: Slice index must be an integer or None
a[o:] # E: Slice index must be an integer or None
a[:o] # E: Slice index must be an integer or None
[builtins fixtures/slice.pyi]
[case testNoneSliceBounds]
from typing import Any
a = None # type: Any
a[None:1]
a[1:None]
a[None:]
a[:None]
[builtins fixtures/slice.pyi]
[case testNoneSliceBoundsWithStrictOptional]
# flags: --strict-optional
from typing import Any
a = None # type: Any
a[None:1]
a[1:None]
a[None:]
a[:None]
[builtins fixtures/slice.pyi]
-- String interpolation
-- --------------------
[case testStringInterpolationType]
from typing import Tuple
i, f, s, t = None, None, None, None # type: (int, float, str, Tuple[int])
'%d' % i
'%f' % f
'%s' % s
'%d' % (f,)
'%d' % (s,) # E: Incompatible types in string interpolation (expression has type "str", placeholder has type "Union[int, float, SupportsInt]")
'%d' % t
'%d' % s # E: Incompatible types in string interpolation (expression has type "str", placeholder has type "Union[int, float, SupportsInt]")
'%f' % s # E: Incompatible types in string interpolation (expression has type "str", placeholder has type "Union[int, float, SupportsFloat]")
'%x' % f # E: Incompatible types in string interpolation (expression has type "float", placeholder has type "int")
'%i' % f
'%o' % f # E: Incompatible types in string interpolation (expression has type "float", placeholder has type "int")
[builtins fixtures/primitives.pyi]
[typing fixtures/typing-medium.pyi]
[case testStringInterpolationSAcceptsAnyType]
from typing import Any
i, o, s = None, None, None # type: (int, object, str)
'%s %s %s' % (i, o, s)
[builtins fixtures/primitives.pyi]
[case testStringInterpolationSBytesVsStrErrorPy3]
xb: bytes
xs: str
'%s' % xs # OK
'%s' % xb # E: On Python 3 '%s' % b'abc' produces "b'abc'", not 'abc'; use '%r' % b'abc' if this is desired behavior
'%(name)s' % {'name': b'value'} # E: On Python 3 '%s' % b'abc' produces "b'abc'", not 'abc'; use '%r' % b'abc' if this is desired behavior
[builtins fixtures/primitives.pyi]
[case testStringInterpolationSBytesVsStrResultsPy2]
# flags: --python-version 2.7
xs = 'x'
xu = u'x'
reveal_type('%s' % xu) # N: Revealed type is 'builtins.unicode'
reveal_type('%s, %d' % (u'abc', 42)) # N: Revealed type is 'builtins.unicode'
reveal_type('%(key)s' % {'key': xu}) # N: Revealed type is 'builtins.unicode'
reveal_type('%r' % xu) # N: Revealed type is 'builtins.str'
reveal_type('%s' % xs) # N: Revealed type is 'builtins.str'
[builtins fixtures/primitives.pyi]
[typing fixtures/typing-medium.pyi]
[case testStringInterpolationCount]
'%d %d' % 1 # E: Not enough arguments for format string
'%d %d' % (1, 2)
'%d %d' % (1, 2, 3) # E: Not all arguments converted during string formatting
t = 1, 's'
'%d %s' % t
'%s %d' % t # E: Incompatible types in string interpolation (expression has type "str", placeholder has type "Union[int, float, SupportsInt]")
'%d' % t # E: Not all arguments converted during string formatting
[builtins fixtures/primitives.pyi]
[typing fixtures/typing-medium.pyi]
[case testStringInterpolationWithAnyType]
from typing import Any
a = None # type: Any
'%d %d' % a
[builtins fixtures/primitives.pyi]
[typing fixtures/typing-medium.pyi]
[case testStringInterpolationInvalidPlaceholder]
'%W' % 1 # E: Unsupported format character 'W'
'%b' % 1 # E: Format character 'b' is only supported on bytes patterns
[case testStringInterPolationPython2]
# flags: --python-version 2.7
b'%b' % 1 # E: Format character 'b' is only supported in Python 3.5 and later
b'%s' % 1
b'%a' % 1 # E: Format character 'a' is only supported in Python 3
[case testBytesInterpolationBefore35]
# flags: --python-version 3.4
b'%b' % 1 # E: Unsupported left operand type for % ("bytes")
[case testBytesInterpolation]
b'%b' % 1 # E: Incompatible types in string interpolation (expression has type "int", placeholder has type "bytes")
b'%b' % b'1'
b'%a' % 3
[case testStringInterpolationWidth]
'%2f' % 3.14
'%*f' % 3.14 # E: Not enough arguments for format string
'%*f' % (4, 3.14)
'%*f' % (1.1, 3.14) # E: * wants int
[builtins fixtures/primitives.pyi]
[typing fixtures/typing-medium.pyi]
[case testStringInterpolationPrecision]
'%.2f' % 3.14
'%.*f' % 3.14 # E: Not enough arguments for format string
'%.*f' % (4, 3.14)
'%.*f' % (1.1, 3.14) # E: * wants int
[builtins fixtures/primitives.pyi]
[typing fixtures/typing-medium.pyi]
[case testStringInterpolationWidthAndPrecision]
'%4.2f' % 3.14
'%4.*f' % 3.14 # E: Not enough arguments for format string
'%*.2f' % 3.14 # E: Not enough arguments for format string
'%*.*f' % 3.14 # E: Not enough arguments for format string
'%*.*f' % (4, 2, 3.14)
[builtins fixtures/primitives.pyi]
[typing fixtures/typing-medium.pyi]
[case testStringInterpolationFlagsAndLengthModifiers]
'%04hd' % 1
'%-.4ld' % 1
'%+*Ld' % (1, 1)
'% .*ld' % (1, 1)
[builtins fixtures/primitives.pyi]
[typing fixtures/typing-medium.pyi]
[case testStringInterpolationDoublePercentage]
'%% %d' % 1
'%3% %d' % 1
'%*%' % 1
'%*% %d' % 1 # E: Not enough arguments for format string
[builtins fixtures/primitives.pyi]
[typing fixtures/typing-medium.pyi]
[case testStringInterpolationC]
'%c' % 1
'%c' % 's'
'%c' % '' # E: "%c" requires int or char
'%c' % 'ab' # E: "%c" requires int or char
[builtins fixtures/primitives.pyi]
[case testStringInterpolationMappingTypes]
'%(a)d %(b)s' % {'a': 1, 'b': 's'}
'%(a)d %(b)s' % {'a': 's', 'b': 1} # E: Incompatible types in string interpolation (expression has type "str", placeholder with key 'a' has type "Union[int, float, SupportsInt]")
b'%(x)s' % {b'x': b'data'}
[builtins fixtures/primitives.pyi]
[typing fixtures/typing-medium.pyi]
[case testStringInterpolationMappingKeys]
'%()d' % {'': 2}
'%(a)d' % {'a': 1, 'b': 2, 'c': 3}
'%(q)d' % {'a': 1, 'b': 2, 'c': 3} # E: Key 'q' not found in mapping
'%(a)d %%' % {'a': 1}
[builtins fixtures/primitives.pyi]
[typing fixtures/typing-medium.pyi]
[case testStringInterpolationMappingDictTypes]
from typing import Any, Dict
a = None # type: Any
ds, do, di = None, None, None # type: Dict[str, int], Dict[object, int], Dict[int, int]
'%(a)' % 1 # E: Format requires a mapping (expression has type "int", expected type for mapping is "Mapping[str, Any]")
'%()d' % a
'%()d' % ds
'%()d' % do # E: Format requires a mapping (expression has type "Dict[object, int]", expected type for mapping is "Mapping[str, Any]")
b'%()d' % ds # E: Format requires a mapping (expression has type "Dict[str, int]", expected type for mapping is "Mapping[bytes, Any]")
[builtins fixtures/primitives.pyi]
[case testStringInterpolationMappingInvalidDictTypesPy2]
# flags: --py2 --no-strict-optional
from typing import Any, Dict
di = None # type: Dict[int, int]
'%()d' % di # E: Format requires a mapping (expression has type "Dict[int, int]", expected type for mapping is "Union[Mapping[str, Any], Mapping[unicode, Any]]")
[builtins_py2 fixtures/python2.pyi]
[case testStringInterpolationMappingInvalidSpecifiers]
'%(a)d %d' % 1 # E: String interpolation mixes specifier with and without mapping keys
'%(b)*d' % 1 # E: String interpolation contains both stars and mapping keys
'%(b).*d' % 1 # E: String interpolation contains both stars and mapping keys
[case testStringInterpolationMappingFlagsAndLengthModifiers]
'%(a)1d' % {'a': 1}
'%(a).1d' % {'a': 1}
'%(a)#1.1ld' % {'a': 1}
[builtins fixtures/primitives.pyi]
[typing fixtures/typing-medium.pyi]
[case testStringInterpolationFloatPrecision]
'%.f' % 1.2
'%.3f' % 1.2
'%.f' % 'x'
'%.3f' % 'x'
[builtins fixtures/primitives.pyi]
[typing fixtures/typing-medium.pyi]
[out]
main:3: error: Incompatible types in string interpolation (expression has type "str", placeholder has type "Union[int, float, SupportsFloat]")
main:4: error: Incompatible types in string interpolation (expression has type "str", placeholder has type "Union[int, float, SupportsFloat]")
[case testStringInterpolationSpaceKey]
'%( )s' % {' ': 'foo'}
[case testByteByteInterpolation]
def foo(a: bytes, b: bytes):
b'%s:%s' % (a, b)
foo(b'a', b'b') == b'a:b'
[builtins fixtures/tuple.pyi]
[case testStringInterpolationStarArgs]
x = (1, 2)
"%d%d" % (*x,)
[typing fixtures/typing-medium.pyi]
[builtins fixtures/tuple.pyi]
[case testBytePercentInterpolationSupported]
b'%s' % (b'xyz',)
b'%(name)s' % {'name': b'jane'} # E: Dictionary keys in bytes formatting must be bytes, not strings
b'%(name)s' % {b'name': 'jane'} # E: On Python 3 b'%s' requires bytes, not string
b'%c' % (123)
[builtins fixtures/tuple.pyi]
[case testUnicodeInterpolation_python2]
u'%s' % (u'abc',)
[case testStringInterpolationVariableLengthTuple]
from typing import Tuple
def f(t: Tuple[int, ...]) -> None:
'%d %d' % t
'%d %d %d' % t
[builtins fixtures/primitives.pyi]
[typing fixtures/typing-medium.pyi]
[case testStringInterpolationUnionType]
from typing import Tuple, Union
a: Union[Tuple[int, str], Tuple[str, int]] = ('A', 1)
'%s %s' % a
'%s' % a # E: Not all arguments converted during string formatting
b: Union[Tuple[int, str], Tuple[int, int], Tuple[str, int]] = ('A', 1)
'%s %s' % b
'%s %s %s' % b # E: Not enough arguments for format string
c: Union[Tuple[str, int], Tuple[str, int, str]] = ('A', 1)
'%s %s' % c # E: Not all arguments converted during string formatting
[builtins fixtures/tuple.pyi]
-- str.format() calls
-- ------------------
[case testFormatCallParseErrors]
'}'.format() # E: Invalid conversion specifier in format string: unexpected }
'{'.format() # E: Invalid conversion specifier in format string: unmatched {
'}}'.format() # OK
'{{'.format() # OK
'{{}}}'.format() # E: Invalid conversion specifier in format string: unexpected }
'{{{}}'.format() # E: Invalid conversion specifier in format string: unexpected }
'{}}{{}'.format() # E: Invalid conversion specifier in format string: unexpected }
'{{{}:{}}}'.format(0) # E: Cannot find replacement for positional format specifier 1
[builtins fixtures/primitives.pyi]
[case testFormatCallValidationErrors]
'{!}}'.format(0) # E: Invalid conversion specifier in format string: unexpected }
'{!x}'.format(0) # E: Invalid conversion type "x", must be one of "r", "s" or "a"
'{!:}'.format(0) # E: Invalid conversion specifier in format string
'{{}:s}'.format(0) # E: Invalid conversion specifier in format string: unexpected }
'{{}.attr}'.format(0) # E: Invalid conversion specifier in format string: unexpected }
'{{}[key]}'.format(0) # E: Invalid conversion specifier in format string: unexpected }
'{ {}:s}'.format() # E: Conversion value must not contain { or }
'{ {}.attr}'.format() # E: Conversion value must not contain { or }
'{ {}[key]}'.format() # E: Conversion value must not contain { or }
[builtins fixtures/primitives.pyi]
[case testFormatCallEscaping]
'{}'.format() # E: Cannot find replacement for positional format specifier 0
'{}'.format(0) # OK
'{{}}'.format() # OK
'{{}}'.format(0) # E: Not all arguments converted during string formatting
'{{{}}}'.format() # E: Cannot find replacement for positional format specifier 0
'{{{}}}'.format(0) # OK
'{{}} {} {{}}'.format(0) # OK
'{{}} {:d} {{}} {:d}'.format('a', 'b') # E: Incompatible types in string interpolation (expression has type "str", placeholder has type "int")
'foo({}, {}) == {{}} ({{}} expected)'.format(0) # E: Cannot find replacement for positional format specifier 1
'foo({}, {}) == {{}} ({{}} expected)'.format(0, 1) # OK
'foo({}, {}) == {{}} ({{}} expected)'.format(0, 1, 2) # E: Not all arguments converted during string formatting
[builtins fixtures/primitives.pyi]
[case testFormatCallNestedFormats]
'{:{}{}}'.format(42, '*') # E: Cannot find replacement for positional format specifier 2
'{:{}{}}'.format(42, '*', '^') # OK
'{:{}{}}'.format(42, '*', '^', 0) # E: Not all arguments converted during string formatting
# NOTE: we don't check format specifiers that contain { or } at all
'{:{{}}}'.format() # E: Cannot find replacement for positional format specifier 0
'{:{:{}}}'.format() # E: Formatting nesting must be at most two levels deep
'{:{{}:{}}}'.format() # E: Invalid conversion specifier in format string: unexpected }
'{!s:{fill:d}{align}}'.format(42, fill='*', align='^') # E: Incompatible types in string interpolation (expression has type "str", placeholder has type "int")
[builtins fixtures/primitives.pyi]
[case testFormatCallAutoNumbering]
'{}, {{}}, {0}'.format() # E: Cannot combine automatic field numbering and manual field specification
'{0}, {1}, {}'.format() # E: Cannot combine automatic field numbering and manual field specification
'{0}, {1}, {0}'.format(1, 2, 3) # E: Not all arguments converted during string formatting
'{}, {other:+d}, {}'.format(1, 2, other='no') # E: Incompatible types in string interpolation (expression has type "str", placeholder has type "int")
'{0}, {other}, {}'.format() # E: Cannot combine automatic field numbering and manual field specification
'{:{}}, {:{:.5d}{}}'.format(1, 2, 3, 'a', 5) # E: Incompatible types in string interpolation (expression has type "str", placeholder has type "int")
[builtins fixtures/primitives.pyi]
[case testFormatCallMatchingPositional]
'{}'.format(positional='no') # E: Cannot find replacement for positional format specifier 0 \
# E: Not all arguments converted during string formatting
'{.x}, {}, {}'.format(1, 'two', 'three') # E: "int" has no attribute "x"
'Reverse {2.x}, {1}, {0}'.format(1, 2, 'three') # E: "str" has no attribute "x"
''.format(1, 2) # E: Not all arguments converted during string formatting
[builtins fixtures/primitives.pyi]
[case testFormatCallMatchingNamed]
'{named}'.format(0) # E: Cannot find replacement for named format specifier "named" \
# E: Not all arguments converted during string formatting
'{one.x}, {two}'.format(one=1, two='two') # E: "int" has no attribute "x"
'{one}, {two}, {.x}'.format(1, one='two', two='three') # E: "int" has no attribute "x"
''.format(stuff='yes') # E: Not all arguments converted during string formatting
[builtins fixtures/primitives.pyi]
[case testFormatCallMatchingVarArg]
from typing import List
args: List[int] = []
'{}, {}'.format(1, 2, *args) # Don't flag this because args may be empty
strings: List[str]
'{:d}, {[0].x}'.format(*strings) # E: Incompatible types in string interpolation (expression has type "str", placeholder has type "int") \
# E: "str" has no attribute "x"
# TODO: this is a runtime error, but error message is confusing
'{[0][:]:d}'.format(*strings) # E: Syntax error in format specifier "0[0]["
[builtins fixtures/primitives.pyi]
[case testFormatCallMatchingKwArg]
from typing import Dict
kwargs: Dict[str, str] = {}
'{one}, {two}'.format(one=1, two=2, **kwargs) # Don't flag this because args may be empty
'{stuff:.3d}'.format(**kwargs) # E: Incompatible types in string interpolation (expression has type "str", placeholder has type "int")
'{stuff[0]:f}, {other}'.format(**kwargs) # E: Incompatible types in string interpolation (expression has type "str", placeholder has type "Union[int, float]")
'{stuff[0]:c}'.format(**kwargs)
[builtins fixtures/primitives.pyi]
[case testFormatCallCustomFormatSpec]
from typing import Union
class Bad:
...
class Good:
def __format__(self, spec: str) -> str: ...
'{:OMG}'.format(Good())
'{:OMG}'.format(Bad()) # E: Unrecognized format specification "OMG"
'{!s:OMG}'.format(Good()) # E: Unrecognized format specification "OMG"
'{:{}OMG{}}'.format(Bad(), 'too', 'dynamic')
x: Union[Good, Bad]
'{:OMG}'.format(x) # E: Unrecognized format specification "OMG"
[builtins fixtures/primitives.pyi]
[case testFormatCallFormatTypes]
'{:x}'.format(42)
'{:E}'.format(42)
'{:g}'.format(42)
'{:x}'.format('no') # E: Incompatible types in string interpolation (expression has type "str", placeholder has type "int")
'{:E}'.format('no') # E: Incompatible types in string interpolation (expression has type "str", placeholder has type "Union[int, float]")
'{:g}'.format('no') # E: Incompatible types in string interpolation (expression has type "str", placeholder has type "Union[int, float]")
'{:n}'.format(3.14)
'{:d}'.format(3.14) # E: Incompatible types in string interpolation (expression has type "float", placeholder has type "int")
'{:s}'.format(42)
'{:s}'.format('yes')
'{:z}'.format('what') # E: Unsupported format character 'z'
'{:Z}'.format('what') # E: Unsupported format character 'Z'
[builtins fixtures/primitives.pyi]
[case testFormatCallFormatTypesChar]
'{:c}'.format(42)
'{:c}'.format('no') # E: ":c" requires int or char
'{:c}'.format('c')
class C:
...
'{:c}'.format(C()) # E: Incompatible types in string interpolation (expression has type "C", placeholder has type "Union[int, float, str]")
x: str
'{:c}'.format(x)
[builtins fixtures/primitives.pyi]
[case testFormatCallFormatTypesCustomFormat]
from typing import Union
class Bad:
...
class Good:
def __format__(self, spec: str) -> str: ...
x: Union[Good, Bad]
y: Union[Good, int]
z: Union[Bad, int]
t: Union[Good, str]
'{:d}'.format(x) # E: Incompatible types in string interpolation (expression has type "Bad", placeholder has type "int")
'{:d}'.format(y)
'{:d}'.format(z) # E: Incompatible types in string interpolation (expression has type "Bad", placeholder has type "int")
'{:d}'.format(t) # E: Incompatible types in string interpolation (expression has type "str", placeholder has type "int")
[builtins fixtures/primitives.pyi]
[case testFormatCallFormatTypesBytes]
from typing import Union, TypeVar, NewType, Generic
A = TypeVar('A', str, bytes)
B = TypeVar('B', bound=bytes)
x: Union[str, bytes]
a: str
b: bytes
N = NewType('N', bytes)
n: N
'{}'.format(a)
'{}'.format(b) # E: On Python 3 '{}'.format(b'abc') produces "b'abc'", not 'abc'; use '{!r}'.format(b'abc') if this is desired behavior
'{}'.format(x) # E: On Python 3 '{}'.format(b'abc') produces "b'abc'", not 'abc'; use '{!r}'.format(b'abc') if this is desired behavior
'{}'.format(n) # E: On Python 3 '{}'.format(b'abc') produces "b'abc'", not 'abc'; use '{!r}'.format(b'abc') if this is desired behavior
class C(Generic[B]):
x: B
def meth(self) -> None:
'{}'.format(self.x) # E: On Python 3 '{}'.format(b'abc') produces "b'abc'", not 'abc'; use '{!r}'.format(b'abc') if this is desired behavior
def func(x: A) -> A:
'{}'.format(x) # E: On Python 3 '{}'.format(b'abc') produces "b'abc'", not 'abc'; use '{!r}'.format(b'abc') if this is desired behavior
return x
'{!r}'.format(b)
'{!r}'.format(x)
'{!r}'.format(n)
class D(bytes):
def __str__(self) -> str:
return "overrides __str__ of bytes"
'{}'.format(D())
[builtins fixtures/primitives.pyi]
[case testFormatCallFormatTypesBytesNotPy2]
# flags: --py2
from typing import Union, TypeVar, NewType, Generic
A = TypeVar('A', str, unicode)
B = TypeVar('B', bound=str)
x = '' # type: Union[str, unicode]
a = ''
b = b''
N = NewType('N', str)
n = N(b'')
'{}'.format(a)
'{}'.format(b)
'{}'.format(x)
'{}'.format(n)
u'{}'.format(a)
u'{}'.format(b)
u'{}'.format(x)
u'{}'.format(n)
class C(Generic[B]):
x = None # type: B
def meth(self):
# type: () -> None
'{}'.format(self.x)
def func(x):
# type: (A) -> A
'{}'.format(x)
return x
'{!r}'.format(b)
'{!r}'.format(x)
'{!r}'.format(n)
[builtins_py2 fixtures/python2.pyi]
[case testFormatCallFinal]
from typing_extensions import Final
FMT: Final = '{.x}, {:{:d}}'
FMT.format(1, 2, 'no') # E: "int" has no attribute "x" \
# E: Incompatible types in string interpolation (expression has type "str", placeholder has type "int")
[builtins fixtures/primitives.pyi]
[case testFormatCallFinalChar]
from typing_extensions import Final
GOOD: Final = 'c'
BAD: Final = 'no'
OK: Final[str] = '...'
'{:c}'.format(GOOD)
'{:c}'.format(BAD) # E: ":c" requires int or char
'{:c}'.format(OK)
[builtins fixtures/primitives.pyi]
[case testFormatCallForcedConversions]
'{!r}'.format(42)
'{!s}'.format(42)
'{!s:d}'.format(42) # E: Incompatible types in string interpolation (expression has type "str", placeholder has type "int")
'{!s:s}'.format('OK')
'{} and {!x}'.format(0, 1) # E: Invalid conversion type "x", must be one of "r", "s" or "a"
[builtins fixtures/primitives.pyi]
[case testFormatCallAccessorsBasic]
from typing import Any
x: Any
'{.x:{[0]}}'.format('yes', 42) # E: "str" has no attribute "x" \
# E: Value of type "int" is not indexable
'{.1+}'.format(x) # E: Syntax error in format specifier "0.1+"
'{name.x[x]()[x]:.2f}'.format(name=x) # E: Only index and member expressions are allowed in format field accessors; got "name.x[x]()[x]"
[builtins fixtures/primitives.pyi]
[case testFormatCallAccessorsIndices]
from typing_extensions import TypedDict
class User(TypedDict):
id: int
name: str
u: User
'{user[name]:.3f}'.format(user=u) # E: Incompatible types in string interpolation (expression has type "str", placeholder has type "Union[int, float]")
def f() -> str: ...
'{[f()]}'.format(u) # E: Invalid index expression in format field accessor "[f()]"
[builtins fixtures/primitives.pyi]
[case testFormatCallFlags]
from typing import Union
class Good:
def __format__(self, spec: str) -> str: ...
'{:#}'.format(42)
'{:#}'.format('no') # E: Numeric flags are only allowed for numeric types
'{!s:#}'.format(42) # E: Numeric flags are only allowed for numeric types
'{:#s}'.format(42) # E: Numeric flags are only allowed for numeric types
'{:+s}'.format(42) # E: Numeric flags are only allowed for numeric types
'{:+d}'.format(42)
'{:#d}'.format(42)
x: Union[float, Good]
'{:+f}'.format(x)
[builtins fixtures/primitives.pyi]
[typing fixtures/typing-medium.pyi]
[case testFormatCallSpecialCases]
'{:08b}'.format(int('3'))
class S:
def __int__(self) -> int: ...
'{:+d}'.format(S()) # E: Incompatible types in string interpolation (expression has type "S", placeholder has type "int")
'%d' % S() # This is OK however
'{:%}'.format(0.001)
[builtins fixtures/primitives.pyi]
[typing fixtures/typing-medium.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]
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 = None # type: 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 = None # type: 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 = None # type: 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 = None # type: 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 = None # type: 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 = None # type: 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 = None # type: 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 = None # type: Dict[A, B]
abl = None # type: 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 = None # type: 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 = None # type: Iterator[int]
if int():
a = (x for x in a)
b = None # type: 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 = None # type: 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
a = None # type: A
None + a # Fail
f + a # Fail
a + f # Fail
cast(A, f)
def f() -> None:
pass
[out]
main:5: error: Unsupported left operand type for + ("None")
main:6: error: Unsupported left operand type for + ("Callable[[], None]")
main:7: error: Unsupported operand types for + ("A" and "Callable[[], None]")
[case testOperatorMethodWithInvalidArgCount]
a = None # type: 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 = None # type: A
a + a
[out]
[case testOperatorMethodAsVar2]
class A:
def f(self, x: int) -> str: pass
__add__ = f
s = None # type: str
s = A() + 1
A() + (A() + 1)
[out]
main:7: error: Argument 1 has incompatible type "str"; expected "int"
[case testIndexedLvalueWithSubtypes]
a, b, c = None, None, None # type: (A, B, 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 = None # type: 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
[file builtins.py]
class object:
def __init__(self): pass
class ellipsis:
def __init__(self): pass
__class__ = object()
class type: pass
class function: pass
class str: pass
[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 testRevealTypeVar]
reveal_type = 1
1 + "foo" # E: Unsupported operand types for + ("int" and "str")
[case testRevealForward]
def f() -> None:
reveal_type(x)
x = 1 + 1
[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 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
a = {'a': 1}
b = {'z': 26, **a}
c = {**b}
d = {**a, **b, 'c': 3}
e = {1: 'a', **a} # E: Argument 1 to "update" of "dict" has incompatible type "Dict[str, int]"; expected "Mapping[int, str]"
f = {**b} # type: Dict[int, int] # E: List item 0 has incompatible type "Dict[str, int]"; expected "Mapping[int, int]"
[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 testBytesVsByteArray_python2]
# flags: --strict-equality --py2
b'hi' in bytearray(b'hi')
[builtins_py2 fixtures/python2.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 --strict-optional
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 --strict-optional
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 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: "Union[Literal['a'], Literal['b']]", right operand type: "Literal['c']")
...
if returns_1_or_2() is THREE: # E: Non-overlapping identity check (left operand type: "Union[Literal[1], Literal[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 testStrictEqualityPromotionsLiterals]
# flags: --strict-equality --py2
from typing import Final
U_FOO = u'foo' # type: Final
if str() == U_FOO:
pass
assert u'foo' == 'foo'
assert u'foo' == u'bar' # E: Non-overlapping equality check (left operand type: "Literal[u'foo']", right operand type: "Literal[u'bar']")
[builtins_py2 fixtures/python2.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 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