Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Tornado – how can I fix 'URLhandler takes exactly X arguments' error?

Tags:

python

tornado

Here is the error:

TypeError: __init__() takes exactly 1 argument (3 given)
ERROR:root:Exception in callback <tornado.stack_context._StackContextWrapper object at 0x1017d4470>
Traceback (most recent call last):
  File "/Library/Python/2.7/site-packages/tornado-2.4.1-py2.7.egg/tornado/ioloop.py", line  421, in _run_callback
    callback()
  File "/Library/Python/2.7/site-packages/tornado-2.4.1-py2.7.egg/tornado/iostream.py", line 311, in wrapper
    callback(*args)
  File "/Library/Python/2.7/site-packages/tornado-2.4.1-py2.7.egg/tornado/httpserver.py", line 268, in _on_headers
    self.request_callback(self._request)
  File "/Library/Python/2.7/site-packages/tornado-2.4.1-py2.7.egg/tornado/web.py", line 1395, in __call__
    handler = spec.handler_class(self, request, **spec.kwargs)
TypeError: __init__() takes exactly 1 argument (3 given)

And here is the code:

class IndexHandler(tornado.web.RequestHandler):
    def __init__(self):
        self.title = "Welcome!"

    def get(self):
        self.render("index.html", title=self.title)

I've simplified the code down to the above, and I am baffled as to why this is producing that error. I must be doing something wrong, but I have no idea what (3 Arguments passed???...uhmm?)

Note: the title variable is merely the <title>{{ title }}</title> in my index.html template.

I am running Python 2.7.3, in 32 Bit version in order to work with Mysqldb-Python. As you can see, my Tornado version is 2.4.1. I am also running on OSX Lion (if that makes any difference...) Maybe a compatibility issue that is ultimately producing this error?

All help is appreciated in debugging this. Thank you.

like image 872
Friendly King Avatar asked Dec 27 '22 09:12

Friendly King


2 Answers

@Princess of the Universe is right, but maybe this needs a bit of elaboration.

Tornado is going to call __init__ on RequestHandler subclasses with the parameters application, request, **kwargs, so you need to allow for that.

You can do this:

def __init__(self, application, request, **kwargs):
    self.title = "Welcome!"
    super(IndexHandler, self).__init__(application, request, **kwargs)

Which means your IndexHandler class is now initialized with the same signature as the parent class.

However, I would favour the initialize method, which Tornado provides for this purpose:

def initialize(self):
    self.title = "Welcome!"
like image 165
Cole Maclean Avatar answered Jan 19 '23 00:01

Cole Maclean


You are overriding

__init__()

in an inappropriate way.

See

http://www.tornadoweb.org/documentation/web.html

The signature is

class tornado.web.RequestHandler(application, request, **kwargs)[source]

It is clear that you have to provide the same API for the constructor of the derived class.

like image 34
Andreas Jung Avatar answered Jan 18 '23 23:01

Andreas Jung