<div dir="ltr">That was actually Yury's original design, but I insisted on a Mapping so you can introspect it. (There needs to be some way to introspect a Context, for debugging.) Again, more later. :-(<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jan 3, 2018 at 4:44 PM, Victor Stinner <span dir="ltr"><<a href="mailto:victor.stinner@gmail.com" target="_blank">victor.stinner@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Ok, I finally got access to a computer and I was able to test the PEP<br>
567 implementation: see my code snippet below.<br>
<br>
The behaviour is more tricky than what I expected. While running<br>
context.run(), the context object is out of sync of the "current<br>
context". It's only synchronized again at run() exit. So<br>
ContextVar.set() doesn't immediately modifies the "current context"<br>
object (set by Context.run()).<br>
<br>
Ok, and now something completely different! What if Context looses its<br>
whole mapping API and becomes a "blackbox" object only with a run()<br>
method and no attribute? It can be documented as an object mapping<br>
context variables to their values, but don't give access to these<br>
values directly. It would avoid to have explain the weird run()<br>
behaviour (context out of sync). It would avoid to have to decide if<br>
it's a mutable or immutable mapping. It would avoid to have to explain<br>
the internal O(1) copy using HAMT.<br>
<br>
Code testing Context.run():<br>
---<br>
import contextvars<br>
<br>
name = contextvars.ContextVar('name', default='name')<br>
<br>
def assertNotIn(var, context):<br>
    try:<br>
        context[var]<br>
    except LookupError:<br>
        pass<br>
    else:<br>
        raise AssertionError("name is set is context")<br>
<br>
<br>
def func1():<br>
    name.set('yury')<br>
    assert name.get() == 'yury'<br>
    assertNotIn(name, context)<br>
<br>
def func2():<br>
    assert name.get() == 'yury'<br>
    assert context[name] == 'yury'<br>
<br>
context = contextvars.copy_context()<br>
<br>
assert name.get() == 'name'<br>
assertNotIn(name, context)<br>
<br>
context.run(func1)<br>
<br>
assert name.get() == 'name'<br>
assert context[name] == 'yury'<br>
<br>
context.run(func2)<br>
<br>
assert name.get() == 'name'<br>
assert context[name] == 'yury'<br>
---<br>
<br>
Victor<br>
</blockquote></div><br><br clear="all"><br>-- <br><div class="gmail_signature" data-smartmail="gmail_signature">--Guido van Rossum (<a href="http://python.org/~guido" target="_blank">python.org/~guido</a>)</div>
</div>