Kaydet (Commit) dae1a6a4 authored tarafından Antoine Pitrou's avatar Antoine Pitrou

Issue #2153: modernize coding style of unittest.py, remove obsolete compatibility stuff.

Patch by Virgil Dupras.
üst fd9633ed
...@@ -67,16 +67,6 @@ __all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases']) ...@@ -67,16 +67,6 @@ __all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases'])
############################################################################## ##############################################################################
# Backward compatibility # Backward compatibility
############################################################################## ##############################################################################
if sys.version_info[:2] < (2, 2):
def isinstance(obj, clsinfo):
import __builtin__
if type(clsinfo) in (tuple, list):
for cls in clsinfo:
if cls is type: cls = types.ClassType
if __builtin__.isinstance(obj, cls):
return 1
return 0
else: return __builtin__.isinstance(obj, clsinfo)
def _CmpToKey(mycmp): def _CmpToKey(mycmp):
'Convert a cmp= function into a key= function' 'Convert a cmp= function into a key= function'
...@@ -91,15 +81,12 @@ def _CmpToKey(mycmp): ...@@ -91,15 +81,12 @@ def _CmpToKey(mycmp):
# Test framework core # Test framework core
############################################################################## ##############################################################################
# All classes defined herein are 'new-style' classes, allowing use of 'super()'
__metaclass__ = type
def _strclass(cls): def _strclass(cls):
return "%s.%s" % (cls.__module__, cls.__name__) return "%s.%s" % (cls.__module__, cls.__name__)
__unittest = 1 __unittest = 1
class TestResult: class TestResult(object):
"""Holder for test result information. """Holder for test result information.
Test results are automatically managed by the TestCase and TestSuite Test results are automatically managed by the TestCase and TestSuite
...@@ -174,7 +161,7 @@ class TestResult: ...@@ -174,7 +161,7 @@ class TestResult:
(_strclass(self.__class__), self.testsRun, len(self.errors), (_strclass(self.__class__), self.testsRun, len(self.errors),
len(self.failures)) len(self.failures))
class AssertRaisesContext: class AssertRaisesContext(object):
def __init__(self, expected, test_case): def __init__(self, expected, test_case):
self.expected = expected self.expected = expected
self.failureException = test_case.failureException self.failureException = test_case.failureException
...@@ -193,7 +180,7 @@ class AssertRaisesContext: ...@@ -193,7 +180,7 @@ class AssertRaisesContext:
# Let unexpected exceptions skip through # Let unexpected exceptions skip through
return False return False
class TestCase: class TestCase(object):
"""A class whose instances are single test cases. """A class whose instances are single test cases.
By default, the test code itself should be placed in a method named By default, the test code itself should be placed in a method named
...@@ -231,8 +218,8 @@ class TestCase: ...@@ -231,8 +218,8 @@ class TestCase:
testMethod = getattr(self, methodName) testMethod = getattr(self, methodName)
self._testMethodDoc = testMethod.__doc__ self._testMethodDoc = testMethod.__doc__
except AttributeError: except AttributeError:
raise ValueError, "no such test method in %s: %s" % \ raise ValueError("no such test method in %s: %s" % \
(self.__class__, methodName) (self.__class__, methodName))
def setUp(self): def setUp(self):
"Hook method for setting up the test fixture before exercising it." "Hook method for setting up the test fixture before exercising it."
...@@ -287,9 +274,7 @@ class TestCase: ...@@ -287,9 +274,7 @@ class TestCase:
try: try:
try: try:
self.setUp() self.setUp()
except KeyboardInterrupt: except Exception:
raise
except:
result.addError(self, self._exc_info()) result.addError(self, self._exc_info())
return return
...@@ -299,16 +284,12 @@ class TestCase: ...@@ -299,16 +284,12 @@ class TestCase:
ok = True ok = True
except self.failureException: except self.failureException:
result.addFailure(self, self._exc_info()) result.addFailure(self, self._exc_info())
except KeyboardInterrupt: except Exception:
raise
except:
result.addError(self, self._exc_info()) result.addError(self, self._exc_info())
try: try:
self.tearDown() self.tearDown()
except KeyboardInterrupt: except Exception:
raise
except:
result.addError(self, self._exc_info()) result.addError(self, self._exc_info())
ok = False ok = False
if ok: result.addSuccess(self) if ok: result.addSuccess(self)
...@@ -333,15 +314,15 @@ class TestCase: ...@@ -333,15 +314,15 @@ class TestCase:
def fail(self, msg=None): def fail(self, msg=None):
"""Fail immediately, with the given message.""" """Fail immediately, with the given message."""
raise self.failureException, msg raise self.failureException(msg)
def failIf(self, expr, msg=None): def failIf(self, expr, msg=None):
"Fail the test if the expression is true." "Fail the test if the expression is true."
if expr: raise self.failureException, msg if expr: raise self.failureException(msg)
def failUnless(self, expr, msg=None): def failUnless(self, expr, msg=None):
"""Fail the test unless the expression is true.""" """Fail the test unless the expression is true."""
if not expr: raise self.failureException, msg if not expr: raise self.failureException(msg)
def failUnlessRaises(self, excClass, callableObj=None, *args, **kwargs): def failUnlessRaises(self, excClass, callableObj=None, *args, **kwargs):
"""Fail unless an exception of class excClass is thrown """Fail unless an exception of class excClass is thrown
...@@ -368,16 +349,14 @@ class TestCase: ...@@ -368,16 +349,14 @@ class TestCase:
operator. operator.
""" """
if not first == second: if not first == second:
raise self.failureException, \ raise self.failureException(msg or '%r != %r' % (first, second))
(msg or '%r != %r' % (first, second))
def failIfEqual(self, first, second, msg=None): def failIfEqual(self, first, second, msg=None):
"""Fail if the two objects are equal as determined by the '==' """Fail if the two objects are equal as determined by the '=='
operator. operator.
""" """
if first == second: if first == second:
raise self.failureException, \ raise self.failureException(msg or '%r == %r' % (first, second))
(msg or '%r == %r' % (first, second))
def failUnlessAlmostEqual(self, first, second, places=7, msg=None): def failUnlessAlmostEqual(self, first, second, places=7, msg=None):
"""Fail if the two objects are unequal as determined by their """Fail if the two objects are unequal as determined by their
...@@ -388,8 +367,8 @@ class TestCase: ...@@ -388,8 +367,8 @@ class TestCase:
as significant digits (measured from the most signficant digit). as significant digits (measured from the most signficant digit).
""" """
if round(abs(second-first), places) != 0: if round(abs(second-first), places) != 0:
raise self.failureException, \ raise self.failureException(
(msg or '%r != %r within %r places' % (first, second, places)) msg or '%r != %r within %r places' % (first, second, places))
def failIfAlmostEqual(self, first, second, places=7, msg=None): def failIfAlmostEqual(self, first, second, places=7, msg=None):
"""Fail if the two objects are equal as determined by their """Fail if the two objects are equal as determined by their
...@@ -400,8 +379,8 @@ class TestCase: ...@@ -400,8 +379,8 @@ class TestCase:
as significant digits (measured from the most signficant digit). as significant digits (measured from the most signficant digit).
""" """
if round(abs(second-first), places) == 0: if round(abs(second-first), places) == 0:
raise self.failureException, \ raise self.failureException(
(msg or '%r == %r within %r places' % (first, second, places)) msg or '%r == %r within %r places' % (first, second, places))
# Synonyms for assertion methods # Synonyms for assertion methods
...@@ -421,7 +400,7 @@ class TestCase: ...@@ -421,7 +400,7 @@ class TestCase:
class TestSuite: class TestSuite(object):
"""A test suite is a composite test consisting of a number of TestCases. """A test suite is a composite test consisting of a number of TestCases.
For use, create an instance of TestSuite, then add test case instances. For use, create an instance of TestSuite, then add test case instances.
...@@ -554,7 +533,7 @@ class FunctionTestCase(TestCase): ...@@ -554,7 +533,7 @@ class FunctionTestCase(TestCase):
# Locating and loading tests # Locating and loading tests
############################################################################## ##############################################################################
class TestLoader: class TestLoader(object):
"""This class is responsible for loading tests according to various """This class is responsible for loading tests according to various
criteria and returning them wrapped in a TestSuite criteria and returning them wrapped in a TestSuite
""" """
...@@ -605,12 +584,12 @@ class TestLoader: ...@@ -605,12 +584,12 @@ class TestLoader:
for part in parts: for part in parts:
parent, obj = obj, getattr(obj, part) parent, obj = obj, getattr(obj, part)
if type(obj) == types.ModuleType: if isinstance(obj, types.ModuleType):
return self.loadTestsFromModule(obj) return self.loadTestsFromModule(obj)
elif (isinstance(obj, (type, types.ClassType)) and elif (isinstance(obj, (type, types.ClassType)) and
issubclass(obj, TestCase)): issubclass(obj, TestCase)):
return self.loadTestsFromTestCase(obj) return self.loadTestsFromTestCase(obj)
elif (type(obj) == types.UnboundMethodType and elif (isinstance(obj, types.UnboundMethodType) and
isinstance(parent, (type, types.ClassType)) and isinstance(parent, (type, types.ClassType)) and
issubclass(parent, TestCase)): issubclass(parent, TestCase)):
return TestSuite([parent(obj.__name__)]) return TestSuite([parent(obj.__name__)])
...@@ -675,7 +654,7 @@ def findTestCases(module, prefix='test', sortUsing=cmp, suiteClass=TestSuite): ...@@ -675,7 +654,7 @@ def findTestCases(module, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
# Text UI # Text UI
############################################################################## ##############################################################################
class _WritelnDecorator: class _WritelnDecorator(object):
"""Used to decorate file-like objects with a handy 'writeln' method""" """Used to decorate file-like objects with a handy 'writeln' method"""
def __init__(self,stream): def __init__(self,stream):
self.stream = stream self.stream = stream
...@@ -754,7 +733,7 @@ class _TextTestResult(TestResult): ...@@ -754,7 +733,7 @@ class _TextTestResult(TestResult):
self.stream.writeln("%s" % err) self.stream.writeln("%s" % err)
class TextTestRunner: class TextTestRunner(object):
"""A test runner class that displays results in textual form. """A test runner class that displays results in textual form.
It prints out the names of tests as they are run, errors as they It prints out the names of tests as they are run, errors as they
...@@ -800,7 +779,7 @@ class TextTestRunner: ...@@ -800,7 +779,7 @@ class TextTestRunner:
# Facilities for running tests from the command line # Facilities for running tests from the command line
############################################################################## ##############################################################################
class TestProgram: class TestProgram(object):
"""A command-line program that runs a set of tests; this is primarily """A command-line program that runs a set of tests; this is primarily
for making test modules conveniently executable. for making test modules conveniently executable.
""" """
...@@ -822,7 +801,7 @@ Examples: ...@@ -822,7 +801,7 @@ Examples:
def __init__(self, module='__main__', defaultTest=None, def __init__(self, module='__main__', defaultTest=None,
argv=None, testRunner=TextTestRunner, argv=None, testRunner=TextTestRunner,
testLoader=defaultTestLoader): testLoader=defaultTestLoader):
if type(module) == type(''): if isinstance(module, basestring):
self.module = __import__(module) self.module = __import__(module)
for part in module.split('.')[1:]: for part in module.split('.')[1:]:
self.module = getattr(self.module, part) self.module = getattr(self.module, part)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment