In Tornado 4.1 [1], I've added a functools.singledispatch-based registry for objects that can be yielded in coroutines. This allows for Future-like objects from different frameworks to be mixed seamlessly in the same coroutine (We currently have support for tornado.concurrent.Future, concurrent.futures.Future, asyncio.Future[2], and twisted.internet.defer.Deferred)
I'd like to suggest that asyncio add something similar to facilitate the use of libraries from different frameworks in the same coroutine, not just sharing the same event loop. It would be a pretty simple change: just call a function decorated with @singledispatch (whose default implementation is the identity function) before handling the result in Task._step. I've included a simple example of a hybrid tornado/asyncio coroutine below. -Ben [1] Currently in beta, installable with `pip install https://github.com/tornadoweb/tornado/archive/v4.1.0b1.zip` [2] The future objects are all similar enough that they don't really need this level of abstraction, but they serve as a proof of concept. # requirements: # python3.4 (for 3.3, add asyncio and singledispatch) # aiohttp # https://github.com/tornadoweb/tornado/archive/v4.1.0b1.zip import aiohttp import asyncio import tornado.gen import tornado.httpclient import tornado.ioloop import tornado.platform.asyncio @tornado.gen.coroutine def main(): t_client = tornado.httpclient.AsyncHTTPClient() t_response = yield t_client.fetch('http://www.google.com') print('tornado: read %d bytes with status code %d' % (len(t_response.body), t_response.code)) a_response = yield from aiohttp.request('GET', 'http://www.google.com') a_body = yield from a_response.read() print('aiohttp: read %d bytes with status code %d' % (len(a_body), a_response.status)) # Alternate python2-compatible syntax a_response2 = yield asyncio.async(aiohttp.request('GET', ' http://www.google.com')) a_body2 = yield asyncio.async(a_response2.read()) print('aiohttp2: read %d bytes with status code %d' % (len(a_body2), a_response2.status)) if __name__ == '__main__': tornado.ioloop.IOLoop.configure(tornado.platform.asyncio.AsyncIOMainLoop) tornado.ioloop.IOLoop.current().run_sync(main)
