<div dir="ltr"><div class="gmail_default" style="font-family:monospace,monospace"><span style="font-family:arial,sans-serif">On Tue, Oct 10, 2017 at 5:40 PM, Yury Selivanov </span><span dir="ltr" style="font-family:arial,sans-serif"><<a href="mailto:yselivanov.ml@gmail.com" target="_blank">yselivanov.ml@gmail.com</a>></span><span style="font-family:arial,sans-serif"> wrote:</span><br></div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="gmail-">On Tue, Oct 10, 2017 at 8:34 AM, Koos Zevenhoven <<a href="mailto:k7hoven@gmail.com">k7hoven@gmail.com</a>> wrote:<br>
> On Tue, Oct 10, 2017 at 4:22 AM, Yury Selivanov <<a href="mailto:yselivanov.ml@gmail.com">yselivanov.ml@gmail.com</a>><br>
> wrote:<br>
>><br>
>> On Mon, Oct 9, 2017 at 8:37 PM, Koos Zevenhoven <<a href="mailto:k7hoven@gmail.com">k7hoven@gmail.com</a>> wrote:<br>
>> > You can cause unbound growth in PEP 550 too. All you have to do is nest<br>
>> > an<br>
>> > unbounded number of generators.<br>
>><br>
>> You can only nest up to 'sys.get_recursion_limit()' number of generators.<br>
>><br>
>> With PEP 555 you can do:<br>
>><br>
>>   while True:<br>
>>     context_var.assign(42).__<wbr>enter__()<br>
>><br>
><br>
> Well, in PEP 550, you can explicitly stack an unbounded number of<br>
> LogicalContexts in a while True loop.<br>
<br>
</span>No, you can't. PEP 550 doesn't have APIs to "stack ... LogicalContexts".<br>
<span class="gmail-"><br></span></blockquote><div><br></div><div><div class="gmail_default"><font face="monospace, monospace">​​</font><div class="gmail_default" style="display:inline"><font face="monospace, monospace">​That's ridiculous. Quoting PEP 550: "​</font></div><font face="monospace, monospace">The contextvars.run_with_logical_context(lc: LogicalContext, func, *args, **kwargs) function, which runs func with the provided logical context on top of the current execution context.<div class="gmail_default" style="display:inline">​"​</div></font></div></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="gmail-">
> Or you can run out of memory using<br>
> plain lists even faster:<br>
><br>
> l = [42]<br>
><br>
> while True:<br>
>     l *= 2 # ensure exponential blow-up<br>
><br>
> I don't see why your example with context_var.assign(42).__<wbr>enter__() would<br>
> be any more likely.<br>
<br>
</span>Of course you can write broken code. The point is that contexts work<br>
like scopes/mappings, and it's counter-intuitive that setting a<br>
variable with 'cv.assign(..).__enter__()' will break the world.  If a<br>
naive user tries to convert their existing decimal-like API to use<br>
your PEP, everything would work initially, but then blow up in<br>
production.<br>
<br></blockquote><div><br></div><div><div class="gmail_default" style="font-family:monospace,monospace">​The docs will tell them what to do. You can pass a context argument down the call chain. You don't "set" context arguments!​ That's why I'm changing to "context argument", and I've said this many times now.</div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
[..]<br>
<span class="gmail-">> Really, it was my mistake to ever make you think that<br>
> context_var.assign(42).__<wbr>enter__() can be compared to .set(42) in PEP 550.<br>
> I'll say it once more: PEP 555 context arguments have no equivalent of the<br>
> PEP-550 .set(..).<br>
<br>
</span>Any API exposing a context manager should have an alternative<br>
try..finally API.  In your case it's<br>
'context_var.assign(42).__<wbr>enter__()'.  'With' statements are sugar in<br>
Python.  It's unprecedented to design API solely around them.<br>
<span class="gmail-"><br>
<div class="gmail_default" style="font-family:monospace,monospace;display:inline">​[..]</div></span></blockquote><div> </div><div><div class="gmail_default" style="font-family:monospace,monospace;display:inline">​Yury writes:​</div> </div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div class="gmail-h5">
>> >> That question was also hand-waved by you:<br>
>> >> numpy and decimal will have to come up with new/better APIs to use PEP<br>
>> >> 555.  Well, that's just not good enough.<br>
>> ><br>
>> ><br></div></div></blockquote><div> </div><div><div class="gmail_default" style="font-family:monospace,monospace;display:inline">​Koos writes:​</div> <br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div class="gmail-h5">
>> > What part of my explanation of this are you unhappy with? For instance,<br>
>> > the<br>
>> > 12th (I think) email in this thread, which is my response to Nathaniel.<br>
>> > Could you reply to that and tell us your concern?<br>
>><br>
>> I'm sorry, I'm not going to find some 12th email in some thread.  I<br>
>> stated in this thread the following: not being able to use PEP 555 to<br>
>> fix *existing* decimal & numpy APIs is not good enough.  And decimal &<br>
>> numpy is only one example, there's tons of code out there that can<br>
>> benefit from its APIs to be fixed to support for async code in Python<br>
>> 3.7.<br>
>><br>
><br>
> Well, anyone interested can read that 12th email in this thread. In short,<br>
> my recommendation for libraries would be as follows:<br>
><br>
> * If the library does not provide a context manager yet, they should add<br>
> one, using PEP 555. That will then work nicely in coroutines and generators.<br>
><br>
> * If the library does have a context manager, implement it using PEP 555. Or<br>
> to be safe, add a new API function, so behavior in existing async code won't<br>
> change.<br>
><br>
> * If the library needs to support some kind of set_state(..) operation,<br>
> implement it by getting the state using a PEP 555 context argument and<br>
> mutating its contents.<br>
><br>
> * Fall back to thread-local storage if no context argument is present or if<br>
> the Python version does not support context arguments.<br>
<br>
</div></div>The last bullet point is the problem.  Everybody is saying to you that<br>
it's not acceptable.  It's your choice to ignore that.<br>
<br></blockquote><div><br></div><div><div class="gmail_default" style="font-family:monospace,monospace">​Never has anyone told me that that is not acceptable. Please stop that. </div></div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
[..]<br>
<span class="gmail-">>> What do you mean by "just sweep it under the carpet"?  Capturing the<br>
>> context at the moment of generators creation is a design choice with<br>
>> some consequences (that I illustrated in my previous email).  There<br>
>> are cons and pros of doing that.<br>
>><br>
><br>
> "Capturing the context at generator creation" and "isolating generators<br>
> completely" are two different things.<br>
><br>
> I've described pros of the former. The latter has no pros that I'm aware of,<br>
> except if sweeping things under the carpet is considered as one.<br>
><br>
> Yes, the latter works in some use cases, but in others it does not. For<br>
> instance, if an async framework wants to make some information available<br>
> throughout the async task. If you isolate generators, then async programmers<br>
> will have to avoid generators, because they don't have access to the<br>
> information the framework is trying to provide.<br>
<br>
</span>This is plain incorrect. Please read PEP 550v1 before continuing the<br>
discussion about it.<br>
<span class="gmail-"><br></span></blockquote><div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">I thought you wrote that they are isolated both ways. Maybe there's a misunderstanding. I found your "New PEP 550" email in the archives in some thread. That might be v1, but the figure supposedly explaining this part is missing. Whatever. This is not about PEP 550v1 anyway.</div></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="gmail-">
> Also, if you refactor your<br>
> generator into subgenerators using `yield from`, the subgenerators will not<br>
> see the context set by the outer generator.<br>
<br>
</span>Subgenerators see the context changes in the outer generator in all<br>
versions of PEP 550.<br>
<br>
The point you didn't like is that in all versions of PEP 550<br>
subgenerators could not leak any context to the outer generator.<br>
Please don't confuse these two.<br></blockquote><div><br></div><div class="gmail_default" style="font-family:monospace,monospace">​That's a different thing. But it's not exactly right: I didn't like the fact that ​some subroutines (functions, coroutines, (async) generators) leak context and some don't.</div></div><div class="gmail_default" style="font-family:monospace,monospace">​</div><div class="gmail_default" style="font-family:monospace,monospace">––Koos</div><br clear="all"><div><br></div>-- <br><div class="gmail_signature">+ Koos Zevenhoven + <a href="http://twitter.com/k7hoven" target="_blank">http://twitter.com/k7hoven</a> +</div>
</div></div>