[Python-Dev] PEP 550 v4

Stefan Krah stefan at bytereef.org
Mon Aug 28 11:52:15 EDT 2017


On Mon, Aug 28, 2017 at 11:23:12AM -0400, Yury Selivanov wrote:
> On Mon, Aug 28, 2017 at 7:19 AM, Stefan Krah <stefan at bytereef.org> wrote:
> > Okay, so if I understand this correctly we actually will not have dynamic
> > scoping for regular functions:  bar() has returned, so the new context
> > would not be found on the stack with proper dynamic scoping.
> 
> Correct. Although I would avoid associating PEP 550 with dynamic
> scoping entirely, as we never intended to implement it.

Good, I agree it does not make sense.


> [..]
> > What about this?
> >
> > async def bar():
> >     setcontext(Context(prec=1))
> >     for i in range(10):
> >         await asyncio.sleep(1)
> >         yield i
> >
> > async def foo():
> >     async for i in bar():
> >         # ctx.prec=1?
> >         print(Decimal(100) / 3)
> >
> >
> >
> > I'm searching for some abstract model to reason about the scopes.
> 
> Whatever is set in coroutines, generators, and async generators does
> not leak out.  In the above example, "prec=1" will only be set inside
> "bar()", and "foo()" will not see that.  (Same will happen for a
> regular function and a generator).

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.


Stefan Krah





More information about the Python-Dev mailing list