Does setting PYTHONASYNCIODEBUG=1 complain about these mistakes? If so, I think we're good; if not, we should add some checks if loop._debug is true.
On Wed, Dec 9, 2015 at 5:30 AM, Vincent Michel <vxgmic...@gmail.com> wrote: > Hi all, > > I recently realized that when a future is yielded, `Task._wakeup` is added > as a done callback without checking that their loops are the same. That > means that `Task._wakeup` might end up being called in the future loop > instead of its own loop, which seems wrong. Is there a reason not to check > this in `Task._step`? > > def _step(self, exc=None): > [...] > if isinstance(result, futures.Future): > if self._loop is not result._loop: > > > > > > > > > self._loop.call_soon( > self._step, > RuntimeError( > 'a future using a different loop has been yielded') > > A common mistake is to forget the `loop` argument when using a different > loop than the one provided by `asyncio.get_event_loop`: > > async def coro(): > await asyncio.sleep(3) > loop = asyncio.new_event_loop() > loop.run_until_complete(coro()) > > This code blocks forever, since the `sleep` is scheduled in a different > event loop. It can be quite painful to debug, especially for someone > experimenting with asyncio for the first time. But with the modification > proposed above, this example would raise the following exception instead: > > RuntimeError: a future using a different loop has been yielded > > Part of the problem is also that one might expect the current loop to be > used, while it actually defaults to the result of `asyncio.get_event_loop`. > > Has this issue been discussed already? > > Thanks. > > > > -- --Guido van Rossum (python.org/~guido)