<div dir="ltr">> <span style="line-height:22.1590900421143px">An async procedure call whose refcount reaches zero without </span><span style="line-height:22.1590900421143px">completing simply goes away; finally: blocks are *not* called and there </span><span style="line-height:22.1590900421143px">is *no* warning.</span><div><span style="line-height:22.1590900421143px"><br></span></div><div>I believe OP is looking at these two scenarios:</div><div><br></div>def generator():<br>    try:<br>        yield None<br>        yield None<br>    finally:<br>        print('finally')<br><br><br>gen = generator()<br>gen.send(None)<br>del gen<br>#  prints finally on GC<br><br><br>class Awaitable:<br>    def __await__(self):<br>        return self<br>    def __next__(self):<br>        return self<br><br><br>async def coroutine():<br>    try:<br>        await Awaitable()<br>        await Awaitable()<br>    finally:<br>        print('finally')<br><br><br>coro = coroutine()<br>coro.send(None)<br>del coro<br># prints finally on GC<div><br></div><div>I don't see any difference in the behaviour between the two. My guess is that OP's code is not hitting a zero refcount.</div></div><br><div class="gmail_quote"><div dir="ltr">On Sat, Dec 19, 2015 at 5:00 PM Gustavo Carneiro <<a href="mailto:gjcarneiro@gmail.com">gjcarneiro@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">I tried to reproduce the problem you describe, but failed.  Here's my test program (forgive the awful tab indentation, long story):<div><br></div><div>--------------</div><div><div><font face="monospace, monospace">import asyncio</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">async def foo():</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">   </span>print("resource acquire")</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">       </span>try:</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">              </span>await asyncio.sleep(100)</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">  </span>finally:</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">          </span>print("resource release")</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">async def main():</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">        </span>task = asyncio.ensure_future(foo())</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">       </span>print("task created")</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">   </span>await asyncio.sleep(0)</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">    </span>print("about to cancel task")</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">   </span>task.cancel()</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">     </span>print("task cancelled, about to wait for it")</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">   </span>try:</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">              </span>await task</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">        </span>except asyncio.CancelledError:</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">            </span>pass</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">      </span>print("waited for cancelled task")</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">if __name__ == '__main__':</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">      </span>loop = asyncio.get_event_loop()</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">   </span>loop.run_until_complete(main())</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">   </span>loop.close()</font></div></div><div>-----------</div><div><br></div><div>I get this output:</div><div><br></div><div>----------------</div><div><div><font face="monospace, monospace">10:54:28 ~/Documents$ python3.5 foo.py </font></div><div><font face="monospace, monospace">task created</font></div><div><font face="monospace, monospace">resource acquire</font></div><div><font face="monospace, monospace">about to cancel task</font></div><div><font face="monospace, monospace">task cancelled, about to wait for it</font></div><div><font face="monospace, monospace">resource release</font></div><div><font face="monospace, monospace">waited for cancelled task</font></div></div><div>----------------</div><div><br></div><div>Which seems to indicate that the finally clause is correctly executed when the task is waited for, after being cancelled.</div><div><br></div><div>But maybe I completely misunderstood your problem...</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote"></div></div><div class="gmail_extra"><div class="gmail_quote">On 19 December 2015 at 21:40, Matthias Urlichs <span dir="ltr"><<a href="mailto:matthias@urlichs.de" target="_blank">matthias@urlichs.de</a>></span> wrote:<br></div></div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span>On 19.12.2015 20:25, Guido van Rossum wrote:<br>
> Perhaps you can add a check for a simple boolean 'stop' flag to your<br>
> condition check, and when you want to stop the loop you set that flag<br>
> and then call notify() on the condition. Then you can follow the<br>
> standard condition variable protocol instead of all this nonsense. :-)<br>
</span>Your example does not work.<br>
<span><br>
>    def stop_it(self):<br>
>        self.stopped = True<br>
>        self.uptodate.notify()<br>
<br>
</span>self.uptodate needs to be locked before I can call .notify() on it.<br>
Creating a new task just for that seems like overkill, and I'd have to<br>
add a generation counter to prevent a race condition. Doable, but ugly.<br>
<br>
However, this doesn't fix the generic problem; Condition.wait() was just<br>
what bit me today.<br>
When a non-async generator goes out of scope, its finally: blocks will<br>
execute. An async procedure call whose refcount reaches zero without<br>
completing simply goes away; finally: blocks are *not* called and there<br>
is *no* warning.<br>
I consider that to be a bug.<br>
<br>
--<br>
-- Matthias Urlichs<br>
<span><br>
_______________________________________________<br>
Python-Dev mailing list<br>
<a href="mailto:Python-Dev@python.org" target="_blank">Python-Dev@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-dev" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-dev</a><br>
</span></blockquote></div></div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Unsubscribe: <a href="https://mail.python.org/mailman/options/python-dev/gjcarneiro%40gmail.com" rel="noreferrer" target="_blank">https://mail.python.org/mailman/options/python-dev/gjcarneiro%40gmail.com</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div><div dir="ltr">Gustavo J. A. M. Carneiro<div>Gambit Research<br>"The universe is always one step beyond logic." -- Frank Herbert</div></div></div>
</div>
_______________________________________________<br>
Python-Dev mailing list<br>
<a href="mailto:Python-Dev@python.org" target="_blank">Python-Dev@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-dev" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-dev</a><br>
Unsubscribe: <a href="https://mail.python.org/mailman/options/python-dev/kevinjacobconway%40gmail.com" rel="noreferrer" target="_blank">https://mail.python.org/mailman/options/python-dev/kevinjacobconway%40gmail.com</a><br>
</blockquote></div>