mypy: Unsupported left operand type

Question:

If I write generics and use parameters of the generic type, then I get "Unsupported left operand type".

import typing

_ExampleType = typing.TypeVar('_ExampleType')

class Example(typing.Generic[_ExampleType]):

    def __init__(self, a: _ExampleType, b: _ExampleType) -> None:

        self.x: _ExampleType = a if a < b else b
        self.y: _ExampleType = b if a < b else a

mypy output:

generic.py: note: In member "__init__" of class "Example":
generic.py:9: error: Unsupported left operand type for < ("_ExampleType")
generic.py:10: error: Unsupported left operand type for < ("_ExampleType")
Found 2 errors in 1 file (checked 1 source file)

Is there any way to define an "interface" the generic type should provide? Or in other words: How can I say the _ExampleType has to be for example "Hashable" or "Comparable"?

Asked By: Rasc

||

Answers:

You need to define a bound on your TypeVar to specify that it can only be bound to a type that is comparable. Unfortunately there isn’t a built-in Comparable protocol (AFAIK) so you need to define it yourself:

import typing

class Comparable(typing.Protocol):
    def __lt__(self: '_ExampleType', other: '_ExampleType') -> bool: ...

_ExampleType = typing.TypeVar('_ExampleType', bound=Comparable)

class Example(typing.Generic[_ExampleType]):

    def __init__(self, a: _ExampleType, b: _ExampleType) -> None:

        self.x: _ExampleType = a if a < b else b
        self.y: _ExampleType = b if a < b else a
Answered By: Samwise
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.