Thanks to visit codestin.com
Credit goes to github.com

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

Closed
@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