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() ```