]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-113848: Handle CancelledError subclasses in asyncio TaskGroup() and timeout()...
authorSerhiy Storchaka <storchaka@gmail.com>
Tue, 9 Jan 2024 19:41:31 +0000 (21:41 +0200)
committerGitHub <noreply@github.com>
Tue, 9 Jan 2024 19:41:31 +0000 (21:41 +0200)
Lib/asyncio/taskgroups.py
Lib/asyncio/timeouts.py
Misc/NEWS.d/next/Library/2024-01-09-12-19-55.gh-issue-113848.kXoCy0.rst [new file with mode: 0644]

index cb9c1ce4d7d1d29f2f259c877446d277e1060fd1..e1c56d140bef7de4bf1d1685525850ee934bc73b 100644 (file)
@@ -73,8 +73,10 @@ class TaskGroup:
                 self._base_error is None):
             self._base_error = exc
 
-        propagate_cancellation_error = \
-            exc if et is exceptions.CancelledError else None
+        if et is not None and issubclass(et, exceptions.CancelledError):
+            propagate_cancellation_error = exc
+        else:
+            propagate_cancellation_error = None
         if self._parent_cancel_requested:
             # If this flag is set we *must* call uncancel().
             if self._parent_task.uncancel() == 0:
@@ -133,7 +135,7 @@ class TaskGroup:
         if propagate_cancellation_error and not self._errors:
             raise propagate_cancellation_error
 
-        if et is not None and et is not exceptions.CancelledError:
+        if et is not None and not issubclass(et, exceptions.CancelledError):
             self._errors.append(exc)
 
         if self._errors:
index 30042abb3ad804d8ed5d4255cf6949b0f00c3e40..2c5dd295ff5ade171730072f32c6ce9036e940dd 100644 (file)
@@ -109,10 +109,11 @@ class Timeout:
         if self._state is _State.EXPIRING:
             self._state = _State.EXPIRED
 
-            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 from exc_val
+            if self._task.uncancel() <= self._cancelling and exc_type is not None:
+                if issubclass(exc_type, exceptions.CancelledError):
+                    # Since there are no new cancel requests, we're
+                    # handling this.
+                    raise TimeoutError from exc_val
         elif self._state is _State.ENTERED:
             self._state = _State.EXITED
 
diff --git a/Misc/NEWS.d/next/Library/2024-01-09-12-19-55.gh-issue-113848.kXoCy0.rst b/Misc/NEWS.d/next/Library/2024-01-09-12-19-55.gh-issue-113848.kXoCy0.rst
new file mode 100644 (file)
index 0000000..8d5032a
--- /dev/null
@@ -0,0 +1,3 @@
+:func:`asyncio.TaskGroup()` and :func:`asyncio.timeout()` context managers
+now handle :exc:`~asyncio.CancelledError` subclasses as well as exact
+:exc:`!CancelledError`.