<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 8 October 2017 at 08:40, Koos Zevenhoven <span dir="ltr"><<a href="mailto:k7hoven@gmail.com" target="_blank">k7hoven@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><span class="gmail-"><div style="font-family:monospace,monospace"><span style="font-family:arial,sans-serif">On Sun, Oct 8, 2017 at 12:16 AM, Nathaniel Smith </span><span dir="ltr" style="font-family:arial,sans-serif"><<a href="mailto:njs@pobox.com" target="_blank">njs@pobox.com</a>></span><span style="font-family:arial,sans-serif"> wrote:</span><br></div></span><div class="gmail_extra"><div class="gmail_quote"><span class="gmail-"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto"><span class="gmail-m_-8202751580970511457gmail-"><div class="gmail_extra" dir="auto"><div class="gmail_quote">On Oct 7, 2017 12:20, "Koos Zevenhoven" <<a href="mailto:k7hoven@gmail.com" target="_blank">k7hoven@gmail.com</a>> wrote:<blockquote class="gmail-m_-8202751580970511457gmail-m_-8935789036438109007quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div class="gmail-m_-8202751580970511457gmail-m_-8935789036438109007elided-text"><div><br></div></div><div><div style="font-family:monospace,monospace">​Unfortunately, we actually need a third kind of generator semantics, something like this:</div><div style="font-family:monospace,monospace"><br></div><div style="font-family:monospace,monospace">@​contextvars.caller_context</div><div style="font-family:monospace,monospace">def genfunc():</div><div style="font-family:monospace,monospace">    assert cvar.value is the_value</div><div style="font-family:monospace,monospace">    yield</div><div style="font-family:monospace,monospace">    assert cvar.value is the_value</div><div style="font-family:monospace,monospace"><br></div><div style="font-family:monospace,monospace">with cvar.assign(the_value):</div><div style="font-family:monospace,monospace">    gen = genfunc()</div><div style="font-family:monospace,monospace"><br></div><div style="font-family:monospace,monospace">next(gen)</div><div style="font-family:monospace,monospace"><br></div><div style="font-family:monospace,monospace">with cvar.assign(1234567890):</div><div style="font-family:monospace,monospace">    try:</div><div style="font-family:monospace,monospace">        next(gen)</div><div style="font-family:monospace,monospace">    except StopIteration:</div><div style="font-family:monospace,monospace">        pass</div><div style="font-family:monospace,monospace"><br></div><div style="font-family:monospace,monospace">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.</div></div></div></div></div></blockquote></div></div><div dir="auto"><br></div></span><div dir="auto">That's certainly a semantics that one can write down (and it's what the very first version of PEP 550 did), </div></div></blockquote><div><br></div></span><div><div style="font-family:monospace,monospace">​​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. ​​</div></div></div></div></div></blockquote><div><br></div><div>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:</div><div><br></div><div>    def use_creation_context(g):</div>        @functools.wraps(g)<div>        def make_generator_wrapper(*args, **kwds):</div><div>            gi = g(*args, **kwds)</div><div>            return _GeneratorWithCapturedEC(gi)</div><div>        return make_generator_wrapper</div><div><br></div><div>    class _GeneratorWithCapturedEC:</div><div>        def __init__(self, gi):</div><div>            self._gi = gi</div><div><div>            self._ec = contextvars.get_execution_context()</div><div>        def __next__(self):</div><div>            return self.send(None)<br></div><div>        def send(self, value):<div><div><div>            return contextvars.run_with_execution_context(<a href="http://self.ec">self.ec</a>, self._gi.send, value)<br></div><div></div>        def throw(self, *exc_details):</div><div>            return contextvars.run_with_execution_context(<a href="http://self.ec">self.ec</a>, self._gi.throw, *exc_details)</div><div></div></div></div></div><div><div>        def close(self):</div><div>            return self.throw(GeneratorExit)</div><div><br></div></div><div>Cheers,</div><div>Nick.<br></div></div><br>-- <br><div class="gmail_signature">Nick Coghlan   |   <a href="mailto:ncoghlan@gmail.com" target="_blank">ncoghlan@gmail.com</a>   |   Brisbane, Australia</div>
</div></div>