From f2c9f8e7093468a0882dc31dda5e62ea7b2461cb Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Mon, 20 Dec 2021 17:54:54 +0300 Subject: [PATCH 1/4] Documents explicit type aliases Refs https://www.python.org/dev/peps/pep-0613/ --- docs/source/kinds_of_types.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/source/kinds_of_types.rst b/docs/source/kinds_of_types.rst index 7cdedf6718670..6fd8a798988f7 100644 --- a/docs/source/kinds_of_types.rst +++ b/docs/source/kinds_of_types.rst @@ -522,6 +522,21 @@ assigning the type to a variable: another type -- it's equivalent to the target type except for :ref:`generic aliases `. +Since Mypy 0.920 you can also use explicit type aliases which are defined by :pep:`613`. + +Implicit type alias declaration rules create confusion when type aliases involve forward references, +invalid types, or violate other restrictions enforced on type alias declaration. +Because the distinction between an unannotated value and a type alias is implicit, +ambiguous or incorrect type alias declarations implicitly default to a valid value assignment. + +.. code-block:: python + + from typing import TypeAlias # or `from typing_extensions` before `python3.10` + + AliasType: TypeAlias = Union[list[dict[tuple[int, str], set[int]]], tuple[str, list[str]]] + +Explicit type aliases solves the ambiguness and improves readability. + .. _named-tuples: Named tuples From e3fd193af975bebd5b5ca270485f76000c4864b1 Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Mon, 20 Dec 2021 17:59:24 +0300 Subject: [PATCH 2/4] Update kinds_of_types.rst --- docs/source/kinds_of_types.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/source/kinds_of_types.rst b/docs/source/kinds_of_types.rst index 6fd8a798988f7..b3a73efba3b7e 100644 --- a/docs/source/kinds_of_types.rst +++ b/docs/source/kinds_of_types.rst @@ -362,7 +362,6 @@ is needed: .. code-block:: python - class Container: items: list[str] # No initializer @@ -522,7 +521,7 @@ assigning the type to a variable: another type -- it's equivalent to the target type except for :ref:`generic aliases `. -Since Mypy 0.920 you can also use explicit type aliases which are defined by :pep:`613`. +Since Mypy 0.930 you can also use explicit type aliases which are defined by :pep:`613`. Implicit type alias declaration rules create confusion when type aliases involve forward references, invalid types, or violate other restrictions enforced on type alias declaration. From 78cec8c2b93eb4c6c0ac0ed98b0ea71946387c79 Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Mon, 20 Dec 2021 19:47:44 +0300 Subject: [PATCH 3/4] Update docs/source/kinds_of_types.rst Co-authored-by: Jelle Zijlstra --- docs/source/kinds_of_types.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/kinds_of_types.rst b/docs/source/kinds_of_types.rst index b3a73efba3b7e..73a6acac1db8d 100644 --- a/docs/source/kinds_of_types.rst +++ b/docs/source/kinds_of_types.rst @@ -534,7 +534,7 @@ ambiguous or incorrect type alias declarations implicitly default to a valid val AliasType: TypeAlias = Union[list[dict[tuple[int, str], set[int]]], tuple[str, list[str]]] -Explicit type aliases solves the ambiguness and improves readability. +Explicit type aliases are unambiguous and improve readability. .. _named-tuples: From 250384764adfa23220f0e35fd2e13cf39e819585 Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Tue, 21 Dec 2021 10:49:23 +0300 Subject: [PATCH 4/4] Update common_issues.rst --- docs/source/common_issues.rst | 53 ++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/docs/source/common_issues.rst b/docs/source/common_issues.rst index d3c1761bc9947..9d6423137c414 100644 --- a/docs/source/common_issues.rst +++ b/docs/source/common_issues.rst @@ -638,39 +638,48 @@ Mypy has both type aliases and variables with types like ``Type[...]`` and it is 1. Variables with type ``Type[...]`` should be created by assignments with an explicit type annotations: -.. code-block:: python + .. code-block:: python - class A: ... - tp: Type[A] = A + class A: ... + tp: Type[A] = A -2. Aliases are created by assignments without an explicit type: +2. Aliases are created by assignments without an explicit type. -.. code-block:: python + .. code-block:: python + + class A: ... + Alias = A - class A: ... - Alias = A + Or you can also use :pep:`613` and explicit type aliases: + + .. code-block:: python + + from typing import TypeAlias # or `from typing_extensions` before `python3.10` + + class A: ... + Alias: TypeAlias = A 3. The difference is that aliases are completely known statically and can be used in type context (annotations): -.. code-block:: python + .. code-block:: python - class A: ... - class B: ... + class A: ... + class B: ... - if random() > 0.5: - Alias = A - else: - Alias = B # error: Cannot assign multiple types to name "Alias" without an explicit "Type[...]" annotation \ - # error: Incompatible types in assignment (expression has type "Type[B]", variable has type "Type[A]") + if random() > 0.5: + Alias = A + else: + Alias = B # error: Cannot assign multiple types to name "Alias" without an explicit "Type[...]" annotation \ + # error: Incompatible types in assignment (expression has type "Type[B]", variable has type "Type[A]") - tp: Type[object] # tp is a type variable - if random() > 0.5: - tp = A - else: - tp = B # This is OK + tp: Type[object] # tp is a type variable + if random() > 0.5: + tp = A + else: + tp = B # This is OK - def fun1(x: Alias) -> None: ... # This is OK - def fun2(x: tp) -> None: ... # error: Variable "__main__.tp" is not valid as a type + def fun1(x: Alias) -> None: ... # This is OK + def fun2(x: tp) -> None: ... # error: Variable "__main__.tp" is not valid as a type Incompatible overrides ----------------------