0

我正在为我的项目中的一些 utils 函数尝试 mypy,但是我在使用这个结合了 groupby 和 next 的函数时遇到了问题。

这是功能代码:

from itertools import groupby
from typing import Iterable, Any


def all_same(iterable: Iterable[Any]) -> bool:
    """Return True if all elements in iterable are equal
    >>> all_same([3, 3, 3])
    True
    >>> all_same([3, 3, 1])
    False
    >>> all_same([])
    True
    >>> all_same(['a', 'a'])
    True
    """
    g = groupby(iterable)
    return bool(next(g, True)) and not bool(next(g, False))

我不断收到这个错误,因为它无法推断type argument 1 of "next"

$ mypy testing.py 
testing.py: note: In function "all_same":
testing.py:17: error: Cannot infer type argument 1 of "next"

我想这意味着它无法推断g这里的类型,对吧?

我很难理解这是否是我的类型注释或groupby.

作为参考,这是类型注释groupby

@overload
def groupby(iterable: Iterable[_T]) -> Iterator[Tuple[_T, Iterator[_T]]]: ...

所以这意味着,“groupby 接受一个 T 类型的迭代器,并返回一个包含两项的元组迭代器:(一个 T 类型的项,一个 T 类型的对象的迭代器)”。对我来说看起来不错,但是 mypy 应该能够推断出nextas的第一个参数Iterator[Tuple[Any, Iterator[Any]]],对吧?

我错过了什么?

4

1 回答 1

1

原因next是由于. 该next函数被定义为具有以下类型签名:

@overload
def next(i: Iterator[_T]) -> _T: ...
@overload
def next(i: Iterator[_T], default: _T) -> _T: ...

基本上,mypy 期望默认值的类型与迭代器中任何内容的内容相同。

但是,g将具有 type Iterator[Tuple[Any, Iterator[Any]]],并且Tuple[Any, Iterator[Any]]bool.

不幸的是,我不确定修复你的算法以进行类型检查的最佳方法是什么,因为给定的类型签名对next我来说似乎很合理 + 似乎不太可能改变(尽管你可以提出问题,如果你想支持这种改变?)。也许这里的答案可能有用?

于 2016-06-29T05:29:26.397 回答