<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 class="" style="white-space:pre"> </span>print("resource acquire")</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>try:</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>await asyncio.sleep(100)</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>finally:</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </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 class="" style="white-space:pre"> </span>task = asyncio.ensure_future(foo())</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>print("task created")</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>await asyncio.sleep(0)</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>print("about to cancel task")</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>task.cancel()</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>print("task cancelled, about to wait for it")</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>try:</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>await task</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>except asyncio.CancelledError:</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>pass</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </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 class="" style="white-space:pre"> </span>loop = asyncio.get_event_loop()</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>loop.run_until_complete(main())</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </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">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><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">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 class=""><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 class=""><br>
_______________________________________________<br>
Python-Dev mailing list<br>
<a href="mailto:Python-Dev@python.org">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>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 class="gmail_signature"><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>