Ticket #15828: unittest-django-vs-python-2.7.2.diff
File unittest-django-vs-python-2.7.2.diff, 55.4 KB (added by , 13 years ago) |
---|
-
unittest/__init__.py
diff -u -Naur -x .svn -x .DS_Store -x test -x '*.pyc' -w django/utils/unittest/__init__.py /Users/myk/Downloads/cpython-eb3c9b74884c/Lib/unittest/__init__.py
old new 1 1 """ 2 unittest2 2 Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's 3 Smalltalk testing framework. 3 4 4 unittest2 is a backport of the new features added to the unittest testing 5 framework in Python 2.7. It is tested to run on Python 2.4 - 2.6. 5 This module contains the core framework classes that form the basis of 6 specific test cases and suites (TestCase, TestSuite etc.), and also a 7 text-based utility class for running the tests and reporting the results 8 (TextTestRunner). 6 9 7 To use unittest2 instead of unittest simply replace ``import unittest`` with 8 ``import unittest2``. 10 Simple usage: 9 11 12 import unittest 13 14 class IntegerArithmenticTestCase(unittest.TestCase): 15 def testAdd(self): ## test method names begin 'test*' 16 self.assertEqual((1 + 2), 3) 17 self.assertEqual(0 + 1, 1) 18 def testMultiply(self): 19 self.assertEqual((0 * 10), 0) 20 self.assertEqual((5 * 8), 40) 21 22 if __name__ == '__main__': 23 unittest.main() 24 25 Further information is available in the bundled documentation, and from 26 27 http://docs.python.org/library/unittest.html 10 28 11 29 Copyright (c) 1999-2003 Steve Purcell 12 30 Copyright (c) 2003-2010 Python Software Foundation … … 26 44 SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 27 45 """ 28 46 29 import sys30 31 # Django hackery to load the appropriate version of unittest32 33 try:34 # check the system path first35 from unittest2 import *36 except ImportError:37 if sys.version_info >= (2,7):38 # unittest2 features are native in Python 2.739 from unittest import *40 else:41 # otherwise use our bundled version42 47 __all__ = ['TestResult', 'TestCase', 'TestSuite', 43 48 'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main', 44 49 'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless', 45 'expectedFailure', 'TextTestResult', '__version__', 'collector'] 46 47 __version__ = '0.5.1' 50 'expectedFailure', 'TextTestResult', 'installHandler', 51 'registerResult', 'removeResult', 'removeHandler'] 48 52 49 53 # Expose obsolete functions for backwards compatibility 50 54 __all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases']) 51 55 56 __unittest = True 52 57 53 from django.utils.unittest.collector import collector 54 from django.utils.unittest.result import TestResult 55 from django.utils.unittest.case import \ 56 TestCase, FunctionTestCase, SkipTest, skip, skipIf,\ 57 skipUnless, expectedFailure 58 59 from django.utils.unittest.suite import BaseTestSuite, TestSuite 60 from django.utils.unittest.loader import \ 61 TestLoader, defaultTestLoader, makeSuite, getTestCaseNames,\ 62 findTestCases 63 64 from django.utils.unittest.main import TestProgram, main, main_ 65 from django.utils.unittest.runner import TextTestRunner, TextTestResult 66 67 try: 68 from django.utils.unittest.signals import\ 69 installHandler, registerResult, removeResult, removeHandler 70 except ImportError: 71 # Compatibility with platforms that don't have the signal module 72 pass 73 else: 74 __all__.extend(['installHandler', 'registerResult', 'removeResult', 75 'removeHandler']) 58 from .result import TestResult 59 from .case import (TestCase, FunctionTestCase, SkipTest, skip, skipIf, 60 skipUnless, expectedFailure) 61 from .suite import BaseTestSuite, TestSuite 62 from .loader import (TestLoader, defaultTestLoader, makeSuite, getTestCaseNames, 63 findTestCases) 64 from .main import TestProgram, main 65 from .runner import TextTestRunner, TextTestResult 66 from .signals import installHandler, registerResult, removeResult, removeHandler 76 67 77 68 # deprecated 78 69 _TextTestResult = TextTestResult 79 80 __unittest = True -
unittest/__main__.py
diff -u -Naur -x .svn -x .DS_Store -x test -x '*.pyc' -w django/utils/unittest/__main__.py /Users/myk/Downloads/cpython-eb3c9b74884c/Lib/unittest/__main__.py
old new 2 2 3 3 import sys 4 4 if sys.argv[0].endswith("__main__.py"): 5 sys.argv[0] = " unittest2"5 sys.argv[0] = "python -m unittest" 6 6 7 7 __unittest = True 8 8 9 from django.utils.unittest.main import main_ 10 main_() 9 from .main import main, TestProgram, USAGE_AS_MAIN 10 TestProgram.USAGE = USAGE_AS_MAIN 11 12 main(module=None) -
unittest/case.py
diff -u -Naur -x .svn -x .DS_Store -x test -x '*.pyc' -w django/utils/unittest/case.py /Users/myk/Downloads/cpython-eb3c9b74884c/Lib/unittest/case.py
old new 1 1 """Test case implementation""" 2 2 3 import collections 3 4 import sys 5 import functools 4 6 import difflib 5 7 import pprint 6 8 import re 7 import unittest8 9 import warnings 9 10 10 from django.utils.unittest import result 11 from django.utils.unittest.util import\ 12 safe_repr, safe_str, strclass,\ 13 unorderable_list_difference 11 from . import result 12 from .util import ( 13 strclass, safe_repr, unorderable_list_difference, 14 _count_diff_all_purpose, _count_diff_hashable 15 ) 14 16 15 from django.utils.unittest.compatibility import wraps16 17 17 18 __unittest = True 18 19 … … 27 28 Usually you can use TestResult.skip() or one of the skipping decorators 28 29 instead of raising this directly. 29 30 """ 31 pass 30 32 31 33 class _ExpectedFailure(Exception): 32 34 """ … … 36 38 """ 37 39 38 40 def __init__(self, exc_info): 39 # can't use super because Python 2.4 exceptions are old style 40 Exception.__init__(self) 41 super(_ExpectedFailure, self).__init__() 41 42 self.exc_info = exc_info 42 43 43 44 class _UnexpectedSuccess(Exception): 44 45 """ 45 46 The test was supposed to fail, but it didn't! 46 47 """ 48 pass 47 49 48 50 def _id(obj): 49 51 return obj … … 54 56 """ 55 57 def decorator(test_item): 56 58 if not (isinstance(test_item, type) and issubclass(test_item, TestCase)): 57 @ wraps(test_item)59 @functools.wraps(test_item) 58 60 def skip_wrapper(*args, **kwargs): 59 61 raise SkipTest(reason) 60 62 test_item = skip_wrapper … … 82 84 83 85 84 86 def expectedFailure(func): 85 @ wraps(func)87 @functools.wraps(func) 86 88 def wrapper(*args, **kwargs): 87 89 try: 88 90 func(*args, **kwargs) … … 110 112 except AttributeError: 111 113 exc_name = str(self.expected) 112 114 raise self.failureException( 113 " %s not raised" % (exc_name,))115 "{0} not raised".format(exc_name)) 114 116 if not issubclass(exc_type, self.expected): 115 117 # let unexpected exceptions pass through 116 118 return False … … 127 129 return True 128 130 129 131 130 class _TypeEqualityDict(object): 131 132 def __init__(self, testcase): 133 self.testcase = testcase 134 self._store = {} 135 136 def __setitem__(self, key, value): 137 self._store[key] = value 138 139 def __getitem__(self, key): 140 value = self._store[key] 141 if isinstance(value, basestring): 142 return getattr(self.testcase, value) 143 return value 144 145 def get(self, key, default=None): 146 if key in self._store: 147 return self[key] 148 return default 149 150 151 class TestCase(unittest.TestCase): 132 class TestCase(object): 152 133 """A class whose instances are single test cases. 153 134 154 135 By default, the test code itself should be placed in a method named … … 176 157 177 158 failureException = AssertionError 178 159 160 # This attribute determines whether long messages (including repr of 161 # objects used in assert methods) will be printed on failure in *addition* 162 # to any explicit message passed. 163 164 longMessage = False 165 179 166 # This attribute sets the maximum length of a diff in failure messages 180 167 # by assert methods using difflib. It is looked up as an instance attribute 181 168 # so can be configured by individual tests if required. 182 169 183 170 maxDiff = 80*8 184 171 185 # This attribute determines whether long messages (including repr of 186 # objects used in assert methods) will be printed on failure in *addition* 187 # to any explicit message passed. 188 189 longMessage = True 172 # If a string is longer than _diffThreshold, use normal comparison instead 173 # of difflib. See #11763. 174 _diffThreshold = 2**16 190 175 191 176 # Attribute used by TestSuite for classSetUp 192 177 … … 202 187 try: 203 188 testMethod = getattr(self, methodName) 204 189 except AttributeError: 205 raise ValueError("no such test method in %s: %s" % \190 raise ValueError("no such test method in %s: %s" % 206 191 (self.__class__, methodName)) 207 192 self._testMethodDoc = testMethod.__doc__ 208 193 self._cleanups = [] … … 210 195 # Map types to custom assertEqual functions that will compare 211 196 # instances of said type in more detail to generate a more useful 212 197 # error message. 213 self._type_equality_funcs = _TypeEqualityDict(self)214 self.addTypeEqualityFunc(dict, 'assertDictEqual')215 self.addTypeEqualityFunc(list, 'assertListEqual')216 self.addTypeEqualityFunc(tuple, 'assertTupleEqual')217 self.addTypeEqualityFunc(set, 'assertSetEqual')218 self.addTypeEqualityFunc(frozenset, 'assertSetEqual')219 self.addTypeEqualityFunc(unicode, 'assertMultiLineEqual')198 self._type_equality_funcs = {} 199 self.addTypeEqualityFunc(dict, self.assertDictEqual) 200 self.addTypeEqualityFunc(list, self.assertListEqual) 201 self.addTypeEqualityFunc(tuple, self.assertTupleEqual) 202 self.addTypeEqualityFunc(set, self.assertSetEqual) 203 self.addTypeEqualityFunc(frozenset, self.assertSetEqual) 204 self.addTypeEqualityFunc(unicode, self.assertMultiLineEqual) 220 205 221 206 def addTypeEqualityFunc(self, typeobj, function): 222 207 """Add a type specific assertEqual style function to compare a type. … … 243 228 244 229 def setUp(self): 245 230 "Hook method for setting up the test fixture before exercising it." 231 pass 232 233 def tearDown(self): 234 "Hook method for deconstructing the test fixture after testing it." 235 pass 246 236 247 237 @classmethod 248 238 def setUpClass(cls): … … 252 242 def tearDownClass(cls): 253 243 "Hook method for deconstructing the class fixture after running all tests in the class." 254 244 255 def tearDown(self):256 "Hook method for deconstructing the test fixture after testing it."257 258 245 def countTestCases(self): 259 246 return 1 260 247 … … 299 286 if addSkip is not None: 300 287 addSkip(self, reason) 301 288 else: 302 warnings.warn(" Use of a TestResult without an addSkip method is deprecated",303 DeprecationWarning, 2)289 warnings.warn("TestResult has no addSkip method, skips not reported", 290 RuntimeWarning, 2) 304 291 result.addSuccess(self) 305 292 306 293 def run(self, result=None): … … 315 302 result.startTest(self) 316 303 317 304 testMethod = getattr(self, self._testMethodName) 318 319 305 if (getattr(self.__class__, "__unittest_skip__", False) or 320 306 getattr(testMethod, "__unittest_skip__", False)): 321 307 # If the class or method was skipped. … … 330 316 success = False 331 317 try: 332 318 self.setUp() 333 except SkipTest ,e:319 except SkipTest as e: 334 320 self._addSkip(result, str(e)) 335 except Exception: 321 except KeyboardInterrupt: 322 raise 323 except: 336 324 result.addError(self, sys.exc_info()) 337 325 else: 338 326 try: 339 327 testMethod() 328 except KeyboardInterrupt: 329 raise 340 330 except self.failureException: 341 331 result.addFailure(self, sys.exc_info()) 342 except _ExpectedFailure ,e:332 except _ExpectedFailure as e: 343 333 addExpectedFailure = getattr(result, 'addExpectedFailure', None) 344 334 if addExpectedFailure is not None: 345 335 addExpectedFailure(self, e.exc_info) 346 336 else: 347 warnings.warn(" Use of a TestResult without an addExpectedFailure method is deprecated",348 DeprecationWarning)337 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes", 338 RuntimeWarning) 349 339 result.addSuccess(self) 350 340 except _UnexpectedSuccess: 351 341 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None) 352 342 if addUnexpectedSuccess is not None: 353 343 addUnexpectedSuccess(self) 354 344 else: 355 warnings.warn(" Use of a TestResult without an addUnexpectedSuccess method is deprecated",356 DeprecationWarning)345 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures", 346 RuntimeWarning) 357 347 result.addFailure(self, sys.exc_info()) 358 except SkipTest ,e:348 except SkipTest as e: 359 349 self._addSkip(result, str(e)) 360 except Exception:350 except: 361 351 result.addError(self, sys.exc_info()) 362 352 else: 363 353 success = True 364 354 365 355 try: 366 356 self.tearDown() 367 except Exception: 357 except KeyboardInterrupt: 358 raise 359 except: 368 360 result.addError(self, sys.exc_info()) 369 361 success = False 370 362 … … 388 380 function, args, kwargs = self._cleanups.pop(-1) 389 381 try: 390 382 function(*args, **kwargs) 391 except Exception: 383 except KeyboardInterrupt: 384 raise 385 except: 392 386 ok = False 393 387 result.addError(self, sys.exc_info()) 394 388 return ok … … 414 408 raise self.failureException(msg) 415 409 416 410 def assertFalse(self, expr, msg=None): 417 " Fail the test if the expression is true."411 """Check that the expression is false.""" 418 412 if expr: 419 msg = self._formatMessage(msg, "%s is not False" % safe_repr(expr))413 msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr)) 420 414 raise self.failureException(msg) 421 415 422 416 def assertTrue(self, expr, msg=None): 423 """ Fail the test unlessthe expression is true."""417 """Check that the expression is true.""" 424 418 if not expr: 425 msg = self._formatMessage(msg, "%s is not True" % safe_repr(expr))419 msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr)) 426 420 raise self.failureException(msg) 427 421 428 422 def _formatMessage(self, msg, standardMsg): … … 440 434 if msg is None: 441 435 return standardMsg 442 436 try: 437 # don't switch to '{}' formatting in Python 2.X 438 # it changes the way unicode input is handled 443 439 return '%s : %s' % (standardMsg, msg) 444 440 except UnicodeDecodeError: 445 return '%s : %s' % (safe_str(standardMsg), safe_str(msg))441 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg)) 446 442 447 443 448 444 def assertRaises(self, excClass, callableObj=None, *args, **kwargs): … … 468 464 the_exception = cm.exception 469 465 self.assertEqual(the_exception.error_code, 3) 470 466 """ 467 context = _AssertRaisesContext(excClass, self) 471 468 if callableObj is None: 472 return _AssertRaisesContext(excClass, self)473 try:469 return context 470 with context: 474 471 callableObj(*args, **kwargs) 475 except excClass:476 return477 478 if hasattr(excClass,'__name__'):479 excName = excClass.__name__480 else:481 excName = str(excClass)482 raise self.failureException("%s not raised" % excName)483 472 484 473 def _getAssertEqualityFunc(self, first, second): 485 474 """Get a detailed comparison function for the types of the two args. … … 528 517 safe_repr(second))) 529 518 raise self.failureException(msg) 530 519 520 531 521 def assertAlmostEqual(self, first, second, places=None, msg=None, delta=None): 532 522 """Fail if the two objects are unequal as determined by their 533 523 difference rounded to the given number of decimal places … … 613 603 def _deprecate(original_func): 614 604 def deprecated_func(*args, **kwargs): 615 605 warnings.warn( 616 ('Please use %s instead.' %original_func.__name__),606 'Please use {0} instead.'.format(original_func.__name__), 617 607 PendingDeprecationWarning, 2) 618 608 return original_func(*args, **kwargs) 619 609 return deprecated_func … … 626 616 failUnlessRaises = _deprecate(assertRaises) 627 617 failIf = _deprecate(assertFalse) 628 618 629 def assertSequenceEqual(self, seq1, seq2, 630 msg=None, seq_type=None, max_diff=80*8): 619 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None): 631 620 """An equality assertion for ordered sequences (like lists and tuples). 632 621 633 622 For the purposes of this function, a valid ordered sequence type is one … … 640 629 datatype should be enforced. 641 630 msg: Optional message to use on failure instead of a list of 642 631 differences. 643 max_diff: Maximum size off the diff, larger diffs are not shown644 632 """ 645 633 if seq_type is not None: 646 634 seq_type_name = seq_type.__name__ … … 671 659 if seq1 == seq2: 672 660 return 673 661 674 seq1_repr = repr(seq1)675 seq2_repr = repr(seq2)662 seq1_repr = safe_repr(seq1) 663 seq2_repr = safe_repr(seq2) 676 664 if len(seq1_repr) > 30: 677 665 seq1_repr = seq1_repr[:30] + '...' 678 666 if len(seq2_repr) > 30: … … 727 715 diffMsg = '\n' + '\n'.join( 728 716 difflib.ndiff(pprint.pformat(seq1).splitlines(), 729 717 pprint.pformat(seq2).splitlines())) 730 731 718 standardMsg = self._truncateMessage(standardMsg, diffMsg) 732 719 msg = self._formatMessage(msg, standardMsg) 733 720 self.fail(msg) … … 770 757 msg: Optional message to use on failure instead of a list of 771 758 differences. 772 759 773 assertSetEqual uses ducktyping to support 774 different types of sets, and is optimized for sets specifically775 (parameters must support adifference method).760 assertSetEqual uses ducktyping to support different types of sets, and 761 is optimized for sets specifically (parameters must support a 762 difference method). 776 763 """ 777 764 try: 778 765 difference1 = set1.difference(set2) … … 821 808 def assertIs(self, expr1, expr2, msg=None): 822 809 """Just like self.assertTrue(a is b), but with a nicer default message.""" 823 810 if expr1 is not expr2: 824 standardMsg = '%s is not %s' % (safe_repr(expr1), safe_repr(expr2)) 811 standardMsg = '%s is not %s' % (safe_repr(expr1), 812 safe_repr(expr2)) 825 813 self.fail(self._formatMessage(msg, standardMsg)) 826 814 827 815 def assertIsNot(self, expr1, expr2, msg=None): … … 831 819 self.fail(self._formatMessage(msg, standardMsg)) 832 820 833 821 def assertDictEqual(self, d1, d2, msg=None): 834 self.assert True(isinstance(d1, dict), 'First argument is not a dictionary')835 self.assert True(isinstance(d2, dict), 'Second argument is not a dictionary')822 self.assertIsInstance(d1, dict, 'First argument is not a dictionary') 823 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary') 836 824 837 825 if d1 != d2: 838 826 standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True)) … … 870 858 871 859 def assertItemsEqual(self, expected_seq, actual_seq, msg=None): 872 860 """An unordered sequence specific comparison. It asserts that 873 expected_seq and actual_seq contain the same elements. It is874 the equivalent of::861 actual_seq and expected_seq have the same element counts. 862 Equivalent to:: 875 863 876 self.assertEqual(sorted(expected_seq), sorted(actual_seq)) 877 878 Raises with an error message listing which elements of expected_seq 879 are missing from actual_seq and vice versa if any. 864 self.assertEqual(Counter(iter(actual_seq)), 865 Counter(iter(expected_seq))) 880 866 881 867 Asserts that each element has the same count in both sequences. 882 868 Example: 883 869 - [0, 1, 1] and [1, 0, 1] compare equal. 884 870 - [0, 0, 1] and [0, 1] compare unequal. 885 871 """ 872 first_seq, second_seq = list(actual_seq), list(expected_seq) 873 with warnings.catch_warnings(): 874 if sys.py3kwarning: 875 # Silence Py3k warning raised during the sorting 876 for _msg in ["(code|dict|type) inequality comparisons", 877 "builtin_function_or_method order comparisons", 878 "comparing unequal types"]: 879 warnings.filterwarnings("ignore", _msg, DeprecationWarning) 886 880 try: 887 expected = sorted(expected_seq)888 actual = sorted(actual_seq)881 first = collections.Counter(first_seq) 882 second = collections.Counter(second_seq) 889 883 except TypeError: 890 # Unsortable items (example: set(), complex(), ...) 891 expected = list(expected_seq) 892 actual = list(actual_seq) 893 missing, unexpected = unorderable_list_difference( 894 expected, actual, ignore_duplicate=False 895 ) 884 # Handle case with unhashable elements 885 differences = _count_diff_all_purpose(first_seq, second_seq) 896 886 else: 897 return self.assertSequenceEqual(expected, actual, msg=msg) 887 if first == second: 888 return 889 differences = _count_diff_hashable(first_seq, second_seq) 898 890 899 errors = [] 900 if missing: 901 errors.append('Expected, but missing:\n %s' % 902 safe_repr(missing)) 903 if unexpected: 904 errors.append('Unexpected, but present:\n %s' % 905 safe_repr(unexpected)) 906 if errors: 907 standardMsg = '\n'.join(errors) 908 self.fail(self._formatMessage(msg, standardMsg)) 891 if differences: 892 standardMsg = 'Element counts were not equal:\n' 893 lines = ['First has %d, Second has %d: %r' % diff for diff in differences] 894 diffMsg = '\n'.join(lines) 895 standardMsg = self._truncateMessage(standardMsg, diffMsg) 896 msg = self._formatMessage(msg, standardMsg) 897 self.fail(msg) 909 898 910 899 def assertMultiLineEqual(self, first, second, msg=None): 911 900 """Assert that two multi-line strings are equal.""" 912 self.assert True(isinstance(first, basestring), (913 'First argument is not a string') )914 self.assert True(isinstance(second, basestring), (915 'Second argument is not a string') )901 self.assertIsInstance(first, basestring, 902 'First argument is not a string') 903 self.assertIsInstance(second, basestring, 904 'Second argument is not a string') 916 905 917 906 if first != second: 918 standardMsg = '%s != %s' % (safe_repr(first, True), safe_repr(second, True)) 919 diff = '\n' + ''.join(difflib.ndiff(first.splitlines(True), 920 second.splitlines(True))) 907 # don't use difflib if the strings are too long 908 if (len(first) > self._diffThreshold or 909 len(second) > self._diffThreshold): 910 self._baseAssertEqual(first, second, msg) 911 firstlines = first.splitlines(True) 912 secondlines = second.splitlines(True) 913 if len(firstlines) == 1 and first.strip('\r\n') == first: 914 firstlines = [first + '\n'] 915 secondlines = [second + '\n'] 916 standardMsg = '%s != %s' % (safe_repr(first, True), 917 safe_repr(second, True)) 918 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines)) 921 919 standardMsg = self._truncateMessage(standardMsg, diff) 922 920 self.fail(self._formatMessage(msg, standardMsg)) 923 921 … … 982 980 args: Extra args. 983 981 kwargs: Extra kwargs. 984 982 """ 983 context = _AssertRaisesContext(expected_exception, self, expected_regexp) 985 984 if callable_obj is None: 986 return _AssertRaisesContext(expected_exception, self, expected_regexp)987 try:985 return context 986 with context: 988 987 callable_obj(*args, **kwargs) 989 except expected_exception, exc_value:990 if isinstance(expected_regexp, basestring):991 expected_regexp = re.compile(expected_regexp)992 if not expected_regexp.search(str(exc_value)):993 raise self.failureException('"%s" does not match "%s"' %994 (expected_regexp.pattern, str(exc_value)))995 else:996 if hasattr(expected_exception, '__name__'):997 excName = expected_exception.__name__998 else:999 excName = str(expected_exception)1000 raise self.failureException("%s not raised" % excName)1001 988 1002 989 def assertRegexpMatches(self, text, expected_regexp, msg=None): 1003 990 """Fail the test unless the text matches the regular expression.""" … … 1021 1008 text) 1022 1009 raise self.failureException(msg) 1023 1010 1011 1024 1012 class FunctionTestCase(TestCase): 1025 1013 """A test case that wraps a test function. 1026 1014 … … 1072 1060 self._testFunc.__name__) 1073 1061 1074 1062 def __repr__(self): 1075 return "<%s te stFunc=%s>" % (strclass(self.__class__),1063 return "<%s tec=%s>" % (strclass(self.__class__), 1076 1064 self._testFunc) 1077 1065 1078 1066 def shortDescription(self): -
unittest/collector.py
diff -u -Naur -x .svn -x .DS_Store -x test -x '*.pyc' -w django/utils/unittest/collector.py /Users/myk/Downloads/cpython-eb3c9b74884c/Lib/unittest/collector.py
old new 1 import os2 import sys3 from django.utils.unittest.loader import defaultTestLoader4 5 def collector():6 # import __main__ triggers code re-execution7 __main__ = sys.modules['__main__']8 setupDir = os.path.abspath(os.path.dirname(__main__.__file__))9 return defaultTestLoader.discover(setupDir) -
unittest/compatibility.py
diff -u -Naur -x .svn -x .DS_Store -x test -x '*.pyc' -w django/utils/unittest/compatibility.py /Users/myk/Downloads/cpython-eb3c9b74884c/Lib/unittest/compatibility.py
old new 1 import os2 import sys3 4 try:5 from functools import wraps6 except ImportError:7 # only needed for Python 2.48 def wraps(_):9 def _wraps(func):10 return func11 return _wraps12 13 __unittest = True14 15 def _relpath_nt(path, start=os.path.curdir):16 """Return a relative version of a path"""17 18 if not path:19 raise ValueError("no path specified")20 start_list = os.path.abspath(start).split(os.path.sep)21 path_list = os.path.abspath(path).split(os.path.sep)22 if start_list[0].lower() != path_list[0].lower():23 unc_path, rest = os.path.splitunc(path)24 unc_start, rest = os.path.splitunc(start)25 if bool(unc_path) ^ bool(unc_start):26 raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)"27 % (path, start))28 else:29 raise ValueError("path is on drive %s, start on drive %s"30 % (path_list[0], start_list[0]))31 # Work out how much of the filepath is shared by start and path.32 for i in range(min(len(start_list), len(path_list))):33 if start_list[i].lower() != path_list[i].lower():34 break35 else:36 i += 137 38 rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]39 if not rel_list:40 return os.path.curdir41 return os.path.join(*rel_list)42 43 # default to posixpath definition44 def _relpath_posix(path, start=os.path.curdir):45 """Return a relative version of a path"""46 47 if not path:48 raise ValueError("no path specified")49 50 start_list = os.path.abspath(start).split(os.path.sep)51 path_list = os.path.abspath(path).split(os.path.sep)52 53 # Work out how much of the filepath is shared by start and path.54 i = len(os.path.commonprefix([start_list, path_list]))55 56 rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]57 if not rel_list:58 return os.path.curdir59 return os.path.join(*rel_list)60 61 if os.path is sys.modules.get('ntpath'):62 relpath = _relpath_nt63 else:64 relpath = _relpath_posix -
unittest/loader.py
diff -u -Naur -x .svn -x .DS_Store -x test -x '*.pyc' -w django/utils/unittest/loader.py /Users/myk/Downloads/cpython-eb3c9b74884c/Lib/unittest/loader.py
old new 5 5 import sys 6 6 import traceback 7 7 import types 8 import unittest9 8 9 from functools import cmp_to_key as _CmpToKey 10 10 from fnmatch import fnmatch 11 11 12 from django.utils.unittest import case, suite 13 14 try: 15 from os.path import relpath 16 except ImportError: 17 from django.utils.unittest.compatibility import relpath 12 from . import case, suite 18 13 19 14 __unittest = True 20 15 21 22 def _CmpToKey(mycmp):23 'Convert a cmp= function into a key= function'24 class K(object):25 def __init__(self, obj):26 self.obj = obj27 def __lt__(self, other):28 return mycmp(self.obj, other.obj) == -129 return K30 31 32 16 # what about .pyc or .pyo (etc) 33 17 # we would need to avoid loading the same tests multiple times 34 18 # from '.py', '.pyc' *and* '.pyo' … … 36 20 37 21 38 22 def _make_failed_import_test(name, suiteClass): 39 message = 'Failed to import test module: %s' % name 40 if hasattr(traceback, 'format_exc'): 41 # Python 2.3 compatibility 42 # format_exc returns two frames of discover.py as well 43 message += '\n%s' % traceback.format_exc() 23 message = 'Failed to import test module: %s\n%s' % (name, traceback.format_exc()) 44 24 return _make_failed_test('ModuleImportFailure', name, ImportError(message), 45 25 suiteClass) 46 26 … … 55 35 return suiteClass((TestClass(methodname),)) 56 36 57 37 58 class TestLoader( unittest.TestLoader):38 class TestLoader(object): 59 39 """ 60 40 This class is responsible for loading tests according to various criteria 61 41 and returning them wrapped in a TestSuite … … 68 48 def loadTestsFromTestCase(self, testCaseClass): 69 49 """Return a suite of all tests cases contained in testCaseClass""" 70 50 if issubclass(testCaseClass, suite.TestSuite): 71 raise TypeError("Test cases should not be derived from TestSuite." 51 raise TypeError("Test cases should not be derived from TestSuite." \ 72 52 " Maybe you meant to derive from TestCase?") 73 53 testCaseNames = self.getTestCaseNames(testCaseClass) 74 54 if not testCaseNames and hasattr(testCaseClass, 'runTest'): … … 81 61 tests = [] 82 62 for name in dir(module): 83 63 obj = getattr(module, name) 84 if isinstance(obj, type) and issubclass(obj, unittest.TestCase):64 if isinstance(obj, type) and issubclass(obj, case.TestCase): 85 65 tests.append(self.loadTestsFromTestCase(obj)) 86 66 87 67 load_tests = getattr(module, 'load_tests', None) … … 121 101 122 102 if isinstance(obj, types.ModuleType): 123 103 return self.loadTestsFromModule(obj) 124 elif isinstance(obj, type) and issubclass(obj, unittest.TestCase):104 elif isinstance(obj, type) and issubclass(obj, case.TestCase): 125 105 return self.loadTestsFromTestCase(obj) 126 106 elif (isinstance(obj, types.UnboundMethodType) and 127 107 isinstance(parent, type) and 128 108 issubclass(parent, case.TestCase)): 129 109 return self.suiteClass([parent(obj.__name__)]) 130 elif isinstance(obj, unittest.TestSuite):110 elif isinstance(obj, suite.TestSuite): 131 111 return obj 132 112 elif hasattr(obj, '__call__'): 133 113 test = obj() 134 if isinstance(test, unittest.TestSuite):114 if isinstance(test, suite.TestSuite): 135 115 return test 136 elif isinstance(test, unittest.TestCase):116 elif isinstance(test, case.TestCase): 137 117 return self.suiteClass([test]) 138 118 else: 139 119 raise TypeError("calling %s returned %s, not a test" % … … 215 195 top_part = start_dir.split('.')[0] 216 196 start_dir = os.path.abspath(os.path.dirname((the_module.__file__))) 217 197 if set_implicit_top: 218 self._top_level_dir = os.path.abspath(os.path.dirname(os.path.dirname(sys.modules[top_part].__file__)))198 self._top_level_dir = self._get_directory_containing_module(top_part) 219 199 sys.path.remove(top_level_dir) 220 200 221 201 if is_not_importable: … … 224 204 tests = list(self._find_tests(start_dir, pattern)) 225 205 return self.suiteClass(tests) 226 206 207 def _get_directory_containing_module(self, module_name): 208 module = sys.modules[module_name] 209 full_path = os.path.abspath(module.__file__) 210 211 if os.path.basename(full_path).lower().startswith('__init__.py'): 212 return os.path.dirname(os.path.dirname(full_path)) 213 else: 214 # here we have been given a module rather than a package - so 215 # all we can do is search the *same* directory the module is in 216 # should an exception be raised instead 217 return os.path.dirname(full_path) 218 227 219 def _get_name_from_path(self, path): 228 220 path = os.path.splitext(os.path.normpath(path))[0] 229 221 230 _relpath = relpath(path, self._top_level_dir)222 _relpath = os.path.relpath(path, self._top_level_dir) 231 223 assert not os.path.isabs(_relpath), "Path must be within the project" 232 224 assert not _relpath.startswith('..'), "Path must be within the project" 233 225 -
unittest/main.py
diff -u -Naur -x .svn -x .DS_Store -x test -x '*.pyc' -w django/utils/unittest/main.py /Users/myk/Downloads/cpython-eb3c9b74884c/Lib/unittest/main.py
old new 4 4 import os 5 5 import types 6 6 7 from django.utils.unittest import loader, runner 8 try: 9 from django.utils.unittest.signals import installHandler 10 except ImportError: 11 installHandler = None 7 from . import loader, runner 8 from .signals import installHandler 12 9 13 10 __unittest = True 14 11 … … 26 23 %(failfast)s%(catchbreak)s%(buffer)s 27 24 Examples: 28 25 %(progName)s test_module - run tests from test_module 29 %(progName)s test_module.TestClass - run tests from 30 test_module.TestClass 31 %(progName)s test_module.TestClass.test_method - run specified test method 26 %(progName)s module.TestClass - run tests from module.TestClass 27 %(progName)s module.Class.test_method - run specified test method 32 28 33 29 [tests] can be a list of any number of test modules, classes and test 34 30 methods. … … 63 59 """ 64 60 65 61 62 66 63 class TestProgram(object): 67 64 """A command-line program that runs a set of tests; this is primarily 68 65 for making test modules conveniently executable. … … 72 69 # defaults for testing 73 70 failfast = catchbreak = buffer = progName = None 74 71 75 def __init__(self, module='__main__', defaultTest=None, 76 argv=None, testRunner=None,77 testLoader=loader.defaultTestLoader, exit=True,78 verbosity=1, failfast=None, catchbreak=None,buffer=None):72 def __init__(self, module='__main__', defaultTest=None, argv=None, 73 testRunner=None, testLoader=loader.defaultTestLoader, 74 exit=True, verbosity=1, failfast=None, catchbreak=None, 75 buffer=None): 79 76 if isinstance(module, basestring): 80 77 self.module = __import__(module) 81 78 for part in module.split('.')[1:]: … … 86 83 argv = sys.argv 87 84 88 85 self.exit = exit 89 self.verbosity = verbosity90 86 self.failfast = failfast 91 87 self.catchbreak = catchbreak 88 self.verbosity = verbosity 92 89 self.buffer = buffer 93 90 self.defaultTest = defaultTest 94 91 self.testRunner = testRunner … … 104 101 'buffer': ''} 105 102 if self.failfast != False: 106 103 usage['failfast'] = FAILFAST 107 if self.catchbreak != False and installHandler is not None:104 if self.catchbreak != False: 108 105 usage['catchbreak'] = CATCHBREAK 109 106 if self.buffer != False: 110 107 usage['buffer'] = BUFFEROUTPUT … … 132 129 self.failfast = True 133 130 # Should this raise an exception if -f is not valid? 134 131 if opt in ('-c','--catch'): 135 if self.catchbreak is None and installHandler is not None:132 if self.catchbreak is None: 136 133 self.catchbreak = True 137 134 # Should this raise an exception if -c is not valid? 138 135 if opt in ('-b','--buffer'): … … 172 169 parser.add_option('-f', '--failfast', dest='failfast', default=False, 173 170 help='Stop on first fail or error', 174 171 action='store_true') 175 if self.catchbreak != False and installHandler is not None:172 if self.catchbreak != False: 176 173 parser.add_option('-c', '--catch', dest='catchbreak', default=False, 177 174 help='Catch ctrl-C and display results so far', 178 175 action='store_true') … … 198 195 # if they weren't set explicitly in the constructor 199 196 if self.failfast is None: 200 197 self.failfast = options.failfast 201 if self.catchbreak is None and installHandler is not None:198 if self.catchbreak is None: 202 199 self.catchbreak = options.catchbreak 203 200 if self.buffer is None: 204 201 self.buffer = options.buffer … … 234 231 sys.exit(not self.result.wasSuccessful()) 235 232 236 233 main = TestProgram 237 238 def main_():239 TestProgram.USAGE = USAGE_AS_MAIN240 main(module=None)241 -
unittest/result.py
diff -u -Naur -x .svn -x .DS_Store -x test -x '*.pyc' -w django/utils/unittest/result.py /Users/myk/Downloads/cpython-eb3c9b74884c/Lib/unittest/result.py
old new 1 1 """Test result object""" 2 2 3 import os 3 4 import sys 4 5 import traceback 5 import unittest6 6 7 7 from StringIO import StringIO 8 8 9 from django.utils.unittestimport util10 from django.utils.unittest.compatibilityimport wraps9 from . import util 10 from functools import wraps 11 11 12 12 __unittest = True 13 13 … … 19 19 return method(self, *args, **kw) 20 20 return inner 21 21 22 23 22 STDOUT_LINE = '\nStdout:\n%s' 24 23 STDERR_LINE = '\nStderr:\n%s' 25 24 26 class TestResult(unittest.TestResult): 25 26 class TestResult(object): 27 27 """Holder for test result information. 28 28 29 29 Test results are automatically managed by the TestCase and TestSuite … … 35 35 formatted traceback of the error that occurred. 36 36 """ 37 37 _previousTestClass = None 38 _testRunEntered = False 38 39 _moduleSetUpFailed = False 39 40 def __init__(self): 40 def __init__(self, stream=None, descriptions=None, verbosity=None): 41 41 self.failfast = False 42 42 self.failures = [] 43 43 self.errors = [] … … 53 53 self._original_stderr = sys.stderr 54 54 self._mirrorOutput = False 55 55 56 def printErrors(self): 57 "Called by TestRunner after test run" 58 56 59 def startTest(self, test): 57 60 "Called when the given test is about to be run" 58 61 self.testsRun += 1 59 62 self._mirrorOutput = False 63 self._setupStdout() 64 65 def _setupStdout(self): 60 66 if self.buffer: 61 67 if self._stderr_buffer is None: 62 68 self._stderr_buffer = StringIO() … … 72 78 73 79 def stopTest(self, test): 74 80 """Called when the given test has been run""" 81 self._restoreStdout() 82 self._mirrorOutput = False 83 84 def _restoreStdout(self): 75 85 if self.buffer: 76 86 if self._mirrorOutput: 77 87 output = sys.stdout.getvalue() … … 91 101 self._stdout_buffer.truncate() 92 102 self._stderr_buffer.seek(0) 93 103 self._stderr_buffer.truncate() 94 self._mirrorOutput = False95 96 104 97 105 def stopTestRun(self): 98 106 """Called once after all tests are executed. … … 135 143 136 144 def wasSuccessful(self): 137 145 "Tells whether or not this result was a success" 138 return (len(self.failures) + len(self.errors) == 0)146 return len(self.failures) == len(self.errors) == 0 139 147 140 148 def stop(self): 141 149 "Indicates that the tests should be aborted" … … 147 155 # Skip test runner traceback levels 148 156 while tb and self._is_relevant_tb_level(tb): 149 157 tb = tb.tb_next 158 150 159 if exctype is test.failureException: 151 160 # Skip assert*() traceback levels 152 161 length = self._count_relevant_tb_levels(tb) … … 167 176 msgLines.append(STDERR_LINE % error) 168 177 return ''.join(msgLines) 169 178 179 170 180 def _is_relevant_tb_level(self, tb): 171 181 return '__unittest' in tb.tb_frame.f_globals 172 182 … … 178 188 return length 179 189 180 190 def __repr__(self): 181 return "<%s run=%i errors=%i failures=%i>" % \191 return ("<%s run=%i errors=%i failures=%i>" % 182 192 (util.strclass(self.__class__), self.testsRun, len(self.errors), 183 len(self.failures)) 193 len(self.failures))) -
unittest/runner.py
diff -u -Naur -x .svn -x .DS_Store -x test -x '*.pyc' -w django/utils/unittest/runner.py /Users/myk/Downloads/cpython-eb3c9b74884c/Lib/unittest/runner.py
old new 2 2 3 3 import sys 4 4 import time 5 import unittest6 5 7 from django.utils.unittest import result 8 9 try: 10 from django.utils.unittest.signals import registerResult 11 except ImportError: 12 def registerResult(_): 13 pass 6 from . import result 7 from .signals import registerResult 14 8 15 9 __unittest = True 16 10 … … 87 81 def addSkip(self, test, reason): 88 82 super(TextTestResult, self).addSkip(test, reason) 89 83 if self.showAll: 90 self.stream.writeln("skipped %r" % (reason,))84 self.stream.writeln("skipped {0!r}".format(reason)) 91 85 elif self.dots: 92 86 self.stream.write("s") 93 87 self.stream.flush() … … 121 115 self.stream.writeln(self.separator2) 122 116 self.stream.writeln("%s" % err) 123 117 124 def stopTestRun(self):125 super(TextTestResult, self).stopTestRun()126 self.printErrors()127 128 118 129 class TextTestRunner( unittest.TextTestRunner):119 class TextTestRunner(object): 130 120 """A test runner class that displays results in textual form. 131 121 132 122 It prints out the names of tests as they are run, errors as they … … 150 140 def run(self, test): 151 141 "Run the given test case or test suite." 152 142 result = self._makeResult() 143 registerResult(result) 153 144 result.failfast = self.failfast 154 145 result.buffer = self.buffer 155 registerResult(result)156 157 146 startTime = time.time() 158 147 startTestRun = getattr(result, 'startTestRun', None) 159 148 if startTestRun is not None: … … 164 153 stopTestRun = getattr(result, 'stopTestRun', None) 165 154 if stopTestRun is not None: 166 155 stopTestRun() 167 else:168 result.printErrors()169 156 stopTime = time.time() 170 157 timeTaken = stopTime - startTime 158 result.printErrors() 171 159 if hasattr(result, 'separator2'): 172 160 self.stream.writeln(result.separator2) 173 161 run = result.testsRun … … 180 168 results = map(len, (result.expectedFailures, 181 169 result.unexpectedSuccesses, 182 170 result.skipped)) 183 expectedFails, unexpectedSuccesses, skipped = results184 171 except AttributeError: 185 172 pass 173 else: 174 expectedFails, unexpectedSuccesses, skipped = results 175 186 176 infos = [] 187 177 if not result.wasSuccessful(): 188 178 self.stream.write("FAILED") -
unittest/signals.py
diff -u -Naur -x .svn -x .DS_Store -x test -x '*.pyc' -w django/utils/unittest/signals.py /Users/myk/Downloads/cpython-eb3c9b74884c/Lib/unittest/signals.py
old new 1 1 import signal 2 2 import weakref 3 3 4 from django.utils.unittest.compatibilityimport wraps4 from functools import wraps 5 5 6 6 __unittest = True 7 7 -
unittest/suite.py
diff -u -Naur -x .svn -x .DS_Store -x test -x '*.pyc' -w django/utils/unittest/suite.py /Users/myk/Downloads/cpython-eb3c9b74884c/Lib/unittest/suite.py
old new 1 1 """TestSuite""" 2 2 3 3 import sys 4 import unittest 5 from django.utils.unittest import case, util 4 5 from . import case 6 from . import util 6 7 7 8 __unittest = True 8 9 9 10 10 class BaseTestSuite(unittest.TestSuite): 11 def _call_if_exists(parent, attr): 12 func = getattr(parent, attr, lambda: None) 13 func() 14 15 16 class BaseTestSuite(object): 11 17 """A simple test suite that doesn't provide class or module shared fixtures. 12 18 """ 13 19 def __init__(self, tests=()): … … 40 46 def addTest(self, test): 41 47 # sanity checks 42 48 if not hasattr(test, '__call__'): 43 raise TypeError(" %r is not callable" % (repr(test),))49 raise TypeError("{} is not callable".format(repr(test))) 44 50 if isinstance(test, type) and issubclass(test, 45 51 (case.TestCase, TestSuite)): 46 52 raise TypeError("TestCases and TestSuites must be instantiated " … … 79 85 subclassing, do not forget to call the base class constructor. 80 86 """ 81 87 88 def run(self, result, debug=False): 89 topLevel = False 90 if getattr(result, '_testRunEntered', False) is False: 91 result._testRunEntered = topLevel = True 82 92 83 def run(self, result):84 self._wrapped_run(result)85 self._tearDownPreviousClass(None, result)86 self._handleModuleTearDown(result)87 return result88 89 def debug(self):90 """Run the tests without collecting errors in a TestResult"""91 debug = _DebugResult()92 self._wrapped_run(debug, True)93 self._tearDownPreviousClass(None, debug)94 self._handleModuleTearDown(debug)95 96 ################################97 # private methods98 def _wrapped_run(self, result, debug=False):99 93 for test in self: 100 94 if result.shouldStop: 101 95 break … … 110 104 getattr(result, '_moduleSetUpFailed', False)): 111 105 continue 112 106 113 if hasattr(test, '_wrapped_run'): 114 test._wrapped_run(result, debug) 115 elif not debug: 107 if not debug: 116 108 test(result) 117 109 else: 118 110 test.debug() 119 111 112 if topLevel: 113 self._tearDownPreviousClass(None, result) 114 self._handleModuleTearDown(result) 115 result._testRunEntered = False 116 return result 117 118 def debug(self): 119 """Run the tests without collecting errors in a TestResult""" 120 debug = _DebugResult() 121 self.run(debug, True) 122 123 ################################ 124 120 125 def _handleClassSetUp(self, test, result): 121 126 previousClass = getattr(result, '_previousTestClass', None) 122 127 currentClass = test.__class__ … … 136 141 137 142 setUpClass = getattr(currentClass, 'setUpClass', None) 138 143 if setUpClass is not None: 144 _call_if_exists(result, '_setupStdout') 139 145 try: 140 146 setUpClass() 141 except Exception ,e:147 except Exception as e: 142 148 if isinstance(result, _DebugResult): 143 149 raise 144 150 currentClass._classSetupFailed = True 145 151 className = util.strclass(currentClass) 146 152 errorName = 'setUpClass (%s)' % className 147 153 self._addClassOrModuleLevelException(result, e, errorName) 154 finally: 155 _call_if_exists(result, '_restoreStdout') 148 156 149 157 def _get_previous_module(self, result): 150 158 previousModule = None … … 162 170 163 171 self._handleModuleTearDown(result) 164 172 165 166 173 result._moduleSetUpFailed = False 167 174 try: 168 175 module = sys.modules[currentModule] … … 170 177 return 171 178 setUpModule = getattr(module, 'setUpModule', None) 172 179 if setUpModule is not None: 180 _call_if_exists(result, '_setupStdout') 173 181 try: 174 182 setUpModule() 175 183 except Exception, e: … … 178 186 result._moduleSetUpFailed = True 179 187 errorName = 'setUpModule (%s)' % currentModule 180 188 self._addClassOrModuleLevelException(result, e, errorName) 189 finally: 190 _call_if_exists(result, '_restoreStdout') 181 191 182 192 def _addClassOrModuleLevelException(self, result, exception, errorName): 183 193 error = _ErrorHolder(errorName) … … 201 211 202 212 tearDownModule = getattr(module, 'tearDownModule', None) 203 213 if tearDownModule is not None: 214 _call_if_exists(result, '_setupStdout') 204 215 try: 205 216 tearDownModule() 206 except Exception ,e:217 except Exception as e: 207 218 if isinstance(result, _DebugResult): 208 219 raise 209 220 errorName = 'tearDownModule (%s)' % previousModule 210 221 self._addClassOrModuleLevelException(result, e, errorName) 222 finally: 223 _call_if_exists(result, '_restoreStdout') 211 224 212 225 def _tearDownPreviousClass(self, test, result): 213 226 previousClass = getattr(result, '_previousTestClass', None) … … 223 236 224 237 tearDownClass = getattr(previousClass, 'tearDownClass', None) 225 238 if tearDownClass is not None: 239 _call_if_exists(result, '_setupStdout') 226 240 try: 227 241 tearDownClass() 228 242 except Exception, e: … … 231 245 className = util.strclass(previousClass) 232 246 errorName = 'tearDownClass (%s)' % className 233 247 self._addClassOrModuleLevelException(result, e, errorName) 248 finally: 249 _call_if_exists(result, '_restoreStdout') 234 250 235 251 236 252 class _ErrorHolder(object): -
unittest/util.py
diff -u -Naur -x .svn -x .DS_Store -x test -x '*.pyc' -w django/utils/unittest/util.py /Users/myk/Downloads/cpython-eb3c9b74884c/Lib/unittest/util.py
old new 1 1 """Various utility functions.""" 2 from collections import namedtuple, OrderedDict 2 3 3 __unittest = True4 4 5 __unittest = True 5 6 6 7 _MAX_LENGTH = 80 7 8 def safe_repr(obj, short=False): … … 13 14 return result 14 15 return result[:_MAX_LENGTH] + ' [truncated]...' 15 16 16 def safe_str(obj):17 try:18 return str(obj)19 except Exception:20 return object.__str__(obj)21 17 22 18 def strclass(cls): 23 19 return "%s.%s" % (cls.__module__, cls.__name__) … … 62 58 break 63 59 return missing, unexpected 64 60 61 65 62 def unorderable_list_difference(expected, actual, ignore_duplicate=False): 66 63 """Same behavior as sorted_list_difference but 67 64 for lists of unorderable items (like dicts). … … 97 94 98 95 # anything left in actual is unexpected 99 96 return missing, actual 97 98 _Mismatch = namedtuple('Mismatch', 'actual expected value') 99 100 def _count_diff_all_purpose(actual, expected): 101 'Returns list of (cnt_act, cnt_exp, elem) triples where the counts differ' 102 # elements need not be hashable 103 s, t = list(actual), list(expected) 104 m, n = len(s), len(t) 105 NULL = object() 106 result = [] 107 for i, elem in enumerate(s): 108 if elem is NULL: 109 continue 110 cnt_s = cnt_t = 0 111 for j in range(i, m): 112 if s[j] == elem: 113 cnt_s += 1 114 s[j] = NULL 115 for j, other_elem in enumerate(t): 116 if other_elem == elem: 117 cnt_t += 1 118 t[j] = NULL 119 if cnt_s != cnt_t: 120 diff = _Mismatch(cnt_s, cnt_t, elem) 121 result.append(diff) 122 123 for i, elem in enumerate(t): 124 if elem is NULL: 125 continue 126 cnt_t = 0 127 for j in range(i, n): 128 if t[j] == elem: 129 cnt_t += 1 130 t[j] = NULL 131 diff = _Mismatch(0, cnt_t, elem) 132 result.append(diff) 133 return result 134 135 def _ordered_count(iterable): 136 'Return dict of element counts, in the order they were first seen' 137 c = OrderedDict() 138 for elem in iterable: 139 c[elem] = c.get(elem, 0) + 1 140 return c 141 142 def _count_diff_hashable(actual, expected): 143 'Returns list of (cnt_act, cnt_exp, elem) triples where the counts differ' 144 # elements must be hashable 145 s, t = _ordered_count(actual), _ordered_count(expected) 146 result = [] 147 for elem, cnt_s in s.items(): 148 cnt_t = t.get(elem, 0) 149 if cnt_s != cnt_t: 150 diff = _Mismatch(cnt_s, cnt_t, elem) 151 result.append(diff) 152 for elem, cnt_t in t.items(): 153 if elem not in s: 154 diff = _Mismatch(0, cnt_t, elem) 155 result.append(diff) 156 return result