diff --git a/Lib/asyncio/runners.py b/Lib/asyncio/runners.py index 7489a50f8e48da..ae9721e57ae17e 100644 --- a/Lib/asyncio/runners.py +++ b/Lib/asyncio/runners.py @@ -118,7 +118,7 @@ def run(self, coro, *, context=None): events.set_event_loop(self._loop) return self._loop.run_until_complete(task) except exceptions.CancelledError: - if self._interrupt_count > 0 and task.uncancel() == 0: + if self._interrupt_count > 0 and tasks._uncancel(task) == 0: raise KeyboardInterrupt() else: raise # CancelledError diff --git a/Lib/asyncio/taskgroups.py b/Lib/asyncio/taskgroups.py index 3ca65062efd272..ced9334df02a43 100644 --- a/Lib/asyncio/taskgroups.py +++ b/Lib/asyncio/taskgroups.py @@ -63,7 +63,7 @@ async def __aexit__(self, et, exc, tb): if et is not None: if et is exceptions.CancelledError: - if self._parent_cancel_requested and not self._parent_task.uncancel(): + if self._parent_cancel_requested and tasks._uncancel(self._parent_task) == 0: # Do nothing, i.e. swallow the error. pass else: diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index 3952b5f2a7743d..73881675195533 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -67,14 +67,30 @@ def _set_task_name(task, name): try: set_name = task.set_name except AttributeError: - warnings.warn("Task.set_name() was added in Python 3.8, " + warnings._deprecated( + name="missing asyncio.Task.set_name()", + message="Task.set_name() was added in Python 3.8, " "the method support will be mandatory for third-party " - "task implementations since 3.13.", - DeprecationWarning, stacklevel=3) + "task implementations since 3.13.", remove=(3, 13)) else: set_name(name) +def _uncancel(task): + try: + uncancel = task.uncancel + except AttributeError: + warnings._deprecated( + name="missing asyncio.Task.uncancel()", + message="Task.uncancel() was added in Python 3.11, " + "the method support will be mandatory for third-party " + "task implementations since 3.16.", + remove=(3, 16)) + return -1 + else: + return uncancel() + + class Task(futures._PyFuture): # Inherit Python Task implementation # from a Python Future implementation. diff --git a/Lib/asyncio/timeouts.py b/Lib/asyncio/timeouts.py index a89205348ff24c..85478ba93879c7 100644 --- a/Lib/asyncio/timeouts.py +++ b/Lib/asyncio/timeouts.py @@ -92,7 +92,7 @@ async def __aexit__( if self._state is _State.EXPIRING: self._state = _State.EXPIRED - if self._task.uncancel() == 0 and exc_type is exceptions.CancelledError: + if tasks._uncancel(self._task) == 0 and exc_type is exceptions.CancelledError: # Since there are no outstanding cancel requests, we're # handling this. raise TimeoutError diff --git a/Misc/NEWS.d/next/Library/2022-07-21-17-19-41.gh-issue-95098.eLTdR_.rst b/Misc/NEWS.d/next/Library/2022-07-21-17-19-41.gh-issue-95098.eLTdR_.rst new file mode 100644 index 00000000000000..e2655af600679f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-07-21-17-19-41.gh-issue-95098.eLTdR_.rst @@ -0,0 +1 @@ +support custom tasks with missing uncancel methods