[Python-Dev] PEP 567 v2

Nathaniel Smith njs at pobox.com
Tue Jan 9 02:18:01 EST 2018

On Thu, Jan 4, 2018 at 9:42 PM, Guido van Rossum <guido at python.org> wrote:
> On Thu, Jan 4, 2018 at 7:58 PM, Nathaniel Smith <njs at pobox.com> wrote:
>> This does make me think that I should write up a short PEP for
>> extending PEP 567 to add context lookup, PEP 550 style: it can start
>> out in Status: deferred and then we can debate it properly before 3.8,
>> but at least having the roadmap written down now would make it easier
>> to catch these details. (And it might also help address Paul's
>> reasonable complaint about "unstated requirements".)
> Anything that will help us kill a 550-pound gorilla sounds good to me. :-)
> It might indeed be pretty short if we follow the lead of ChainMap (even
> using a different API than MutableMapping to mutate it). Maybe
> copy_context() would map to new_child()? Using ChainMap as a model we might
> even avoid the confusion between Lo[gi]calContext and ExecutionContext which
> was the nail in PEP 550's coffin. The LC associated with a generator in PEP
> 550 would be akin to a loose dict which can be pushed on top of a ChainMap
> using cm = cm.new_child(<dict>). (Always taking for granted that instead of
> an actual dict we'd use some specialized mutable object implementing the
> Mapping protocol and a custom mutation protocol so it can maintain
> ContextVar cache consistency.)

The approach I took in PEP 568 is even simpler, I think. The PEP is a
few pages long because I wanted to be exhaustive to make sure we
weren't missing any details, but the tl;dr is: The ChainMap lives
entirely inside the threadstate, so there's no need to create a LC/EC
distinction -- users just see Contexts, or there's the one stack
introspection API, get_context_stack(), which returns a List[Context].
Instead of messing with new_child, copy_context is just
Context(dict(chain_map)) -- i.e., it creates a flattened copy of the
current mapping. (If we used new_child, then we'd have to have a way
to return a ChainMap, reintroducing the LC/EC mess. Plus it would
allow for changes to the Context's inside one ChainMap to "leak" into
the child or vice-versa.) And Context push/pop is just push/pop on the
threadstate's ChainMap's '.maps' attribute.


Nathaniel J. Smith -- https://vorpus.org

More information about the Python-Dev mailing list