tornado.gen.BadYieldError: yielded unknown object None

B.S picture B.S · May 16, 2016 · Viewed 8.5k times · Source

I`m using Python and Tornado to build basic apps with a jquery UI slider element. My goal is, when users interact with the slider, it will be sent a value to a python function, and the result will be displayed in python console. My custom.js is:

$(function() {
$("#slider-range-max").slider({
    min : 0,
    max : 100,
    slide : function(event, ui) {
        $("#amount").val(ui.value);
        ajax({
              url: "/action",
              data: {parameter:ui.value},
            });
      },
   });
   $("#amount").val($("#slider-range-max").slider("value"));
});

main.py

define("port", default=8888, help="run on the given port", type=int)
class Application(tornado.web.Application):
  def __init__(self):
     handlers = [
        (r"/", AuxHandler),
        (r"/action", MainHandler)
    ]
    settings = {
        "template_path": Settings.TEMPLATE_PATH,
        "static_path": Settings.STATIC_PATH,
    }

    tornado.web.Application.__init__(self, handlers, **settings)

class AuxHandler(tornado.web.RequestHandler):
  def get(self):
    self.render("index.html")

class MainHandler(tornado.web.RequestHandler):
  @asynchronous
  @tornado.gen.coroutine
  def get(self):
    speed = int(self.get_argument("parameter"))
    p=P()
    if speed > 1:
        p.startApp(speed)
    if speed<1:
        p.stopApp()

def main():
  tornado.options.parse_command_line()
  http_server = tornado.httpserver.HTTPServer(Application())
  http_server.listen(options.port)
  tornado.ioloop.IOLoop.instance().start()
if __name__ == "__main__":
  main()

and p.py

@tornado.gen.coroutine
def startApp(self,speed):
    x= yield print(speed)
    while True:
        yield x

In console I receive this:

12
[I 160516 12:47:19 web:1946] 304 GET /action?parameter=12 (::1) 0.00ms
13
[I 160516 12:47:19 web:1946] 304 GET /action?parameter=13 (::1) 15.60ms
14
[E 160516 12:47:19 concurrent:336] Future <tornado.concurrent.Future object at 0x02FAA7D0> exception was never retrieved: Traceback (most recent call last):
  File "C:\Users\home\AppData\Local\Programs\Python\Python35-32\lib\site-packages\tornado\gen.py", line 1014, in run
    yielded = self.gen.throw(*exc_info)
  File "E:\work\python\Example2\p.py", line 11, in startApp
    x= yield print(speed)
  File "C:\Users\home\AppData\Local\Programs\Python\Python35-32\lib\site-packages\tornado\gen.py", line 1008, in run
    value = future.result()
  File "C:\Users\home\AppData\Local\Programs\Python\Python35-32\lib\site-packages\tornado\concurrent.py", line 232, in result
    raise_exc_info(self._exc_info)
  File "<string>", line 3, in raise_exc_info
  File "C:\Users\home\AppData\Local\Programs\Python\Python35-32\lib\site-packages\tornado\gen.py", line 1090, in handle_yield
    self.future = convert_yielded(yielded)
  File "C:\Users\home\AppData\Local\Programs\Python\Python35-32\lib\functools.py", line 743, in wrapper
    return dispatch(args[0].__class__)(*args, **kw)
  File "C:\Users\home\AppData\Local\Programs\Python\Python35-32\lib\site-packages\tornado\gen.py", line 1222, in convert_yielded
    raise BadYieldError("yielded unknown object %r" % (yielded,))
tornado.gen.BadYieldError: yielded unknown object None

I don`t know how to handle this "yielded unknown object None" error or if my approach is correct. Any idea will be very helpfully.

Answer

A. Jesse Jiryu Davis picture A. Jesse Jiryu Davis · May 16, 2016

The exception is from yield print(speed). print returns None, and you can't yield None. You can only yield Futures and similar awaitable objects, typically when you yield the result of calling a coroutine. See Refactoring Tornado Coroutines for a guide to calling coroutines.

If you want to print the value of speed, just do this:

def startApp(self, speed):
    print(speed)