]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Make HTTPError (both of them) copyable.
authorBen Darnell <ben@bendarnell.com>
Mon, 28 Sep 2015 00:55:09 +0000 (20:55 -0400)
committerBen Darnell <ben@bendarnell.com>
Mon, 28 Sep 2015 00:57:11 +0000 (20:57 -0400)
`Exception.__reduce__` causes copy.copy() to create a new argument
with the arguments from `Exception.__init__`, then overwrite
attributes from the original `__dict__`. This means that copying fails
if there are mandatory arguments that are not passed to `__init__`.

Fixes #1485

tornado/httpclient.py
tornado/test/httpclient_test.py
tornado/test/web_test.py
tornado/web.py

index c2e6862361691251659b185f097ae389a1baa654..9179227b1e3e584cb6c03970765528847f46c242 100644 (file)
@@ -603,9 +603,12 @@ class HTTPError(Exception):
     """
     def __init__(self, code, message=None, response=None):
         self.code = code
-        message = message or httputil.responses.get(code, "Unknown")
+        self.message = message or httputil.responses.get(code, "Unknown")
         self.response = response
-        Exception.__init__(self, "HTTP %d: %s" % (self.code, message))
+        super(HTTPError, self).__init__(code, message, response)
+
+    def __str__(self):
+        return "HTTP %d: %s" % (self.code, self.message)
 
 
 class _RequestProxy(object):
index ecc63e4a49e50f1a685c1ad247978a089c2de8e0..c5738f27feb8e9285fcf46bb1ba63f68b8235f7f 100644 (file)
@@ -5,6 +5,7 @@ from __future__ import absolute_import, division, print_function, with_statement
 import base64
 import binascii
 from contextlib import closing
+import copy
 import functools
 import sys
 import threading
@@ -605,3 +606,15 @@ class HTTPRequestTestCase(unittest.TestCase):
         request = HTTPRequest('http://example.com', if_modified_since=http_date)
         self.assertEqual(request.headers,
                          {'If-Modified-Since': format_timestamp(http_date)})
+
+
+class HTTPErrorTestCase(unittest.TestCase):
+    def test_copy(self):
+        e = HTTPError(403)
+        e2 = copy.copy(e)
+        self.assertIsNot(e, e2)
+        self.assertEqual(e.code, e2.code)
+
+    def test_str(self):
+        e = HTTPError(403)
+        self.assertEqual(str(e), "HTTP 403: Forbidden")
index 829dfe48341cf7f6c04f411bac46ae81b845e8d9..89a54cfab5609d536f6e15ed9e382db18c04c7f2 100644 (file)
@@ -15,6 +15,7 @@ from tornado.web import RequestHandler, authenticated, Application, asynchronous
 
 import binascii
 import contextlib
+import copy
 import datetime
 import email.utils
 import itertools
@@ -2670,3 +2671,12 @@ class RequestSummaryTest(SimpleHandlerTestCase):
     def test_missing_remote_ip(self):
         resp = self.fetch("/")
         self.assertEqual(resp.body, b"GET / (None)")
+
+
+class HTTPErrorTest(unittest.TestCase):
+    def test_copy(self):
+        e = HTTPError(403, reason="Go away")
+        e2 = copy.copy(e)
+        self.assertIsNot(e, e2)
+        self.assertEqual(e.status_code, e2.status_code)
+        self.assertEqual(e.reason, e2.reason)
index dd0df5efd0726327c4ff2d4043f1c8c503363bc0..b33ddbb488c2f6a71c14c9f29630a8a5248e9cfb 100644 (file)
@@ -2063,7 +2063,7 @@ class HTTPError(Exception):
         determined automatically from ``status_code``, but can be used
         to use a non-standard numeric code.
     """
-    def __init__(self, status_code, log_message=None, *args, **kwargs):
+    def __init__(self, status_code=500, log_message=None, *args, **kwargs):
         self.status_code = status_code
         self.log_message = log_message
         self.args = args