summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandru Mărășteanu <alexei@users.noreply.github.com>2023-08-01 20:20:25 (GMT)
committerGitHub <noreply@github.com>2023-08-01 20:20:25 (GMT)
commitc8872f4285d3b61c252e3384bec6d30618b7d698 (patch)
tree5342a9e6e508a286303ddf949cb7352d241e7361
parent030f6b1e84274616c22666f27c5695867ab85833 (diff)
downloadcpython-c8872f4285d3b61c252e3384bec6d30618b7d698.zip
cpython-c8872f4285d3b61c252e3384bec6d30618b7d698.tar.gz
cpython-c8872f4285d3b61c252e3384bec6d30618b7d698.tar.bz2
Clarify `Self` interaction with subclasses (#107511)
-rw-r--r--Doc/library/typing.rst31
1 files changed, 21 insertions, 10 deletions
diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst
index f96a805..fad945f 100644
--- a/Doc/library/typing.rst
+++ b/Doc/library/typing.rst
@@ -963,13 +963,17 @@ using ``[]``.
For example::
- from typing import Self
+ from typing import Self, reveal_type
class Foo:
def return_self(self) -> Self:
...
return self
+ class SubclassOfFoo(Foo): pass
+
+ reveal_type(Foo().return_self()) # Revealed type is "Foo"
+ reveal_type(SubclassOfFoo().return_self()) # Revealed type is "SubclassOfFoo"
This annotation is semantically equivalent to the following,
albeit in a more succinct fashion::
@@ -983,15 +987,11 @@ using ``[]``.
...
return self
- In general if something currently follows the pattern of::
-
- class Foo:
- def return_self(self) -> "Foo":
- ...
- return self
-
- You should use :data:`Self` as calls to ``SubclassOfFoo.return_self`` would have
- ``Foo`` as the return type and not ``SubclassOfFoo``.
+ In general, if something returns ``self``, as in the above examples, you
+ should use ``Self`` as the return annotation. If ``Foo.return_self`` was
+ annotated as returning ``"Foo"``, then the type checker would infer the
+ object returned from ``SubclassOfFoo.return_self`` as being of type ``Foo``
+ rather than ``SubclassOfFoo``.
Other common use cases include:
@@ -999,6 +999,17 @@ using ``[]``.
of the ``cls`` parameter.
- Annotating an :meth:`~object.__enter__` method which returns self.
+ You should not use ``Self`` as the return annotation if the method is not
+ guaranteed to return an instance of a subclass when the class is
+ subclassed::
+
+ class Eggs:
+ # Self would be an incorrect return annotation here,
+ # as the object returned is always an instance of Eggs,
+ # even in subclasses
+ def returns_eggs(self) -> "Eggs":
+ return Eggs()
+
See :pep:`673` for more details.
.. versionadded:: 3.11