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