summaryrefslogtreecommitdiffstats
path: root/Lib/asyncio
diff options
context:
space:
mode:
authorKristján Valur Jónsson <sweskman@gmail.com>2023-03-22 17:52:10 (GMT)
committerGitHub <noreply@github.com>2023-03-22 17:52:10 (GMT)
commit04adf2df395ded81922c71360a5d66b597471e49 (patch)
treee00fe057435866b27b7fa66465d2d6d9b47745c1 /Lib/asyncio
parent1ca315538f2f9da6c7b86c4c46e76d454c1ec4b9 (diff)
downloadcpython-04adf2df395ded81922c71360a5d66b597471e49.zip
cpython-04adf2df395ded81922c71360a5d66b597471e49.tar.gz
cpython-04adf2df395ded81922c71360a5d66b597471e49.tar.bz2
gh-102780: Fix uncancel() call in asyncio timeouts (#102815)
Also use `raise TimeOut from <CancelledError instance>` so that the CancelledError is set in the `__cause__` field rather than in the `__context__` field. Co-authored-by: Guido van Rossum <gvanrossum@gmail.com> Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Diffstat (limited to 'Lib/asyncio')
-rw-r--r--Lib/asyncio/timeouts.py7
1 files changed, 4 insertions, 3 deletions
diff --git a/Lib/asyncio/timeouts.py b/Lib/asyncio/timeouts.py
index d07b291..029c468 100644
--- a/Lib/asyncio/timeouts.py
+++ b/Lib/asyncio/timeouts.py
@@ -84,6 +84,7 @@ class Timeout:
async def __aenter__(self) -> "Timeout":
self._state = _State.ENTERED
self._task = tasks.current_task()
+ self._cancelling = self._task.cancelling()
if self._task is None:
raise RuntimeError("Timeout should be used inside a task")
self.reschedule(self._when)
@@ -104,10 +105,10 @@ class Timeout:
if self._state is _State.EXPIRING:
self._state = _State.EXPIRED
- if self._task.uncancel() == 0 and exc_type is exceptions.CancelledError:
- # Since there are no outstanding cancel requests, we're
+ if self._task.uncancel() <= self._cancelling and exc_type is exceptions.CancelledError:
+ # Since there are no new cancel requests, we're
# handling this.
- raise TimeoutError
+ raise TimeoutError from exc_val
elif self._state is _State.ENTERED:
self._state = _State.EXITED