'Using type hints to denote subclass of multiple classes, i.e. `typing.Intersection`?

I am looking for but unable to find a concise way to denote the type hint obj: "subclass of A and B". The type hint obj: typing.Union[A, B] does not cover this case as it will accept an instance of A or B or any of their subclasses.

I am writing a protocol that can be implemented by classes. This interface has an __eq__ method that can compare multiple instances of the same class implementing this protocol. By implementing this protocol, the classes get a default implementation of the __eq__ method.

import typing

@typing.runtime_checkable
class MyInterface(typing.Protocol):

    def __eq__(o1, o2) -> bool:
        ''' checks if `o1` and `o2` are equal to one another '''
        from random import randint
        return bool(randint(0,1)) # TODO: write a better implementation

    ...

I want to add type hints to denote that 1. both objects to __eq__ must be instances of the same class and 2. must implement MyProtocol.

Here are the things I have considered:

  • One could define a typevar like so: T = typing.TypeVar('T') and use that in the signature:
def __eq__(o1: T, o2: T) -> bool:

However, this does not enforce implementing MyProtocol.

  • I could instead be explicit about the protocol:
def __eq__(o1: 'MyProtocol', o2: 'MyProtocol') -> bool:

However, this does not prevent the static types from being two different class hierarchies without a shared structure that both implement a protocol (e.g., BankAccount implements HasOpen and Door implements HasOpen).

What's a good way to achieve this?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source