[Python-Dev] PEP 550 v4 (original) (raw)
Greg Ewing greg.ewing at canterbury.ac.nz
Tue Sep 5 19:59:49 EDT 2017
- Previous message (by thread): [Python-Dev] PEP 549: Instance Properties (aka: module properties)
- Next message (by thread): [Python-Dev] PEP 550 v4
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Yury Selivanov wrote:
Question: how to write a context manager with contextvar.new?
var = newcontextvar() 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.
If you tie the introduction of a new scope for context vars to generators, as PEP 550 currently does, then this isn't a problem.
But I'm trying to avoid doing that. The basic issue is that, ever since yield-from, "generator" and "task" are not synonymous.
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:
push_local_context()
pop_local_context()
Now introducing a temporary decimal context looks like:
push_local_context()
decimal.localcontextvar.new(decimal.getcontext().copy())
decimal.localcontextvar.prec = 5
do_some_calculations()
pop_local_context()
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:
class LocalDecimalContext():
def __enter__(self):
push_local_context()
ctx = decimal.getcontext().copy()
decimal.localcontextvar.new(ctx)
return ctx
def __exit__(self):
pop_local_context()
Usage:
with LocalDecimalContext() as ctx:
ctx.prec = 5
do_some_calculations()
-- Greg
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
- Previous message (by thread): [Python-Dev] PEP 549: Instance Properties (aka: module properties)
- Next message (by thread): [Python-Dev] PEP 550 v4
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]