Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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
like image 866
Martin Thoma Avatar asked Jul 09 '20 07:07

Martin Thoma


People also ask

What does * args and * Kwargs mean?

*args passes variable number of non-keyworded arguments and on which operation of the tuple can be performed. **kwargs passes variable number of keyword arguments dictionary to function on which operation of a dictionary can be performed.

How do you write Kwargs?

Understanding **kwargsThe double asterisk form of **kwargs is used to pass a keyworded, variable-length argument dictionary to a function. Again, the two asterisks ( ** ) are the important element here, as the word kwargs is conventionally used, though not enforced by the language.

What is the type of * args in Python?

*args allows us to pass a variable number of non-keyword arguments to a Python function. In the function, we should use an asterisk ( * ) before the parameter name to pass a variable number of arguments.

How do you type hints in Python?

Here's how you can add type hints to our function: Add a colon and a data type after each function parameter. Add an arrow ( -> ) and a data type after the function to specify the return data type.


1 Answers

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

like image 120
alex_noname Avatar answered Oct 24 '22 02:10

alex_noname