[Python-Dev] PEP 567 v2 (original) (raw)

Guido van Rossum guido at python.org
Fri Jan 5 00:42:17 EST 2018


On Thu, Jan 4, 2018 at 7:58 PM, Nathaniel Smith <njs at pobox.com> wrote:

On Thu, Jan 4, 2018 at 6:09 PM, Guido van Rossum <guido at python.org> wrote: > However you've not convinced me that it would be better to make Context > implement the full MutableMapping interface (with _delitem_ always > raising). There are use cases for inspecting Context, e.g. a debugger that > wants to print the Context for some or all suspended tasks. But I don't see > a use case for mutating a Context object that's not the current context, and > when it is the current context, ContextVar.set() is more direct. I also > don't see use cases for other MutableMapping methods like pop() or update(). > (And clear() falls under the same prohibition as delitem().)

I was looking at this again, and I realized there's some confusion. I've been repeating the thing about not wanting to implement delitem too, but actually, I think delitem is not the problem :-). The problem is that we don't want to provide ContextVar.unset() -- that's the operation that adds complication in a PEP 550 world. If you have a stack of Contexts that ContextVar.get() searches, and set/unset are only allowed to mutate the top entry in the stack, then the only way to implement unset() is to do something like contextstack[-1][self] = MISSING, so it can hide any entries below it in the stack. This is extra complication for a feature that it's not clear anyone cares about. (And if it turns out people do care, we could add it later.)

Ah yes, that's it.

A stack of Contexts could have the same semantics as ChainMap, in which delitem deletes the key from the first mapping if present and otherwise raises KeyError even if it is present in a later mapping.

That's enough to implement var.reset(), but not enough to implement arbitrary var.unset().

I'm fine with only having var.reset() and not var.unset().

Deleting entries from individual Context objects shouldn't create conceptual problems. OTOH I don't see how it's useful either. I don't think implementing MutableMapping would actually cause problems, but it's a bunch of extra code to write/test/maintain without any clear use cases.

The implementation would have to maintain cache consistency, but that's not necessarily a big deal, and it only needs to be done in a few places.

But I agree that the a case hasn't been indicated yet. (I like being able to specify ContextVar's behavior using Context as a MutableMapping, but that's not a real use case.)

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

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



More information about the Python-Dev mailing list