如何摆脱“不兼容类型”Callable[[NamedArg(int, 'val')], ..'?

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

我正在尝试转发和/或存储

Callable
,同时提供尽可能多的类型提示。目前,我正在努力解决一个看起来很简单的
mypy
错误,但我不知何故无法解决它。想象一下这个小片段包含一组
Callable

from collections.abc import Callable, MutableSequence

functions: MutableSequence[Callable[[int], None]] = []

def foo(val: int) -> None:
    print(val)

functions.append(foo)

虽然有点无意义,但它确实有效,并且

mypy --strict
给了我零问题。

现在我想让

foo
只接受命名参数:

def foo(*, val: int) -> None:

mypy
给了我

./foo.py:11: error: Argument 1 to "append" of "MutableSequence" has incompatible type "Callable[[NamedArg(int, 'val')], None]"; expected "Callable[[int], None]"  [arg-type]

..这听起来似乎有道理,但是有没有办法解决这个问题呢?

NamedArg
无法通过
typing
typing_extensions
导入,只能通过
mypy_extensions
导入,将其作为依赖项感觉很奇怪。 但即使我接受它,它也给了我一堂课,而不是一些
Generic

如何解决这个问题而不丢失命名参数的类型提示?

顺便说一句,在现实生活中的项目中,我正在转发 kw-args,因此允许上面代码片段中的列表仅接受带有一个(通用)参数名称(如

MutableSequence[Callable[[NamedArg(int, 'val')], None]]
)的 kw-arg 就可以了。

python python-3.x mypy python-typing keyword-argument
1个回答
0
投票

如果

Callable[...]
语法不足以定义您的签名,您需要的是回调协议

应用于您的示例,它看起来像这样:

from collections.abc import MutableSequence
from typing import Protocol

class FooCallable(Protocol):

    def __call__(self, *, val: int) -> None:
        ...

functions: MutableSequence[FooCallable] = []

def foo(*, val: int) -> None:
    print(val)

functions.append(foo)
© www.soinside.com 2019 - 2024. All rights reserved.