我有以下设置:
@pytest.fixture
def check_answer() -> t.Callable[[dict[str, t.Any], dict[str, t.Any], int], None]:
def _check(
first_response: dict[str, t.Any],
second_response: dict[str, t.Any],
named_optional_arg: int = 1,
) -> None:
*assert stuff*
return _check
然后我将
check_answer
作为参数传递给 test_my_answer
,我想将其称为 check_answer(ans1, ans2, named_optional_arg=5)
。可选参数很少使用,因此在调用该名称时存在该名称很重要,但是,当我包含该名称时,由于意外的关键字参数,我从 mypy 中收到错误。
问题在于您的类型签名不够具体,无法捕获
_check
具有 named_optional_arg
的事实。 Callable
不足以输入关键字参数,这就是必须使用回调协议的地方:
from collections.abc import Mapping
from typing import Protocol, Any
class Checker(Protocol):
def __call__(
self,
first_response: Mapping[str, Any],
second_response: Mapping[str, Any],
/,
*,
named_optional_arg: int = ...
):
...
您可以阅读*(单星)和/(斜杠)作为独立参数做什么?,了解如何在参数列表中使用
/
和 *
来描述函数的确切方式的更多信息允许被调用。在这种情况下,我已经做到了,前两个参数必须由位置指定,第三个可选参数必须由名称指定。
dict
替换为 Mapping
。这是因为检查/断言只需要读取响应,而不需要写入响应。
然后您可以将声明更改为:
@pytest.fixture
def check_answer() -> Checker:
...