*Introducing* :data:`TypeAlias`
* :pep:`647`: User-Defined Type Guards
*Introducing* :data:`TypeGuard`
+* :pep:`673`: Self type
+ *Introducing* :data:`Self`
.. _type-aliases:
.. versionadded:: 3.5.4
.. versionadded:: 3.6.2
+.. data:: Self
+
+ Special type to represent the current enclosed class.
+ For example::
+
+ from typing import Self
+
+ class Foo:
+ def returns_self(self) -> Self:
+ ...
+ return self
+
+
+ This annotation is semantically equivalent to the following,
+ albeit in a more succinct fashion::
+
+ from typing import TypeVar
+
+ Self = TypeVar("Self", bound="Foo")
+
+ class Foo:
+ def returns_self(self: Self) -> Self:
+ ...
+ return self
+
+ In general if something currently follows the pattern of::
+
+ class Foo:
+ def return_self(self) -> "Foo":
+ ...
+ return self
+
+ You should use use :data:`Self` as calls to ``SubclassOfFoo.returns_self`` would have
+ ``Foo`` as the return type and not ``SubclassOfFoo``.
+
+ Other common use cases include:
+
+ - :class:`classmethod`\s that are used as alternative constructors and return instances
+ of the ``cls`` parameter.
+ - Annotating an :meth:`object.__enter__` method which returns self.
+
+ For more information, see :pep:`673`.
+
+ .. versionadded:: 3.11
+
.. data:: TypeAlias
Special annotation for explicitly declaring a :ref:`type alias <type-aliases>`.
PEP-654: Exception Groups and ``except*``.
(Contributed by Irit Katriel in :issue:`45292`.)
+PEP-673: ``Self`` Type.
+(Contributed by James Hilton-Balfe and Pradeep Kumar in :issue:`30924`.)
New Features
============
from typing import IO, TextIO, BinaryIO
from typing import Pattern, Match
from typing import Annotated, ForwardRef
+from typing import Self
from typing import TypeAlias
from typing import ParamSpec, Concatenate, ParamSpecArgs, ParamSpecKwargs
from typing import TypeGuard
type(NoReturn)()
-class TypeVarTests(BaseTestCase):
+class SelfTests(BaseTestCase):
+ def test_basics(self):
+ class Foo:
+ def bar(self) -> Self: ...
+
+ self.assertEqual(gth(Foo.bar), {'return': Self})
+
+ def test_repr(self):
+ self.assertEqual(repr(Self), 'typing.Self')
+
+ def test_cannot_subscript(self):
+ with self.assertRaises(TypeError):
+ Self[int]
+
+ def test_cannot_subclass(self):
+ with self.assertRaises(TypeError):
+ class C(type(Self)):
+ pass
+
+ def test_cannot_init(self):
+ with self.assertRaises(TypeError):
+ Self()
+ with self.assertRaises(TypeError):
+ type(Self)()
+
+ def test_no_isinstance(self):
+ with self.assertRaises(TypeError):
+ isinstance(1, Self)
+ with self.assertRaises(TypeError):
+ issubclass(int, Self)
+ def test_alias(self):
+ # TypeAliases are not actually part of the spec
+ alias_1 = Tuple[Self, Self]
+ alias_2 = List[Self]
+ alias_3 = ClassVar[Self]
+ self.assertEqual(get_args(alias_1), (Self, Self))
+ self.assertEqual(get_args(alias_2), (Self,))
+ self.assertEqual(get_args(alias_3), (Self,))
+
+
+class TypeVarTests(BaseTestCase):
def test_basic_plain(self):
T = TypeVar('T')
# T equals itself.
'ParamSpecKwargs',
'reveal_type',
'runtime_checkable',
+ 'Self',
'Text',
'TYPE_CHECKING',
'TypeAlias',
if (isinstance(arg, _GenericAlias) and
arg.__origin__ in invalid_generic_forms):
raise TypeError(f"{arg} is not valid as type argument")
- if arg in (Any, NoReturn, ClassVar, Final, TypeAlias):
+ if arg in (Any, NoReturn, Self, ClassVar, Final, TypeAlias):
return arg
if isinstance(arg, _SpecialForm) or arg in (Generic, Protocol):
raise TypeError(f"Plain {arg} is not valid as type argument")
"""
raise TypeError(f"{self} is not subscriptable")
+
+@_SpecialForm
+def Self(self, parameters):
+ """Used to spell the type of "self" in classes.
+
+ Example::
+
+ from typing import Self
+
+ class Foo:
+ def returns_self(self) -> Self:
+ ...
+ return self
+
+ This is especially useful for:
+ - classmethods that are used as alternative constructors
+ - annotating an `__enter__` method which returns self
+ """
+ raise TypeError(f"{self} is not subscriptable")
+
+
@_SpecialForm
def ClassVar(self, parameters):
"""Special type construct to mark class variables.
--- /dev/null
+Implement :pep:`673` :class:`typing.Self`.
+Patch by James Hilton-Balfe.