[Python-Dev] PEP 550 v4
greg.ewing at canterbury.ac.nz
Tue Sep 5 19:59:49 EDT 2017
Yury Selivanov wrote:
> Question: how to write a context manager with contextvar.new?
> var = new_context_var()
> class CM:
> def __enter__(self):
> 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__.
If you tie the introduction of a new scope for context vars
to generators, as PEP 550 currently does, then this isn't a
But I'm trying to avoid doing that. The basic issue is that,
ever since yield-from, "generator" and "task" are not
When you use a generator to implement an iterator, you
probably want it to behave as a distinct task with its
own local context. But a generator used with yield-from
isn't a task of its own, it's just part of another task,
and there is nothing built into Python that lets you
tell the difference automatically.
So I'm now thinking that the introduction of a new local
context should also be explicit.
Suppose we have these primitives:
Now introducing a temporary decimal context looks like:
decimal.localcontextvar.prec = 5
Since calls (either normal or generator) no longer automatically
result in a new local context, we can easily factor this out into
a context manager:
ctx = decimal.getcontext().copy()
with LocalDecimalContext() as ctx:
ctx.prec = 5
> 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:
More information about the Python-Dev