gpt4 book ai didi

mypy - 为什么 mypy 不从@overload 推断函数注解?

转载 作者:行者123 更新时间:2023-12-04 14:15:05 41 4
gpt4 key购买 nike

我使用 disallow-untyped-defs 选项运行 mypy。当我用@overload 注释函数类型并在定义中省略注释时,mypy 仍然会产生错误。对我来说,似乎应该将函数视为带注释的。

例子.py:

from typing import overload
@overload
def f(arg: int) -> int: ...
@overload
def f(arg: str) -> str: ...

def f(arg):
if type(arg) == int:
return 1
elif type(arg) == str:
return "a"
else:
raise ValueError

命令行:

mypy --disallow-untyped-defs example.py

输出:

example.py:7: error: Function is missing a type annotation
Found 1 error in 1 file (checked 1 source file)

最佳答案

这是预期的行为。 Mypy 希望您将类型注释添加到重载的实现中,如下所示:

from typing import overload, Union

@overload
def f(arg: int) -> int: ...
@overload
def f(arg: str) -> str: ...
def f(arg: Union[int, str]) -> Union[int, str]:
if type(arg) == int:
return 1
elif type(arg) == str:
return "a"
else:
raise ValueError

这样,mypy 仍将拥有成功键入检查 f 主体所需的所有信息。

mypy 之所以不根据重载类型签名自动推断实现类型签名或尝试使用重载签名对实现进行两次类型检查,是因为这两个签名通常最终彼此非常不同。

例如,这是一个更复杂的重载示例:

@overload
def zip(/, i1: Iterable[_T1]) -> Iterator[Tuple[_T1]]: ...
@overload
def zip(/, i1: Iterable[_T1], i2: Iterable[_T2]) -> Iterator[Tuple[_T1, _T2]]: ...
@overload
def zip(/, i1: Iterable[_T1], i2: Iterable[_T2],
i3: Iterable[_T3]) -> Iterator[Tuple[_T1, _T2, _T3]]: ...
@overload
def zip(/, i1: Iterable[_T1], i2: Iterable[_T2], i3: Iterable[_T3],
i4: Iterable[_T4]) -> Iterator[Tuple[_T1, _T2, _T3, _T4]]: ...
@overload
def zip(/, i1: Iterable[_T1], i2: Iterable[_T2], i3: Iterable[_T3],
i4: Iterable[_T4], i5: Iterable[_T5]) -> Iterator[Tuple[_T1, _T2, _T3, _T4, _T5]]: ...
@overload
def zip(/, i1: Iterable[Any], i2: Iterable[Any], i3: Iterable[Any],
i4: Iterable[Any], i5: Iterable[Any], i6: Iterable[Any],
*remainder: Iterable[Any]) -> Iterator[Tuple[Any, ...]]: ...
def zip(*iterables: Iterable[Any]) -> Iterator[Tuple[Any, ...]]:
sentinel = object()
iterators = [iter(it) for it in iterables]
while iterators:
result = []
for it in iterators:
elem = next(it, sentinel)
if elem is sentinel:
return
result.append(elem)
yield tuple(result)

对于 mypy 来说,推断这个例子中的实现签名应该是什么将是非常具有挑战性的:参数的数量不匹配,弄清楚如何处理所有的 TypeVars(保留它们?丢弃它们? ) 很棘手...

这些都是 mypy 理论上可以解决的问题,但从长远来看,它是否真的为用户节省了那么多时间还不清楚。在像这样的复杂情况下,用户实际上可能更愿意能够准确说明实现签名是什么。

(如果一个问题 (a) 很难并且 (b) 是一个小问题,它往往无法解决,尤其是在开源项目中。)

因此,为了保持体验的一致性,mypy 不会尝试在每种情况下自动推断实现签名。

关于mypy - 为什么 mypy 不从@overload 推断函数注解?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61026741/

41 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com