blob: 7d25eb271f534869ad0f486ba5d8a0ce49463627 [file] [log] [blame]
[case testCallableDef]
def f() -> None: pass
if callable(f):
f()
else:
f += 5
[builtins fixtures/callable.pyi]
[case testCallableLambda]
f = lambda: None
if callable(f):
f()
else:
f += 5
[builtins fixtures/callable.pyi]
[case testCallableNotCallable]
x = 5
if callable(x):
x()
else:
x += 5
[builtins fixtures/callable.pyi]
[case testUnion]
from typing import Callable, Union
x = 5 # type: Union[int, Callable[[], str]]
if callable(x):
y = x() + 'test'
else:
z = x + 6
[builtins fixtures/callable.pyi]
[case testUnionMultipleReturnTypes]
from typing import Callable, Union
x = 5 # type: Union[int, Callable[[], str], Callable[[], int]]
if callable(x):
y = x() + 2 # E: Unsupported operand types for + ("str" and "int") \
# N: Left operand is of type "Union[str, int]"
else:
z = x + 6
[builtins fixtures/callable.pyi]
[case testUnionMultipleNonCallableTypes]
from typing import Callable, Union
x = 5 # type: Union[int, str, Callable[[], str]]
if callable(x):
y = x() + 'test'
else:
z = x + 6 # E: Unsupported operand types for + ("str" and "int") \
# N: Left operand is of type "Union[int, str]"
[builtins fixtures/callable.pyi]
[case testCallableThenIsinstance]
from typing import Callable, Union
x = 5 # type: Union[int, str, Callable[[], str], Callable[[], int]]
if callable(x):
y = x()
if isinstance(y, int):
b1 = y + 2
else:
b2 = y + 'test'
else:
if isinstance(x, int):
b3 = x + 3
else:
b4 = x + 'test2'
[builtins fixtures/callable.pyi]
[case testIsinstanceThenCallable]
from typing import Callable, Union
x = 5 # type: Union[int, str, Callable[[], str], Callable[[], int]]
if isinstance(x, int):
b1 = x + 1
else:
if callable(x):
y = x()
if isinstance(y, int):
b2 = y + 1
else:
b3 = y + 'test'
else:
b4 = x + 'test2'
[builtins fixtures/callable.pyi]
[case testCallableWithDifferentArgTypes]
from typing import Callable, Union
x = 5 # type: Union[int, Callable[[], None], Callable[[int], None]]
if callable(x):
x() # E: Too few arguments
[builtins fixtures/callable.pyi]
[case testClassInitializer]
from typing import Callable, Union
class A:
x = 5
a = A # type: Union[A, Callable[[], A]]
if callable(a):
a = a()
a.x + 6
[builtins fixtures/callable.pyi]
[case testCallableVariables]
from typing import Union
class A:
x = 5
class B:
x = int
x = A() # type: Union[A, B]
if callable(x.x):
y = x.x()
else:
y = x.x + 5
[builtins fixtures/callable.pyi]
[case testCallableAnd]
from typing import Union, Callable
x = 5 # type: Union[int, Callable[[], str]]
if callable(x) and x() == 'test':
x()
else:
x + 5 # E: Unsupported left operand type for + ("Callable[[], str]") \
# N: Left operand is of type "Union[int, Callable[[], str]]"
[builtins fixtures/callable.pyi]
[case testCallableOr]
from typing import Union, Callable
x = 5 # type: Union[int, Callable[[], str]]
if callable(x) or x() == 'test': # E: "int" not callable
x() # E: "int" not callable
else:
x + 5
[builtins fixtures/callable.pyi]
[case testCallableOrOtherType]
from typing import Union, Callable
x = 5 # type: Union[int, Callable[[], str]]
if callable(x) or x == 2:
pass
else:
pass
[builtins fixtures/callable.pyi]
[case testAnyCallable]
from typing import Any
x = 5 # type: Any
if callable(x):
reveal_type(x) # N: Revealed type is "Any"
else:
reveal_type(x) # N: Revealed type is "Any"
[builtins fixtures/callable.pyi]
[case testCallableCallableClasses]
from typing import Union
class A:
pass
class B:
def __call__(self) -> None:
pass
a = A() # type: A
b = B() # type: B
c = A() # type: Union[A, B]
if callable(a):
5 + 'test' # E: Unsupported operand types for + ("int" and "str")
if not callable(b):
5 + 'test'
if callable(c):
reveal_type(c) # N: Revealed type is "__main__.B"
else:
reveal_type(c) # N: Revealed type is "__main__.A"
[builtins fixtures/callable.pyi]
[case testDecoratedCallMethods]
from typing import Any, Callable, Union, TypeVar
F = TypeVar('F', bound=Callable)
def decorator(f: F) -> F:
pass
def change(f: Callable) -> Callable[[Any], str]:
pass
def untyped(f):
pass
class Some1:
@decorator
def __call__(self) -> int:
pass
class Some2:
@change
def __call__(self) -> int:
pass
class Some3:
@untyped
def __call__(self) -> int:
pass
class Some4:
__call__: Any
s1: Some1
s2: Some2
s3: Some3
s4: Some4
if callable(s1):
1 + 'a' # E: Unsupported operand types for + ("int" and "str")
else:
2 + 'b'
if callable(s2):
1 + 'a' # E: Unsupported operand types for + ("int" and "str")
else:
2 + 'b'
if callable(s3):
1 + 'a' # E: Unsupported operand types for + ("int" and "str")
else:
2 + 'b' # E: Unsupported operand types for + ("int" and "str")
if callable(s4):
1 + 'a' # E: Unsupported operand types for + ("int" and "str")
else:
2 + 'b' # E: Unsupported operand types for + ("int" and "str")
[builtins fixtures/callable.pyi]
[case testCallableNestedUnions]
from typing import Callable, Union
T = Union[Union[int, Callable[[], int]], Union[str, Callable[[], str]]]
def f(t: T) -> None:
if callable(t):
reveal_type(t()) # N: Revealed type is "Union[builtins.int, builtins.str]"
else:
reveal_type(t) # N: Revealed type is "Union[builtins.int, builtins.str]"
[builtins fixtures/callable.pyi]
[case testCallableTypeVarEmpty]
from typing import TypeVar
T = TypeVar('T')
def f(t: T) -> T:
if callable(t):
return 5 # E: Incompatible return value type (got "int", expected "T")
else:
return t
[builtins fixtures/callable.pyi]
[case testCallableTypeVarUnion]
from typing import Callable, TypeVar, Union
T = TypeVar('T', int, Callable[[], int], Union[str, Callable[[], str]])
def f(t: T) -> None:
if callable(t):
reveal_type(t()) # N: Revealed type is "Any" \
# N: Revealed type is "builtins.int" \
# N: Revealed type is "builtins.str"
else:
reveal_type(t) # N: Revealed type is "builtins.int" # N: Revealed type is "builtins.str"
[builtins fixtures/callable.pyi]
[case testCallableTypeVarBound]
from typing import TypeVar
class A:
def __call__(self) -> str:
return 'hi'
T = TypeVar('T', bound=A)
def f(t: T) -> str:
if callable(t):
return t()
else:
return 5
[builtins fixtures/callable.pyi]
[case testCallableTypeType]
from typing import Type
class A:
pass
T = Type[A]
def f(t: T) -> A:
if callable(t):
return t()
else:
return 5
[builtins fixtures/callable.pyi]
[case testCallableTypeUnion]
from abc import ABCMeta, abstractmethod
from typing import Type, Union
class A(metaclass=ABCMeta):
@abstractmethod
def f(self) -> None:
pass
class B:
pass
x = B # type: Union[Type[A], Type[B]]
if callable(x):
# Abstract classes raise an error when called, but are indeed `callable`
pass
else:
'test' + 5
[builtins fixtures/callable.pyi]
[case testCallableUnionOfTypes]
from abc import ABCMeta, abstractmethod
from typing import Type, Union
class A(metaclass=ABCMeta):
@abstractmethod
def f(self) -> None:
pass
class B:
pass
x = B # type: Type[Union[A, B]]
if callable(x):
# Abstract classes raise an error when called, but are indeed `callable`
pass
else:
'test' + 5
[builtins fixtures/callable.pyi]
[case testCallableObject]
def f(o: object) -> None:
if callable(o):
o(1,2,3)
1 + 'boom' # E: Unsupported operand types for + ("int" and "str")
o('hi') + 12
reveal_type(o) # N: Revealed type is "__main__.<callable subtype of object>"
[builtins fixtures/callable.pyi]
[case testCallableObject2]
class Foo(object):
def bar(self) -> None:
pass
def g(o: Foo) -> None:
o.bar()
if callable(o):
o.foo() # E: "Foo" has no attribute "foo"
o.bar()
o(1,2,3)
else:
o.bar()
[builtins fixtures/callable.pyi]
[case testCallableObjectAny]
from typing import Any
class Foo(Any):
def bar(self) -> None:
pass
def g(o: Foo) -> None:
o.bar()
o.baz()
if callable(o):
o('test')
o.lurr(1,2,3)
[builtins fixtures/callable.pyi]
[case testCallableObjectGeneric]
from typing import TypeVar, Generic
T = TypeVar('T')
class Test(Generic[T]):
def __self__(self, x: T) -> None:
self.x = x
def g(o: Test[T], x: T) -> T:
if callable(o):
o.foo() # E: "Test[T]" has no attribute "foo"
o(1,2,3)
o.x = x
o.x = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "T")
1 + o.x # E: Unsupported operand types for + ("int" and "T")
return o.x
return x
[builtins fixtures/callable.pyi]
[case testCallablePromote]
def take_float(f: float) -> None:
pass
def g(o: int) -> None:
if callable(o):
take_float(o)
o(1,2,3)
[builtins fixtures/callable.pyi]
[case testCallableTuple]
from typing import NamedTuple
Thing = NamedTuple('Thing', [('s', str), ('n', int)])
def g(o: Thing) -> None:
if callable(o):
o.s + o.n # E: Unsupported operand types for + ("str" and "int")
i, s = o
i + s # E: Unsupported operand types for + ("str" and "int")
o(1,2,3)
[builtins fixtures/callable.pyi]
[case testCallableNoArgs]
if callable(): # E: Missing positional argument "x" in call to "callable"
pass
[builtins fixtures/callable.pyi]
[case testCallableWithNoneArgs]
fn = None
if callable(fn):
fn()
[builtins fixtures/callable.pyi]
[case testCallableUnionOfNoneAndCallable]
from typing import Union, Callable
def f() -> int:
return 42
fn = f # type: Union[None, Callable[[], int]]
if callable(fn):
reveal_type(fn) # N: Revealed type is "def () -> builtins.int"
else:
reveal_type(fn) # N: Revealed type is "None"
[builtins fixtures/callable.pyi]
[case testBuiltinsTypeAsCallable]
# flags: --python-version 3.7
from __future__ import annotations
reveal_type(type) # N: Revealed type is "def (x: Any) -> builtins.type"
_TYPE = type
reveal_type(_TYPE) # N: Revealed type is "def (x: Any) -> builtins.type"
_TYPE('bar')
[builtins fixtures/callable.pyi]
[case testErrorMessageAboutSelf]
# https://github.com/python/mypy/issues/11309
class Some:
def method(self, a) -> None: pass
@classmethod
def cls_method(cls, a) -> None: pass
@staticmethod
def st_method(a) -> None: pass
def bad_method(a) -> None: pass
@classmethod
def bad_cls_method(a) -> None: pass
@staticmethod
def bad_st_method() -> None: pass
s: Some
s.method(1)
s.cls_method(1)
Some.cls_method(1)
s.st_method(1)
Some.st_method(1)
s.method(1, 2) # E: Too many arguments for "method" of "Some"
s.cls_method(1, 2) # E: Too many arguments for "cls_method" of "Some"
Some.cls_method(1, 2) # E: Too many arguments for "cls_method" of "Some"
s.st_method(1, 2) # E: Too many arguments for "st_method" of "Some"
Some.st_method(1, 2) # E: Too many arguments for "st_method" of "Some"
s.bad_method(1) # E: Too many arguments for "bad_method" of "Some" \
# N: Looks like the first special argument in a method is not named "self", "cls", or "mcs", maybe it is missing?
s.bad_cls_method(1) # E: Too many arguments for "bad_cls_method" of "Some" \
# N: Looks like the first special argument in a method is not named "self", "cls", or "mcs", maybe it is missing?
Some.bad_cls_method(1) # E: Too many arguments for "bad_cls_method" of "Some" \
# N: Looks like the first special argument in a method is not named "self", "cls", or "mcs", maybe it is missing?
s.bad_st_method(1) # E: Too many arguments for "bad_st_method" of "Some"
Some.bad_st_method(1) # E: Too many arguments for "bad_st_method" of "Some"
[builtins fixtures/callable.pyi]
[case testClassMethodAliasStub]
from a import f
f("no") # E: Argument 1 has incompatible type "str"; expected "int"
[file a.pyi]
from b import C
f = C.f
[file b.pyi]
import a
class C(B):
@classmethod
def f(self, x: int) -> C: ...
class B: ...
[builtins fixtures/classmethod.pyi]