On 8 October 2017 at 08:40, Koos Zevenhoven <k7ho...@gmail.com> wrote:
> On Sun, Oct 8, 2017 at 12:16 AM, Nathaniel Smith <n...@pobox.com> wrote: > >> On Oct 7, 2017 12:20, "Koos Zevenhoven" <k7ho...@gmail.com> wrote: >> >> >> Unfortunately, we actually need a third kind of generator semantics, >> something like this: >> >> @contextvars.caller_context >> def genfunc(): >> assert cvar.value is the_value >> yield >> assert cvar.value is the_value >> >> with cvar.assign(the_value): >> gen = genfunc() >> >> next(gen) >> >> with cvar.assign(1234567890): >> try: >> next(gen) >> except StopIteration: >> pass >> >> Nick, Yury and I (and Nathaniel, Guido, Jim, ...?) somehow just narrowly >> missed the reasons for this in discussions related to PEP 550. Perhaps >> because we had mostly been looking at it from an async angle. >> >> >> That's certainly a semantics that one can write down (and it's what the >> very first version of PEP 550 did), >> > > I do remember Yury mentioning that the first draft of PEP 550 captured > something when the generator function was called. I think I started reading > the discussions after that had already been removed, so I don't know > exactly what it was. But I doubt that it was *exactly* the above, because > PEP 550 uses set and get operations instead of "assignment contexts" like > PEP 555 (this one) does. > We didn't forget it, we just don't think it's very useful. However, if you really want those semantics under PEP 550, you can do something like this: def use_creation_context(g): @functools.wraps(g) def make_generator_wrapper(*args, **kwds): gi = g(*args, **kwds) return _GeneratorWithCapturedEC(gi) return make_generator_wrapper class _GeneratorWithCapturedEC: def __init__(self, gi): self._gi = gi self._ec = contextvars.get_execution_context() def __next__(self): return self.send(None) def send(self, value): return contextvars.run_with_execution_context(self.ec, self._gi.send, value) def throw(self, *exc_details): return contextvars.run_with_execution_context(self.ec, self._gi.throw, *exc_details) def close(self): return self.throw(GeneratorExit) Cheers, Nick. -- Nick Coghlan | ncogh...@gmail.com | Brisbane, Australia
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/