I think the problem is that it's hard to tell the difference between these two:
async def sleep1(): await asyncio.sleep(1) def sleep1(): return Task(asyncio.sleep(1)) since both may be documented as being a "coroutine" but the latter references the loop when you calls it, while the former only references the loop when it's scheduled/awaited (because asyncio.sleep() is a generator). And this is in turn because with a generator or coroutine, the body doesn't execute when you call it -- but with something that returns a Future (or Task), the body *does* execute in the call's context. We should strive to make more things coroutines (though I'm not sure how to turn gather() into a coroutine -- I recall it was complicated to write, with the variant behaviors and possible timeouts or cancellations). On Tue, Nov 8, 2016 at 10:51 AM, Yury Selivanov <yseliva...@gmail.com> wrote: > Martin, > > > On Nov 8, 2016, at 1:39 PM, Martin Richard <mart...@martiusweb.net> > wrote: > > > > I fully agree about coroutines, one thing though: I often see functions > returning awaitables documented as "coroutines", and I see that as a > problem since it gives the assumption that it won't be executed until > processed by the loop. > > > > For instance, asynctest can't identify them as coroutines, they won't > get mocked correctly: it used to be the case with aiohttp (until the > wrapper class was added to the asyncio.COROUTINE_TYPES list for python > 3.5): https://github.com/Martiusweb/asynctest/issues/23 > > > > In asyncio, it is still the case from some primitives of the loop > (run_in_executor(), getaddrinfo()), since they are methods of the loop > instance, I guess it's fine. > > I re-read this email a few times, but I still don’t fully understand the > problem you’re trying to describe. Maybe you can describe it in more > detail? > > Yury > > -- --Guido van Rossum (python.org/~guido)