Is there a way to do the following?
def myfunction() -> any_subclass_of[MyClass]:
...
Because the following says there's incompatible types in assignment:
def myfunction() -> MyClass:
...
var: MySubClass = myfunction()
Type[MyClass] also doesn't seem to work.
Assuming that
def myfunction() -> any_subclass_of[MyClass]:
...
means that myfunction
could return a value whose type is any possible subclass of MyClass
(including MyClass
itself), then the type hint is simply
def myfunction() -> MyClass:
...
Classes are covariant, so any instance of MySubClass
is also an instance of MyClass
.
The problem with
var: MySubClass = myfunction()
is that you are requiring that myfunction
return a value that is not just an instance of MyClass
, but also of MySubClass
, and myfunction
makes no such promise. For example,
def myfunction() -> MyClass:
return MyClass()
or
class OtherClass(MyClass):
pass
def myfunction() -> MyClass:
return OtherClass()
A static type checker will not look inside a function hinted as returning MyClass
to see which subclass it "actually" returns; the promise is that an instance of MyClass
will be, no more and no less. As a result, you simply cannot assign the value of myfunction()
to a variable annotated with MySubClass
, because the type checker cannot guarantee that is safe.
Type
is use to indicate that you will return an actual type, not a value of a type. For example,
def myfunction() -> Type[MyClass]
return MySubClass
var : Type[MyClass] = myfunction()
is fine, because you asked that var
be either MyClass
or one of its subclasses, and that's what myfunction
returns.
var : Type[MySubClass] = myfunction()
fails for the same reasons as above: no promise was made that the return value of myfunction
would not only be MyClass
or a subclass, but also MySubClass
or a subclass.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With