简体   繁体   English

通用类型“Callable”缺少类型参数

[英]Missing type parameters for generic type "Callable"

What is the correct way to add type hints to the following function?向以下 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"现在mypy抱怨Missing type parameters for generic type "Callable"

The code needs to be compatible with both Python 3.9 and 3.10.该代码需要与 Python 3.9 和 3.10 兼容。 I can use typing_extensions if needed.如果需要,我可以使用typing_extensions

Edit:编辑:

The following passes mypy but has too many Any 's for my taste.以下通过mypy ,但Any太多了,不符合我的口味。 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) :无需查看click ,您可以立即解决的问题是提供与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 .这将防止您在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:简单浏览click似乎表明您想将 format_callback 的返回值传递给以下format_callback构造函数之一或其子类构造函数:

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 .现在,根据您链接到的另一个答案,它将关键字参数callback@click.argument@click.option ,看起来您实际上想要使用click.core.Parameter.__init__ ,因为装饰器' 后备类分别是ArgumentClass = click.core.ArgumentOptionClass = click.core.Option ,它们都是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 .这意味着根据click.core.Parameter.__init__::callback的类型注释,返回Callable类型的第二个参数不能是dict[str, Any] 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.由于您在click.Contextclick.Parameter丢弃为_, __ ,当然, lambda是这些仅用于文档目的。 They could easily be object, object instead.它们很容易变成object, object

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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