Skip to content

asyncio context propagation in Python 3.5/3.6 #71

Closed
@a-feld

Description

@a-feld

The contextvars approach to context propagation requires copying current context on asyncio task creation. This is done internally in asyncio for Python 3.7; however, on Python <3.7 context is not propagated automatically.

Example:

import asyncio
import contextvars

current_task = contextvars.ContextVar("current_task")


async def foo(foo_started, bar_done):
    current_task.set("foo")
    foo_started.set()
    await bar_done.wait()
    print("foo task:", current_task.get())


async def bar(foo_started, bar_done):
    await foo_started.wait()
    current_task.set("bar")
    bar_done.set()


async def main():
    foo_started = asyncio.Event()
    bar_done = asyncio.Event()

    await asyncio.gather(
        foo(foo_started, bar_done),
        bar(foo_started, bar_done),
    )


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

In Python 3.7, the code above will print foo task: foo
In Python 3.5 and 3.6, the code above will print foo task: bar

Metadata

Metadata

Assignees

Labels

apiAffects the API package.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions