缺少泛型类型“Callable”的类型参数

问题描述 投票:0回答:1

向以下函数添加类型提示的正确方法是什么?

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)

现在

mypy
正在向
Missing type parameters for generic type "Callable"

抱怨

代码需要兼容Python 3.9和3.10。如果需要的话我可以使用

typing_extensions

编辑:

以下通过了

mypy
,但有太多
Any
不适合我的口味。有更好的办法吗?

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)
python mypy python-typing python-click
1个回答
2
投票

无需查看

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)

这将防止您在

format_callback
的内部输入错误的内容。


简单扫描一下

click
似乎表明您希望将
format_callback
的返回值传递给以下类构造函数之一或其子类构造函数:

现在,根据您链接到的其他答案,它将关键字参数

callback
传递给
@click.argument
@click.option
,看起来您实际上想使用
click.core.Parameter.__init__
,因为装饰器的后备类分别是
ArgumentClass = click.core.Argument
OptionClass = click.core.Option
,它们是 click.Core.Parameterboth
子类
。这意味着根据
Callable
的类型注释,返回
dict[str, Any]
类型的第二个参数不能是
click.core.Parameter.__init__::callback
。那么,你真的应该用这个来代替:

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

由于您将

click.Context
click.Parameter
丢弃为
_, __
中的
lambda
,当然,前提是这些仅用于文档目的。他们很容易成为
object, object

© www.soinside.com 2019 - 2024. All rights reserved.