On Wed, Aug 16, 2017 at 12:51 PM, Yury Selivanov <yselivanov...@gmail.com> wrote: > On Wed, Aug 16, 2017 at 5:36 AM, Nick Coghlan <ncogh...@gmail.com> wrote: >> On 16 August 2017 at 17:18, Nathaniel Smith <n...@pobox.com> wrote: >> [Yury wrote] > [..] >>>> * If ``coro.cr_local_context`` is an empty ``LocalContext`` object >>>> that ``coro`` was created with, the interpreter will set >>>> ``coro.cr_local_context`` to ``None``. >>> >>> I like all the ideas in this section, but this specific point feels a >>> bit weird. Coroutine objects need a second hidden field somewhere to >>> keep track of whether the object they end up with is the same one they >>> were created with? >> >> It feels odd to me as well, and I'm wondering if we can actually >> simplify this by saying: >> >> 1. Generator contexts (both sync and async) are isolated by default >> (__local_context__ = LocalContext()) >> 2. Coroutine contexts are *not* isolated by default (__local_context__ = >> None) >> >> Running top level task coroutines in separate execution contexts then >> becomes the responsibility of the event loop, which the PEP already >> lists as a required change in 3rd party libraries to get this all to >> work properly. > > This is an interesting twist, and I like it. > > This will change asyncio.Task from: > > class Task: > > def __init__(self, coro): > ... > self.exec_context = sys.get_execution_context() > > def step(): > > sys.run_with_execution_context(self.coro.send) > > > to: > > class Task: > > def __init__(self, coro): > ... > self.local_context = sys.new_local_context() > > def step(): > > sys.run_with_local_context(self.local_context, self.coro.send) > > And we don't need ceval to do anything for "await", which means that > with this approach we won't touch ceval.c at all.
And immediately after I hit "send" I realized that this is a bit more complicated. In order for Tasks to remember the full execution context of where they were created, we need a new method that would allow to run with *both* exec and local contexts: class Task: def __init__(self, coro): ... self.local_context = sys.new_local_context() self.exec_context = sys.get_execution_context() def step(): sys.run_with_contexts(self.exec_context, self.local_context, self.coro.send) This is needed for the following PEP example to work properly: current_request = sys.new_context_item(description='request') async def child(): print('current request:', repr(current_request.get())) async def handle_request(request): current_request.set(request) event_loop.create_task(child) run(top_coro()) See https://www.python.org/dev/peps/pep-0550/#tasks Yury _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/