Self
type for a method parameter is an automatic LSP violation
#1761
Replies: 3 comments 12 replies
-
I'm not convinced this is a problem. If it is a problem, it's definitely not unique to
class Animal:
def hug[S: Animal](self: S, friend: S) -> None: ... Note that my code sample doesn't involve |
Beta Was this translation helpful? Give feedback.
-
Banning For example, consider a method that returns a list. You can then append to that list. It acts as a parameter even though it is a return value. from typing import Self
class Animal:
def __init__(self) -> None:
self.relatives: list[Self] = [self]
def get_relatives(self) -> list[Self]:
return self.relatives
class Cat(Animal):
def meow(self) -> None:
...
class Duck(Animal): ...
cat = Cat()
a: Animal = cat
a.get_relatives().append(Duck())
print(a.relatives) # cat and duck
for relative in cat.relatives:
relative.meow() # AttributeError: 'Duck' object has no attribute 'meow' From a practical point of view, I think this doesn't matter much. It is fine to return a |
Beta Was this translation helpful? Give feedback.
-
I remember discussing this issue with Pradeep during the drafting stage of PEP 647. Having the If implementation complexity is not a concern, then I think it can indeed be argued that the suggested behavior of |
Beta Was this translation helpful? Give feedback.
-
Example code:
Essentially, the
Animal.hug
method has this property: "you can call it with anyAnimal
". But as soon as you subclassAnimal
, that property is automatically violated, because only instances of that subclass are now allowed in this method. For example, ifCat.hug
assumed that thefriend
is also a Cat, it might fail at runtime whenfriend
isDuck
.Using a
TypeVar
(which Self is essentially syntax sugar for) would lead to similar issues.Maybe
Self
should not be allowed as a parameter type in methods?Beta Was this translation helpful? Give feedback.
All reactions