[Python-Dev] Timeout for PEP 550 / Execution Context discussion

Guido van Rossum guido at python.org
Tue Oct 17 00:31:35 EDT 2017


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!).

On Mon, Oct 16, 2017 at 9:09 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:

> On 17 October 2017 at 03:00, Guido van Rossum <guido at python.org> wrote:
>
>> On Mon, Oct 16, 2017 at 9:11 AM, Yury Selivanov <yselivanov.ml at gmail.com>
>> wrote:
>>
>>> > I agree, but I don't see how making the type a subtype (or duck type)
>>> of
>>> > MutableMapping prevents any of those strategies. (Maybe you were
>>> equating
>>> > MutableMapping with "subtype of dict"?)
>>>
>>> Question: why do we want EC objects to be mappings?  I'd rather make
>>> them opaque, which will result in less code and make it more
>>> future-proof.
>>>
>>
>> I'd rather have them mappings, since that's what they represent. It helps
>> users understand what's going on behind the scenes, just like modules,
>> classes and (most) instances have a `__dict__` that you can look at and (in
>> most cases) manipulate.
>>
>
> Perhaps rather than requiring that EC's *be* mappings, we could instead
> require that they expose a mapping API as their __dict__ attribute, similar
> to the way class dictionaries work?
>
> Then the latter could return a proxy that translated mapping operations
> into the appropriate method calls on the ContextVar being used as the key.
>
> Something like:
>
>     class ExecutionContextProxy:
>         def __init__(self, ec):
>             self._ec = ec
>             # Omitted from the methods below: checking if this EC is the
>             # active EC, and implicitly switching to it if it isn't (for
> read ops)
>             # or complaining (for write ops)
>
>         # Individual operations call methods on the key itself
>         def __getitem__(self, key):
>             return key.get()
>         def __setitem__(self, key, value):
>             if not isinstance(key, ContextVar):
>                 raise TypeError("Execution context keys must be context
> variables")
>             key.set(value)
>         def __delitem__(self, key):
>             key.delete()
>
>         # The key set would be the context vars assigned in the active
> context
>         def __contains__(self, key):
>             # Note: PEP 550 currently calls the below method ec.vars(),
>             # but I just realised that's confusing, given that the vars()
> builtin
>             # returns a mapping
>             return key in self._ec.assigned_vars()
>         def __iter__(self):
>             return iter(self._ec.assigned_vars())
>         def keys(self):
>             return self._ec.assigned_vars()
>
>         # These are the simple iterator versions of values() and items()
>         # but they could be enhanced to return dynamic views instead
>         def values(self):
>             for k in self._ec.assigned_vars():
>                 yield k.get()
>         def items(self):
>             for k in self._ec.assigned_vars():
>                 yield (k, k.get())
>
> The nice thing about defining the mapping API as a wrapper around
> otherwise opaque interpreter internals is that it makes it clearer which
> operations are expected to matter for runtime performance (i.e. the ones
> handled by the ExecutionContext itself), and which are mainly being
> provided as intuition pumps for humans attempting to understand how
> execution contexts actually work (whether for debugging purposes, or simply
> out of curiosity)
>
> If there's a part of the mapping proxy API where we don't have a strong
> intuition about how it should work, then instead of attempting to guess
> suitable semantics, we can instead define it as raising RuntimeError for
> now, and then wait and see if the appropriate semantics become clearer over
> time.
>
> Cheers,
> Nick.
>
> --
> Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
>



-- 
--Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20171016/873c0297/attachment-0001.html>


More information about the Python-Dev mailing list