避免可排序元素列表的类型警告

Avoiding type warning for lists of sortable elements

我有一个数据class X 的元素列表(标记为order=True)并将它们传递给max()。我在 IDE: Expected type 'Iterable' (matched generic type 'Iterable[SupportsLessThanT]'), got 'List[X]' instead 中收到类型检查警告。我怎样才能避免这个错误?我必须声明什么才能使警告消失? (我当然不想打压。)

我想因为 class X 被标记为 order=True 它显然是可排序的,所以将它传递给 max() 应该没有问题。但显然这对类型系统来说是未知的。

@dataclass(frozen=True, order=True)
class X:
    value: int

def f(xs: List[X]) -> None:
    q = max(xs)  # here's the above mentioned type checking warning

我尝试在 class X 中继承各种东西,但没有任何帮助。

是否有解决此问题的假定方法,还是我必须忽略警告?

延迟评估注释 (https://docs.python.org/3/whatsnew/3.7.html#pep-563-postponed-evaluation-of-annotations) 可以提供帮助。

from __future__ import annotations

from typing import Sequence

from dataclasses import dataclass


@dataclass(frozen=True, order=True)
class X:
    value: int


def f(xs: Sequence[X: X]) -> None:
    q = max(xs)  # no warning here anymore

这在 IDE 和从命令行启动时都有效。

代码没有问题。这纯粹是类型检查器的问题,在本例中为 PyCharm/Intellij。其他类型检查器(例如 MyPy)正确理解 dataclass 支持排序。

# so.py
from typing import List
from dataclasses import dataclass


@dataclass(frozen=True, order=True)
class X:
    value: int

def f(xs: List[X]) -> None:
    q = max(xs)
python -m mypy so.py --strict
Success: no issues found in 1 source file

由于内置的​​ PyCharm/Intellij 类型检查器很少是最新的,因此不将其视为权威是值得的。依靠第二个类型检查器并忽略该问题,直到更新内置类型检查器。

如果你想帮助内置类型检查器,你可以手动定义一个Protocol来表达“这个类型是可订购的”。从此 Protocol 继承 dataclass 将其标记为可订购。

from typing import List, Protocol
from dataclasses import dataclass

class Orderable(Protocol):
    def __lt__(self, other) -> bool:
        ...
    def __gt__(self, other) -> bool:
        ...
    # add more comparison methods as desired

@dataclass(frozen=True, order=True)
class X(Orderable):
    value: int

def f(xs: List[X]) -> None:
    q = max(xs)  # fine for PyCharm/Intellij