Reputation: 1541
I have a set of classes, Lets call them Foo
and Bar
, where both inherit from a base class Father
that is defined outside of the current scope (not by me). I have defined a protocol class DummyProtocol
that has a function do_something
.
class DummyProtocol(Protocol):
def do_something(self):
...
class Foo(Father):
def do_something(self):
pass
class Bar(Father):
def do_something(self):
pass
I have a function create_instance
.
def create_dummy_and_father_instance(cls, *args, **kwargs):
return cls(*args, **kwargs)
I want to typehint it in a way, that cls is typehinted to accept a class that is of type Father
that also implements the DummyProtocol
.
So I changed the function to this to indicate that cls is a type that inherit from both Father
and DummyProtocol
def create_dummy_and_father_instance(
cls: Type[tuple[Father, DummyProtocol]], *args, **kwargs
):
return cls(*args, **kwargs)
But I get this error in mypy
:
Cannot instantiate type "Type[Tuple[Father, DummyProtocol]]"
Upvotes: 8
Views: 2726
Reputation: 400
I came across the same issue and found this discussion on proposed Intersection
types which seem to be exactly what is needed (e.g. see this comment).
Unfortunately this feature is not yet supported by the Python typing system, but there's a PEP in the making.
Upvotes: 5
Reputation: 1920
You can define a second Father class which inherits from Father and Protocol (see also mypy: how to verify a type has multiple super classes):
class DummyProtocol(Protocol):
def do_something(self):
...
class Father:
pass
class Father2(Father, DummyProtocol):
pass
class Foo(Father2):
def do_something(self):
pass
class Bar(Father2):
def do_something(self):
pass
class FooNot(Father):
pass
def create_dummy_and_father_instance(
cls: Type[Father2]
):
return cls()
create_dummy_and_father_instance(Foo)
create_dummy_and_father_instance(Bar)
create_dummy_and_father_instance(FooNot) # mypy error ok
Upvotes: 2