Thanks for the pointers... The issue I was trying to solve is making sure
things get cleaned up properly when running unit tests using aiohttp
(https://github.com/KeepSafe/aiohttp)
I'm using unittest, with setUp() and tearDown() looking something like this:
def setUp(self):
self.loop = asyncio.new_event_loop()
asyncio.set_event_loop(None)
def tearDown(self):
self.client.logout()
# self.loop.run_until_complete(asyncio.sleep(0, loop=self.loop))
self.loop.stop()
self.loop.close()
def test_aiohttp_client(self):
self.client = HttpTestClient(loop=self.loop)
self.loop.run_until_complete(self.client.doSomething())
During the test, aiohttp registers a callback using loop.call_soon() that
needs to be called to properly to close down sockets etc. Without the
commented-out call to asyncio.sleep() in tearDown(), that callback is not
called and I'm getting ResourceWarning messages. Calling asyncio.sleep() in
tearDown() solved most of those issues, but I'm changing it to loop.stop()
followed by loop.run_forever() as it's certainly cleaner. Thanks!
Den tisdagen den 1:e april 2014 kl. 13:55:10 UTC+11 skrev Guido van Rossum:
>
> On Mon, Mar 31, 2014 at 6:03 PM, Lars Andersson <[email protected]<javascript:>
> > wrote:
>
>>
>> Ok, I see. Maybe the stop function should raise an exception if called on
>> a loop that is not running?
>>
>
> I think it's too late for that, it already has assigned semantics in that
> case. To understand those, look at the code for stop():
> http://code.google.com/p/tulip/source/browse/asyncio/base_events.py#210 .
>
>>
>> Calling async.sleep(0) to flush remaining callbacks on a loop about to be
>> closed works for me now,
>>
>
> Yeah, I think that's skating on thin ice. :-)
>
>
>> but maybe something like
>>
>> loop.flush()
>>
>> that runs the loop and calls all remaining callbacks() would be more
>> clear.
>>
>
> I recommend that you try to restructure your program a little bit and then
> you won't have this problem at all. Have you looked at some of the examples
> in the Tulip example directory?
> http://code.google.com/p/tulip/source/browse/examples/
>
> But you can probably implement flush() yourself as follows:
>
> loop.stop()
> loop.run_forever()
>
>
>> Or, to avoid bloating the API, why not let loop.run_until_complete()
>> accept an empty argument list and behave in the same way?
>>
>> Anyway, thanks for the clarification. Adding something along the lines of
>> what you just wrote to the module docs would probably make it less likely
>> to be misunderstood.
>>
>
> I'm sorry the docs didn't guide you in the right direction. Unfortunately
> I don't see the blind spots in the docs any more since I already know what
> the library does. :-( I'll try to think of a way to improve them based on
> your feedback.
>
>
>>
>>
>> Den tisdagen den 1:e april 2014 kl. 11:28:51 UTC+11 skrev Guido van
>> Rossum:
>>>
>>> I think there may be some ambiguity in the wording. :-(
>>>
>>> The intention is that you should call stop() from *inside* the loop,
>>> i.e. when it is already running. It seems you interpreted the docs to mean
>>> that stop() itself runs the remaining callbacks. That is not the case -- it
>>> merely tells a running loop to stop.
>>>
>>> How could we have made this clearer in the docs?
>>>
>>>
>>> On Mon, Mar 31, 2014 at 4:55 PM, Lars Andersson <[email protected]>wrote:
>>>
>>>> Hi,
>>>>
>>>> I'm a bit confused by the behaviour of loop.stop()
>>>>
>>>> The asyncio docs states that:
>>>>
>>>> "Every callback scheduled before
>>>> stop()<https://docs.python.org/dev/library/asyncio-eventloop.html#asyncio.BaseEventLoop.stop>
>>>> is
>>>> called will run."
>>>>
>>>> Still, when running asyncio from python3.4 on OS X 10.9.2, the
>>>> following program does not end up calling the callback() function:
>>>>
>>>> import asyncio
>>>>
>>>> def callback():
>>>> print("CALLBACK CALLED")
>>>>
>>>> loop = asyncio.get_event_loop()
>>>> loop.call_soon(callback)
>>>> #loop.run_until_complete(asyncio.sleep(0))
>>>> loop.stop()
>>>>
>>>>
>>>> Uncommenting the line calling asyncio.sleep(0) seems to fix the
>>>> problem, and the callback is actually called. Is this expected behaviour?
>>>>
>>>>
>>>
>>>
>>> --
>>> --Guido van Rossum (python.org/~guido)
>>>
>>
>
>
> --
> --Guido van Rossum (python.org/~guido)
>