I've got a list of elements of a dataclass X (marked order=True
) and pass them to max()
. I get a type checking warning in my IDE: Expected type 'Iterable' (matched generic type 'Iterable[SupportsLessThanT]'), got 'List[X]' instead
. How can I avoid this error? What do I have to declare to make the warning disappear? (I don't want to suppress it of course.)
I thought because the class X is marked as order=True
it would be obviously sortable, so that passing it to max()
should be no problem. But apparently this isn't known to the type system.
@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
I tried inheriting various things in the class X but nothing helped.
Is there a supposed way to deal with this or do I have to ignore the warning?
The code is fine as is. This is purely an issue of the type checker, in this case PyCharm/Intellij. Other type checkers such as MyPy correctly understand that the dataclass
supports ordering.
# 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
Since the builtin PyCharm/Intellij type checker is rarely up to date, it can be worthwhile not to treat it as authoritative. Rely on a second type checker and ignore the issue until the builtin type checker is updated.
If you want to help the builtin type checker, you can manually define a Protocol
to express "this type is orderable". Inheriting the dataclass
from this Protocol
marks it as orderable.
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