mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
gh-96037: Always insert TimeoutError when exit an expired asyncio.timeout() block (GH-113819)
If other exception was raised during exiting an expired asyncio.timeout() block, insert TimeoutError in the exception context just above the CancelledError.
This commit is contained in:
parent
ab0ad62038
commit
aef4a1203c
3 changed files with 133 additions and 13 deletions
|
@ -110,10 +110,15 @@ class Timeout:
|
|||
self._state = _State.EXPIRED
|
||||
|
||||
if self._task.uncancel() <= self._cancelling and exc_type is not None:
|
||||
# Since there are no new cancel requests, we're
|
||||
# handling this.
|
||||
if issubclass(exc_type, exceptions.CancelledError):
|
||||
# Since there are no new cancel requests, we're
|
||||
# handling this.
|
||||
raise TimeoutError from exc_val
|
||||
elif exc_val is not None:
|
||||
self._insert_timeout_error(exc_val)
|
||||
if isinstance(exc_val, ExceptionGroup):
|
||||
for exc in exc_val.exceptions:
|
||||
self._insert_timeout_error(exc)
|
||||
elif self._state is _State.ENTERED:
|
||||
self._state = _State.EXITED
|
||||
|
||||
|
@ -126,6 +131,16 @@ class Timeout:
|
|||
# drop the reference early
|
||||
self._timeout_handler = None
|
||||
|
||||
@staticmethod
|
||||
def _insert_timeout_error(exc_val: BaseException) -> None:
|
||||
while exc_val.__context__ is not None:
|
||||
if isinstance(exc_val.__context__, exceptions.CancelledError):
|
||||
te = TimeoutError()
|
||||
te.__context__ = te.__cause__ = exc_val.__context__
|
||||
exc_val.__context__ = te
|
||||
break
|
||||
exc_val = exc_val.__context__
|
||||
|
||||
|
||||
def timeout(delay: Optional[float]) -> Timeout:
|
||||
"""Timeout async context manager.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue