bpo-41923: PEP 613: Add TypeAlias to typing module (#22532)

This special marker annotation is intended to help in distinguishing
proper PEP 484-compliant type aliases from regular top-level variable
assignments.
This commit is contained in:
Mikhail Golubev 2020-10-08 00:44:31 +03:00 committed by GitHub
parent f90dc36c15
commit 4f3c25043d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 94 additions and 2 deletions

View file

@ -34,6 +34,8 @@ In the function ``greeting``, the argument ``name`` is expected to be of type
:class:`str` and the return type :class:`str`. Subtypes are accepted as
arguments.
.. _type-aliases:
Type aliases
============
@ -489,6 +491,17 @@ These can be used as types in annotations and do not support ``[]``.
.. versionadded:: 3.5.4
.. versionadded:: 3.6.2
.. data:: TypeAlias
Special annotation for explicitly declaring a :ref:`type alias <type-aliases>`.
For example::
from typing import TypeAlias
Factors: TypeAlias = list[int]
.. versionadded:: 3.10
Special forms
"""""""""""""

View file

@ -99,8 +99,29 @@ in :issue:`38605`.)
* :pep:`618`: The :func:`zip` function now has an optional ``strict`` flag, used
to require that all the iterables have an equal length.
PEP604: New Type Operator
-------------------------
PEP 613: TypeAlias Annotation
-----------------------------
:pep:`484` introduced the concept of type aliases, only requiring them to be
top-level unannotated assignments. This simplicity sometimes made it difficult
for type checkers to distinguish between type aliases and ordinary assignments,
especially when forward references or invalid types were involved. Compare::
StrCache = 'Cache[str]' # a type alias
LOG_PREFIX = 'LOG[DEBUG]' # a module constant
Now the :mod:`typing` module has a special annotation :data:`TypeAlias` to
declare type aliases more explicitly::
StrCache: TypeAlias = 'Cache[str]' # a type alias
LOG_PREFIX = 'LOG[DEBUG]' # a module constant
See :pep:`613` for more details.
(Contributed by Mikhail Golubev in :issue:`41923`.)
PEP604: New Type Union Operator
-------------------------------
A new type union operator was introduced which enables the syntax ``X | Y``.
This provides a cleaner way of expressing 'either type X or type Y' instead of

View file

@ -24,6 +24,7 @@
from typing import IO, TextIO, BinaryIO
from typing import Pattern, Match
from typing import Annotated, ForwardRef
from typing import TypeAlias
import abc
import typing
import weakref
@ -4176,6 +4177,45 @@ def test_annotated_in_other_types(self):
self.assertEqual(X[int], List[Annotated[int, 5]])
class TypeAliasTests(BaseTestCase):
def test_canonical_usage_with_variable_annotation(self):
Alias: TypeAlias = Employee
def test_canonical_usage_with_type_comment(self):
Alias = Employee # type: TypeAlias
def test_cannot_instantiate(self):
with self.assertRaises(TypeError):
TypeAlias()
def test_no_isinstance(self):
with self.assertRaises(TypeError):
isinstance(42, TypeAlias)
def test_no_issubclass(self):
with self.assertRaises(TypeError):
issubclass(Employee, TypeAlias)
with self.assertRaises(TypeError):
issubclass(TypeAlias, Employee)
def test_cannot_subclass(self):
with self.assertRaises(TypeError):
class C(TypeAlias):
pass
with self.assertRaises(TypeError):
class C(type(TypeAlias)):
pass
def test_repr(self):
self.assertEqual(repr(TypeAlias), 'typing.TypeAlias')
def test_cannot_subscript(self):
with self.assertRaises(TypeError):
TypeAlias[int]
class AllTests(BaseTestCase):
"""Tests for __all__."""

View file

@ -113,6 +113,7 @@
'runtime_checkable',
'Text',
'TYPE_CHECKING',
'TypeAlias',
]
# The pseudo-submodules 're' and 'io' are part of the public
@ -460,6 +461,21 @@ def open_helper(file: str, mode: MODE) -> str:
return _GenericAlias(self, parameters)
@_SpecialForm
def TypeAlias(self, parameters):
"""Special marker indicating that an assignment should
be recognized as a proper type alias definition by type
checkers.
For example::
Predicate: TypeAlias = Callable[..., bool]
It's invalid when used anywhere except as in the example above.
"""
raise TypeError(f"{self} is not subscriptable")
class ForwardRef(_Final, _root=True):
"""Internal wrapper to hold a forward reference."""

View file

@ -611,6 +611,7 @@ Christoph Gohlke
Tim Golden
Yonatan Goldschmidt
Mark Gollahon
Mikhail Golubev
Guilherme Gonçalves
Tiago Gonçalves
Chris Gonnerman

View file

@ -0,0 +1 @@
Implement :pep:`613`, introducing :data:`typing.TypeAlias` annotation.