Coroutines et tâches

Cette section donne un aperçu des API de haut-niveau du module asyncio pour utiliser les coroutines et les tâches.

Coroutines

Source code: Lib/asyncio/coroutines.py


Coroutines declared with the async/await syntax is the preferred way of writing asyncio applications. For example, the following snippet of code prints "hello", waits 1 second, and then prints "world":

>>> import asyncio

>>> async def main():
...     print('hello')
...     await asyncio.sleep(1)
...     print('world')

>>> asyncio.run(main())
hello
world

Appeler une coroutine ne la planifie pas pour exécution :

>>> main()
<coroutine object main at 0x1053bb7c8>

To actually run a coroutine, asyncio provides the following mechanisms:

  • La fonction asyncio.run() pour exécuter la fonction « main() », le point d'entrée de haut-niveau (voir l'exemple ci-dessus).

  • Attendre une coroutine. Le morceau de code suivant attend une seconde, affiche « hello », attend 2 secondes supplémentaires, puis affiche enfin « world » :

    import asyncio
    import time
    
    async def say_after(delay, what):
        await asyncio.sleep(delay)
        print(what)
    
    async def main():
        print(f"started at {time.strftime('%X')}")
    
        await say_after(1, 'hello')
        await say_after(2, 'world')
    
        print(f"finished at {time.strftime('%X')}")
    
    asyncio.run(main())
    

    Sortie attendue :

    started at 17:13:52
    hello
    world
    finished at 17:13:55
    
  • La fonction asyncio.create_task() pour exécuter de manière concurrente des coroutines en tant que tâches asyncio.

    Modifions l'exemple ci-dessus et lançons deux coroutines say_after de manière concurrente :

    async def main():
        task1 = asyncio.create_task(
            say_after(1, 'hello'))
    
        task2 = asyncio.create_task(
            say_after(2, 'world'))
    
        print(f"started at {time.strftime('%X')}")
    
        # Wait until both tasks are completed (should take
        # around 2 seconds.)
        await task1
        await task2
    
        print(f"finished at {time.strftime('%X')}")
    

    La sortie attendue montre à présent que ce code s'exécute une seconde plus rapidement que le précédent :

    started at 17:14:32
    hello
    world
    finished at 17:14:34
    
  • The asyncio.TaskGroup class provides a more modern alternative to create_task(). Using this API, the last example becomes:

    async def main():
        async with asyncio.TaskGroup() as tg:
            task1 = tg.create_task(
                say_after(1, 'hello'))
    
            task2 = tg.create_task(
                say_after(2, 'world'))
    
            print(f"started at {time.strftime('%X')}")
    
        # The await is implicit when the context manager exits.
    
        print(f"finished at {time.strftime('%X')}")
    

    The timing and output should be the same as for the previous version.

    Nouveau dans la version 3.11: asyncio.TaskGroup.

Attendables

Un objet est dit attendable (awaitable en anglais, c.-à-d. qui peut être attendu) s'il peut être utilisé dans une expression await. Beaucoup d'API d'asyncio sont conçues pour accepter des attendables.

Il existe trois types principaux d'attendables : les coroutines, les tâches et les futurs.

Coroutines

Les coroutines sont des awaitables et peuvent donc être attendues par d'autres coroutines :

import asyncio

async def nested():
    return 42

async def main():
    # Nothing happens if we just call "nested()".
    # A coroutine object is created but not awaited,
    # so it *won't run at all*.
    nested()

    # Let's do it differently now and await it:
    print(await nested())  # will print "42".

asyncio.run(main())

Important

Dans cette documentation, le terme « coroutine » est utilisé pour désigner deux concepts voisins :

  • une fonction coroutine : une fonction async def ;

  • un objet coroutine : un objet renvoyé par une fonction coroutine.

Tâches

Les tâches servent à planifier des coroutines de façon à ce qu'elles s'exécutent de manière concurrente.

Lorsqu'une coroutine est encapsulée dans une tâche à l'aide de fonctions comme asyncio.create_task(), la coroutine est automatiquement planifiée pour s'exécuter prochainement :

import asyncio

async def nested():
    return 42

