mirror of
https://github.com/python/cpython.git
synced 2025-08-04 17:08:35 +00:00
gh-118660: Add second type parameter to (Async)ContextManager (#118681)
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
parent
a855f824a2
commit
71080b8a0f
4 changed files with 42 additions and 7 deletions
|
@ -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:`~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.
|
||||
|
||||
.. 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 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 optional second type parameter, ``AExitT_co``,
|
||||
which defaults to ``bool | None``, represents the type returned by the
|
||||
:meth:`~object.__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 optional second type parameter, ``AExitT_co``.
|
||||
|
||||
Deprecation Timeline of Major Features
|
||||
======================================
|
||||
|
||||
|
|
|
@ -7511,6 +7511,15 @@ class OtherABCTests(BaseTestCase):
|
|||
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
|
||||
|
@ -7522,11 +7531,17 @@ class OtherABCTests(BaseTestCase):
|
|||
|
||||
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):
|
||||
|
@ -9953,7 +9968,7 @@ class SpecialAttrsTests(BaseTestCase):
|
|||
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',
|
||||
|
@ -9963,7 +9978,7 @@ class SpecialAttrsTests(BaseTestCase):
|
|||
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',
|
||||
|
|
|
@ -3783,7 +3783,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
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
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``.
|
Loading…
Add table
Add a link
Reference in a new issue