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