[Python-Dev] PEP 550 v4 (original) (raw)

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


On Mon, Aug 28, 2017 at 1:33 PM, Stefan Krah <stefan at bytereef.org> wrote: [..]

* Context managers like decimal contexts, numpy.errstate, and warnings.catchwarnings. The decimal context works like this: 1) There is a default context template (user settable). 2) Whenever the first operation in a new thread occurs, the thread-local context is initialized with a copy of the template.

I don't find it very intuitive if setcontext() is somewhat local in coroutines but they don't participate in some form of CLS. You have to think about things like "what happens in a fresh thread when a coroutine calls setcontext() before any other decimal operation has taken place".

I'm sorry, I don't follow you here.

PEP 550 semantics:

setcontext() in a regular code would set the context for the whole thread.

setcontext() in a coroutine/generator/async generator would set the context for all the code it calls.

So perhaps Nathaniel is right that the PEP is not so useful for numpy and decimal backwards compat.

Nathaniel's argument is pretty weak as I see it. He argues that some people would take the following code:

def bar():
   # set decimal context

def foo():
   bar()
   # use the decimal context set in bar()

and blindly convert it to async/await:

async def bar():
   # set decimal context

async def foo():
   await bar()
   # use the decimal context set in bar()

And that it's a problem that it will stop working.

But almost nobody converts the code by simply slapping async/await on top of it -- things don't work this way. It was never a goal for async/await or asyncio, or even trio/curio. Porting code to async/await almost always requires a thoughtful rewrite.

In async/await, the above code is an anti-pattern. It's super fragile and can break by adding a timeout around "await bar". There's no workaround here.

Asynchronous code is fundamentally non-local and a more complex topic on its own, with its own concepts: Asynchronous Tasks, timeouts, cancellation, etc. Fundamentally: "(synchronous code) != (asynchronous code) - (async/await)".

Yury



More information about the Python-Dev mailing list