How do I annotate a callable with *args and **kwargs?

南笙酒味 提交于 2021-01-19 06:22:52

问题


I have a function which returns a function. I would like to find a proper type annotation. However, the returned function has *args and *kwargs. How is that annotated within Callable[[Parameters???], ReturnType]?

Example:

from typing import Callable
import io
import pandas as pd

def get_conversion_function(file_type: str) -> Callable[[io.BytesIO, TODO], pd.DataFrame]:
    def to_csv(bytes_, *args, **kwargs):
        return pd.read_csv(bytes_, **kwargs)
    if file_type == "csv":
        return to_csv

回答1:


As I know, python's typing` does not allow do that straightforwardly as stated in the docs of typing.Callable:

There is no syntax to indicate optional or keyword arguments; such function types are rarely used as callback types. Callable[..., ReturnType] (literal ellipsis) can be used to type hint a callable taking any number of arguments and returning ReturnType.

But you could use mypy extensions like this:

from typing import Callable
from mypy_extensions import Arg, VarArg, KwArg

def foo(a: str, *args: int, **kwargs: float) -> str:
    return 'Hello, {}'.format(a)
    
def bar() -> Callable[[Arg(str, 'a'), VarArg(int), KwArg(float)], str]:
    return foo




回答2:


With the introduction of typing.Protocol, MyPy (and other compliant type checkers) support the full call syntax natively via the __call__ special method.

MyPy: Callback Protocols

Protocols can be used to define flexible callback types that are hard (or even impossible) to express using the Callable[...] syntax, such as variadic, overloaded, and complex generic callbacks. (...)

Simply define a Protocol whose __call__ method has the desired signature.

from typing import Protocol

class SomeCallable(Protocol):
      def __call__(self, a: str, b: int, *args: float, kwargs: str) -> bytes: ...

def my_callable(a: str, b: int, *args: float, kwargs: str) -> bytes:
    return b"Hello World"

def my_func(key: str) -> SomeCallable:
    return my_callable


来源:https://stackoverflow.com/questions/62809562/how-do-i-annotate-a-callable-with-args-and-kwargs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!