Replace all occurrences of 3-argument raise statements with the
version from testing.py, which works better with 2to3. Closes #508
This commit is contained in:
parent
25f4990043
commit
a9443b7fdc
|
@ -74,6 +74,7 @@ import itertools
|
|||
import sys
|
||||
import threading
|
||||
|
||||
from tornado.util import raise_exc_info
|
||||
|
||||
class _State(threading.local):
|
||||
def __init__(self):
|
||||
|
@ -248,4 +249,4 @@ def _nested(*managers):
|
|||
# Don't rely on sys.exc_info() still containing
|
||||
# the right information. Another exception may
|
||||
# have been raised and caught by an exit method
|
||||
raise exc[0], exc[1], exc[2]
|
||||
raise_exc_info(exc)
|
||||
|
|
|
@ -24,6 +24,7 @@ TEST_MODULES = [
|
|||
'tornado.test.template_test',
|
||||
'tornado.test.testing_test',
|
||||
'tornado.test.twisted_test',
|
||||
'tornado.test.util_test',
|
||||
'tornado.test.web_test',
|
||||
'tornado.test.wsgi_test',
|
||||
]
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
from __future__ import absolute_import, division, with_statement
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from tornado.util import raise_exc_info
|
||||
|
||||
class RaiseExcInfoTest(unittest.TestCase):
|
||||
def test_two_arg_exception(self):
|
||||
# This test would fail on python 3 if raise_exc_info were simply
|
||||
# a three-argument raise statement, because TwoArgException
|
||||
# doesn't have a "copy constructor"
|
||||
class TwoArgException(Exception):
|
||||
def __init__(self, a, b):
|
||||
super(TwoArgException, self).__init__()
|
||||
self.a, self.b = a, b
|
||||
|
||||
try:
|
||||
raise TwoArgException(1, 2)
|
||||
except TwoArgException:
|
||||
exc_info = sys.exc_info()
|
||||
try:
|
||||
raise_exc_info(exc_info)
|
||||
self.fail("didn't get expected exception")
|
||||
except TwoArgException, e:
|
||||
self.assertTrue(e is exc_info[1])
|
|
@ -32,6 +32,7 @@ except ImportError:
|
|||
HTTPServer = None
|
||||
IOLoop = None
|
||||
from tornado.stack_context import StackContext, NullContext
|
||||
from tornado.util import raise_exc_info
|
||||
import contextlib
|
||||
import logging
|
||||
import signal
|
||||
|
@ -142,12 +143,7 @@ class AsyncTestCase(unittest.TestCase):
|
|||
if self.__failure is not None:
|
||||
failure = self.__failure
|
||||
self.__failure = None
|
||||
# 2to3 isn't smart enough to convert three-argument raise
|
||||
# statements correctly in some cases.
|
||||
if isinstance(failure[1], failure[0]):
|
||||
raise failure[1], None, failure[2]
|
||||
else:
|
||||
raise failure[0], failure[1], failure[2]
|
||||
raise_exc_info(failure)
|
||||
|
||||
|
||||
def run(self, result=None):
|
||||
|
|
|
@ -46,6 +46,24 @@ else:
|
|||
bytes_type = str
|
||||
|
||||
|
||||
def raise_exc_info(exc_info):
|
||||
"""Re-raise an exception (with original traceback) from an exc_info tuple.
|
||||
|
||||
The argument is a ``(type, value, traceback)`` tuple as returned by
|
||||
`sys.exc_info`.
|
||||
"""
|
||||
# 2to3 isn't smart enough to convert three-argument raise
|
||||
# statements correctly in some cases.
|
||||
if isinstance(exc_info[1], exc_info[0]):
|
||||
raise exc_info[1], None, exc_info[2]
|
||||
# After 2to3: raise exc_info[1].with_traceback(exc_info[2])
|
||||
else:
|
||||
# I think this branch is only taken for string exceptions,
|
||||
# which were removed in Python 2.6.
|
||||
raise exc_info[0], exc_info[1], exc_info[2]
|
||||
# After 2to3: raise exc_info[0](exc_info[1]).with_traceback(exc_info[2])
|
||||
|
||||
|
||||
def doctests():
|
||||
import doctest
|
||||
return doctest.DocTestSuite()
|
||||
|
|
|
@ -83,7 +83,7 @@ from tornado import locale
|
|||
from tornado import stack_context
|
||||
from tornado import template
|
||||
from tornado.escape import utf8, _unicode
|
||||
from tornado.util import b, bytes_type, import_object, ObjectDict
|
||||
from tornado.util import b, bytes_type, import_object, ObjectDict, raise_exc_info
|
||||
|
||||
try:
|
||||
from io import BytesIO # python 3
|
||||
|
@ -739,7 +739,7 @@ class RequestHandler(object):
|
|||
kwargs['exception'] = exc_info[1]
|
||||
try:
|
||||
# Put the traceback into sys.exc_info()
|
||||
raise exc_info[0], exc_info[1], exc_info[2]
|
||||
raise_exc_info(exc_info)
|
||||
except Exception:
|
||||
self.finish(self.get_error_html(status_code, **kwargs))
|
||||
else:
|
||||
|
@ -984,7 +984,7 @@ class RequestHandler(object):
|
|||
# the exception value instead of the full triple,
|
||||
# so re-raise the exception to ensure that it's in
|
||||
# sys.exc_info()
|
||||
raise type, value, traceback
|
||||
raise_exc_info((type, value, traceback))
|
||||
except Exception:
|
||||
self._handle_request_exception(value)
|
||||
return True
|
||||
|
|
Loading…
Reference in New Issue