简体   繁体   中英

Missing type parameters for generic type "Callable"

What is the correct way to add type hints to the following function?

from typing import Callable

def format_callback(f: Callable) -> Callable:
    """Function to wrap a function to use as a click callback.

    Taken from https://stackoverflow.com/a/42110044/8056572
    """
    return lambda _, __, x: f(x)

Now mypy is complaining with Missing type parameters for generic type "Callable"

The code needs to be compatible with both Python 3.9 and 3.10. I can use typing_extensions if needed.

Edit:

The following passes mypy but has too many Any 's for my taste. Is there a better way?

from typing import Any
from typing import Callable

import click


def format_callback(f: Callable[[Any], Any]) -> Callable[[click.Context, dict[str, Any], Any], Any]:
    """Function to wrap a function to use as a click callback.

    Taken from https://stackoverflow.com/a/42110044/8056572
    """
    return lambda _, __, x: f(x)

Without looking at click , the immediate fix you can do is to provide type variables that match f(x) :

from typing import Any, Callable, TypeVar

import click

ArgT = TypeVar("ArgT")
ReturnT = TypeVar("ReturnT")

def format_callback(
    f: Callable[[ArgT], ReturnT]
) -> Callable[[click.Context, dict[str, Any], ArgT], ReturnT]:
    return lambda _, __, x: f(x)

This will guard you against bad typing in the internal body of format_callback .


A brief scan of click seems to indicate that you want to pass the return value of format_callback to one of the following class constructors or their subclass constructors:

Now, based on the other answer that you linked to, which passes the keyword argument callback to @click.argument and @click.option , it seems like you'd actually want to use click.core.Parameter.__init__ , because the decorators' fallback classes are ArgumentClass = click.core.Argument and OptionClass = click.core.Option , respectively, which are both subclasses of click.Core.Parameter . This means that the second argument to the return Callable type cannot be dict[str, Any] , according to the type annotation for click.core.Parameter.__init__::callback . Then, you really should have this instead:

def format_callback(
    f: Callable[[ArgT], ReturnT]
) -> Callable[[click.Context, click.Parameter, ArgT], ReturnT]:
    return lambda _, __, x: f(x)

Since you're discarding click.Context and click.Parameter as _, __ in your lambda , providing these are only for documentation purposes, of course. They could easily be object, object instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM