Search code examples
pythonmypy

mypy: Unsupported left operand type


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"?


Solution

  • 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