<div><br><div class="gmail_quote"><div dir="auto">On Wed, Jan 3, 2018 at 2:36 AM Victor Stinner <<a href="mailto:victor.stinner@gmail.com">victor.stinner@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><span style="font-family:sans-serif">> I would really like to invite more people to review this PEP! I expect I'll be accepting it in the next two weeks, but it needs to go through more rigorous review.</span><div dir="auto"><span style="font-family:sans-serif"><br></span></div></div><div dir="auto"><div dir="auto"><span style="font-family:sans-serif">I read again the PEP and I am still very confused by Context.run().</span></div><div dir="auto"><span style="font-family:sans-serif"><br></span></div><div dir="auto"><span style="font-family:sans-serif">The PEP states multiple times that a context is immutable:</span></div><div dir="auto"><span style="font-family:sans-serif"><br></span></div><div dir="auto"><span style="font-family:sans-serif">* "read-only mapping"</span></div><div dir="auto"><span style="font-family:sans-serif">* inherit from Mapping, not from MutableMapping</span></div></div></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div dir="auto"><span style="font-family:sans-serif"></span></div><div dir="auto"><span style="font-family:sans-serif"><br></span></div><div dir="auto"><span style="font-family:sans-serif">But run() does modify the context (or please correct me if I </span><span style="font-family:sans-serif">completely </span><span style="font-family:sans-serif">misunderstood the PEP! I had to read it 3 times to check if run() mutates or not the context).</span></div><div dir="auto"><span style="font-family:sans-serif"><br></span></div><div dir="auto"><span style="font-family:sans-serif">It would help if the ctx.run() example in the PEP would not only test var.get() but also test ctx.get(var). Or maybe show that the variable value is kept in a second function call, but the variable is "restored" between run() calls.</span></div><div dir="auto"><span style="font-family:sans-serif"><br></span></div><div dir="auto"><span style="font-family:sans-serif">The PEP tries hard to hide "context data", which is the only read only thing in the whole PEP, whereas it's a key concept to understand the implementation.</span></div><div dir="auto"><span style="font-family:sans-serif"><br></span></div><div dir="auto"><span style="font-family:sans-serif">I understood that:</span></div><div dir="auto"><span style="font-family:sans-serif"><br></span></div><div dir="auto"><span style="font-family:sans-serif">* _ContextData is immutable</span></div><div dir="auto"><span style="font-family:sans-serif">* ContextVar.set() creates a new _ContextData and sets it in the current Python thread state</span></div><div dir="auto"><span style="font-family:sans-serif">* When the called function completes, Context.run() sets its context data to the new context data from the Python thread state: so run() does modify the "immutable" context</span></div></div></blockquote><div dir="auto"><br></div><div dir="auto">tuples in Python are immutable, but you can have a tuple with a dict as its single element. The tuple is immutable, the dict is mutable.</div><div dir="auto"><br></div><div dir="auto">At the C level we have APIs that can mutate a tuple though.</div><div dir="auto"><br></div><div dir="auto">Now, tuple is not a direct analogy to Context, but there are some parallels. Context is a container like tuple, with some additional APIs on top.</div><div dir="auto"><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div dir="auto"><span style="font-family:sans-serif"></span></div><div dir="auto"><span style="font-family:sans-serif"><br></span></div><div dir="auto"><span style="font-family:sans-serif"><br></span></div><div dir="auto"><span style="font-family:sans-serif">The distinction between the internal/hiden *immutable* context data and public/visible "mutable" (from my point of view) context is unclear to me in the PEP.</span></div><div dir="auto"><span style="font-family:sans-serif"><br></span></div><div dir="auto"><span style="font-family:sans-serif">The concept of "current context" is not defined in the PEP. In practice, there is no "current context", there is only a "current context data" in the current Python thread. There is no need for a concrete context instance to store variable variables values. It's also hard to understand that in the PEP.</span></div><div dir="auto"><span style="font-family:sans-serif"><br></span></div><div dir="auto"><span style="font-family:sans-serif"><br></span></div><div dir="auto"><span style="font-family:sans-serif">Why Context could not inherit from MutableMapping? (Allow ctx.set(var, value) and ctx [var] = value.) Is it just to keep the API small: changes should only be made using var.set()?</span></div></div></blockquote><div dir="auto"><br></div><div dir="auto">Because that would be confusing to end users.</div><div dir="auto"><br></div><div dir="auto"> ctx = copy_context()</div><div dir="auto"> ctx[var] = something</div><div dir="auto"><br></div><div dir="auto">What did we just do? Did we modify the 'var' in the code that is currently executing? No, you still need to call Context.run to see the new value for var.</div><div dir="auto"><br></div><div dir="auto">Another problem is that MutableMapping defines a __delitem__ method, which i don't want the Context to implement. Deleting variables like that is incompatible with PEP 550, where it's ambiguous (due to the stacked nature of contexts).</div><div dir="auto"><br></div><div dir="auto">Now we don't want PEP 550 in 3.7, but I want to keep the door open for its design, in case we want context to work with generators.</div><div dir="auto"><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div dir="auto"><span style="font-family:sans-serif"></span></div><div dir="auto"><span style="font-family:sans-serif"><br></span></div><div dir="auto"><span style="font-family:sans-serif">Or maybe Context.run() should really be immutable and return the result of the called function *and* a new context? But I dislike such theorical </span><span style="font-family:sans-serif">API, since it would be complex to return the new context if the called function raises an exception.</span></div></div></blockquote><div dir="auto"><br></div><div dir="auto">It can't return a new context because the callable you're running can raise an exception. In which case you'd lose modifications prior to the error.</div><div dir="auto"><br></div><div dir="auto">ps i'm on vacation and don't always have an internet connection.</div><div dir="auto"><br></div><div dir="auto">yury</div><div dir="auto"><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div dir="auto"><span style="font-family:sans-serif"></span></div><div dir="auto"><span style="font-family:sans-serif"><br></span></div><div dir="auto"><span style="font-family:sans-serif">Victor</span></div></div>
_______________________________________________<br>
Python-Dev mailing list<br>
<a href="mailto:Python-Dev@python.org" target="_blank">Python-Dev@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-dev" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-dev</a><br>
Unsubscribe: <a href="https://mail.python.org/mailman/options/python-dev/yselivanov.ml%40gmail.com" rel="noreferrer" target="_blank">https://mail.python.org/mailman/options/python-dev/yselivanov.ml%40gmail.com</a><br>
</blockquote></div></div>