如何使用 mypy 类型检查 next() 与 groupby 结果的用法?

How to type-check usage of next() with groupby result using mypy?

我正在为我的项目中的一些 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.

的类型注释中的问题

作为参考,这是 the type annotation for groupby:

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

所以这意味着,"groupby takes an iterable of type T, and returns an iterator of tuples containing two items: (one item of type T, an iterator of the objects of type T)"。 对我来说看起来不错,但是 mypy 应该能够将 next 的第一个参数推断为 Iterator[Tuple[Any, Iterator[Any]]],对吗?

我错过了什么?

原因是type annotation for nextnext 函数定义为具有以下类型签名:

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

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

但是,g 将具有 Iterator[Tuple[Any, Iterator[Any]]] 类型,而 Tuple[Any, Iterator[Any]]bool 的类型不同。

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