Merge raises_regressions_675327 for Python 2.4 fixes

This commit is contained in:
Martin
2010-12-10 23:54:51 +00:00
3 changed files with 47 additions and 23 deletions

View File

@@ -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

View File

@@ -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):

View File

@@ -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)