On Tue, Jun 22 2021 at 04:40:45 AM -0000, Mark Gordon
<msg...@gmail.com> wrote:
Yury Selivanov wrote:
On Mon, Jun 21, 2021 at 7:20 PM Mark Gordon msg...@gmail.com
<mailto:msg...@gmail.com> wrote:
> Yeah, it would indeed inherit the copy. We could, theoretically,
make
> asyncio.Task accept context objects and not copy them, but what
would
> that
> give us?
> My main thinking was to just be similar to the closest
synchronous analog
> I'm aware of, contextvars.Context.run. I would think an
explanation of why
> the Context object API exists as it does, letting you manipulate
and run in
> contexts directly, would equally motivate the async analogs.
Maybe the
> exception would be if this API exists purely just to support
async tasks
> (then maybe it should be private?).
> At any rate, the issue attached to the pull requests gives one
example of
> seeking to do asyncio tests with providing fixture data through
an existing
> context object. I could also imagine a use case of wanting to
track the
> number of database requests made within a logical request that
may span
> multiple tasks. Having the subtasks inherit the same context
could help
> with this.
> To track things like database requests just put a mutable object
in the
context somewhere at the top level, referenced by a well-known
contextvar
in your code. That single object will be part of all contexts
derived from
the top one throughout the application lifecycle.
Using mutable objects in contexts seems strange as it works against
their copy semantics. I agree it will work in this use case.
That's a feature :) Perhaps we should add an example to the docs.
> *Ultimately, contextvars enable implicit flow
> of information from outer code to nested code and not vice versa.
*
> Just to clarify, are you stating an established position of the
python
> community or is this your personal view of how context vars
should be used?
> I'm stating this as the original contextvars PEP author and
implementer. I
Oh very cool, thanks for taking the time to look at this.
don't see how the reverse flow is possible to implement within all
restrictions of the design space. To propagate information from
nested
calls to outer calls just use mutable objects, as I outlined above.
> Additionally (obviously) it will also be running in a separate
task.
> There's no way around that, unfortunately. Even if we add some
kind of
> helper to run coroutines in a context, there still we be a task
object
> that
> iterates the coroutine.
> I was just pointing out that the stated work-around requires
creating an
> additional task to run the called coroutine rather than running
directly in
> the calling task.
> Yes, and I'm saying that running a coroutine "directly on the
stack" within
some context is not technically possible, without wrapping it into
a Task.
Is there something wrong with the solution of changing the context
associated with a task before execution, yielding, run the coroutine,
then swap it back and yield again when the coroutine exits? This is
the hacky solution that appears to work for me on python 3.8 if I
force use of _PyTask (and the linked PR extends this idea to work for
the CTask implementation).
There's not much wrong about this approach for simple coroutines. But
if a coroutine runs its own tasks or code that forks the context
inside, you won't see those changes in your context. In other words,
the hack you propose will work for some cases, and fail for others. So
that's why I'm -1 on changing the API that way.
Yury
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/python-ideas@python.org/message/CMWE4XSLHW43PRWVI6COVUTU47OBCDMU/
Code of Conduct: http://python.org/psf/codeofconduct/