[Python-Dev] PEP 550 v4

Greg Ewing greg.ewing at canterbury.ac.nz
Mon Aug 28 18:22:57 EDT 2017


Yury Selivanov wrote:
> 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.catch_warnings.
>>
>>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

Maybe not, but it will also affect refactoring of code
that is *already* using async/await, e.g. taking


    async def foobar():
       # set decimal context
       # use the decimal context we just set

and refactoring it as above.

Given that one of the main motivations for yield-from
(and subsequently async/await) was so that you *can*
perform that kind of refactoring easily, that does
indeed seem like a problem to me.

It seems to me that individual generators/coroutines
shouldn't automatically get a context of their own,
they should have to explicitly ask for one.

-- 
Greg


  -- 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
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe: https://mail.python.org/mailman/options/python-dev/greg.ewing%40canterbury.ac.nz



More information about the Python-Dev mailing list