Suppose I have a protocol Foo.
from typing import Protocol, Optional
class Foo(Protocol):
val: Optional[int]
And a function like the following:
def func(obj: Foo) -> None:
if obj.val is not None:
print(obj.val)
I would expect that either ImplA and ImplB (shown below) should be an acceptable argument for func, since val: int is a more specific than val: Optional[int].
class ImplA:
val: int
class ImplB:
val: Optional[int]
a = ImplA()
b = ImplB()
func(a) # It works
func(b) # Argument 1 to "func" has incompatible type "ImplB"; expected "Foo"
As it doesn't work, I have to define Bar and take the union of both classes. However, is there a way to construct a protocol such that both val: Optional[int] and val: int will be accepted without Union?
class Bar(Protocol):
val: int
def func(obj: Union[Foo, Bar]): ...
EDIT:
To achieve this, we need to make sure that the type of val is covariant. As far as I see now, it looks like that Protocol defines it to be an invariant. Is it thus impossible to achieve my requirements?