@@ -828,6 +828,10 @@ class Base:
828828 redeclared_with_narrower_type: str | None
829829 redeclared_with_wider_type: str | None
830830
831+ redeclared_in_method_with_same_type: str | None
832+ redeclared_in_method_with_narrower_type: str | None
833+ redeclared_in_method_with_wider_type: str | None
834+
831835 overwritten_in_subclass_body: str
832836 overwritten_in_subclass_method: str
833837
@@ -873,6 +877,14 @@ class Intermediate(Base):
873877 undeclared = " intermediate"
874878
875879 def set_attributes (self ) -> None :
880+ self .redeclared_in_method_with_same_type: str | None = None
881+
882+ # TODO : This should be an error (violates Liskov)
883+ self .redeclared_in_method_with_narrower_type: str = " foo"
884+
885+ # TODO : This should be an error (violates Liskov)
886+ self .redeclared_in_method_with_wider_type: object = object ()
887+
876888 # TODO : This should be an `invalid-assignment` error
877889 self .overwritten_in_subclass_method = None
878890
@@ -889,18 +901,33 @@ reveal_type(Derived().attribute) # revealed: int | None
889901reveal_type(Derived.redeclared_with_same_type) # revealed: str | None
890902reveal_type(Derived().redeclared_with_same_type) # revealed: str | None
891903
892- # TODO : It would probably be more consistent if these were `str | None`
904+ # We infer the narrower type here, despite the Liskov violation,
905+ # for compatibility with other type checkers (and to reflect the clear user intent)
893906reveal_type(Derived.redeclared_with_narrower_type) # revealed: str
894907reveal_type(Derived().redeclared_with_narrower_type) # revealed: str
895908
896- # TODO : It would probably be more consistent if these were `str | None`
909+ # We infer the wider type here, despite the Liskov violation,
910+ # for compatibility with other type checkers (and to reflect the clear user intent)
897911reveal_type(Derived.redeclared_with_wider_type) # revealed: str | int | None
898912reveal_type(Derived().redeclared_with_wider_type) # revealed: str | int | None
899913
900914# TODO : Both of these should be `str`
901915reveal_type(Derived.overwritten_in_subclass_body) # revealed: Unknown | None
902916reveal_type(Derived().overwritten_in_subclass_body) # revealed: Unknown | None | str
903917
918+ reveal_type(Derived.redeclared_in_method_with_same_type) # revealed: str | None
919+ reveal_type(Derived().redeclared_in_method_with_same_type) # revealed: str | None
920+
921+ # TODO : both of these should be `str`, despite the Liskov violation,
922+ # for compatibility with other type checkers (and to reflect the clear user intent)
923+ reveal_type(Derived.redeclared_in_method_with_narrower_type) # revealed: str | None
924+ reveal_type(Derived().redeclared_in_method_with_narrower_type) # revealed: str | None
925+
926+ # TODO : both of these should be `object`, despite the Liskov violation,
927+ # for compatibility with other type checkers (and to reflect the clear user intent)
928+ reveal_type(Derived.redeclared_in_method_with_wider_type) # revealed: str | None
929+ reveal_type(Derived().redeclared_in_method_with_wider_type) # revealed: object
930+
904931reveal_type(Derived.overwritten_in_subclass_method) # revealed: str
905932reveal_type(Derived().overwritten_in_subclass_method) # revealed: str
906933
0 commit comments