I'm trying to forward and/or store Callables while providing as much type hinting as possible. Currently I'm struggling with a mypy error that seems simple, but I somehow cannot solve it. Imagine this little snippet containing a collection of Callables:
from collections.abc import Callable, MutableSequence
functions: MutableSequence[Callable[[int], None]] = []
def foo(val: int) -> None:
print(val)
functions.append(foo)
While somewhat senseless, it works and mypy --strict gives me zero issues.
Now I want to make foo accept only named parameters:
def foo(*, val: int) -> None:
and mypy gives me
./foo.py:11: error: Argument 1 to "append" of "MutableSequence" has incompatible type "Callable[[NamedArg(int, 'val')], None]"; expected "Callable[[int], None]" [arg-type]
.. which sounds plausible, but is there a way to get around this? NamedArg can't be imported via typing or typing_extensions, but only via mypy_extensions, which feels strange to have it as a dependency.
But even when I accept it, it gives me a class, rather than some Generic.
How can I solve this without losing type hinting for the named arguments?
Btw, in a real-life-project I'm forwarding kw-args, so allowing the list in the snippet above to only accept a kw-arg with one (generic) argument name like MutableSequence[Callable[[NamedArg(int, 'val')], None]] would be fine.
What you need if the
Callable[...]syntax doesn't suffice to define your signature is a Callback Protocol.Applied to your example it'd look like this: