summaryrefslogtreecommitdiffstats
path: root/Lib/asyncio
diff options
context:
space:
mode:
authorThomas Grainger <tagrain@gmail.com>2024-10-14 22:45:58 (GMT)
committerGitHub <noreply@github.com>2024-10-14 22:45:58 (GMT)
commit0b28ea4a35dc7c68c97127f7aad8f0175d77c520 (patch)
tree17d084f9ece3e282b1d745eadfd395bcfc6024c8 /Lib/asyncio
parent1bffd7a2a738506a4ad50c6c3c2c32926cce6d14 (diff)
downloadcpython-0b28ea4a35dc7c68c97127f7aad8f0175d77c520.zip
cpython-0b28ea4a35dc7c68c97127f7aad8f0175d77c520.tar.gz
cpython-0b28ea4a35dc7c68c97127f7aad8f0175d77c520.tar.bz2
gh-124958: Revert "gh-125472: Revert "gh-124958: fix asyncio.TaskGroup and _PyFuture refcycles ... (#125486)
* Revert "gh-125472: Revert "gh-124958: fix asyncio.TaskGroup and _PyFuture refcycles (#12… (#125476)" This reverts commit e99650b80ace3893c2a80b3f2a4aca99cb305191. * fix incompatability with gh-124392
Diffstat (limited to 'Lib/asyncio')
-rw-r--r--Lib/asyncio/futures.py6
-rw-r--r--Lib/asyncio/taskgroups.py41
2 files changed, 34 insertions, 13 deletions
diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py
index 5f6fa23..c95fce0 100644
--- a/Lib/asyncio/futures.py
+++ b/Lib/asyncio/futures.py
@@ -190,8 +190,7 @@ class Future:
the future is done and has an exception set, this exception is raised.
"""
if self._state == _CANCELLED:
- exc = self._make_cancelled_error()
- raise exc
+ raise self._make_cancelled_error()
if self._state != _FINISHED:
raise exceptions.InvalidStateError('Result is not ready.')
self.__log_traceback = False
@@ -208,8 +207,7 @@ class Future:
InvalidStateError.
"""
if self._state == _CANCELLED:
- exc = self._make_cancelled_error()
- raise exc
+ raise self._make_cancelled_error()
if self._state != _FINISHED:
raise exceptions.InvalidStateError('Exception is not set.')
self.__log_traceback = False
diff --git a/Lib/asyncio/taskgroups.py b/Lib/asyncio/taskgroups.py
index f2ee964..9fa772c 100644
--- a/Lib/asyncio/taskgroups.py
+++ b/Lib/asyncio/taskgroups.py
@@ -66,6 +66,20 @@ class TaskGroup:
return self
async def __aexit__(self, et, exc, tb):
+ tb = None
+ try:
+ return await self._aexit(et, exc)
+ finally:
+ # Exceptions are heavy objects that can have object
+ # cycles (bad for GC); let's not keep a reference to
+ # a bunch of them. It would be nicer to use a try/finally
+ # in __aexit__ directly but that introduced some diff noise
+ self._parent_task = None
+ self._errors = None
+ self._base_error = None
+ exc = None
+
+ async def _aexit(self, et, exc):
self._exiting = True
if (exc is not None and
@@ -122,7 +136,10 @@ class TaskGroup:
assert not self._tasks
if self._base_error is not None:
- raise self._base_error
+ try:
+ raise self._base_error
+ finally:
+ exc = None
if self._parent_cancel_requested:
# If this flag is set we *must* call uncancel().
@@ -133,8 +150,14 @@ class TaskGroup:
# Propagate CancelledError if there is one, except if there
# are other errors -- those have priority.
- if propagate_cancellation_error is not None and not self._errors:
- raise propagate_cancellation_error
+ try:
+ if propagate_cancellation_error is not None and not self._errors:
+ try:
+ raise propagate_cancellation_error
+ finally:
+ exc = None
+ finally:
+ propagate_cancellation_error = None
if et is not None and not issubclass(et, exceptions.CancelledError):
self._errors.append(exc)
@@ -146,14 +169,14 @@ class TaskGroup:
if self._parent_task.cancelling():
self._parent_task.uncancel()
self._parent_task.cancel()
- # Exceptions are heavy objects that can have object
- # cycles (bad for GC); let's not keep a reference to
- # a bunch of them.
try:
- me = BaseExceptionGroup('unhandled errors in a TaskGroup', self._errors)
- raise me from None
+ raise BaseExceptionGroup(
+ 'unhandled errors in a TaskGroup',
+ self._errors,
+ ) from None
finally:
- self._errors = None
+ exc = None
+
def create_task(self, coro, *, name=None, context=None):
"""Create a new task in this group and return it.