Vous pouvez utiliser un "protocole appelable" ici, donc:
import typing
class MyCallableType(typing.Protocol):
def __call__(self, bar:int) -> None:
...
def a(foo: MyCallableType):
foo(32)
foo(bar=32)
Maintenant, testons ce qui précède avec mypy
:
jarrivillaga$ mypy --version
mypy 0.910
jarrivillaga$ mypy test.py
Success: no issues found in 1 source file
Notez que cela permet à mypy de détecter toutes sortes d'erreurs, par exemple une fonction avec un nom d'argument incorrect, ou si nous voulons que b
soit une fonction qui spécifie un argument bar avec mot-clé uniquement:
import typing
class MyCallableType(typing.Protocol):
def __call__(self, b:int) -> None:
...
def a(foo: MyCallableType):
foo(32)
foo(b=32)
def bar(b: int) -> None:
pass
def baz(*, b: int) -> None:
pass
def bing(x: int) -> None:
pass
a(bar)
a(baz)
a(bing)
Et mypy se plaindra avec ce qui suit:
jarrivillaga$ mypy test.py
test.py:21: error: Argument 1 to "a" has incompatible type "Callable[[NamedArg(int, 'b')], None]"; expected "MyCallableType"
test.py:22: error: Argument 1 to "a" has incompatible type "Callable[[int], None]"; expected "MyCallableType"
Found 2 errors in 1 file (checked 1 source file)