[Python-Dev] PEP 550 v4

Yury Selivanov yselivanov.ml at gmail.com
Mon Aug 28 12:12:00 EDT 2017


On Mon, Aug 28, 2017 at 11:52 AM, Stefan Krah <stefan at bytereef.org> wrote:
[..]
> But the state "leaks in" as per your previous example:
>
>     async def bar():
>         # use decimal with context=ctx
>
>     async def foo():
>          decimal.setcontext(ctx)
>          await bar()
>
>
> IMHO it shouldn't with coroutine-local-storage (let's call it CLS). So,
> as I see it, there's still some mixture between dynamic scoping and CLS
> because it this example bar() is allowed to search the stack.

The whole proposal will then be mostly useless.  If we forget about
the dynamic scoping (I don't know why it's being brought up all the
time, TBH; nobody uses it, almost no language implements it) the
current proposal is well balanced and solves multiple problems.  Three
points listed in the rationale section:

* Context managers like decimal contexts, numpy.errstate, and
warnings.catch_warnings.
* Request-related data, such as security tokens and request data in
web applications, language context for gettext etc.
* Profiling, tracing, and logging in large code bases.

Two of them require context propagation *down* the stack of
coroutines.  What latest PEP 550 revision does, it prohibits context
propagation *up* the stack in coroutines (it's a requirement to make
async code refactorable and easy to reason about).

Propagation of context "up" the stack in regular code is allowed with
threading.local(), and everybody is used to it.  Doing that for
coroutines doesn't work, because of the reasons covered here:
https://www.python.org/dev/peps/pep-0550/#coroutines-and-asynchronous-tasks

Yury


More information about the Python-Dev mailing list