Merge raises_regressions_675327 for Python 2.4 fixes
This commit is contained in:
@@ -65,6 +65,27 @@ else:
|
||||
_u.__doc__ = __u_doc
|
||||
|
||||
|
||||
if sys.version_info > (2, 5):
|
||||
_error_repr = BaseException.__repr__
|
||||
def isbaseexception(exception):
|
||||
"""Return whether exception inherits from BaseException only"""
|
||||
return (isinstance(exception, BaseException)
|
||||
and not isinstance(exception, Exception))
|
||||
else:
|
||||
def _error_repr(exception):
|
||||
"""Format an exception instance as Python 2.5 and later do"""
|
||||
return exception.__class__.__name__ + repr(exception.args)
|
||||
def isbaseexception(exception):
|
||||
"""Return whether exception would inherit from BaseException only
|
||||
|
||||
This approximates the hierarchy in Python 2.5 and later, compare the
|
||||
difference between the diagrams at the bottom of the pages:
|
||||
<http://docs.python.org/release/2.4.4/lib/module-exceptions.html>
|
||||
<http://docs.python.org/release/2.5.4/lib/module-exceptions.html>
|
||||
"""
|
||||
return isinstance(exception, (KeyboardInterrupt, SystemExit))
|
||||
|
||||
|
||||
def unicode_output_stream(stream):
|
||||
"""Get wrapper for given stream that writes any unicode without exception
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@ import operator
|
||||
from pprint import pformat
|
||||
import sys
|
||||
|
||||
from testtools.compat import classtypes, _error_repr, isbaseexception
|
||||
|
||||
|
||||
class Matcher(object):
|
||||
"""A pattern matcher.
|
||||
@@ -359,25 +361,24 @@ class MatchesException(Matcher):
|
||||
"""
|
||||
Matcher.__init__(self)
|
||||
self.expected = exception
|
||||
|
||||
def _expected_type(self):
|
||||
if type(self.expected) is type:
|
||||
return self.expected
|
||||
return type(self.expected)
|
||||
self._is_instance = type(self.expected) not in classtypes()
|
||||
|
||||
def match(self, other):
|
||||
if type(other) != tuple:
|
||||
return Mismatch('%r is not an exc_info tuple' % other)
|
||||
if not issubclass(other[0], self._expected_type()):
|
||||
return Mismatch('%r is not a %r' % (
|
||||
other[0], self._expected_type()))
|
||||
if (type(self.expected) is not type and
|
||||
other[1].args != self.expected.args):
|
||||
return Mismatch('%r has different arguments to %r.' % (
|
||||
other[1], self.expected))
|
||||
expected_class = self.expected
|
||||
if self._is_instance:
|
||||
expected_class = expected_class.__class__
|
||||
if not issubclass(other[0], expected_class):
|
||||
return Mismatch('%r is not a %r' % (other[0], expected_class))
|
||||
if self._is_instance and other[1].args != self.expected.args:
|
||||
return Mismatch('%s has different arguments to %s.' % (
|
||||
_error_repr(other[1]), _error_repr(self.expected)))
|
||||
|
||||
def __str__(self):
|
||||
return "MatchesException(%r)" % self.expected
|
||||
if self._is_instance:
|
||||
return "MatchesException(%s)" % _error_repr(self.expected)
|
||||
return "MatchesException(%s)" % repr(self.expected)
|
||||
|
||||
|
||||
class StartsWith(Matcher):
|
||||
@@ -501,7 +502,6 @@ class Raises(Matcher):
|
||||
# Catch all exceptions: Raises() should be able to match a
|
||||
# KeyboardInterrupt or SystemExit.
|
||||
except:
|
||||
exc_info = sys.exc_info()
|
||||
if self.exception_matcher:
|
||||
mismatch = self.exception_matcher.match(sys.exc_info())
|
||||
if not mismatch:
|
||||
@@ -510,9 +510,9 @@ class Raises(Matcher):
|
||||
mismatch = None
|
||||
# The exception did not match, or no explicit matching logic was
|
||||
# performed. If the exception is a non-user exception (that is, not
|
||||
# a subclass of Exception) then propogate it.
|
||||
if not issubclass(exc_info[0], Exception):
|
||||
raise exc_info[0], exc_info[1], exc_info[2]
|
||||
# a subclass of Exception on Python 2.5+) then propogate it.
|
||||
if isbaseexception(sys.exc_info()[1]):
|
||||
raise
|
||||
return mismatch
|
||||
|
||||
def __str__(self):
|
||||
|
||||
@@ -183,8 +183,7 @@ class TestMatchesExceptionInstanceInterface(TestCase, TestMatchersInterface):
|
||||
MatchesException(Exception('foo')))
|
||||
]
|
||||
describe_examples = [
|
||||
("<type 'exceptions.Exception'> is not a "
|
||||
"<type 'exceptions.ValueError'>",
|
||||
("%r is not a %r" % (Exception, ValueError),
|
||||
error_base_foo,
|
||||
MatchesException(ValueError("foo"))),
|
||||
("ValueError('bar',) has different arguments to ValueError('foo',).",
|
||||
@@ -203,12 +202,11 @@ class TestMatchesExceptionTypeInterface(TestCase, TestMatchersInterface):
|
||||
matches_mismatches = [error_base_foo]
|
||||
|
||||
str_examples = [
|
||||
("MatchesException(<type 'exceptions.Exception'>)",
|
||||
("MatchesException(%r)" % Exception,
|
||||
MatchesException(Exception))
|
||||
]
|
||||
describe_examples = [
|
||||
("<type 'exceptions.Exception'> is not a "
|
||||
"<type 'exceptions.ValueError'>",
|
||||
("%r is not a %r" % (Exception, ValueError),
|
||||
error_base_foo,
|
||||
MatchesException(ValueError)),
|
||||
]
|
||||
@@ -364,7 +362,12 @@ class TestRaisesBaseTypes(TestCase):
|
||||
# Exception, it is propogated.
|
||||
match_keyb = Raises(MatchesException(KeyboardInterrupt))
|
||||
def raise_keyb_from_match():
|
||||
matcher = Raises(MatchesException(Exception))
|
||||
if sys.version_info > (2, 5):
|
||||
matcher = Raises(MatchesException(Exception))
|
||||
else:
|
||||
# On Python 2.4 KeyboardInterrupt is a StandardError subclass
|
||||
# but should propogate from less generic exception matchers
|
||||
matcher = Raises(MatchesException(EnvironmentError))
|
||||
matcher.match(self.raiser)
|
||||
self.assertThat(raise_keyb_from_match, match_keyb)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user