为什么我得到 mypy no overload variant of "zip" matches argument 错误?
Why do I get mypy no overload variant of "zip" matches argument error?
我有一个 class 方法:
class TimeUtilitiesTestCase():
def test_date_and_delta(self) -> None:
"""Tests date_and_delta utility method."""
now = datetime.datetime.now()
tdelta = datetime.timedelta
int_tests = (3, 29, 86399, 86400, 86401 * 30)
date_tests = [now - tdelta(seconds=x) for x in int_tests]
td_tests = [tdelta(seconds=x) for x in int_tests]
results = [(now - tdelta(seconds=x), tdelta(seconds=x)) for x in int_tests]
for test in (int_tests, date_tests, td_tests):
for arg, result in zip(test, results):
dtime, delta = humanizer_portugues.time.date_and_delta(arg)
self.assertEqualDatetime(dtime, result[0])
self.assertEqualTimedelta(delta, result[1])
self.assertEqual(humanizer_portugues.time.date_and_delta("NaN"), (None, "NaN"))
我是 运行 严格的 mypy 检查(配置 here),我收到错误:
error: No overload variant of "zip" matches argument
types "object", "List[Tuple[datetime, timedelta]]" [call-overload]
for arg, result in zip(test, results):
^
note: Possible overload variants:
note: def [_T1, _T2] zip(*iterables: Tuple[_T1, _T2]) -> Tuple[Tuple[_T
1, ...], Tuple[_T2, ...]]
note: def [_T1, _T2, _T3] zip(*iterables: Tuple[_T1, _T2, _T3]) -> Tupl
e[Tuple[_T1, ...], Tuple[_T2, ...], Tuple[_T3, ...]]
note: <3 more similar overloads not shown, out of 10 total overloads>
如果您想完全重现错误,您可以使用以下命令克隆分支 strict-mypy
:
git clone -b strict-mypy https://github.com/staticdev/humanizer-portugues.git
我尝试将 results
从列表更改为元组,但此错误并没有消失。
我怎么打错了?
编者注:
可以使用以下最小示例重现此问题:
def bug_repr() -> None:
ints = [1, 2]
floats = [3.14, 2.72]
strings = ['a', 'b']
for numeric_list in [ints, floats]:
for number, string in zip(numeric_list, strings): # <-- error here
pass
这给出了同样的错误:
main.py:6: error: No overload variant of "zip" matches argument types "object", "List[str]"
main.py:6: note: Possible overload variants:
main.py:6: note: def [_T1, _T2] zip(*iterables: Tuple[_T1, _T2]) -> Tuple[Tuple[_T1, ...], Tuple[_T2, ...]]
main.py:6: note: def [_T1, _T2, _T3] zip(*iterables: Tuple[_T1, _T2, _T3]) -> Tuple[Tuple[_T1, ...], Tuple[_T2, ...], Tuple[_T3, ...]]
main.py:6: note: <3 more similar overloads not shown, out of 10 total overloads>
Found 1 error in 1 file (checked 1 source file)
您可以在 mypy Playground 上复制此内容。
使用您的最小示例:
问题是,MyPy 推断的类型太窄,即 List[int]
和 List[float]
,因此它无法为 [=15= 推断类型 List of something
].一般来说,当你放入不同的东西时,容器和静态类型安全性存在问题。例如,您输入了一个浮点数和一个整数,那么静态分析如何知道您要取出什么?参见 Docs on Variance
但是您可以声明一个更通用的类型,使用 Union types,声明它可能包含多个类型。
from typing import Union, List
def bug_repr() -> None:
ints: List[Union[int, float]] = [1, 2]
floats: List[Union[int, float]] = [3.14, 2.72]
strings = ['a', 'b']
for numeric_list in [ints, floats]:
for number, string in zip(numeric_list, strings):
pass
或者,您可以将其声明为列表(或序列)而不指定其中的内容:
from typing import List
def bug_repr() -> None:
ints: List = [1, 2]
floats: List = [3.14, 2.72]
strings = ['a', 'b']
for numeric_list in [ints, floats]:
for number, string in zip(numeric_list, strings):
pass
但我不确定在内部循环中为 number
推断出什么类型。
(注意,您也可以使用 Sequence
作为更通用的类型,而不是 List
)
我有一个 class 方法:
class TimeUtilitiesTestCase():
def test_date_and_delta(self) -> None:
"""Tests date_and_delta utility method."""
now = datetime.datetime.now()
tdelta = datetime.timedelta
int_tests = (3, 29, 86399, 86400, 86401 * 30)
date_tests = [now - tdelta(seconds=x) for x in int_tests]
td_tests = [tdelta(seconds=x) for x in int_tests]
results = [(now - tdelta(seconds=x), tdelta(seconds=x)) for x in int_tests]
for test in (int_tests, date_tests, td_tests):
for arg, result in zip(test, results):
dtime, delta = humanizer_portugues.time.date_and_delta(arg)
self.assertEqualDatetime(dtime, result[0])
self.assertEqualTimedelta(delta, result[1])
self.assertEqual(humanizer_portugues.time.date_and_delta("NaN"), (None, "NaN"))
我是 运行 严格的 mypy 检查(配置 here),我收到错误:
error: No overload variant of "zip" matches argument
types "object", "List[Tuple[datetime, timedelta]]" [call-overload]
for arg, result in zip(test, results):
^
note: Possible overload variants:
note: def [_T1, _T2] zip(*iterables: Tuple[_T1, _T2]) -> Tuple[Tuple[_T
1, ...], Tuple[_T2, ...]]
note: def [_T1, _T2, _T3] zip(*iterables: Tuple[_T1, _T2, _T3]) -> Tupl
e[Tuple[_T1, ...], Tuple[_T2, ...], Tuple[_T3, ...]]
note: <3 more similar overloads not shown, out of 10 total overloads>
如果您想完全重现错误,您可以使用以下命令克隆分支 strict-mypy
:
git clone -b strict-mypy https://github.com/staticdev/humanizer-portugues.git
我尝试将 results
从列表更改为元组,但此错误并没有消失。
我怎么打错了?
编者注:
可以使用以下最小示例重现此问题:
def bug_repr() -> None:
ints = [1, 2]
floats = [3.14, 2.72]
strings = ['a', 'b']
for numeric_list in [ints, floats]:
for number, string in zip(numeric_list, strings): # <-- error here
pass
这给出了同样的错误:
main.py:6: error: No overload variant of "zip" matches argument types "object", "List[str]"
main.py:6: note: Possible overload variants:
main.py:6: note: def [_T1, _T2] zip(*iterables: Tuple[_T1, _T2]) -> Tuple[Tuple[_T1, ...], Tuple[_T2, ...]]
main.py:6: note: def [_T1, _T2, _T3] zip(*iterables: Tuple[_T1, _T2, _T3]) -> Tuple[Tuple[_T1, ...], Tuple[_T2, ...], Tuple[_T3, ...]]
main.py:6: note: <3 more similar overloads not shown, out of 10 total overloads>
Found 1 error in 1 file (checked 1 source file)
您可以在 mypy Playground 上复制此内容。
使用您的最小示例:
问题是,MyPy 推断的类型太窄,即 List[int]
和 List[float]
,因此它无法为 [=15= 推断类型 List of something
].一般来说,当你放入不同的东西时,容器和静态类型安全性存在问题。例如,您输入了一个浮点数和一个整数,那么静态分析如何知道您要取出什么?参见 Docs on Variance
但是您可以声明一个更通用的类型,使用 Union types,声明它可能包含多个类型。
from typing import Union, List
def bug_repr() -> None:
ints: List[Union[int, float]] = [1, 2]
floats: List[Union[int, float]] = [3.14, 2.72]
strings = ['a', 'b']
for numeric_list in [ints, floats]:
for number, string in zip(numeric_list, strings):
pass
或者,您可以将其声明为列表(或序列)而不指定其中的内容:
from typing import List
def bug_repr() -> None:
ints: List = [1, 2]
floats: List = [3.14, 2.72]
strings = ['a', 'b']
for numeric_list in [ints, floats]:
for number, string in zip(numeric_list, strings):
pass
但我不确定在内部循环中为 number
推断出什么类型。
(注意,您也可以使用 Sequence
作为更通用的类型,而不是 List
)