tornadoweb / tornado

Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed.
http://www.tornadoweb.org/
Apache License 2.0
21.77k stars 5.51k forks source link

Fix pickling of `httpclient.HTTPError` subclasses and `web.HTTPError` #3439

Open andersk opened 3 weeks ago

andersk commented 3 weeks ago

The args member variable is set by BaseException.__new__ and used by BaseException.__reduce__ for pickling. To avoid interfering with it, we need to avoid calling BaseException.__init__ from classes that have subclasses with incompatible constructors, and rename our own tornado.web.HTTPError.args member.

>>> pickle.loads(pickle.dumps(tornado.simple_httpclient.HTTPTimeoutError("message")))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: HTTPTimeoutError.__init__() takes 2 positional arguments but 4 were given
>>> str(pickle.loads(pickle.dumps(tornado.web.HTTPError(500, "%s", "foo"))))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/anders/python/tornado/tornado/web.py", line 2488, in __str__
    return message + " (" + (self.log_message % self.args) + ")"
                             ~~~~~~~~~~~~~~~~~^~~~~~~~~~~
TypeError: not enough arguments for format string