async def main():
    # Schedule nested() to run soon concurrently
    # with "main()".
    task = asyncio.create_task(nested())

    # "task" can now be used to cancel "nested()", or
    # can simply be awaited to wait until it is complete:
    await task

asyncio.run(main())

Futurs

Un Future est un objet awaitable spécial de bas-niveau, qui représente le résultat final d'une opération asynchrone.

Quand un objet Future est attendu, cela signifie que la coroutine attendra que ce futur soit résolu à un autre endroit.

Les objets Future d'asyncio sont nécessaires pour permettre l'exécution de code basé sur les fonctions de rappel avec la syntaxe async / await.

Il est normalement inutile de créer des objets Future dans la couche applicative du code.

Les objets Future, parfois exposés par des bibliothèques et quelques API d'asyncio, peuvent être attendus :

async def main():
    await function_that_returns_a_future_object()

    # this is also valid:
    await asyncio.gather(
        function_that_returns_a_future_object(),
        some_python_coroutine()
    )

loop.run_in_executor() est l'exemple typique d'une fonction bas-niveau renvoyant un objet Future.

Création de tâches

Source code: Lib/asyncio/tasks.py


asyncio.create_task(coro, *, name=None, context=None)

Encapsule la coroutine coro dans une tâche et la planifie pour exécution. Renvoie l'objet Task.

Si name n’est pas None, il est défini comme le nom de la tâche en utilisant Task.set_name().

An optional keyword-only context argument allows specifying a custom contextvars.Context for the coro to run in. The current context copy is created when no context is provided.

La tâche est exécutée dans la boucle renvoyée par get_running_loop() ; RuntimeError est levée s'il n'y a pas de boucle en cours d'exécution dans le fil actuel.

Note

asyncio.TaskGroup.create_task() is a newer alternative that allows for convenient waiting for a group of related tasks.

Important

Save a reference to the result of this function, to avoid a task disappearing mid-execution. The event loop only keeps weak references to tasks. A task that isn't referenced elsewhere may get garbage collected at any time, even before it's done. For reliable "fire-and-forget" background tasks, gather them in a collection:

background_tasks = set()

for i in range(10):
    task = asyncio.create_task(some_coro(param=i))

    # Add task to the set. This creates a strong reference.
    background_tasks.add(task)

    # To prevent keeping references to finished tasks forever,
    # make each task remove its own reference from the set after
    # completion:
    task.add_done_callback(background_tasks.discard)

Nouveau dans la version 3.7.

Modifié dans la version 3.8: Added the name parameter.

Modifié dans la version 3.11: Added the context parameter.

Task Cancellation

Tasks can easily and safely be cancelled. When a task is cancelled, asyncio.CancelledError will be raised in the task at the next opportunity.

It is recommended that coroutines use try/finally blocks to robustly perform clean-up logic. In case asyncio.CancelledError is explicitly caught, it should generally be propagated when clean-up is complete. Most code can safely ignore asyncio.CancelledError.

The asyncio components that enable structured concurrency, like asyncio.TaskGroup and asyncio.timeout(), are implemented using cancellation internally and might misbehave if a coroutine swallows asyncio.CancelledError. Similarly, user code should not call uncancel.

Task Groups

Task groups combine a task creation API with a convenient and reliable way to wait for all tasks in the group to finish.

class asyncio.TaskGroup

An asynchronous context manager holding a group of tasks. Tasks can be added to the group using create_task(). All tasks are awaited when the context manager exits.

Nouveau dans la version 3.11.

create_task(coro, *, name=None, context=None)

Create a task in this task group. The signature matches that of asyncio.create_task().

Exemple :

async def main():
    async with asyncio.TaskGroup() as tg:
        task1 = tg.create_task(some_coro(...))
        task2 = tg.create_task(another_coro(...))
    print("Both tasks have completed now.")

The async with statement will wait for all tasks in the group to finish. While waiting, new tasks may still be added to the group (for example, by passing tg into one of the coroutines and calling tg.create_task() in that coroutine). Once the last task has finished and the async with block is exited, no new tasks may be added to the group.

