<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 17 October 2017 at 15:02, Nick Coghlan <span dir="ltr"><<a href="mailto:ncoghlan@gmail.com" target="_blank">ncoghlan@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class="gmail-">On 17 October 2017 at 14:31, Guido van Rossum <span dir="ltr"><<a href="mailto:guido@python.org" target="_blank">guido@python.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">No, that version just defers to magic in ContextVar.get/set, whereas what I'd like to see is that the latter are just implemented in terms of manipulating the mapping directly. The only operations for which speed matters would be __getitem__ and __setitem__; most other methods just defer to those. __delitem__ must also be a primitive, as must __iter__ and __len__ -- but those don't need to be as speedy (however __delitem__ must really work!).<br></div></blockquote><div><br></div></span><div>To have the mapping API at the base of the design, we'd want to go back to using the ContextKey version of the API as the core primitive (to ensure we don't get name conflicts between different modules and packages), and then have ContextVar be a convenience wrapper that always accesses the currently active context:</div><div><br></div><div>    class ContextKey:</div><div>        ...</div><div>    class ExecutionContext:</div><div>        ...<br></div><div><br></div><div>    class ContextVar:</div><div>        def __init__(self, name):</div><div>            self._key = ContextKey(name)</div><div><br></div><div>        def get(self):</div><div>            return get_execution_context()[self._<wbr>key]<br></div><div> </div><div><div>        def set(self, value):</div><div>            get_execution_context()[self._<wbr>key] = value<br></div></div></div><div class="gmail_quote"><br></div><div class="gmail_quote"><div><div>        def delete(self, value):</div><div>            del get_execution_context()[self._<wbr>key]</div></div></div></div></div></blockquote><div><br></div><div>Tangent: if we do go this way, it actually maps pretty nicely to the idea of a "threading.ThreadVar" API that wraps threading.local():</div><div><br></div><div>    class ThreadVar:</div><div>        def __init__(self, name):</div><div>            self._name = name</div><div>            self._storage = threading.local()</div><div><br></div><div>        def get(self):</div><div>            return self._storage.value<br></div><div> </div><div><div>        def set(self, value):</div><div>            self._storage.value = value<br></div></div><div class="gmail_quote"><br></div><div class="gmail_quote"><div><div>        def delete(self):</div><div>            del self._storage.value</div></div></div><div><br></div><div>(Note: real implementations of either idea would need to pay more attention to producing clear exception messages and instance representations)</div></div></div><div class="gmail_extra"><br></div><div class="gmail_extra">Cheers,</div><div class="gmail_extra">Nick.</div><div class="gmail_extra"><br></div><div class="gmail_extra">-- <br><div class="gmail_signature">Nick Coghlan   |   <a href="mailto:ncoghlan@gmail.com" target="_blank">ncoghlan@gmail.com</a>   |   Brisbane, Australia</div>
</div></div>