Skip to content

AttributeError: 'Task' object has no attribute 'uncancel'. Did you mean: 'cancel'? when the asyncio loop.set_task_factory factory returns a asyncio.Future-compatible object #95097

@graingert

Description

@graingert

Bug report

https://docs.python.org/3.11/library/asyncio-eventloop.html#asyncio.loop.set_task_factory is documented as: "The callable must return a asyncio.Future-compatible object." however a number of apis now assume tasks have an uncancel() method:

import asyncio import signal import os class Task: def __init__(self, loop, coro, **kwargs): self._task = asyncio.Task(coro, loop=loop, **kwargs) def cancel(self, *args, **kwargs): return self._task.cancel(*args, **kwargs) def add_done_callback(self, *args, **kwargs): return self._task.add_done_callback(*args, **kwargs) def remove_done_callback(self, *args, **kwargs): return self._task.remove_done_callback(*args, **kwargs) @property def _asyncio_future_blocking(self): return self._task._asyncio_future_blocking def result(self, *args, **kwargs): return self._task.result(*args, **kwargs) def done(self, *args, **kwargs): return self._task.done(*args, **kwargs) def cancelled(self, *args, **kwargs): return self._task.cancelled(*args, **kwargs) def exception(self, *args, **kwargs): return self._task.exception(*args, **kwargs) def get_loop(self, *args, **kwargs): return self._task.get_loop(*args, **kwargs) async def amain(): os.kill(os.getpid(), signal.SIGINT) await asyncio.Event().wait() class MyPolicy(asyncio.DefaultEventLoopPolicy): def new_event_loop(self, *args, **kwargs): loop = super().new_event_loop(*args, **kwargs) loop.set_task_factory(Task) return loop asyncio.set_event_loop_policy(MyPolicy()) try: asyncio.run(amain()) except KeyboardInterrupt: print("ok!")

results in:

$ python3.10 demo.py ok! 
$ python3.11 demo.py Traceback (most recent call last): File "/usr/lib/python3.11/asyncio/runners.py", line 120, in run return self._loop.run_until_complete(task) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.11/asyncio/base_events.py", line 650, in run_until_complete return future.result() ^^^^^^^^^^^^^^^ File "/home/graingert/demo.py", line 24, in result return self._task.result(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/graingert/demo.py", line 41, in amain await asyncio.Event().wait() File "/usr/lib/python3.11/asyncio/locks.py", line 213, in wait await fut asyncio.exceptions.CancelledError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/graingert/demo.py", line 52, in <module> asyncio.run(amain()) File "/usr/lib/python3.11/asyncio/runners.py", line 187, in run return runner.run(main) ^^^^^^^^^^^^^^^^ File "/usr/lib/python3.11/asyncio/runners.py", line 122, in run if self._interrupt_count > 0 and task.uncancel() == 0: ^^^^^^^^^^^^^ AttributeError: 'Task' object has no attribute 'uncancel'. Did you mean: 'cancel'?

Your environment

  • CPython versions tested on: 3.10, 3.11.0b4, a6daaf2
  • Operating system and architecture:

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.11only security fixes3.12only security fixesrelease-blockertype-bugAn unexpected behavior, bug, or error

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions