[Python-Dev] Thoughts on "contexts". PEPs 550, 555, 567, 568

Koos Zevenhoven k7hoven at gmail.com
Sun Jan 14 17:47:22 EST 2018

I'll quickly add a few things below just in case there's anyone that cares.

On Wed, Jan 10, 2018 at 2:06 AM, Koos Zevenhoven <k7hoven at gmail.com> wrote:

> The idea was to always explicitly define the scope of contextvar values. A
> context manager / with statement determined the scope of .set(..)
> operations inside the with statement:
> # Version A:
> cvar.set(1)
> with context_scope():
>     cvar.set(2)
>     assert cvar.get() == 2
> assert cvar.get() == 1
> Then I added the ability to define scopes for different variables
> separately:
> # Version B
> cvar1.set(1)
> cvar2.set(2)
> with context_scope(cvar1):
>     cvar1.set(11)
>     cvar2.set(22)
> assert cvar1.get() == 1
> assert cvar2.get() == 22
> However, in practice, most libraries would wrap __enter__, set and
> __exit__ into another context manager. So maybe one might want to allow
> something like
> # Version C:
> assert cvar.get() == something
> with context_scope(cvar, 2):
>     assert cvar.get() == 2
> assert cvar.get() == something
Note here, that the point is to get a natural way to "undo" changes made to
variables when exiting the scope. Undoing everything that is done within
the defined scope is a very natural way to do it. Undoing individual
.set(..) operations is more problematic.

Features B+C could be essentially implemented as described in PEP 555,
except with context_scope(cvar) being essentially the same as pushing and
popping an empty Assignment object onto the reverse-linked stack. By empty,
I mean a "key-value pair with a missing value". Then any set operations
would replace the topmost assignment object for that variable with a new
key-value pair (or push a new Assignment if there isn't one).

​However, to also get feature A, the stack may have to contain full
mappings instead of assignemnt objects with just one key-value pair.

I hope that clarifies some parts. Otherwise, in terms of semantics, the
same things apply as for PEP 555 when it comes to generator function calls
and next(..) etc., so we'd need to make sure it works well enough for all
use cases. For instance, I'm not quite sure if I have a good enough
understanding of the timeout example that Nathaniel wrote in the PEP 550
discussion to tell what would be required in terms of semantics, but I
suppose it should be fine.

-- Koos

> But this then led to combining "__enter__" and ".set(..)" into
> Assignment.__enter__ -- and "__exit__" into Assignment.__exit__ like this:
> # PEP 555 draft version:
> assert cvar.value == something
> with cvar.assign(1):
>     assert cvar.value == 1
> assert cvar.value == something
> Anyway, given the schedule, I'm not really sure about the best thing to do
> here. In principle, something like in versions A, B and C above could be
> done (I hope the proposal was roughly self-explanatory based on earlier
> discussions). However, at this point, I'd probably need a lot of help to
> make that happen for 3.7.
> -- Koos

+ Koos Zevenhoven + http://twitter.com/k7hoven +
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20180115/9e269e5d/attachment-0001.html>

More information about the Python-Dev mailing list