A key point is that inherited (and not overriden) methods of a supertype invoked by an instance of the subtype should at most return an instance of the subtype. However, in Python, it is always that instance of the supertype that is returned.
My question is: Suppose the supertype’s inherited and not overridden method returns an Awaitable which eventually ‘resolve’ into an instance of the supertype, when the method is invoked by an instance of the subtype and awaited, what should it return?
I probably don’t understand what you are trying to say.
I read your post analogue this code:
class Base:
def m(self):
return self
class Child(Base):
pass
o1 = Child()
print(type(o1)) # ok: <class '__main__.Child'>
o2 = o1.m()
print(type(o2)) # What do you expect here?
# It is <class '__main__.Child'>...?
# This is the *only* instance and it is the subtype.
Can you give an example which demonstrates your case?
class SuperType:
def inherited_not_overriden_method(self):
return SuperType()
class SubType(SuperType):
...
if __name__ == '__main__':
inst_of_subtype = SubType()
assert type(inst_of_subtype.inherited_not_overriden_method()) is SubType # this should pass but it fails
the result type may be a subtype of that of the supertype. This is called covariance: the return type of the subtype method is a subtype of the return type of
the supertype method.
Hence, I am looking at how I might enable this behaviour without rewriting all the methods of the SuperType.
There are lots of ways to provide the behavior I think you want, but explicitly writing SuperType() is not one of them. OOP isn’t going to magically change the intent of your code.
As the other replies say you need either change the return statement or implement function stubs in a wrapper or in the SubType.
class SuperType:
def method1(self):
# ...
# many lines of code
# ...
return type(self)() # either this change, if possible
def method2(self):
# ...
# many lines of code
# ...
return SuperType()
class SubType(SuperType):
# or this stub for each needed method
def method2(self):
o = super().method2()
r = SubType() # init new instance with data from o
return r
if __name__ == '__main__':
inst_of_subtype = SubType()
assert type(inst_of_subtype.method1()) is SubType
assert type(inst_of_subtype.method2()) is SubType