The first time any of the tasks belonging to the group fails with an exception other than asyncio.CancelledError, the remaining tasks in the group are cancelled. No further tasks can then be added to the group. At this point, if the body of the async with statement is still active (i.e., __aexit__() hasn't been called yet), the task directly containing the async with statement is also cancelled. The resulting asyncio.CancelledError will interrupt an await, but it will not bubble out of the containing async with statement.

Once all tasks have finished, if any tasks have failed with an exception other than asyncio.CancelledError, those exceptions are combined in an ExceptionGroup or BaseExceptionGroup (as appropriate; see their documentation) which is then raised.

Two base exceptions are treated specially: If any task fails with KeyboardInterrupt or SystemExit, the task group still cancels the remaining tasks and waits for them, but then the initial KeyboardInterrupt or SystemExit is re-raised instead of ExceptionGroup or BaseExceptionGroup.

If the body of the async with statement exits with an exception (so __aexit__() is called with an exception set), this is treated the same as if one of the tasks failed: the remaining tasks are cancelled and then waited for, and non-cancellation exceptions are grouped into an exception group and raised. The exception passed into __aexit__(), unless it is asyncio.CancelledError, is also included in the exception group. The same special case is made for KeyboardInterrupt and SystemExit as in the previous paragraph.

Attente

coroutine asyncio.sleep(delay, result=None)

Attend pendant delay secondes.

Si result est spécifié, il est renvoyé à l'appelant quand la coroutine se termine.

sleep() suspend systématiquement la tâche courante, ce qui permet aux autres tâches de s'exécuter.

Setting the delay to 0 provides an optimized path to allow other tasks to run. This can be used by long-running functions to avoid blocking the event loop for the full duration of the function call.

Exemple d'une coroutine affichant la date toutes les secondes pendant 5 secondes :

import asyncio
import datetime

async def display_date():
    loop = asyncio.get_running_loop()
    end_time = loop.time() + 5.0
    while True:
        print(datetime.datetime.now())
        if (loop.time() + 1.0) >= end_time:
            break
        await asyncio.sleep(1)

asyncio.run(display_date())

Modifié dans la version 3.10: Removed the loop parameter.

Exécution de tâches de manière concurrente

awaitable asyncio.gather(*aws, return_exceptions=False)

Exécute les objets awaitable de la séquence aws, de manière concurrente.

Si un attendable de aws est une coroutine, celui-ci est automatiquement planifié comme une tâche Task.

Si tous les awaitables s'achèvent avec succès, le résultat est la liste des valeurs renvoyées. L'ordre de cette liste correspond à l'ordre des awaitables dans aws.

Si return_exceptions vaut False (valeur par défaut), la première exception levée est immédiatement propagée vers la tâche en attente dans le gather(). Les autres attendables dans la séquence aws ne sont pas annulés et poursuivent leur exécution.

Si return_exceptions vaut True, les exceptions sont traitées de la même manière que les exécutions normales, et incluses dans la liste des résultats.

Si gather() est annulé, tous les awaitables en cours (ceux qui n'ont pas encore fini de s'exécuter) sont également annulés.

Si n'importe quel Task ou Future de la séquence aws est annulé, il est traité comme s'il avait levé CancelledError — l'appel à gather() n'est alors pas annulé. Ceci permet d'empêcher que l'annulation d'une tâche ou d'un futur entraîne l'annulation des autres tâches ou futurs.

Note

A more modern way to create and run tasks concurrently and wait for their completion is asyncio.TaskGroup.

Exemple :

import asyncio

async def factorial(name, number):
    f = 1
    for i in range(2, number + 1):
        print(f"Task {name}: Compute factorial({number}), currently i={i}...")
        await asyncio.sleep(1)
        f *= i
    print(f"Task {name}: factorial({number}) = {f}")
    return f

async def main():
    # Schedule three calls *concurrently*:
    L = await asyncio.gather(
        factorial("A", 2),
        factorial("B", 3),
        factorial("C", 4),
    )
    print(L)

asyncio.run(main())

# Expected output:
#
#     Task A: Compute factorial(2), currently i=2...
#     Task B: Compute factorial(3), currently i=2...
#     Task C: Compute factorial(4), currently i=2...
#     Task A: factorial(2) = 2
#     Task B: Compute factorial(3), currently i=3...
#     Task C: Compute factorial(4), currently i=3...
#     Task B: factorial(3) = 6
#     Task C: Compute factorial(4), currently i=4...
#     Task C: factorial(4) = 24
#     [2, 6, 24]

Note

If return_exceptions is False, cancelling gather() after it has been marked done won't cancel any submitted awaitables. For instance, gather can be marked done after propagating an exception to the caller, therefore, calling gather.cancel() after catching an exception (raised by one of the awaitables) from gather won't cancel any other awaitables.

Modifié dans la version 3.7: Si gather est lui-même annulé, l'annulation est propagée indépendamment de return_exceptions.

Modifié dans la version 3.10: Removed the loop parameter.

Obsolète depuis la version 3.10: Deprecation warning is emitted if no positional arguments are provided or not all positional arguments are Future-like objects and there is no running event loop.

Protection contre l'annulation

awaitable asyncio.shield(aw)

Empêche qu'un objet awaitable puisse être annulé.

Si aw est une coroutine, elle est planifiée automatiquement comme une tâche.

L'instruction :

task = asyncio.create_task(something())
res = await shield(task)

est équivalente à :

res = await something()

à la différence près que, si la coroutine qui la contient est annulée, la tâche s'exécutant dans something() n'est pas annulée. Du point de vue de something(), il n'y a pas eu d'annulation. Cependant, son appelant est bien annulé, donc l'expression await lève bien une CancelledError.

Si something() est annulée d'une autre façon (c.-à-d. depuis elle-même) ceci annule également shield().

Pour ignorer complètement l'annulation (déconseillé), la fonction shield() peut être combinée à une clause try / except, comme dans le code ci-dessous :

task = asyncio.create_task(something())
try:
    res = await shield(task)
except CancelledError:
    res = None

Important

Save a reference to tasks passed to this function, to avoid a task disappearing mid-execution. The event loop only keeps weak references to tasks. A task that isn't referenced elsewhere may get garbage collected at any time, even before it's done.

Modifié dans la version 3.10: Removed the loop parameter.

Obsolète depuis la version 3.10: Deprecation warning is emitted if aw is not Future-like object and there is no running event loop.

Délais d'attente

coroutine asyncio.timeout(delay)

An asynchronous context manager that can be used to limit the amount of time spent waiting on something.

delay can either be None, or a float/int number of seconds to wait. If delay is None, no time limit will be applied; this can be useful if the delay is unknown when the context manager is created.

In either case, the context manager can be rescheduled after creation using Timeout.reschedule().

Exemple :

async def main():
    async with asyncio.timeout(10):
        await long_running_task()

If long_running_task takes more than 10 seconds to complete, the context manager will cancel the current task and handle the resulting asyncio.CancelledError internally, transforming it into an asyncio.TimeoutError which can be caught and handled.

Note

The asyncio.timeout() context manager is what transforms the asyncio.CancelledError into an asyncio.TimeoutError, which means the asyncio.TimeoutError can only be caught outside of the context manager.

Example of catching asyncio.TimeoutError:

async def main():
    try:
        async with asyncio.timeout(10):
            await long_running_task()
    except TimeoutError:
        print("The long operation timed out, but we've handled it.")

    print("This statement will run regardless.")

The context manager produced by asyncio.timeout() can be rescheduled to a different deadline and inspected.

class asyncio.Timeout

An asynchronous context manager that limits time spent inside of it.

Nouveau dans la version 3.11.

when() float | None

Return the current deadline, or None if the current deadline is not set.

The deadline is a float, consistent with the time returned by loop.time().

reschedule(when: float | None)

Change the time the timeout will trigger.

If when is None, any current deadline will be removed, and the context manager will wait indefinitely.

If when is a float, it is set as the new deadline.

if when is in the past, the timeout will trigger on the next iteration of the event loop.

expired() bool

Return whether the context manager has exceeded its deadline (expired).

Exemple :

async def main():
    try:
        # We do not know the timeout when starting, so we pass ``None``.
        async with asyncio.timeout(None) as cm:
            # We know the timeout now, so we reschedule it.
            new_deadline = get_running_loop().time() + 10
            cm.reschedule(new_deadline)

            await long_running_task()
    except TimeoutError:
        pass

    if cm.expired():
        print("Looks like we haven't finished on time.")

Timeout context managers can be safely nested.

Nouveau dans la version 3.11.

coroutine asyncio.timeout_at(when)

Similar to asyncio.timeout(), except when is the absolute time to stop waiting, or None.

Exemple :

async def main():
    loop = get_running_loop()
    deadline = loop.time() + 20
    try:
        async with asyncio.timeout_at(deadline):
            await long_running_task()
    except TimeoutError:
        print("The long operation timed out, but we've handled it.")

    print("This statement will run regardless.")

Nouveau dans la version 3.11.

coroutine asyncio.wait_for(aw, timeout)

Attend la fin de l'awaitable aw avec délai d'attente.

Si aw est une coroutine, elle est planifiée automatiquement comme une tâche.

timeout peut-être soit None, soit le nombre de secondes (entier ou décimal) d'attente. Si timeout vaut None, la fonction s'interrompt jusqu'à ce que le futur s'achève.

If a timeout occurs, it cancels the task and raises TimeoutError.

Pour empêcher l'annulation de la tâche, il est nécessaire de l'encapsuler dans une fonction shield().

The function will wait until the future is actually cancelled, so the total wait time may exceed the timeout. If an exception happens during cancellation, it is propagated.

Si l'attente est annulée, le futur aw est également annulé.

Modifié dans la version 3.10: Removed the loop parameter.

Exemple :

async def eternity():
    # Sleep for one hour
    await asyncio.sleep(3600)
    print('yay!')

async def main():
    # Wait for at most 1 second
    try:
        await asyncio.wait_for(eternity(), timeout=1.0)
    except TimeoutError:
        print('timeout!')

asyncio.run(main())

# Expected output:
#
#     timeout!

Modifié dans la version 3.7: When aw is cancelled due to a timeout, wait_for waits for aw to be cancelled. Previously, it raised TimeoutError immediately.

Modifié dans la version 3.10: Removed the loop parameter.

Primitives d'attente

coroutine asyncio.wait(aws, *, timeout=None, return_when=ALL_COMPLETED)

Run Future and Task instances in the aws iterable concurrently and block until the condition specified by return_when.

The aws iterable must not be empty.

Renvoie deux ensembles de Tasks / Futures : (done, pending).

Utilisation :

done, pending = await asyncio.wait(aws)

timeout (entier ou décimal), si précisé, peut-être utilisé pour contrôler le nombre maximal de secondes d'attente avant de se terminer.

Note that this function does not raise TimeoutError. Futures or Tasks that aren't done when the timeout occurs are simply returned in the second set.

return_when indique quand la fonction doit se terminer. Il peut prendre les valeurs suivantes :

Constante

Description

FIRST_COMPLETED

La fonction se termine lorsque n'importe quel futur se termine ou est annulé.

FIRST_EXCEPTION

La fonction se termine lorsque n'importe quel futur se termine en levant une exception. Si aucun futur ne lève d'exception, équivaut à ALL_COMPLETED.

ALL_COMPLETED

La fonction se termine lorsque les futurs sont tous finis ou annulés.

À la différence de wait_for(), wait() n'annule pas les futurs quand le délai d'attente est dépassé.

Modifié dans la version 3.10: Removed the loop parameter.

Modifié dans la version 3.11: Passing coroutine objects to wait() directly is forbidden.

asyncio.as_completed(aws, *, timeout=None)

Run awaitable objects in the aws iterable concurrently. Return an iterator of coroutines. Each coroutine returned can be awaited to get the earliest next result from the iterable of the remaining awaitables.

Raises TimeoutError if the timeout occurs before all Futures are done.

Exemple :

for coro in as_completed(aws):
    earliest_result = await coro
    # ...

Modifié dans la version 3.10: Removed the loop parameter.

Obsolète depuis la version 3.10: Deprecation warning is emitted if not all awaitable objects in the aws iterable are Future-like objects and there is no running event loop.

Running in Threads

coroutine asyncio.to_thread(func, /, *args, **kwargs)

Asynchronously run function func in a separate thread.

Any *args and **kwargs supplied for this function are directly passed to func. Also, the current contextvars.Context is propagated, allowing context variables from the event loop thread to be accessed in the separate thread.

Return a coroutine that can be awaited to get the eventual result of func.

This coroutine function is primarily intended to be used for executing IO-bound functions/methods that would otherwise block the event loop if they were run in the main thread. For example:

def blocking_io():
    print(f"start blocking_io at {time.strftime('%X')}")
    # Note that time.sleep() can be replaced with any blocking
    # IO-bound operation, such as file operations.
    time.sleep(1)
    print(f"blocking_io complete at {time.strftime('%X')}")

async def main():
    print(f"started main at {time.strftime('%X')}")

    await asyncio.gather(
        asyncio.to_thread(blocking_io),
        asyncio.sleep(1))

    print(f"finished main at {time.strftime('%X')}")


asyncio.run(main())

# Expected output:
#
# started main at 19:50:53
# start blocking_io at 19:50:53
# blocking_io complete at 19:50:54
# finished main at 19:50:54

Directly calling blocking_io() in any coroutine would block the event loop for its duration, resulting in an additional 1 second of run time. Instead, by using asyncio.to_thread(), we can run it in a separate thread without blocking the event loop.

Note

Due to the GIL, asyncio.to_thread() can typically only be used to make IO-bound functions non-blocking. However, for extension modules that release the GIL or alternative Python implementations that don't have one, asyncio.to_thread() can also be used for CPU-bound functions.

Nouveau dans la version 3.9.

Planification depuis d'autres fils d'exécution

asyncio.run_coroutine_threadsafe(coro, loop)

Enregistre une coroutine dans la boucle d'exécution actuelle. Cette opération est compatible avec les programmes à multiples fils d'exécution (thread-safe).

Renvoie un concurrent.futures.Future pour attendre le résultat d'un autre fil d'exécution du système d'exploitation.

Cette fonction est faite pour être appelée par un fil d'exécution distinct de celui dans laquelle la boucle d'événement s'exécute. Exemple :

# Create a coroutine
coro = asyncio.sleep(1, result=3)

# Submit the coroutine to a given loop
future = asyncio.run_coroutine_threadsafe(coro, loop)

# Wait for the result with an optional timeout argument
assert future.result(timeout) == 3

Si une exception est levée dans une coroutine, le futur renvoyé en sera averti. Elle peut également être utilisée pour annuler la tâche de la boucle d'événement :

try:
    result = future.result(timeout)
except TimeoutError:
    print('The coroutine took too long, cancelling the task...')
    future.cancel()
except Exception as exc:
    print(f'The coroutine raised an exception: {exc!r}')
else:
    print(f'The coroutine returned: {result!r}')

Voir la section exécution concurrente et multi-fils d'exécution de la documentation.

À la différence des autres fonctions d'asyncio, cette fonction requiert que loop soit passé de manière explicite.

Nouveau dans la version 3.5.1.

Introspection

asyncio.current_task(loop=None)

Renvoie l'instance de la Task en cours d'exécution, ou None s'il n'y a pas de tâche en cours.

Si loop vaut None, get_running_loop() est appelée pour récupérer la boucle en cours d'exécution.

Nouveau dans la version 3.7.

asyncio.all_tasks(loop=None)

Renvoie l'ensemble des Task non terminés en cours d'exécution dans la boucle.

Si loop vaut None, get_running_loop() est appelée pour récupérer la boucle en cours d'exécution.

Nouveau dans la version 3.7.

Objets Task

class asyncio.Task(coro, *, loop=None, name=None)

Objet compatible avec Future qui exécute une coroutine Python. Cet objet n'est pas utilisable dans des programmes à fils d'exécution multiples.

Les tâches servent à exécuter des coroutines dans des boucles d'événements. Si une coroutine attend un futur, la tâche interrompt son exécution et attend la fin de ce futur. Quand celui-ci est terminé, l'exécution de la coroutine encapsulée reprend.

Les boucles d'événement fonctionnent de manière coopérative : une boucle d'événement exécute une tâche à la fois. Quand une tâche attend la fin d'un futur, la boucle d'événement exécute d'autres tâches, des fonctions de rappel, ou effectue des opérations d'entrées-sorties.

La fonction de haut niveau asyncio.create_task() et les fonctions de bas-niveau loop.create_task() ou ensure_future() permettent de créer des tâches. Il est déconseillé d'instancier manuellement des objets Task.

La méthode cancel() d'une tâche en cours d'exécution permet d'annuler celle-ci. L'appel de cette méthode force la tâche à lever l'exception CancelledError dans la coroutine encapsulée. Si la coroutine attendait un futur au moment de l'annulation, celui-ci est annulé.

La méthode cancelled() permet de vérifier si la tâche a été annulée. Elle renvoie True si la coroutine encapsulée n'a pas ignoré l'exception CancelledError et a bien été annulée.

asyncio.Task hérite de Future, de toute son API, à l'exception de Future.set_result() et de Future.set_exception().

Task implémente le module contextvars. Lors de sa création, une tâche effectue une copie du contexte actuel et exécutera ses coroutines dans cette copie.

Modifié dans la version 3.7: Ajout du support du module contextvars.

Modifié dans la version 3.8: Added the name parameter.

Obsolète depuis la version 3.10: Deprecation warning is emitted if loop is not specified and there is no running event loop.

done()

Renvoie True si la tâche est achevée.

Une tâche est dite achevée quand la coroutine encapsulée a soit renvoyé une valeur, soit levé une exception, ou que la tâche a été annulée.

result()

Renvoie le résultat de la tâche.

Si la tâche est achevée, le résultat de la coroutine encapsulée est renvoyé (sinon, dans le cas où la coroutine a levé une exception, cette exception est de nouveau levée).

Si la tâche a été annulée, cette méthode lève une exception CancelledError.

Si le résultat de la tâche n'est pas encore disponible, cette méthode lève une exception InvalidStateError.

exception()

Renvoie l'exception de la tâche.

Si la coroutine encapsulée lève une exception, cette exception est renvoyée. Si la coroutine s'est exécutée normalement, cette méthode renvoie None.

Si la tâche a été annulée, cette méthode lève une exception CancelledError.

Si la tâche n'est pas encore achevée, cette méthode lève une exception InvalidStateError.

add_done_callback(callback, *, context=None)

Ajoute une fonction de rappel qui sera exécutée quand la tâche sera achevée.

Cette méthode ne doit être utilisée que dans du code basé sur les fonctions de rappel de bas-niveau.

Se référer à la documentation de Future.add_done_callback() pour plus de détails.

remove_done_callback(callback)

Retire callback de la liste de fonctions de rappel.

Cette méthode ne doit être utilisée que dans du code basé sur les fonctions de rappel de bas-niveau.

Se référer à la documentation de Future.remove_done_callback() pour plus de détails.

get_stack(*, limit=None)

Renvoie une liste représentant la pile d'appels de la tâche.

Si la coroutine encapsulée n'est pas terminée, cette fonction renvoie la pile d'appels à partir de l'endroit où celle-ci est interrompue. Si la coroutine s'est terminée normalement ou a été annulée, cette fonction renvoie une liste vide. Si la coroutine a été terminée par une exception, ceci renvoie la pile d'erreurs.

La pile est toujours affichée de l'appelant à l'appelé.

Une seule ligne est renvoyée si la coroutine est suspendue.

L'argument facultatif limit définit le nombre maximal d'appels à renvoyer ; par défaut, tous sont renvoyés. L'ordre de la liste diffère selon la nature de celle-ci : les appels les plus récents d'une pile d'appels sont renvoyés, si la pile est une pile d'erreurs, ce sont les appels les plus anciens qui le sont (dans un souci de cohérence avec le module traceback).

print_stack(*, limit=None, file=None)

Affiche la pile d'appels ou d'erreurs de la tâche.

Le format de sortie des appels produits par get_stack() est similaire à celui du module traceback.

Le paramètre limit est directement passé à get_stack().

The file argument is an I/O stream to which the output is written; by default output is written to sys.stdout.

get_coro()

Renvoie l’objet coroutine encapsulé par la Task.

Nouveau dans la version 3.8.

get_name()

Renvoie le nom de la tâche.

Si aucun nom n’a été explicitement assigné à la tâche, l’implémentation par défaut d’une Task asyncio génère un nom par défaut durant l’instanciation.

Nouveau dans la version 3.8.

set_name(value)

Définit le nom de la tâche.

L’argument value peut être n’importe quel objet qui sera ensuite converti en chaine de caractères.

Dans l’implémentation par défaut de Task, le nom sera visible dans le résultat de repr() d’un objet Task.

Nouveau dans la version 3.8.

cancel(msg=None)

Demande l'annulation d'une tâche.

Provisionne la levée de l'exception CancelledError dans la coroutine encapsulée. L'exception sera levée au prochain cycle de la boucle d'exécution.

La coroutine peut alors faire le ménage ou même ignorer la requête en supprimant l'exception à l'aide d'un bloc try … … except CancelledErrorfinally. Par conséquent, contrairement à Future.cancel(), Task.cancel() ne garantit pas que la tâche sera annulée, bien qu'ignorer totalement une annulation ne soit ni une pratique courante, ni encouragé.

Modifié dans la version 3.9: Added the msg parameter.

Modifié dans la version 3.11: The msg parameter is propagated from cancelled task to its awaiter.

L'exemple ci-dessous illustre comment une coroutine peut intercepter une requête d'annulation :

async def cancel_me():
    print('cancel_me(): before sleep')

    try:
        # Wait for 1 hour
        await asyncio.sleep(3600)
    except asyncio.CancelledError:
        print('cancel_me(): cancel sleep')
        raise
    finally:
        print('cancel_me(): after sleep')

async def main():
    # Create a "cancel_me" Task
    task = asyncio.create_task(cancel_me())

    # Wait for 1 second
    await asyncio.sleep(1)

    task.cancel()
    try:
        await task
    except asyncio.CancelledError:
        print("main(): cancel_me is cancelled now")

asyncio.run(main())

# Expected output:
#
#     cancel_me(): before sleep
#     cancel_me(): cancel sleep
#     cancel_me(): after sleep
#     main(): cancel_me is cancelled now
cancelled()

Renvoie True si la tâche est annulée.

La tâche est annulée quand l'annulation a été demandée avec cancel() et la coroutine encapsulée a propagé l'exception CancelledError qui a été levée en son sein.

uncancel()

Decrement the count of cancellation requests to this Task.

Returns the remaining number of cancellation requests.

Note that once execution of a cancelled task completed, further calls to uncancel() are ineffective.

Nouveau dans la version 3.11.

This method is used by asyncio's internals and isn't expected to be used by end-user code. In particular, if a Task gets successfully uncancelled, this allows for elements of structured concurrency like Task Groups and asyncio.timeout() to continue running, isolating cancellation to the respective structured block. For example:

async def make_request_with_timeout():
    try:
        async with asyncio.timeout(1):
            # Structured block affected by the timeout:
            await make_request()
            await make_another_request()
    except TimeoutError:
        log("There was a timeout")
    # Outer code not affected by the timeout:
    await unrelated_code()

While the block with make_request() and make_another_request() might get cancelled due to the timeout, unrelated_code() should continue running even in case of the timeout. This is implemented with uncancel(). TaskGroup context managers use uncancel() in a similar fashion.

cancelling()

Return the number of pending cancellation requests to this Task, i.e., the number of calls to cancel() less the number of uncancel() calls.

Note that if this number is greater than zero but the Task is still executing, cancelled() will still return False. This is because this number can be lowered by calling uncancel(), which can lead to the task not being cancelled after all if the cancellation requests go down to zero.

This method is used by asyncio's internals and isn't expected to be used by end-user code. See uncancel() for more details.

Nouveau dans la version 3.11.