Tornado coroutine

python, tornado

Solution

As Lutz Horn pointed out, the `tornado.coroutine` decorator requires that you yield only `Future` objects or certain containers containing `Future` objects. So trying to yield a `str` will raise an error. I think the piece you're missing is that any place inside of a coroutine where you want to call `yield something()`, `something` must either also be a coroutine, or return a `Future`. For example, you could fix your example like this:

from tornado.gen import Return

class HelloHandler(RequestHandler):
    @gen.coroutine
    def get(self):
        x = yield self.do_test()
        self.render('hello.html')

    @gen.coroutine
    def do_test(self):
        raise Return('test')
        # return 'test' # Python 3.3+

Or even this (though generally you shouldn't do it this way):

class HelloHandler(RequestHandler):
    @gen.coroutine
    def get(self):
        x = yield self.do_test()
        self.render('hello.html')

    def do_test(self):
        fut = Future()
        fut.set_result("test")
        return fut

Of course, these are contrived examples; since we're not actually doing anything asynchronous in `do_test`, there's no reason to make it a coroutine. Normally you'd be doing some kind of asynchronous I/O in there. For example:

class HelloHandler(RequestHandler):
    @gen.coroutine
    def get(self):
        x = yield self.do_test()
        self.render('hello.html')

    @gen.coroutine
    def do_test(self):
        http_client = AsyncHTTPClient()
        out = yield http_client.fetch("someurl.com") # fetch is a coroutine
        raise Return(out.body)
        # return out.body # Python 3.3+

Problem

I am trying to learn tornado coroutines, but I have error using below code. ``` Traceback (most recent call last): File "D:\projekty\tornado\env\lib\site-packages\tornado\web.py", line 1334, in _execute result = yield result File "D:\projekty\tornado\env\lib\site-packages\tornado\gen.py", line 628, in run value = future.result() File "D:\projekty\tornado\env\lib\site-packages\tornado\concurrent.py", line 109, in result raise_exc_info(self._exc_info) File "D:\projekty\tornado\env\lib\site-packages\tornado\gen.py", line 631, in run yielded = self.gen.throw(*sys.exc_info()) File "index.py", line 20, in get x = yield 'test' File "D:\projekty\tornado\env\lib\site-packages\tornado\gen.py", line 628, in run value = future.result() File "D:\projekty\tornado\env\lib\site-packages\tornado\concurrent.py", line 111, in result raise self._exception BadYieldError: yielded unknown object 'test' ``` Code: ``` from tornado.ioloop import IOLoop from tornado.web import RequestHandler, Application, url from tornado import gen class HelloHandler(RequestHandler): @gen.coroutine def get(self): x = yield 'test' self.render('hello.html') def make_app(): return Application( [url(r"/", HelloHandler)], debug = True ) def main(): app = make_app() app.listen(8888) IOLoop.instance().start() main() ```

Original source

Related problems