From 1013ef34a07c9d405d2d5a3dc1f475be711190f8 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Mon, 6 May 2024 18:13:07 -0700 Subject: [PATCH 1/7] gh-118660: Add second type parameter to (Async)ContextManager --- .../Library/2024-05-06-18-13-02.gh-issue-118660.n01Vb7.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2024-05-06-18-13-02.gh-issue-118660.n01Vb7.rst diff --git a/Misc/NEWS.d/next/Library/2024-05-06-18-13-02.gh-issue-118660.n01Vb7.rst b/Misc/NEWS.d/next/Library/2024-05-06-18-13-02.gh-issue-118660.n01Vb7.rst new file mode 100644 index 00000000000000..d06e895a340337 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-05-06-18-13-02.gh-issue-118660.n01Vb7.rst @@ -0,0 +1,3 @@ +Add a second type parameter to :class:`typing.ContextManager` and +:class:`typing.AsyncContextManager`, representing the return type of +:meth:`__exit__`. This parameter defaults to ``bool | None``. From 2d9458e458321ff7e8a966ea0fb48cb1fc298515 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Mon, 6 May 2024 18:14:11 -0700 Subject: [PATCH 2/7] Add code --- Doc/library/typing.rst | 20 ++++++++++++++++++-- Lib/test/test_typing.py | 23 +++++++++++++++++++---- Lib/typing.py | 2 +- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 652a3f1f70519c..c9fe5f49eee3f7 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -3819,10 +3819,15 @@ Aliases to other ABCs in :mod:`collections.abc` Aliases to :mod:`contextlib` ABCs """"""""""""""""""""""""""""""""" -.. class:: ContextManager(Generic[T_co]) +.. class:: ContextManager(Generic[T_co, ExitT_co]) Deprecated alias to :class:`contextlib.AbstractContextManager`. + The first type parameter, ``T_co``, represents the type returned by + the :meth:`__enter__` method. The second type parameter, ``ExitT_co``, + which defaults to ``bool | None``, represents the type returned by the + :meth:`__exit__` method. + .. versionadded:: 3.5.4 .. deprecated:: 3.9 @@ -3830,10 +3835,18 @@ Aliases to :mod:`contextlib` ABCs now supports subscripting (``[]``). See :pep:`585` and :ref:`types-genericalias`. -.. class:: AsyncContextManager(Generic[T_co]) + .. versionchanged:: 3.13 + Added the second type parameter, ``ExitT_co``. + +.. class:: AsyncContextManager(Generic[T_co, ExitT_co]) Deprecated alias to :class:`contextlib.AbstractAsyncContextManager`. + The first type parameter, ``T_co``, represents the type returned by + the :meth:`__aenter__` method. The second type parameter, ``ExitT_co``, + which defaults to ``bool | None``, represents the type returned by the + :meth:`__aexit__` method. + .. versionadded:: 3.6.2 .. deprecated:: 3.9 @@ -3841,6 +3854,9 @@ Aliases to :mod:`contextlib` ABCs now supports subscripting (``[]``). See :pep:`585` and :ref:`types-genericalias`. + .. versionchanged:: 3.13 + Added the second type parameter, ``ExitT_co``. + Deprecation Timeline of Major Features ====================================== diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 8f0be1fd3f55e5..291a9b3d523b0d 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -7486,6 +7486,15 @@ def manager(): self.assertIsInstance(cm, typing.ContextManager) self.assertNotIsInstance(42, typing.ContextManager) + def test_contextmanager_type_params(self): + cm1 = typing.ContextManager[int] + self.assertEqual(get_args(cm1), (int, bool | None)) + cm2 = typing.ContextManager[int, None] + self.assertEqual(get_args(cm2), (int, types.NoneType)) + + type gen_cm[T1, T2] = typing.ContextManager[T1, T2] + self.assertEqual(get_args(gen_cm.__value__[int, None]), (int, types.NoneType)) + def test_async_contextmanager(self): class NotACM: pass @@ -7497,11 +7506,17 @@ def manager(): cm = manager() self.assertNotIsInstance(cm, typing.AsyncContextManager) - self.assertEqual(typing.AsyncContextManager[int].__args__, (int,)) + self.assertEqual(typing.AsyncContextManager[int].__args__, (int, bool | None)) with self.assertRaises(TypeError): isinstance(42, typing.AsyncContextManager[int]) with self.assertRaises(TypeError): - typing.AsyncContextManager[int, str] + typing.AsyncContextManager[int, str, float] + + def test_asynccontextmanager_type_params(self): + cm1 = typing.AsyncContextManager[int] + self.assertEqual(get_args(cm1), (int, bool | None)) + cm2 = typing.AsyncContextManager[int, None] + self.assertEqual(get_args(cm2), (int, types.NoneType)) class TypeTests(BaseTestCase): @@ -9928,7 +9943,7 @@ def test_special_attrs(self): typing.ValuesView: 'ValuesView', # Subscribed ABC classes typing.AbstractSet[Any]: 'AbstractSet', - typing.AsyncContextManager[Any]: 'AsyncContextManager', + typing.AsyncContextManager[Any, Any]: 'AsyncContextManager', typing.AsyncGenerator[Any, Any]: 'AsyncGenerator', typing.AsyncIterable[Any]: 'AsyncIterable', typing.AsyncIterator[Any]: 'AsyncIterator', @@ -9938,7 +9953,7 @@ def test_special_attrs(self): typing.ChainMap[Any, Any]: 'ChainMap', typing.Collection[Any]: 'Collection', typing.Container[Any]: 'Container', - typing.ContextManager[Any]: 'ContextManager', + typing.ContextManager[Any, Any]: 'ContextManager', typing.Coroutine[Any, Any, Any]: 'Coroutine', typing.Counter[Any]: 'Counter', typing.DefaultDict[Any, Any]: 'DefaultDict', diff --git a/Lib/typing.py b/Lib/typing.py index c159fcfda68ee8..8e82b7883be3a6 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -3764,7 +3764,7 @@ def __getattr__(attr): obj = _alias(getattr(re, attr), 1) elif attr in {"ContextManager", "AsyncContextManager"}: import contextlib - obj = _alias(getattr(contextlib, f"Abstract{attr}"), 1, name=attr) + obj = _alias(getattr(contextlib, f"Abstract{attr}"), 2, name=attr, defaults=(bool | None,)) else: raise AttributeError(f"module {__name__!r} has no attribute {attr!r}") globals()[attr] = obj From 5dd6535fc41435bd331161b8e17a6811b8c58e73 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Mon, 6 May 2024 18:44:51 -0700 Subject: [PATCH 3/7] Fix docs warnings --- Doc/library/typing.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index c9fe5f49eee3f7..addd480e07dd2c 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -717,7 +717,7 @@ This requirement previously also applied to abstract base classes, such as to be explicitly marked to support them, which is unpythonic and unlike what one would normally do in idiomatic dynamically typed Python code. For example, this conforms to :pep:`484`:: - +3826 from collections.abc import Sized, Iterable, Iterator class Bucket(Sized, Iterable[int]): @@ -3824,9 +3824,9 @@ Aliases to :mod:`contextlib` ABCs Deprecated alias to :class:`contextlib.AbstractContextManager`. The first type parameter, ``T_co``, represents the type returned by - the :meth:`__enter__` method. The second type parameter, ``ExitT_co``, + the :meth:`~object.__enter__` method. The second type parameter, ``ExitT_co``, which defaults to ``bool | None``, represents the type returned by the - :meth:`__exit__` method. + :meth:`~object.__exit__` method. .. versionadded:: 3.5.4 @@ -3843,9 +3843,9 @@ Aliases to :mod:`contextlib` ABCs Deprecated alias to :class:`contextlib.AbstractAsyncContextManager`. The first type parameter, ``T_co``, represents the type returned by - the :meth:`__aenter__` method. The second type parameter, ``ExitT_co``, + the :meth:`~object.__aenter__` method. The second type parameter, ``ExitT_co``, which defaults to ``bool | None``, represents the type returned by the - :meth:`__aexit__` method. + :meth:`~object.__aexit__` method. .. versionadded:: 3.6.2 From 059432a86b3d1b06632a8f30241b2c6e145aef0e Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Mon, 6 May 2024 18:48:10 -0700 Subject: [PATCH 4/7] 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 addd480e07dd2c..d555b4341ca55c 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -717,7 +717,7 @@ This requirement previously also applied to abstract base classes, such as to be explicitly marked to support them, which is unpythonic and unlike what one would normally do in idiomatic dynamically typed Python code. For example, this conforms to :pep:`484`:: -3826 + from collections.abc import Sized, Iterable, Iterator class Bucket(Sized, Iterable[int]): From 8592fa2bce20bfdc3f562c99d7edb085b578460b Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Tue, 7 May 2024 06:41:29 -0700 Subject: [PATCH 5/7] Apply suggestions from code review Co-authored-by: Alex Waygood --- Doc/library/typing.rst | 2 +- .../Library/2024-05-06-18-13-02.gh-issue-118660.n01Vb7.rst | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index d555b4341ca55c..33d47e11ece247 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -3838,7 +3838,7 @@ Aliases to :mod:`contextlib` ABCs .. versionchanged:: 3.13 Added the second type parameter, ``ExitT_co``. -.. class:: AsyncContextManager(Generic[T_co, ExitT_co]) +.. class:: AsyncContextManager(Generic[T_co, AExitT_co]) Deprecated alias to :class:`contextlib.AbstractAsyncContextManager`. diff --git a/Misc/NEWS.d/next/Library/2024-05-06-18-13-02.gh-issue-118660.n01Vb7.rst b/Misc/NEWS.d/next/Library/2024-05-06-18-13-02.gh-issue-118660.n01Vb7.rst index d06e895a340337..beb37a0d127a93 100644 --- a/Misc/NEWS.d/next/Library/2024-05-06-18-13-02.gh-issue-118660.n01Vb7.rst +++ b/Misc/NEWS.d/next/Library/2024-05-06-18-13-02.gh-issue-118660.n01Vb7.rst @@ -1,3 +1,4 @@ Add a second type parameter to :class:`typing.ContextManager` and :class:`typing.AsyncContextManager`, representing the return type of -:meth:`__exit__`. This parameter defaults to ``bool | None``. +:meth:`~object.__exit__` and :meth:`~object.__aexit__` respectively. +This parameter defaults to ``bool | None``. From b3f24844545a3c911baac2a6e494b529a73a8f7a Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Tue, 7 May 2024 06:44:57 -0700 Subject: [PATCH 6/7] Apply suggestions from code review Co-authored-by: Alex Waygood --- Doc/library/typing.rst | 4 ++-- .../Library/2024-05-06-18-13-02.gh-issue-118660.n01Vb7.rst | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 33d47e11ece247..827b65e043470d 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -3843,7 +3843,7 @@ Aliases to :mod:`contextlib` ABCs Deprecated alias to :class:`contextlib.AbstractAsyncContextManager`. The first type parameter, ``T_co``, represents the type returned by - the :meth:`~object.__aenter__` method. The second type parameter, ``ExitT_co``, + the :meth:`~object.__aenter__` method. The second type parameter, ``AExitT_co``, which defaults to ``bool | None``, represents the type returned by the :meth:`~object.__aexit__` method. @@ -3855,7 +3855,7 @@ Aliases to :mod:`contextlib` ABCs See :pep:`585` and :ref:`types-genericalias`. .. versionchanged:: 3.13 - Added the second type parameter, ``ExitT_co``. + Added the second type parameter, ``AExitT_co``. Deprecation Timeline of Major Features ====================================== diff --git a/Misc/NEWS.d/next/Library/2024-05-06-18-13-02.gh-issue-118660.n01Vb7.rst b/Misc/NEWS.d/next/Library/2024-05-06-18-13-02.gh-issue-118660.n01Vb7.rst index beb37a0d127a93..1ec5bb27f5695c 100644 --- a/Misc/NEWS.d/next/Library/2024-05-06-18-13-02.gh-issue-118660.n01Vb7.rst +++ b/Misc/NEWS.d/next/Library/2024-05-06-18-13-02.gh-issue-118660.n01Vb7.rst @@ -1,4 +1,4 @@ Add a second type parameter to :class:`typing.ContextManager` and -:class:`typing.AsyncContextManager`, representing the return type of +:class:`typing.AsyncContextManager`, representing the return types of :meth:`~object.__exit__` and :meth:`~object.__aexit__` respectively. This parameter defaults to ``bool | None``. From 865fffcae3084216ee1d772f8ffa75df3c7634a3 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Tue, 7 May 2024 06:51:46 -0700 Subject: [PATCH 7/7] Apply suggestions from code review Co-authored-by: Alex Waygood --- Doc/library/typing.rst | 8 ++++---- .../2024-05-06-18-13-02.gh-issue-118660.n01Vb7.rst | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 827b65e043470d..f53080e0610cb1 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -3824,7 +3824,7 @@ Aliases to :mod:`contextlib` ABCs Deprecated alias to :class:`contextlib.AbstractContextManager`. The first type parameter, ``T_co``, represents the type returned by - the :meth:`~object.__enter__` method. The second type parameter, ``ExitT_co``, + the :meth:`~object.__enter__` method. The optional second type parameter, ``ExitT_co``, which defaults to ``bool | None``, represents the type returned by the :meth:`~object.__exit__` method. @@ -3836,14 +3836,14 @@ Aliases to :mod:`contextlib` ABCs See :pep:`585` and :ref:`types-genericalias`. .. versionchanged:: 3.13 - Added the second type parameter, ``ExitT_co``. + Added the optional second type parameter, ``ExitT_co``. .. class:: AsyncContextManager(Generic[T_co, AExitT_co]) Deprecated alias to :class:`contextlib.AbstractAsyncContextManager`. The first type parameter, ``T_co``, represents the type returned by - the :meth:`~object.__aenter__` method. The second type parameter, ``AExitT_co``, + the :meth:`~object.__aenter__` method. The optional second type parameter, ``AExitT_co``, which defaults to ``bool | None``, represents the type returned by the :meth:`~object.__aexit__` method. @@ -3855,7 +3855,7 @@ Aliases to :mod:`contextlib` ABCs See :pep:`585` and :ref:`types-genericalias`. .. versionchanged:: 3.13 - Added the second type parameter, ``AExitT_co``. + Added the optional second type parameter, ``AExitT_co``. Deprecation Timeline of Major Features ====================================== diff --git a/Misc/NEWS.d/next/Library/2024-05-06-18-13-02.gh-issue-118660.n01Vb7.rst b/Misc/NEWS.d/next/Library/2024-05-06-18-13-02.gh-issue-118660.n01Vb7.rst index 1ec5bb27f5695c..846a7acb6999b8 100644 --- a/Misc/NEWS.d/next/Library/2024-05-06-18-13-02.gh-issue-118660.n01Vb7.rst +++ b/Misc/NEWS.d/next/Library/2024-05-06-18-13-02.gh-issue-118660.n01Vb7.rst @@ -1,4 +1,4 @@ -Add a second type parameter to :class:`typing.ContextManager` and +Add an optional second type parameter to :class:`typing.ContextManager` and :class:`typing.AsyncContextManager`, representing the return types of :meth:`~object.__exit__` and :meth:`~object.__aexit__` respectively. This parameter defaults to ``bool | None``.