From 3d5f69363403582319fd5eae76d5a8e2092015f2 Mon Sep 17 00:00:00 2001 From: Adrian Garcia Badaracco <1755071+adriangb@users.noreply.github.com> Date: Wed, 27 Jul 2022 10:51:50 -0500 Subject: [PATCH 1/6] Update TypeVarTuple example to remove unused TypeVar Notice that "T" is only used once in the function signature, which Pylance will highlight as an error. In this case, Any is just as meaningful as T (and I would argue semantically better, we don't care what the first element is) All of the examples (checked with reveal_type) are still valid. --- Doc/library/typing.rst | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 4d422f539ad184..418aff1899346a 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1302,21 +1302,20 @@ These are not used in annotations. They are building blocks for creating generic *arbitrary* number of types by acting like an *arbitrary* number of type variables wrapped in a tuple. For example:: - T = TypeVar('T') Ts = TypeVarTuple('Ts') - def remove_first_element(tup: tuple[T, *Ts]) -> tuple[*Ts]: + def remove_first_element(tup: tuple[Any, *Ts]) -> tuple[*Ts]: return tup[1:] - # T is bound to int, Ts is bound to () + # Ts is bound to () # Return value is (), which has type tuple[()] remove_first_element(tup=(1,)) - # T is bound to int, Ts is bound to (str,) + # Ts is bound to (str,) # Return value is ('spam',), which has type tuple[str] remove_first_element(tup=(1, 'spam')) - # T is bound to int, Ts is bound to (str, float) + # Ts is bound to (str, float) # Return value is ('spam', 3.0), which has type tuple[str, float] remove_first_element(tup=(1, 'spam', 3.0)) From 71a256bd087984cdfafb6d11ed6bc5dcf2dbd12c Mon Sep 17 00:00:00 2001 From: Adrian Garcia Badaracco <1755071+adriangb@users.noreply.github.com> Date: Tue, 2 Aug 2022 12:55:43 -0500 Subject: [PATCH 2/6] update example --- Doc/library/typing.rst | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 418aff1899346a..328e9aec64cb2e 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1302,22 +1302,23 @@ These are not used in annotations. They are building blocks for creating generic *arbitrary* number of types by acting like an *arbitrary* number of type variables wrapped in a tuple. For example:: + T = TypeVar('T') Ts = TypeVarTuple('Ts') - def remove_first_element(tup: tuple[Any, *Ts]) -> tuple[*Ts]: - return tup[1:] + def move_first_element_to_last(tup: tuple[T, *Ts]) -> tuple[*Ts, T]: + return (*tup[1:], tup[0]) - # Ts is bound to () - # Return value is (), which has type tuple[()] - remove_first_element(tup=(1,)) + # T is bound to int, Ts is bound to () + # Return value is (1, ), which has type tuple[int] + move_first_element_to_last(tup=(1,)) - # Ts is bound to (str,) - # Return value is ('spam',), which has type tuple[str] - remove_first_element(tup=(1, 'spam')) + # T is bound to int, Ts is bound to (str,) + # Return value is ('spam', 1), which has type tuple[str, int] + move_first_element_to_last(tup=(1, 'spam')) - # Ts is bound to (str, float) - # Return value is ('spam', 3.0), which has type tuple[str, float] - remove_first_element(tup=(1, 'spam', 3.0)) + # T is bound to int, Ts is bound to (str, float) + # Return value is ('spam', 3.0, 1), which has type tuple[str, float, int] + move_first_element_to_last(tup=(1, 'spam', 3.0)) Note the use of the unpacking operator ``*`` in ``tuple[T, *Ts]``. Conceptually, you can think of ``Ts`` as a tuple of type variables From 7241bab6910d258e5469bbb6a2474e9d6b02fccb Mon Sep 17 00:00:00 2001 From: Adrian Garcia Badaracco <1755071+adriangb@users.noreply.github.com> Date: Tue, 2 Aug 2022 12:58:13 -0500 Subject: [PATCH 3/6] add invalid example with empty tuple --- Doc/library/typing.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 328e9aec64cb2e..be8cb25b474e05 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1319,6 +1319,11 @@ These are not used in annotations. They are building blocks for creating generic # T is bound to int, Ts is bound to (str, float) # Return value is ('spam', 3.0, 1), which has type tuple[str, float, int] move_first_element_to_last(tup=(1, 'spam', 3.0)) + + # This fails to type check (and at runtime) + # because tuple[()] is not compatible with tuple[T, *Ts] + # (at least one element is required) + move_first_element_to_last(tup=()) Note the use of the unpacking operator ``*`` in ``tuple[T, *Ts]``. Conceptually, you can think of ``Ts`` as a tuple of type variables From b1a3f4c6e585e4bb1ba7138200f0b4642cdb9a6f Mon Sep 17 00:00:00 2001 From: Adrian Garcia Badaracco <1755071+adriangb@users.noreply.github.com> Date: Tue, 2 Aug 2022 21:24:15 +0300 Subject: [PATCH 4/6] Update Doc/library/typing.rst Co-authored-by: Alex Waygood --- Doc/library/typing.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index be8cb25b474e05..8511307337240c 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1319,7 +1319,6 @@ These are not used in annotations. They are building blocks for creating generic # T is bound to int, Ts is bound to (str, float) # Return value is ('spam', 3.0, 1), which has type tuple[str, float, int] move_first_element_to_last(tup=(1, 'spam', 3.0)) - # This fails to type check (and at runtime) # because tuple[()] is not compatible with tuple[T, *Ts] # (at least one element is required) From 1b65abf74439e23e8c47ea59c7b887fb17212712 Mon Sep 17 00:00:00 2001 From: Adrian Garcia Badaracco <1755071+adriangb@users.noreply.github.com> Date: Tue, 2 Aug 2022 21:28:31 +0300 Subject: [PATCH 5/6] Update Doc/library/typing.rst Co-authored-by: Alex Waygood --- Doc/library/typing.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 8511307337240c..b7be059b427f07 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1319,7 +1319,8 @@ These are not used in annotations. They are building blocks for creating generic # T is bound to int, Ts is bound to (str, float) # Return value is ('spam', 3.0, 1), which has type tuple[str, float, int] move_first_element_to_last(tup=(1, 'spam', 3.0)) - # This fails to type check (and at runtime) + + # This fails to type check (and fails at runtime) # because tuple[()] is not compatible with tuple[T, *Ts] # (at least one element is required) move_first_element_to_last(tup=()) From 302e7af2f1769d192d522bad59c51da601335622 Mon Sep 17 00:00:00 2001 From: Adrian Garcia Badaracco <1755071+adriangb@users.noreply.github.com> Date: Wed, 3 Aug 2022 01:21:46 +0300 Subject: [PATCH 6/6] Update typing.rst --- Doc/library/typing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index b7be059b427f07..ad461225a6e4af 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1309,7 +1309,7 @@ These are not used in annotations. They are building blocks for creating generic return (*tup[1:], tup[0]) # T is bound to int, Ts is bound to () - # Return value is (1, ), which has type tuple[int] + # Return value is (1,), which has type tuple[int] move_first_element_to_last(tup=(1,)) # T is bound to int, Ts is bound to (str,)