New submission from Andrew Svetlov <andrew.svet...@gmail.com>:

Now asyncio creates a new context copy on task creation.

It is the perfect behavior *by default* and should stay as is.

However, sometimes passing an explicit context into a task and using back the 
context modified by task code is desired.

The most obvious use-case is testing: both unittest and pytest have multi-phase 
test initialization (asyncSetUp() methods and async fixtures correspondingly).  
If asyncSetUp() updates context variable -- test code expects to see this 
change.

Currently, unittest runs the setup-test-cleanup chain in a single task and uses 
an internal queue to push a new coroutine for execution and get results back. 
It works but is cumbersome.

Another solution is to create a task per test execution step and wrap the task 
creation with Context.run(). The problem is in getting the updated context 
back. A task creates a context copy on starting, thus the modified context is 
stored in the task internal attribute only. To get it back a trampoline async 
function should be used, e.g.

async def wrapper(coro):
    try:
        return await coro
    finally:
        context = contextvars.copy_context()
        # store the context copy somewhere

Again, it looks more complicated as it should be.

The proposal is: 
1. Add 'context' keyword-only argument to asyncio.create_task() and 
loop.create_task().
2. Use this context if explicitly passed, create a copy of the current context 
otherwise.

The proposal is backward-compatible. Low-level API (call_soon(), call_later() 
etc.) already accept 'context' argument.

The attached PR demonstrates how the proposed API simplifies 
unittest.IsolatedAsyncioTestCase internals.

----------
components: asyncio
messages: 414988
nosy: asvetlov, yselivanov
priority: normal
severity: normal
status: open
title: Accept explicit contextvars.Context in asyncio create_task() API
type: enhancement
versions: Python 3.11

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue46994>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to