How to implement an interface in a way that is compatible with static type checks?
Support for structural subtyping was added by PEP 544 -- Protocols: Structural subtyping (static duck typing) starting with Python 3.8. For versions prior to 3.8 the corresponding implementation is made available by the typing-extensions package on PyPI.
Relevant for the discussed scenario is typing.Protocol
as explained by the PEP in more detail. This allows to define implicit subtypes which saves us from the metaclass conflict issue since inheritance is not required. So the code looks like this:
from typing import Protocol # Python 3.8+
from typing_extensions import Protocol # Python 3.5 - 3.7
class Fooish(Protocol):
x : int
def foo(self) -> int:
raise NotImplementedError
# No inheritance required, implementing the defined protocol implicitly subtypes 'Fooish'.
class Foo:
def __init__(self, x: int):
self.x = x
def foo(self):
pass
class MyMeta(type):
pass
class Bar(metaclass=MyMeta):
def bar(self):
pass
# Here, we again create an implicit subtype of 'Fooish'.
class FooBar(Bar):
"""Objects of this type are bar and they are foo-ish."""
@property
def x(self) -> int:
return 0
@x.setter
def x(self, val):
pass
def foo(self):
pass
class Worker:
def __init__(self, obj: Fooish):
self.x = obj.x