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

Yury Selivanov yselivanov.ml at gmail.com
Tue Oct 17 11:54:14 EDT 2017


On Tue, Oct 17, 2017 at 1:02 AM, Nick Coghlan <ncoghlan at gmail.com> wrote:
> On 17 October 2017 at 14:31, Guido van Rossum <guido at python.org> wrote:
>>
>> 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!).
>
>
> 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:
>
>     class ContextKey:
>         ...
>     class ExecutionContext:
>         ...
>
>     class ContextVar:
>         def __init__(self, name):
>             self._key = ContextKey(name)
>
>         def get(self):
>             return get_execution_context()[self._key]
>
>         def set(self, value):
>             get_execution_context()[self._key] = value
>
>         def delete(self, value):
>             del get_execution_context()[self._key]

ContextVar itself will be hashable, we don't need ContextKeys.

>
> While I'd defer to Yury on the technical feasibility, I'd expect that
> version could probably be made to work *if* you were amenable to some of the
> mapping methods on the execution context raising RuntimeError in order to
> avoid locking ourselves in to particular design decisions before we're ready
> to make them.
>
> The reason I say that is because one of the biggest future-proofing concerns
> when it comes to exposing a mapping as the lowest API layer is that it makes
> the following code pattern possible:
>
>     ec = get_execution_context()
>     # Change to a different execution context
>     ec[key] = new_value

I *really* don't want to make ECs behave like 'locals()'.  That will
make everything way more complicated.

My way of thinking about this: "get_execution_context()" returns you a
shallow copy of the current EC (at least conceptually).  So making any
modifications on it won't affect the current environment.  The only
way to actually apply the modified EC object to the environment will
be its 'run(callable)' method.

Yury


More information about the Python-Dev mailing list