[Python-Dev] PEP 550 v4

Yury Selivanov yselivanov.ml at gmail.com
Wed Aug 30 09:55:59 EDT 2017


On Wed, Aug 30, 2017 at 8:55 AM, Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
> Yury Selivanov wrote:
>
>> BTW we already have mechanisms to always propagate context to the
>> caller -- just use threading.local() or a global variable.
>
>
> But then you don't have a way to *not* propagate the
> context change when you don't want to.
>
> Here's my suggestion: Make an explicit distinction between
> creating a new binding for a context var and updating an
> existing one.
>
> So instead of two API calls there would be three:
>
>    contextvar.new(value) # Creates a new binding only
>                          # visible to this frame and
>                          # its callees
>
>    contextvar.set(value) # Updates existing binding in
>                          # context inherited from caller
>
>    contextvar.get()      # Retrieves the current binding
>
> If we assume an extension to the decimal module so
> that decimal.localcontext is a context var, we can
> now do this:
>
>    async def foo():
>       # Establish a new context for this task
>       decimal.localcontext.new(decimal.Context())
>       # Delegate changing the context
>       await bar()
>       # Do some calculations
>       yield 17 * math.pi + 42
>
>    async def bar():
>       # Change context for caller
>       decimal.localcontext.prec = 5

Interesting.

Question: how to write a context manager with contextvar.new?

  var = new_context_var()

   class CM:

        def __enter__(self):
              var.new(42)

   with CM():
        print(var.get() or 'None')

My understanding that the above code will print "None", because
"var.new()" makes 42 visible only to callees of __enter__.

But if I use "set()" in "CM.__enter__", presumably, it will traverse
the stack of LCs to the very bottom and set "var=42" in in it.  Right?

If so, how can fix the example in PEP 550 Rationale:
https://www.python.org/dev/peps/pep-0550/#rationale where we zip() the
"fractions()" generator?

With current PEP 550 semantics that's trivial:
https://www.python.org/dev/peps/pep-0550/#generators

Yury


More information about the Python-Dev mailing list