diff options
| author | Serhiy Storchaka <storchaka@gmail.com> | 2021-06-29 11:28:15 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-06-29 11:28:15 +0300 |
| commit | 6cb145d23f5cf69b6d7414877d142747cd3d134c (patch) | |
| tree | 0617efcd6911c14a1b8003bb9bee5fc68e521103 /Lib/contextlib.py | |
| parent | 20a88004bae8ead66a205a125e1fe979376fc3ea (diff) | |
| download | cpython-git-6cb145d23f5cf69b6d7414877d142747cd3d134c.tar.gz | |
bpo-44471: Change error type for bad objects in ExitStack.enter_context() (GH-26820)
A TypeError is now raised instead of an AttributeError in
ExitStack.enter_context() and AsyncExitStack.enter_async_context()
for objects which do not support the context manager or
asynchronous context manager protocols correspondingly.
Diffstat (limited to 'Lib/contextlib.py')
| -rw-r--r-- | Lib/contextlib.py | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/Lib/contextlib.py b/Lib/contextlib.py index 1a8ef6122c..004d1037b7 100644 --- a/Lib/contextlib.py +++ b/Lib/contextlib.py @@ -473,9 +473,14 @@ class _BaseExitStack: """ # We look up the special methods on the type to match the with # statement. - _cm_type = type(cm) - _exit = _cm_type.__exit__ - result = _cm_type.__enter__(cm) + cls = type(cm) + try: + _enter = cls.__enter__ + _exit = cls.__exit__ + except AttributeError: + raise TypeError(f"'{cls.__module__}.{cls.__qualname__}' object does " + f"not support the context manager protocol") from None + result = _enter(cm) self._push_cm_exit(cm, _exit) return result @@ -600,9 +605,15 @@ class AsyncExitStack(_BaseExitStack, AbstractAsyncContextManager): If successful, also pushes its __aexit__ method as a callback and returns the result of the __aenter__ method. """ - _cm_type = type(cm) - _exit = _cm_type.__aexit__ - result = await _cm_type.__aenter__(cm) + cls = type(cm) + try: + _enter = cls.__aenter__ + _exit = cls.__aexit__ + except AttributeError: + raise TypeError(f"'{cls.__module__}.{cls.__qualname__}' object does " + f"not support the asynchronous context manager protocol" + ) from None + result = await _enter(cm) self._push_async_cm_exit(cm, _exit) return result |
