summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG1
-rw-r--r--nose/plugins/capture.py2
-rw-r--r--nose/proxy.py23
-rw-r--r--nosetests.12
-rw-r--r--unit_tests/test_result_proxy.py26
5 files changed, 43 insertions, 11 deletions
diff --git a/CHANGELOG b/CHANGELOG
index f6eece5..45c83fe 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -7,6 +7,7 @@
- Fixed problems with SkipTest in Python 3.2 (#389)
- Fixes Xunit plugin to handle non-UTF8 characters (#395)
- Makes --plugins more succinct when there are no options (#235)
+- Fixes mishandling of custom exceptions during failures (#405)
- Fixes capture plugin when exception message contains non-ascii chars (#402)
- Fixed bug in doctest plugin under python 3. Thanks to Thomas Kluyver
for the patch. (#391)
diff --git a/nose/plugins/capture.py b/nose/plugins/capture.py
index 1616132..911215d 100644
--- a/nose/plugins/capture.py
+++ b/nose/plugins/capture.py
@@ -94,7 +94,7 @@ class Capture(Plugin):
# 2.5-
if not hasattr(ev, 'message'):
# 2.4
- msg = ev.args[0]
+ msg = len(ev.args) and ev.args[0] or ''
else:
msg = ev.message
if not isinstance(msg, unicode):
diff --git a/nose/proxy.py b/nose/proxy.py
index 0d31d67..8723290 100644
--- a/nose/proxy.py
+++ b/nose/proxy.py
@@ -85,6 +85,19 @@ class ResultProxy(object):
def __repr__(self):
return repr(self.result)
+ def _prepareErr(self, err):
+ if not isinstance(err[1], Exception):
+ # Turn value back into an Exception (required in Python 3.x).
+ # Plugins do all sorts of crazy things with exception values.
+ try:
+ # The actual exception class is needed for failure detail
+ # but maybe other plugins?
+ value = err[0](err[1])
+ except:
+ value = Exception(err[1])
+ err = (err[0], value, err[2])
+ return err
+
def assertMyTest(self, test):
# The test I was called with must be my .test or my
# .test's .test. or my .test.test's .case
@@ -117,12 +130,9 @@ class ResultProxy(object):
# test.passed is set in result, to account for error classes
formatted = plugins.formatError(self.test, err)
if formatted is not None:
- if isinstance(formatted[1], basestring):
- # Turn it back into an Exception (required in Python 3.x)
- formatted = (formatted[0], Exception(formatted[1]), formatted[2])
err = formatted
plugins.addError(self.test, err)
- self.result.addError(self.test, err)
+ self.result.addError(self.test, self._prepareErr(err))
if not self.result.wasSuccessful() and self.config.stopOnError:
self.shouldStop = True
@@ -136,10 +146,8 @@ class ResultProxy(object):
formatted = plugins.formatFailure(self.test, err)
if formatted is not None:
err = formatted
- if not isinstance(err[1], Exception):
- err = (err[0], err[0](err[1]), err[2])
plugins.addFailure(self.test, err)
- self.result.addFailure(self.test, err)
+ self.result.addFailure(self.test, self._prepareErr(err))
if self.config.stopOnError:
self.shouldStop = True
@@ -181,4 +189,3 @@ class ResultProxy(object):
"""Tests that failed""")
testsRun = proxied_attribute('result', 'testsRun',
"""Number of tests run""")
-
diff --git a/nosetests.1 b/nosetests.1
index d58795b..b26af41 100644
--- a/nosetests.1
+++ b/nosetests.1
@@ -466,5 +466,5 @@ jpellerin+nose@gmail.com
.SH COPYRIGHT
LGPL
-.\" Generated by docutils manpage writer on 2011-03-21 10:52.
+.\" Generated by docutils manpage writer on 2011-03-22 09:55.
.\"
diff --git a/unit_tests/test_result_proxy.py b/unit_tests/test_result_proxy.py
index 9ed1e11..3d6e2ac 100644
--- a/unit_tests/test_result_proxy.py
+++ b/unit_tests/test_result_proxy.py
@@ -159,6 +159,30 @@ class TestResultProxy(unittest.TestCase):
case(proxy)
assert proxy.shouldStop
assert res.shouldStop
-
+
+ def test_coercion_of_custom_exception(self):
+ from nose.case import Test
+
+ class CustomException(Exception):
+ def __init__(self, message, two, three):
+ Exception.__init__(self, message)
+
+ class TC(unittest.TestCase):
+ def runTest(self):
+ pass
+
+ test = TC()
+ case = Test(test)
+ res = unittest.TestResult()
+ try:
+ raise CustomException("the error", 2, 3)
+ except:
+ etype, val, tb = sys.exc_info()
+ val = str(val) # simulate plugin shenanigans
+ proxy = ResultProxy(res, test=case)
+ # Python 3 coercion should happen here without error
+ proxy.addError(test, (etype, val, tb))
+ proxy.addFailure(test, (etype, val, tb))
+
if __name__ == '__main__':
unittest.main()