diff -r c95864a37ee2 Doc/library/unittest.rst --- a/Doc/library/unittest.rst Sun May 29 01:40:22 2016 -0400 +++ b/Doc/library/unittest.rst Sun May 29 18:15:14 2016 +0300 @@ -1423,6 +1423,56 @@ Test cases :mod:`unittest`-based test framework. +.. class:: ExtraAssertions + + The :class:`ExtraAssertions` mix-in provides additional assert methods. + Subclass test class from both :class:`TestCase` and :class:`!ExtraAssertions` + for using them in test methods. + + .. versionadded:: 3.6 + + +-----------------------------------------+-----------------------------+---------------+ + | Method | Checks that | New in | + +=========================================+=============================+===============+ + | :meth:`assertHasAttr(a, b) | ``hastattr(a, b)`` | 3.6 | + | ` | | | + +-----------------------------------------+-----------------------------+---------------+ + | :meth:`assertNotHasAttr(a, b) | ``not hastattr(a, b)`` | 3.6 | + | ` | | | + +-----------------------------------------+-----------------------------+---------------+ + | :meth:`assertIsSubclass(a, b) | ``issubclass(a, b)`` | 3.6 | + | ` | | | + +-----------------------------------------+-----------------------------+---------------+ + | :meth:`assertNotIsSubclass(a, b) | ``not issubclass(a, b)`` | 3.6 | + | ` | | | + +-----------------------------------------+-----------------------------+---------------+ + | :meth:`assertStartsWith(a, b) | ``a.startswith(b)`` | 3.6 | + | ` | | | + +-----------------------------------------+-----------------------------+---------------+ + | :meth:`assertEndsWith(a, b) | ``a.endswith(b)`` | 3.6 | + | ` | | | + +-----------------------------------------+-----------------------------+---------------+ + + .. method:: assertHasAttr(obj, name, msg=None) + .. method:: assertNotHasAttr(obj, name, msg=None) + + Test that the object *obj* has (or has not) an attribute *name*. + + .. method:: assertIsSubclass(cls, superclass, msg=None) + assertNotIsSubclass(cls, superclass, msg=None) + + Test that *cls* is (or is not) a subclass of *superclass*. To check + for the exact type, use :func:`assertIs(cls, superclass) `. + + .. method:: assertStartsWith(s, prefix, msg=None) + + Test that the unicode or byte string *s* starts with a *prefix*. + + .. method:: assertEndsWith(s, suffix, msg=None) + + Test that the unicode or byte string *s* ends with a *suffix*. + + .. _deprecated-aliases: Deprecated aliases diff -r c95864a37ee2 Doc/whatsnew/3.6.rst --- a/Doc/whatsnew/3.6.rst Sun May 29 01:40:22 2016 -0400 +++ b/Doc/whatsnew/3.6.rst Sun May 29 18:15:14 2016 +0300 @@ -364,6 +364,19 @@ representing :class:`contextlib.Abstract (Contributed by Brett Cannon in :issue:`25609`.) +unittest +-------- + +The :class:`unittest.ExtraAssertions` mix-in provides additional assertions: +:meth:`~unittest.ExtraAssertions.assertHasAttr`, +:meth:`~unittest.ExtraAssertions.assertNotHasAttr`, +:meth:`~unittest.ExtraAssertions.assertIsSubclass`, +:meth:`~unittest.ExtraAssertions.assertNotIsSubclass`, +:meth:`~unittest.ExtraAssertions.assertStartsWith`, +and :meth:`~unittest.ExtraAssertions.assertEndsWith`. +(Contributed by Serhiy Storchaka in :issue:`XXXXX`.) + + unittest.mock ------------- diff -r c95864a37ee2 Lib/ctypes/test/test_random_things.py --- a/Lib/ctypes/test/test_random_things.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/ctypes/test/test_random_things.py Sun May 29 18:15:14 2016 +0300 @@ -22,7 +22,7 @@ class call_function_TestCase(unittest.Te self.assertEqual(call_function(funcaddr, (None,)), windll.kernel32.GetModuleHandleA(None)) -class CallbackTracbackTestCase(unittest.TestCase): +class CallbackTracbackTestCase(unittest.TestCase, unittest.ExtraAssertions): # When an exception is raised in a ctypes callback function, the C # code prints a traceback. # @@ -54,14 +54,14 @@ class CallbackTracbackTestCase(unittest. def test_IntegerDivisionError(self): cb = CFUNCTYPE(c_int, c_int)(callback_func) out = self.capture_stderr(cb, 0) - self.assertEqual(out.splitlines()[-1][:19], - "ZeroDivisionError: ") + self.assertStartsWith(out.splitlines()[-1], + "ZeroDivisionError: ") def test_FloatDivisionError(self): cb = CFUNCTYPE(c_int, c_double)(callback_func) out = self.capture_stderr(cb, 0.0) - self.assertEqual(out.splitlines()[-1][:19], - "ZeroDivisionError: ") + self.assertStartsWith(out.splitlines()[-1], + "ZeroDivisionError: ") def test_TypeErrorDivisionError(self): cb = CFUNCTYPE(c_int, c_char_p)(callback_func) diff -r c95864a37ee2 Lib/ctypes/test/test_repr.py --- a/Lib/ctypes/test/test_repr.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/ctypes/test/test_repr.py Sun May 29 18:15:14 2016 +0300 @@ -14,16 +14,16 @@ class X(c_char): # This test checks if the __repr__ is correct for subclasses of simple types -class ReprTest(unittest.TestCase): +class ReprTest(unittest.TestCase, unittest.ExtraAssertions): def test_numbers(self): for typ in subclasses: base = typ.__bases__[0] - self.assertTrue(repr(base(42)).startswith(base.__name__)) - self.assertEqual(" string -> td identity. s = repr(td) - self.assertTrue(s.startswith('datetime.')) + self.assertStartsWith(s, 'datetime.') s = s[9:] td2 = eval(s) self.assertEqual(td, td2) @@ -876,7 +876,7 @@ class TestDateOnly(unittest.TestCase): class SubclassDate(date): sub_var = 1 -class TestDate(HarmlessMixedComparison, unittest.TestCase): +class TestDate(HarmlessMixedComparison, unittest.TestCase, unittest.ExtraAssertions): # Tests here should pass for both dates and datetimes, except for a # few tests that TestDateTime overrides. @@ -893,7 +893,7 @@ class TestDate(HarmlessMixedComparison, self.theclass.today()): # Verify dt -> string -> date identity. s = repr(dt) - self.assertTrue(s.startswith('datetime.')) + self.assertStartsWith(s, 'datetime.') s = s[9:] dt2 = eval(s) self.assertEqual(dt, dt2) @@ -1547,7 +1547,7 @@ class TestDateTime(TestDate): self.theclass.now()): # Verify dt -> string -> datetime identity. s = repr(dt) - self.assertTrue(s.startswith('datetime.')) + self.assertStartsWith(s, 'datetime.') s = s[9:] dt2 = eval(s) self.assertEqual(dt, dt2) @@ -2188,7 +2188,7 @@ class TestSubclassDateTime(TestDateTime) class SubclassTime(time): sub_var = 1 -class TestTime(HarmlessMixedComparison, unittest.TestCase): +class TestTime(HarmlessMixedComparison, unittest.TestCase, unittest.ExtraAssertions): theclass = time @@ -2213,7 +2213,7 @@ class TestTime(HarmlessMixedComparison, # Verify t -> string -> time identity. s = repr(t) - self.assertTrue(s.startswith('datetime.')) + self.assertStartsWith(s, 'datetime.') s = s[9:] t2 = eval(s) self.assertEqual(t, t2) diff -r c95864a37ee2 Lib/test/mapping_tests.py --- a/Lib/test/mapping_tests.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/mapping_tests.py Sun May 29 18:15:14 2016 +0300 @@ -3,7 +3,7 @@ import unittest import collections -class BasicTestMappingProtocol(unittest.TestCase): +class BasicTestMappingProtocol(unittest.TestCase, unittest.ExtraAssertions): # This base class can be used to check that an object conforms to the # mapping protocol @@ -69,8 +69,8 @@ class BasicTestMappingProtocol(unittest. if not d: self.fail("Full mapping must compare to True") # keys(), items(), iterkeys() ... def check_iterandlist(iter, lst, ref): - self.assertTrue(hasattr(iter, '__next__')) - self.assertTrue(hasattr(iter, '__iter__')) + self.assertHasAttr(iter, '__next__') + self.assertHasAttr(iter, '__iter__') x = list(iter) self.assertTrue(set(x)==set(lst)==set(ref)) check_iterandlist(iter(d.keys()), list(d.keys()), diff -r c95864a37ee2 Lib/test/pickletester.py --- a/Lib/test/pickletester.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/pickletester.py Sun May 29 18:15:14 2016 +0300 @@ -1175,7 +1175,7 @@ class AbstractUnpickleTests(unittest.Tes self.check_unpickling_error(self.truncated_errors, p) -class AbstractPickleTests(unittest.TestCase): +class AbstractPickleTests(unittest.TestCase, unittest.ExtraAssertions): # Subclass must define self.dumps, self.loads. optimized = False @@ -1542,7 +1542,7 @@ class AbstractPickleTests(unittest.TestC pickled = self.dumps(None, proto) if proto >= 2: proto_header = pickle.PROTO + bytes([proto]) - self.assertTrue(pickled.startswith(proto_header)) + self.assertStartsWith(pickled, proto_header) else: self.assertEqual(count_opcode(pickle.PROTO, pickled), 0) @@ -2786,7 +2786,7 @@ class AAA(object): class BBB(object): pass -class AbstractDispatchTableTests(unittest.TestCase): +class AbstractDispatchTableTests(unittest.TestCase, unittest.ExtraAssertions): def test_default_dispatch_table(self): # No dispatch_table attribute by default @@ -2794,7 +2794,7 @@ class AbstractDispatchTableTests(unittes p = self.pickler_class(f, 0) with self.assertRaises(AttributeError): p.dispatch_table - self.assertFalse(hasattr(p, 'dispatch_table')) + self.assertNotHasAttr(p, 'dispatch_table') def test_class_dispatch_table(self): # A dispatch_table attribute can be specified class-wide diff -r c95864a37ee2 Lib/test/test__osx_support.py --- a/Lib/test/test__osx_support.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test__osx_support.py Sun May 29 18:15:14 2016 +0300 @@ -13,7 +13,7 @@ import test.support import _osx_support @unittest.skipUnless(sys.platform.startswith("darwin"), "requires OS X") -class Test_OSXSupport(unittest.TestCase): +class Test_OSXSupport(unittest.TestCase, unittest.ExtraAssertions): def setUp(self): self.maxDiff = None @@ -66,8 +66,8 @@ class Test_OSXSupport(unittest.TestCase) 'cc not found - check xcode-select') def test__get_system_version(self): - self.assertTrue(platform.mac_ver()[0].startswith( - _osx_support._get_system_version())) + self.assertStartsWith(platform.mac_ver()[0], + _osx_support._get_system_version()) def test__remove_original_values(self): config_vars = { diff -r c95864a37ee2 Lib/test/test_abc.py --- a/Lib/test/test_abc.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_abc.py Sun May 29 18:15:14 2016 +0300 @@ -10,14 +10,14 @@ import abc from inspect import isabstract -class TestLegacyAPI(unittest.TestCase): +class TestLegacyAPI(unittest.TestCase, unittest.ExtraAssertions): def test_abstractproperty_basics(self): @abc.abstractproperty def foo(self): pass self.assertTrue(foo.__isabstractmethod__) def bar(self): pass - self.assertFalse(hasattr(bar, "__isabstractmethod__")) + self.assertNotHasAttr(bar, "__isabstractmethod__") class C(metaclass=abc.ABCMeta): @abc.abstractproperty @@ -66,7 +66,7 @@ class TestLegacyAPI(unittest.TestCase): self.assertEqual(D().foo(), 4) -class TestABC(unittest.TestCase): +class TestABC(unittest.TestCase, unittest.ExtraAssertions): def test_ABC_helper(self): # create an ABC using the helper class and perform basic checks @@ -86,7 +86,7 @@ class TestABC(unittest.TestCase): def foo(self): pass self.assertTrue(foo.__isabstractmethod__) def bar(self): pass - self.assertFalse(hasattr(bar, "__isabstractmethod__")) + self.assertNotHasAttr(bar, "__isabstractmethod__") def test_abstractproperty_basics(self): @property @@ -254,21 +254,21 @@ class TestABC(unittest.TestCase): class B(object): pass b = B() - self.assertFalse(issubclass(B, A)) - self.assertFalse(issubclass(B, (A,))) + self.assertNotIsSubclass(B, A) + self.assertNotIsSubclass(B, (A,)) self.assertNotIsInstance(b, A) self.assertNotIsInstance(b, (A,)) B1 = A.register(B) - self.assertTrue(issubclass(B, A)) - self.assertTrue(issubclass(B, (A,))) + self.assertIsSubclass(B, A) + self.assertIsSubclass(B, (A,)) self.assertIsInstance(b, A) self.assertIsInstance(b, (A,)) self.assertIs(B1, B) class C(B): pass c = C() - self.assertTrue(issubclass(C, A)) - self.assertTrue(issubclass(C, (A,))) + self.assertIsSubclass(C, A) + self.assertIsSubclass(C, (A,)) self.assertIsInstance(c, A) self.assertIsInstance(c, (A,)) @@ -279,16 +279,16 @@ class TestABC(unittest.TestCase): class B(object): pass b = B() - self.assertTrue(issubclass(B, A)) - self.assertTrue(issubclass(B, (A,))) + self.assertIsSubclass(B, A) + self.assertIsSubclass(B, (A,)) self.assertIsInstance(b, A) self.assertIsInstance(b, (A,)) @A.register class C(B): pass c = C() - self.assertTrue(issubclass(C, A)) - self.assertTrue(issubclass(C, (A,))) + self.assertIsSubclass(C, A) + self.assertIsSubclass(C, (A,)) self.assertIsInstance(c, A) self.assertIsInstance(c, (A,)) self.assertIs(C, A.register(C)) @@ -314,18 +314,18 @@ class TestABC(unittest.TestCase): A.register(int) self.assertIsInstance(42, A) self.assertIsInstance(42, (A,)) - self.assertTrue(issubclass(int, A)) - self.assertTrue(issubclass(int, (A,))) + self.assertIsSubclass(int, A) + self.assertIsSubclass(int, (A,)) class B(A): pass B.register(str) class C(str): pass self.assertIsInstance("", A) self.assertIsInstance("", (A,)) - self.assertTrue(issubclass(str, A)) - self.assertTrue(issubclass(str, (A,))) - self.assertTrue(issubclass(C, A)) - self.assertTrue(issubclass(C, (A,))) + self.assertIsSubclass(str, A) + self.assertIsSubclass(str, (A,)) + self.assertIsSubclass(C, A) + self.assertIsSubclass(C, (A,)) def test_registration_edge_cases(self): class A(metaclass=abc.ABCMeta): @@ -353,39 +353,39 @@ class TestABC(unittest.TestCase): def test_registration_transitiveness(self): class A(metaclass=abc.ABCMeta): pass - self.assertTrue(issubclass(A, A)) - self.assertTrue(issubclass(A, (A,))) + self.assertIsSubclass(A, A) + self.assertIsSubclass(A, (A,)) class B(metaclass=abc.ABCMeta): pass - self.assertFalse(issubclass(A, B)) - self.assertFalse(issubclass(A, (B,))) - self.assertFalse(issubclass(B, A)) - self.assertFalse(issubclass(B, (A,))) + self.assertNotIsSubclass(A, B) + self.assertNotIsSubclass(A, (B,)) + self.assertNotIsSubclass(B, A) + self.assertNotIsSubclass(B, (A,)) class C(metaclass=abc.ABCMeta): pass A.register(B) class B1(B): pass - self.assertTrue(issubclass(B1, A)) - self.assertTrue(issubclass(B1, (A,))) + self.assertIsSubclass(B1, A) + self.assertIsSubclass(B1, (A,)) class C1(C): pass B1.register(C1) - self.assertFalse(issubclass(C, B)) - self.assertFalse(issubclass(C, (B,))) - self.assertFalse(issubclass(C, B1)) - self.assertFalse(issubclass(C, (B1,))) - self.assertTrue(issubclass(C1, A)) - self.assertTrue(issubclass(C1, (A,))) - self.assertTrue(issubclass(C1, B)) - self.assertTrue(issubclass(C1, (B,))) - self.assertTrue(issubclass(C1, B1)) - self.assertTrue(issubclass(C1, (B1,))) + self.assertNotIsSubclass(C, B) + self.assertNotIsSubclass(C, (B,)) + self.assertNotIsSubclass(C, B1) + self.assertNotIsSubclass(C, (B1,)) + self.assertIsSubclass(C1, A) + self.assertIsSubclass(C1, (A,)) + self.assertIsSubclass(C1, B) + self.assertIsSubclass(C1, (B,)) + self.assertIsSubclass(C1, B1) + self.assertIsSubclass(C1, (B1,)) C1.register(int) class MyInt(int): pass - self.assertTrue(issubclass(MyInt, A)) - self.assertTrue(issubclass(MyInt, (A,))) + self.assertIsSubclass(MyInt, A) + self.assertIsSubclass(MyInt, (A,)) self.assertIsInstance(42, A) self.assertIsInstance(42, (A,)) diff -r c95864a37ee2 Lib/test/test_abstract_numbers.py --- a/Lib/test/test_abstract_numbers.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_abstract_numbers.py Sun May 29 18:15:14 2016 +0300 @@ -5,10 +5,10 @@ import operator import unittest from numbers import Complex, Real, Rational, Integral -class TestNumbers(unittest.TestCase): +class TestNumbers(unittest.TestCase, unittest.ExtraAssertions): def test_int(self): - self.assertTrue(issubclass(int, Integral)) - self.assertTrue(issubclass(int, Complex)) + self.assertIsSubclass(int, Integral) + self.assertIsSubclass(int, Complex) self.assertEqual(7, int(7).real) self.assertEqual(0, int(7).imag) @@ -18,8 +18,8 @@ class TestNumbers(unittest.TestCase): self.assertEqual(1, int(7).denominator) def test_float(self): - self.assertFalse(issubclass(float, Rational)) - self.assertTrue(issubclass(float, Real)) + self.assertNotIsSubclass(float, Rational) + self.assertIsSubclass(float, Real) self.assertEqual(7.3, float(7.3).real) self.assertEqual(0, float(7.3).imag) @@ -27,8 +27,8 @@ class TestNumbers(unittest.TestCase): self.assertEqual(-7.3, float(-7.3).conjugate()) def test_complex(self): - self.assertFalse(issubclass(complex, Real)) - self.assertTrue(issubclass(complex, Complex)) + self.assertNotIsSubclass(complex, Real) + self.assertIsSubclass(complex, Complex) c1, c2 = complex(3, 2), complex(4,1) # XXX: This is not ideal, but see the comment in math_trunc(). diff -r c95864a37ee2 Lib/test/test_argparse.py --- a/Lib/test/test_argparse.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_argparse.py Sun May 29 18:15:14 2016 +0300 @@ -4962,11 +4962,11 @@ class TestAddArgumentMetavar(TestCase): # from argparse import * tests # ============================ -class TestImportStar(TestCase): +class TestImportStar(TestCase, unittest.ExtraAssertions): def test(self): for name in argparse.__all__: - self.assertTrue(hasattr(argparse, name)) + self.assertHasAttr(argparse, name) def test_all_exports_everything_but_modules(self): items = [ diff -r c95864a37ee2 Lib/test/test_ast.py --- a/Lib/test/test_ast.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_ast.py Sun May 29 18:15:14 2016 +0300 @@ -188,7 +188,7 @@ eval_tests = [ # TODO: expr_context, slice, boolop, operator, unaryop, cmpop, comprehension # excepthandler, arguments, keywords, alias -class AST_Tests(unittest.TestCase): +class AST_Tests(unittest.TestCase, unittest.ExtraAssertions): def _assertTrueorder(self, ast_node, parent_pos): if not isinstance(ast_node, ast.AST) or ast_node._fields is None: @@ -259,12 +259,12 @@ class AST_Tests(unittest.TestCase): compile(mod, "", "exec") def test_base_classes(self): - self.assertTrue(issubclass(ast.For, ast.stmt)) - self.assertTrue(issubclass(ast.Name, ast.expr)) - self.assertTrue(issubclass(ast.stmt, ast.AST)) - self.assertTrue(issubclass(ast.expr, ast.AST)) - self.assertTrue(issubclass(ast.comprehension, ast.AST)) - self.assertTrue(issubclass(ast.Gt, ast.AST)) + self.assertIsSubclass(ast.For, ast.stmt) + self.assertIsSubclass(ast.Name, ast.expr) + self.assertIsSubclass(ast.stmt, ast.AST) + self.assertIsSubclass(ast.expr, ast.AST) + self.assertIsSubclass(ast.comprehension, ast.AST) + self.assertIsSubclass(ast.Gt, ast.AST) def test_field_attr_existence(self): for name, item in ast.__dict__.items(): diff -r c95864a37ee2 Lib/test/test_asyncio/test_base_events.py --- a/Lib/test/test_asyncio/test_base_events.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_asyncio/test_base_events.py Sun May 29 18:15:14 2016 +0300 @@ -1012,7 +1012,7 @@ class MyDatagramProto(asyncio.DatagramPr self.done.set_result(None) -class BaseEventLoopWithSelectorTests(test_utils.TestCase): +class BaseEventLoopWithSelectorTests(test_utils.TestCase, unittest.ExtraAssertions): def setUp(self): self.loop = asyncio.new_event_loop() @@ -1163,7 +1163,7 @@ class BaseEventLoopWithSelectorTests(tes with self.assertRaises(OSError) as cm: self.loop.run_until_complete(coro) - self.assertTrue(str(cm.exception).startswith('Multiple exceptions: ')) + self.assertStartsWith(str(cm.exception), 'Multiple exceptions: ') self.assertTrue(m_socket.socket.return_value.close.called) def _test_create_connection_ip_addr(self, m_socket, allow_inet_pton): diff -r c95864a37ee2 Lib/test/test_asyncio/test_events.py --- a/Lib/test/test_asyncio/test_events.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_asyncio/test_events.py Sun May 29 18:15:14 2016 +0300 @@ -232,7 +232,7 @@ class MySubprocessProtocol(asyncio.Subpr self.returncode = self.transport.get_returncode() -class EventLoopTestsMixin: +class EventLoopTestsMixin(unittest.ExtraAssertions): def setUp(self): super().setUp() @@ -427,7 +427,7 @@ class EventLoopTestsMixin: self.loop.run_until_complete( self.loop.sock_recv(sock, 1024)) sock.close() - self.assertTrue(data.startswith(b'HTTP/1.0 200 OK')) + self.assertStartsWith(data, b'HTTP/1.0 200 OK') def test_sock_client_ops(self): with test_utils.run_test_server() as httpd: @@ -1695,7 +1695,7 @@ class EventLoopTestsMixin: self.loop.add_signal_handler(signal.SIGTERM, func) -class SubprocessTestsMixin: +class SubprocessTestsMixin(unittest.ExtraAssertions): def check_terminated(self, returncode): if sys.platform == 'win32': @@ -1859,7 +1859,7 @@ class SubprocessTestsMixin: transp.close() self.assertEqual(b'OUT:test', proto.data[1]) - self.assertTrue(proto.data[2].startswith(b'ERR:test'), proto.data[2]) + self.assertStartsWith(proto.data[2], b'ERR:test') self.assertEqual(0, proto.returncode) def test_subprocess_stderr_redirect_to_stdout(self): @@ -1878,8 +1878,7 @@ class SubprocessTestsMixin: stdin.write(b'test') self.loop.run_until_complete(proto.completed) - self.assertTrue(proto.data[1].startswith(b'OUT:testERR:test'), - proto.data[1]) + self.assertStartsWith(proto.data[1], b'OUT:testERR:test') self.assertEqual(b'', proto.data[2]) transp.close() diff -r c95864a37ee2 Lib/test/test_asyncio/test_locks.py --- a/Lib/test/test_asyncio/test_locks.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_asyncio/test_locks.py Sun May 29 18:15:14 2016 +0300 @@ -16,7 +16,7 @@ STR_RGX_REPR = ( RGX_REPR = re.compile(STR_RGX_REPR) -class LockTests(test_utils.TestCase): +class LockTests(test_utils.TestCase, unittest.ExtraAssertions): def setUp(self): self.loop = self.new_test_loop() @@ -36,7 +36,7 @@ class LockTests(test_utils.TestCase): def test_repr(self): lock = asyncio.Lock(loop=self.loop) - self.assertTrue(repr(lock).endswith('[unlocked]>')) + self.assertEndsWith(repr(lock), '[unlocked]>') self.assertTrue(RGX_REPR.match(repr(lock))) @asyncio.coroutine @@ -44,7 +44,7 @@ class LockTests(test_utils.TestCase): yield from lock self.loop.run_until_complete(acquire_lock()) - self.assertTrue(repr(lock).endswith('[locked]>')) + self.assertEndsWith(repr(lock), '[locked]>') self.assertTrue(RGX_REPR.match(repr(lock))) def test_lock(self): @@ -232,7 +232,7 @@ class LockTests(test_utils.TestCase): self.assertFalse(lock.locked()) -class EventTests(test_utils.TestCase): +class EventTests(test_utils.TestCase, unittest.ExtraAssertions): def setUp(self): self.loop = self.new_test_loop() @@ -252,12 +252,12 @@ class EventTests(test_utils.TestCase): def test_repr(self): ev = asyncio.Event(loop=self.loop) - self.assertTrue(repr(ev).endswith('[unset]>')) + self.assertEndsWith(repr(ev), '[unset]>') match = RGX_REPR.match(repr(ev)) self.assertEqual(match.group('extras'), 'unset') ev.set() - self.assertTrue(repr(ev).endswith('[set]>')) + self.assertEndsWith(repr(ev), '[set]>') self.assertTrue(RGX_REPR.match(repr(ev))) ev._waiters.append(mock.Mock()) @@ -671,7 +671,7 @@ class ConditionTests(test_utils.TestCase asyncio.Condition(lock, loop=loop) -class SemaphoreTests(test_utils.TestCase): +class SemaphoreTests(test_utils.TestCase, unittest.ExtraAssertions): def setUp(self): self.loop = self.new_test_loop() @@ -695,11 +695,11 @@ class SemaphoreTests(test_utils.TestCase def test_repr(self): sem = asyncio.Semaphore(loop=self.loop) - self.assertTrue(repr(sem).endswith('[unlocked,value:1]>')) + self.assertEndsWith(repr(sem), '[unlocked,value:1]>') self.assertTrue(RGX_REPR.match(repr(sem))) self.loop.run_until_complete(sem.acquire()) - self.assertTrue(repr(sem).endswith('[locked]>')) + self.assertEndsWith(repr(sem), '[locked]>') self.assertTrue('waiters' not in repr(sem)) self.assertTrue(RGX_REPR.match(repr(sem))) diff -r c95864a37ee2 Lib/test/test_asyncio/test_queues.py --- a/Lib/test/test_asyncio/test_queues.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_asyncio/test_queues.py Sun May 29 18:15:14 2016 +0300 @@ -13,7 +13,7 @@ class _QueueTestBase(test_utils.TestCase self.loop = self.new_test_loop() -class QueueBasicTests(_QueueTestBase): +class QueueBasicTests(_QueueTestBase, unittest.ExtraAssertions): def _test_repr_or_str(self, fn, expect_id): """Test Queue's repr or str. @@ -31,7 +31,7 @@ class QueueBasicTests(_QueueTestBase): loop = self.new_test_loop(gen) q = asyncio.Queue(loop=loop) - self.assertTrue(fn(q).startswith('.func(1)() running, ') - self.assertTrue(coro_repr.startswith(expected), - coro_repr) + self.assertStartsWith(coro_repr, expected) def test_task_basics(self): @asyncio.coroutine diff -r c95864a37ee2 Lib/test/test_asyncio/test_windows_utils.py --- a/Lib/test/test_asyncio/test_windows_utils.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_asyncio/test_windows_utils.py Sun May 29 18:15:14 2016 +0300 @@ -128,7 +128,7 @@ class PipeTests(unittest.TestCase): raise RuntimeError('expected ERROR_INVALID_HANDLE') -class PopenTests(unittest.TestCase): +class PopenTests(unittest.TestCase, unittest.ExtraAssertions): def test_popen(self): command = r"""if 1: @@ -170,8 +170,8 @@ class PopenTests(unittest.TestCase): self.assertGreater(len(out), 0) self.assertGreater(len(err), 0) # allow for partial reads... - self.assertTrue(msg.upper().rstrip().startswith(out)) - self.assertTrue(b"stderr".startswith(err)) + self.assertStartsWith(msg.upper().rstrip(), out) + self.assertStartsWith(b"stderr", err) # The context manager calls wait() and closes resources with p: diff -r c95864a37ee2 Lib/test/test_base64.py --- a/Lib/test/test_base64.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_base64.py Sun May 29 18:15:14 2016 +0300 @@ -85,7 +85,7 @@ class LegacyBase64TestCase(unittest.Test self.assertRaises(TypeError, base64.encode, StringIO('YWJj\n'), StringIO()) -class BaseXYTestCase(unittest.TestCase): +class BaseXYTestCase(unittest.TestCase, unittest.ExtraAssertions): # Modern API completely ignores exported dimension and format data and # treats any buffer as a stream of bytes @@ -632,7 +632,7 @@ class BaseXYTestCase(unittest.TestCase): self.assertRaises(ValueError, f, 'with non-ascii \xcb') def test_ErrorHeritage(self): - self.assertTrue(issubclass(binascii.Error, ValueError)) + self.assertIsSubclass(binascii.Error, ValueError) class TestMain(unittest.TestCase): diff -r c95864a37ee2 Lib/test/test_binascii.py --- a/Lib/test/test_binascii.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_binascii.py Sun May 29 18:15:14 2016 +0300 @@ -12,7 +12,7 @@ a2b_functions = ['a2b_base64', 'a2b_hex' all_functions = a2b_functions + b2a_functions + ['crc32', 'crc_hqx'] -class BinASCIITest(unittest.TestCase): +class BinASCIITest(unittest.TestCase, unittest.ExtraAssertions): type2test = bytes # Create binary test data @@ -26,13 +26,13 @@ class BinASCIITest(unittest.TestCase): def test_exceptions(self): # Check module exceptions - self.assertTrue(issubclass(binascii.Error, Exception)) - self.assertTrue(issubclass(binascii.Incomplete, Exception)) + self.assertIsSubclass(binascii.Error, Exception) + self.assertIsSubclass(binascii.Incomplete, Exception) def test_functions(self): # Check presence of all functions for name in all_functions: - self.assertTrue(hasattr(getattr(binascii, name), '__call__')) + self.assertHasAttr(getattr(binascii, name), '__call__') self.assertRaises(TypeError, getattr(binascii, name)) def test_returned_value(self): diff -r c95864a37ee2 Lib/test/test_buffer.py --- a/Lib/test/test_buffer.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_buffer.py Sun May 29 18:15:14 2016 +0300 @@ -754,7 +754,7 @@ if SHORT_TEST: @unittest.skipUnless(struct, 'struct module required for this test.') @unittest.skipUnless(ndarray, 'ndarray object required for this test') -class TestBufferProtocol(unittest.TestCase): +class TestBufferProtocol(unittest.TestCase, unittest.ExtraAssertions): def setUp(self): # The suboffsets tests need sizeof(void *). @@ -2835,11 +2835,11 @@ class TestBufferProtocol(unittest.TestCa def test_memoryview_repr(self): m = memoryview(bytearray(9)) r = m.__repr__() - self.assertTrue(r.startswith("Calendar for 2004', stdout) def test_html_output_current_year(self): diff -r c95864a37ee2 Lib/test/test_capi.py --- a/Lib/test/test_capi.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_capi.py Sun May 29 18:15:14 2016 +0300 @@ -37,7 +37,7 @@ class InstanceMethod: id = _testcapi.instancemethod(id) testfunction = _testcapi.instancemethod(testfunction) -class CAPITest(unittest.TestCase): +class CAPITest(unittest.TestCase, unittest.ExtraAssertions): def test_instancemethod(self): inst = InstanceMethod() @@ -61,9 +61,9 @@ class CAPITest(unittest.TestCase): (out, err) = p.communicate() self.assertEqual(out, b'') # This used to cause an infinite loop. - self.assertTrue(err.rstrip().startswith( - b'Fatal Python error:' - b' PyThreadState_Get: no current thread')) + self.assertStartsWith(err.rstrip(), + b'Fatal Python error:' + b' PyThreadState_Get: no current thread') def test_memoryview_from_NULL_pointer(self): self.assertRaises(ValueError, _testcapi.make_memoryview_from_NULL_pointer) diff -r c95864a37ee2 Lib/test/test_cmd_line.py --- a/Lib/test/test_cmd_line.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_cmd_line.py Sun May 29 18:15:14 2016 +0300 @@ -19,14 +19,15 @@ def _kill_python_and_exit_code(p): returncode = p.wait() return data, returncode -class CmdLineTest(unittest.TestCase): +class CmdLineTest(unittest.TestCase, unittest.ExtraAssertions): def test_directories(self): assert_python_failure('.') assert_python_failure('< .') def verify_valid_flag(self, cmd_line): rc, out, err = assert_python_ok(*cmd_line) - self.assertTrue(out == b'' or out.endswith(b'\n')) + if out != b'': + self.assertEndsWith(out, b'\n') self.assertNotIn(b'Traceback', out) self.assertNotIn(b'Traceback', err) @@ -46,7 +47,7 @@ class CmdLineTest(unittest.TestCase): for switch in '-V', '--version': rc, out, err = assert_python_ok(switch) self.assertFalse(err.startswith(version)) - self.assertTrue(out.startswith(version)) + self.assertStartsWith(out, version) def test_verbose(self): # -v causes imports to write to stderr. If the write to @@ -235,7 +236,7 @@ class CmdLineTest(unittest.TestCase): p.stdin.flush() data, rc = _kill_python_and_exit_code(p) self.assertEqual(rc, 0) - self.assertTrue(data.startswith(b'x'), data) + self.assertStartsWith(data, b'x') def test_large_PYTHONPATH(self): path1 = "ABCDE" * 100 diff -r c95864a37ee2 Lib/test/test_cmd_line_script.py --- a/Lib/test/test_cmd_line_script.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_cmd_line_script.py Sun May 29 18:15:14 2016 +0300 @@ -106,7 +106,7 @@ def _make_launch_script(script_dir, scri importlib.invalidate_caches() return to_return -class CmdLineTest(unittest.TestCase): +class CmdLineTest(unittest.TestCase, unittest.ExtraAssertions): def _check_output(self, script_name, exit_code, data, expected_file, expected_argv0, expected_path0, expected_package, @@ -492,9 +492,9 @@ class CmdLineTest(unittest.TestCase): exitcode, stdout, stderr = assert_python_failure(script_name) text = stderr.decode('ascii').split('\n') self.assertEqual(len(text), 4) - self.assertTrue(text[0].startswith('Traceback')) - self.assertTrue(text[1].startswith(' File ')) - self.assertTrue(text[3].startswith('NameError')) + self.assertStartsWith(text[0], 'Traceback') + self.assertStartsWith(text[1], ' File ') + self.assertStartsWith(text[3], 'NameError') def test_non_ascii(self): # Mac OS X denies the creation of a file with an invalid UTF-8 name. diff -r c95864a37ee2 Lib/test/test_collections.py --- a/Lib/test/test_collections.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_collections.py Sun May 29 18:15:14 2016 +0300 @@ -428,7 +428,7 @@ class TestNamedTuple(unittest.TestCase): ### Abstract Base Classes ################################################################################ -class ABCTestCase(unittest.TestCase): +class ABCTestCase(unittest.TestCase, unittest.ExtraAssertions): def validate_abstract_methods(self, abc, *names): methodstubs = dict.fromkeys(names, lambda s, *args: 0) @@ -450,11 +450,11 @@ class ABCTestCase(unittest.TestCase): C = type('C', (object,), {'__hash__': None}) setattr(C, name, stub) self.assertIsInstance(C(), abc) - self.assertTrue(issubclass(C, abc)) + self.assertIsSubclass(C, abc) C = type('C', (object,), {'__hash__': None}) self.assertNotIsInstance(C(), abc) - self.assertFalse(issubclass(C, abc)) + self.assertNotIsSubclass(C, abc) def validate_comparison(self, instance): ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub'] @@ -515,12 +515,12 @@ class TestOneTrickPonyABCs(ABCTestCase): non_samples = [None, int(), gen(), object()] for x in non_samples: self.assertNotIsInstance(x, Awaitable) - self.assertFalse(issubclass(type(x), Awaitable), repr(type(x))) + self.assertNotIsSubclass(type(x), Awaitable) samples = [Bar(), MinimalCoro()] for x in samples: self.assertIsInstance(x, Awaitable) - self.assertTrue(issubclass(type(x), Awaitable)) + self.assertIsSubclass(type(x), Awaitable) c = coro() # Iterable coroutines (generators with CO_ITERABLE_COROUTINE @@ -535,7 +535,7 @@ class TestOneTrickPonyABCs(ABCTestCase): class CoroLike: pass Coroutine.register(CoroLike) self.assertTrue(isinstance(CoroLike(), Awaitable)) - self.assertTrue(issubclass(CoroLike, Awaitable)) + self.assertIsSubclass(CoroLike, Awaitable) CoroLike = None support.gc_collect() # Kill CoroLike to clean-up ABCMeta cache @@ -565,12 +565,12 @@ class TestOneTrickPonyABCs(ABCTestCase): non_samples = [None, int(), gen(), object(), Bar()] for x in non_samples: self.assertNotIsInstance(x, Coroutine) - self.assertFalse(issubclass(type(x), Coroutine), repr(type(x))) + self.assertNotIsSubclass(type(x), Coroutine) samples = [MinimalCoro()] for x in samples: self.assertIsInstance(x, Awaitable) - self.assertTrue(issubclass(type(x), Awaitable)) + self.assertIsSubclass(type(x), Awaitable) c = coro() # Iterable coroutines (generators with CO_ITERABLE_COROUTINE @@ -592,7 +592,7 @@ class TestOneTrickPonyABCs(ABCTestCase): def __await__(self): pass self.assertTrue(isinstance(CoroLike(), Coroutine)) - self.assertTrue(issubclass(CoroLike, Coroutine)) + self.assertIsSubclass(CoroLike, Coroutine) class CoroLike: def send(self, value): @@ -601,15 +601,15 @@ class TestOneTrickPonyABCs(ABCTestCase): pass def __await__(self): pass - self.assertFalse(isinstance(CoroLike(), Coroutine)) - self.assertFalse(issubclass(CoroLike, Coroutine)) + self.assertNotIsInstance(CoroLike(), Coroutine) + self.assertNotIsSubclass(CoroLike, Coroutine) def test_Hashable(self): # Check some non-hashables non_samples = [bytearray(), list(), set(), dict()] for x in non_samples: self.assertNotIsInstance(x, Hashable) - self.assertFalse(issubclass(type(x), Hashable), repr(type(x))) + self.assertNotIsSubclass(type(x), Hashable) # Check some hashables samples = [None, int(), float(), complex(), @@ -619,14 +619,14 @@ class TestOneTrickPonyABCs(ABCTestCase): ] for x in samples: self.assertIsInstance(x, Hashable) - self.assertTrue(issubclass(type(x), Hashable), repr(type(x))) + self.assertIsSubclass(type(x), Hashable), repr(type(x)) self.assertRaises(TypeError, Hashable) # Check direct subclassing class H(Hashable): def __hash__(self): return super().__hash__() self.assertEqual(hash(H()), 0) - self.assertFalse(issubclass(int, H)) + self.assertNotIsSubclass(int, H) self.validate_abstract_methods(Hashable, '__hash__') self.validate_isinstance(Hashable, '__hash__') @@ -635,12 +635,12 @@ class TestOneTrickPonyABCs(ABCTestCase): async def __aiter__(self): return self self.assertTrue(isinstance(AI(), AsyncIterable)) - self.assertTrue(issubclass(AI, AsyncIterable)) + self.assertIsSubclass(AI, AsyncIterable) # Check some non-iterables non_samples = [None, object, []] for x in non_samples: self.assertNotIsInstance(x, AsyncIterable) - self.assertFalse(issubclass(type(x), AsyncIterable), repr(type(x))) + self.assertNotIsSubclass(type(x), AsyncIterable) self.validate_abstract_methods(AsyncIterable, '__aiter__') self.validate_isinstance(AsyncIterable, '__aiter__') @@ -651,12 +651,12 @@ class TestOneTrickPonyABCs(ABCTestCase): async def __anext__(self): raise StopAsyncIteration self.assertTrue(isinstance(AI(), AsyncIterator)) - self.assertTrue(issubclass(AI, AsyncIterator)) + self.assertIsSubclass(AI, AsyncIterator) non_samples = [None, object, []] # Check some non-iterables for x in non_samples: self.assertNotIsInstance(x, AsyncIterator) - self.assertFalse(issubclass(type(x), AsyncIterator), repr(type(x))) + self.assertNotIsSubclass(type(x), AsyncIterator) # Similarly to regular iterators (see issue 10565) class AnextOnly: async def __anext__(self): @@ -669,7 +669,7 @@ class TestOneTrickPonyABCs(ABCTestCase): non_samples = [None, 42, 3.14, 1j] for x in non_samples: self.assertNotIsInstance(x, Iterable) - self.assertFalse(issubclass(type(x), Iterable), repr(type(x))) + self.assertNotIsSubclass(type(x), Iterable) # Check some iterables samples = [bytes(), str(), tuple(), list(), set(), frozenset(), dict(), @@ -679,13 +679,13 @@ class TestOneTrickPonyABCs(ABCTestCase): ] for x in samples: self.assertIsInstance(x, Iterable) - self.assertTrue(issubclass(type(x), Iterable), repr(type(x))) + self.assertIsSubclass(type(x), Iterable) # Check direct subclassing class I(Iterable): def __iter__(self): return super().__iter__() self.assertEqual(list(I()), []) - self.assertFalse(issubclass(str, I)) + self.assertNotIsSubclass(str, I) self.validate_abstract_methods(Iterable, '__iter__') self.validate_isinstance(Iterable, '__iter__') @@ -694,16 +694,16 @@ class TestOneTrickPonyABCs(ABCTestCase): non_samples = [None, 42, 3.14, 1j, dict(), set(), frozenset()] for x in non_samples: self.assertNotIsInstance(x, Reversible) - self.assertFalse(issubclass(type(x), Reversible), repr(type(x))) + self.assertNotIsSubclass(type(x), Reversible) # Check some reversibles samples = [tuple(), list()] for x in samples: self.assertIsInstance(x, Reversible) - self.assertTrue(issubclass(type(x), Reversible), repr(type(x))) + self.assertIsSubclass(type(x), Reversible) # Check also Mapping, MutableMapping, and Sequence - self.assertTrue(issubclass(Sequence, Reversible), repr(Sequence)) - self.assertFalse(issubclass(Mapping, Reversible), repr(Mapping)) - self.assertFalse(issubclass(MutableMapping, Reversible), repr(MutableMapping)) + self.assertIsSubclass(Sequence, Reversible) + self.assertNotIsSubclass(Mapping, Reversible) + self.assertNotIsSubclass(MutableMapping, Reversible) # Check direct subclassing class R(Reversible): def __iter__(self): @@ -711,14 +711,14 @@ class TestOneTrickPonyABCs(ABCTestCase): def __reversed__(self): return iter(list()) self.assertEqual(list(reversed(R())), []) - self.assertFalse(issubclass(float, R)) + self.assertNotIsSubclass(float, R) self.validate_abstract_methods(Reversible, '__reversed__', '__iter__') def test_Iterator(self): non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()] for x in non_samples: self.assertNotIsInstance(x, Iterator) - self.assertFalse(issubclass(type(x), Iterator), repr(type(x))) + self.assertNotIsSubclass(type(x), Iterator) samples = [iter(bytes()), iter(str()), iter(tuple()), iter(list()), iter(dict()), iter(set()), iter(frozenset()), @@ -729,7 +729,7 @@ class TestOneTrickPonyABCs(ABCTestCase): ] for x in samples: self.assertIsInstance(x, Iterator) - self.assertTrue(issubclass(type(x), Iterator), repr(type(x))) + self.assertIsSubclass(type(x), Iterator), repr(type(x)) self.validate_abstract_methods(Iterator, '__next__', '__iter__') # Issue 10565 @@ -762,7 +762,7 @@ class TestOneTrickPonyABCs(ABCTestCase): iter(()), iter([]), NonGen1(), NonGen2(), NonGen3()] for x in non_samples: self.assertNotIsInstance(x, Generator) - self.assertFalse(issubclass(type(x), Generator), repr(type(x))) + self.assertNotIsSubclass(type(x), Generator) class Gen: def __iter__(self): return self @@ -784,7 +784,7 @@ class TestOneTrickPonyABCs(ABCTestCase): for x in samples: self.assertIsInstance(x, Iterator) self.assertIsInstance(x, Generator) - self.assertTrue(issubclass(type(x), Generator), repr(type(x))) + self.assertIsSubclass(type(x), Generator), repr(type(x)) self.validate_abstract_methods(Generator, 'send', 'throw') # mixin tests @@ -817,14 +817,14 @@ class TestOneTrickPonyABCs(ABCTestCase): ] for x in non_samples: self.assertNotIsInstance(x, Sized) - self.assertFalse(issubclass(type(x), Sized), repr(type(x))) + self.assertNotIsSubclass(type(x), Sized) samples = [bytes(), str(), tuple(), list(), set(), frozenset(), dict(), dict().keys(), dict().items(), dict().values(), ] for x in samples: self.assertIsInstance(x, Sized) - self.assertTrue(issubclass(type(x), Sized), repr(type(x))) + self.assertIsSubclass(type(x), Sized), repr(type(x)) self.validate_abstract_methods(Sized, '__len__') self.validate_isinstance(Sized, '__len__') @@ -835,14 +835,14 @@ class TestOneTrickPonyABCs(ABCTestCase): ] for x in non_samples: self.assertNotIsInstance(x, Container) - self.assertFalse(issubclass(type(x), Container), repr(type(x))) + self.assertNotIsSubclass(type(x), Container) samples = [bytes(), str(), tuple(), list(), set(), frozenset(), dict(), dict().keys(), dict().items(), ] for x in samples: self.assertIsInstance(x, Container) - self.assertTrue(issubclass(type(x), Container), repr(type(x))) + self.assertIsSubclass(type(x), Container), repr(type(x)) self.validate_abstract_methods(Container, '__contains__') self.validate_isinstance(Container, '__contains__') @@ -854,7 +854,7 @@ class TestOneTrickPonyABCs(ABCTestCase): ] for x in non_samples: self.assertNotIsInstance(x, Callable) - self.assertFalse(issubclass(type(x), Callable), repr(type(x))) + self.assertNotIsSubclass(type(x), Callable) samples = [lambda: None, type, int, object, len, @@ -862,7 +862,7 @@ class TestOneTrickPonyABCs(ABCTestCase): ] for x in samples: self.assertIsInstance(x, Callable) - self.assertTrue(issubclass(type(x), Callable), repr(type(x))) + self.assertIsSubclass(type(x), Callable), repr(type(x)) self.validate_abstract_methods(Callable, '__call__') self.validate_isinstance(Callable, '__call__') @@ -870,16 +870,16 @@ class TestOneTrickPonyABCs(ABCTestCase): for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable: class C(B): pass - self.assertTrue(issubclass(C, B)) - self.assertFalse(issubclass(int, C)) + self.assertIsSubclass(C, B) + self.assertNotIsSubclass(int, C) def test_registration(self): for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable: class C: __hash__ = None # Make sure it isn't hashable by default - self.assertFalse(issubclass(C, B), B.__name__) + self.assertNotIsSubclass(C, B) B.register(C) - self.assertTrue(issubclass(C, B)) + self.assertIsSubclass(C, B) class WithSet(MutableSet): @@ -910,7 +910,7 @@ class TestCollectionABCs(ABCTestCase): def test_Set(self): for sample in [set, frozenset]: self.assertIsInstance(sample(), Set) - self.assertTrue(issubclass(sample, Set)) + self.assertIsSubclass(sample, Set) self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__') class MySet(Set): def __contains__(self, x): @@ -991,9 +991,9 @@ class TestCollectionABCs(ABCTestCase): def test_MutableSet(self): self.assertIsInstance(set(), MutableSet) - self.assertTrue(issubclass(set, MutableSet)) + self.assertIsSubclass(set, MutableSet) self.assertNotIsInstance(frozenset(), MutableSet) - self.assertFalse(issubclass(frozenset, MutableSet)) + self.assertNotIsSubclass(frozenset, MutableSet) self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__', 'add', 'discard') @@ -1253,7 +1253,7 @@ class TestCollectionABCs(ABCTestCase): def test_Mapping(self): for sample in [dict]: self.assertIsInstance(sample(), Mapping) - self.assertTrue(issubclass(sample, Mapping)) + self.assertIsSubclass(sample, Mapping) self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__', '__getitem__') class MyMapping(Mapping): @@ -1268,7 +1268,7 @@ class TestCollectionABCs(ABCTestCase): def test_MutableMapping(self): for sample in [dict]: self.assertIsInstance(sample(), MutableMapping) - self.assertTrue(issubclass(sample, MutableMapping)) + self.assertIsSubclass(sample, MutableMapping) self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__', '__getitem__', '__setitem__', '__delitem__') @@ -1300,12 +1300,12 @@ class TestCollectionABCs(ABCTestCase): def test_Sequence(self): for sample in [tuple, list, bytes, str]: self.assertIsInstance(sample(), Sequence) - self.assertTrue(issubclass(sample, Sequence)) + self.assertIsSubclass(sample, Sequence) self.assertIsInstance(range(10), Sequence) - self.assertTrue(issubclass(range, Sequence)) + self.assertIsSubclass(range, Sequence) self.assertIsInstance(memoryview(b""), Sequence) - self.assertTrue(issubclass(memoryview, Sequence)) - self.assertTrue(issubclass(str, Sequence)) + self.assertIsSubclass(memoryview, Sequence) + self.assertIsSubclass(str, Sequence) self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__', '__getitem__') @@ -1347,21 +1347,21 @@ class TestCollectionABCs(ABCTestCase): def test_ByteString(self): for sample in [bytes, bytearray]: self.assertIsInstance(sample(), ByteString) - self.assertTrue(issubclass(sample, ByteString)) + self.assertIsSubclass(sample, ByteString) for sample in [str, list, tuple]: self.assertNotIsInstance(sample(), ByteString) - self.assertFalse(issubclass(sample, ByteString)) + self.assertNotIsSubclass(sample, ByteString) self.assertNotIsInstance(memoryview(b""), ByteString) - self.assertFalse(issubclass(memoryview, ByteString)) + self.assertNotIsSubclass(memoryview, ByteString) def test_MutableSequence(self): for sample in [tuple, str, bytes]: self.assertNotIsInstance(sample(), MutableSequence) - self.assertFalse(issubclass(sample, MutableSequence)) + self.assertNotIsSubclass(sample, MutableSequence) for sample in [list, bytearray, deque]: self.assertIsInstance(sample(), MutableSequence) - self.assertTrue(issubclass(sample, MutableSequence)) - self.assertFalse(issubclass(str, MutableSequence)) + self.assertIsSubclass(sample, MutableSequence) + self.assertNotIsSubclass(str, MutableSequence) self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__', '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert') @@ -1426,7 +1426,7 @@ class CounterSubclassWithGet(Counter): self.called = True return Counter.get(self, key, default) -class TestCounter(unittest.TestCase): +class TestCounter(unittest.TestCase, unittest.ExtraAssertions): def test_basics(self): c = Counter('abcaba') @@ -1434,8 +1434,8 @@ class TestCounter(unittest.TestCase): self.assertEqual(c, Counter(a=3, b=2, c=1)) self.assertIsInstance(c, dict) self.assertIsInstance(c, Mapping) - self.assertTrue(issubclass(Counter, dict)) - self.assertTrue(issubclass(Counter, Mapping)) + self.assertIsSubclass(Counter, dict) + self.assertIsSubclass(Counter, Mapping) self.assertEqual(len(c), 3) self.assertEqual(sum(c.values()), 6) self.assertEqual(sorted(c.values()), [1, 2, 3]) diff -r c95864a37ee2 Lib/test/test_contextlib.py --- a/Lib/test/test_contextlib.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_contextlib.py Sun May 29 18:15:14 2016 +0300 @@ -12,7 +12,7 @@ except ImportError: threading = None -class TestAbstractContextManager(unittest.TestCase): +class TestAbstractContextManager(unittest.TestCase, unittest.ExtraAssertions): def test_enter(self): class DefaultEnter(AbstractContextManager): @@ -36,13 +36,13 @@ class TestAbstractContextManager(unittes def __exit__(self, exc_type, exc_value, traceback): return None - self.assertTrue(issubclass(ManagerFromScratch, AbstractContextManager)) + self.assertIsSubclass(ManagerFromScratch, AbstractContextManager) class DefaultEnter(AbstractContextManager): def __exit__(self, *args): super().__exit__(*args) - self.assertTrue(issubclass(DefaultEnter, AbstractContextManager)) + self.assertIsSubclass(DefaultEnter, AbstractContextManager) class ContextManagerTestCase(unittest.TestCase): diff -r c95864a37ee2 Lib/test/test_copy.py --- a/Lib/test/test_copy.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_copy.py Sun May 29 18:15:14 2016 +0300 @@ -12,13 +12,13 @@ order_comparisons = le, lt, ge, gt equality_comparisons = eq, ne comparisons = order_comparisons + equality_comparisons -class TestCopy(unittest.TestCase): +class TestCopy(unittest.TestCase, unittest.ExtraAssertions): # Attempt full line coverage of copy.py from top to bottom def test_exceptions(self): self.assertIs(copy.Error, copy.error) - self.assertTrue(issubclass(copy.Error, Exception)) + self.assertIsSubclass(copy.Error, Exception) # The copy() method diff -r c95864a37ee2 Lib/test/test_coroutines.py --- a/Lib/test/test_coroutines.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_coroutines.py Sun May 29 18:15:14 2016 +0300 @@ -358,11 +358,11 @@ class TokenizerRegrTest(unittest.TestCas self.assertTrue(inspect.iscoroutinefunction(ns['foo'])) -class CoroutineTest(unittest.TestCase): +class CoroutineTest(unittest.TestCase, unittest.ExtraAssertions): def test_gen_1(self): def gen(): yield - self.assertFalse(hasattr(gen, '__await__')) + self.assertNotHasAttr(gen, '__await__') def test_func_1(self): async def foo(): diff -r c95864a37ee2 Lib/test/test_dbm.py --- a/Lib/test/test_dbm.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_dbm.py Sun May 29 18:15:14 2016 +0300 @@ -37,7 +37,7 @@ def delete_files(): test.support.unlink(f) -class AnyDBMTestCase: +class AnyDBMTestCase(unittest.ExtraAssertions): _dict = {'0': b'', 'a': b'Python:', 'b': b'Programming', @@ -60,7 +60,7 @@ class AnyDBMTestCase: return keys def test_error(self): - self.assertTrue(issubclass(self.module.error, OSError)) + self.assertIsSubclass(self.module.error, OSError) def test_anydbm_not_existing(self): self.assertRaises(dbm.error, dbm.open, _fname) diff -r c95864a37ee2 Lib/test/test_decimal.py --- a/Lib/test/test_decimal.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_decimal.py Sun May 29 18:15:14 2016 +0300 @@ -2429,13 +2429,13 @@ class CUsabilityTest(UsabilityTest): class PyUsabilityTest(UsabilityTest): decimal = P -class PythonAPItests(unittest.TestCase): +class PythonAPItests(unittest.TestCase, unittest.ExtraAssertions): def test_abc(self): Decimal = self.decimal.Decimal - self.assertTrue(issubclass(Decimal, numbers.Number)) - self.assertFalse(issubclass(Decimal, numbers.Real)) + self.assertIsSubclass(Decimal, numbers.Number) + self.assertNotIsSubclass(Decimal, numbers.Real) self.assertIsInstance(Decimal(0), numbers.Number) self.assertNotIsInstance(Decimal(0), numbers.Real) @@ -2526,7 +2526,7 @@ class PythonAPItests(unittest.TestCase): class MyDecimal(Decimal): pass - self.assertTrue(issubclass(MyDecimal, Decimal)) + self.assertIsSubclass(MyDecimal, Decimal) r = MyDecimal.from_float(0.1) self.assertEqual(type(r), MyDecimal) @@ -2742,31 +2742,31 @@ class PythonAPItests(unittest.TestCase): Rounded = decimal.Rounded Clamped = decimal.Clamped - self.assertTrue(issubclass(DecimalException, ArithmeticError)) - - self.assertTrue(issubclass(InvalidOperation, DecimalException)) - self.assertTrue(issubclass(FloatOperation, DecimalException)) - self.assertTrue(issubclass(FloatOperation, TypeError)) - self.assertTrue(issubclass(DivisionByZero, DecimalException)) - self.assertTrue(issubclass(DivisionByZero, ZeroDivisionError)) - self.assertTrue(issubclass(Overflow, Rounded)) - self.assertTrue(issubclass(Overflow, Inexact)) - self.assertTrue(issubclass(Overflow, DecimalException)) - self.assertTrue(issubclass(Underflow, Inexact)) - self.assertTrue(issubclass(Underflow, Rounded)) - self.assertTrue(issubclass(Underflow, Subnormal)) - self.assertTrue(issubclass(Underflow, DecimalException)) - - self.assertTrue(issubclass(Subnormal, DecimalException)) - self.assertTrue(issubclass(Inexact, DecimalException)) - self.assertTrue(issubclass(Rounded, DecimalException)) - self.assertTrue(issubclass(Clamped, DecimalException)) - - self.assertTrue(issubclass(decimal.ConversionSyntax, InvalidOperation)) - self.assertTrue(issubclass(decimal.DivisionImpossible, InvalidOperation)) - self.assertTrue(issubclass(decimal.DivisionUndefined, InvalidOperation)) - self.assertTrue(issubclass(decimal.DivisionUndefined, ZeroDivisionError)) - self.assertTrue(issubclass(decimal.InvalidContext, InvalidOperation)) + self.assertIsSubclass(DecimalException, ArithmeticError) + + self.assertIsSubclass(InvalidOperation, DecimalException) + self.assertIsSubclass(FloatOperation, DecimalException) + self.assertIsSubclass(FloatOperation, TypeError) + self.assertIsSubclass(DivisionByZero, DecimalException) + self.assertIsSubclass(DivisionByZero, ZeroDivisionError) + self.assertIsSubclass(Overflow, Rounded) + self.assertIsSubclass(Overflow, Inexact) + self.assertIsSubclass(Overflow, DecimalException) + self.assertIsSubclass(Underflow, Inexact) + self.assertIsSubclass(Underflow, Rounded) + self.assertIsSubclass(Underflow, Subnormal) + self.assertIsSubclass(Underflow, DecimalException) + + self.assertIsSubclass(Subnormal, DecimalException) + self.assertIsSubclass(Inexact, DecimalException) + self.assertIsSubclass(Rounded, DecimalException) + self.assertIsSubclass(Clamped, DecimalException) + + self.assertIsSubclass(decimal.ConversionSyntax, InvalidOperation) + self.assertIsSubclass(decimal.DivisionImpossible, InvalidOperation) + self.assertIsSubclass(decimal.DivisionUndefined, InvalidOperation) + self.assertIsSubclass(decimal.DivisionUndefined, ZeroDivisionError) + self.assertIsSubclass(decimal.InvalidContext, InvalidOperation) class CPythonAPItests(PythonAPItests): decimal = C diff -r c95864a37ee2 Lib/test/test_descr.py --- a/Lib/test/test_descr.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_descr.py Sun May 29 18:15:14 2016 +0300 @@ -383,19 +383,11 @@ class OperatorsTest(unittest.TestCase): a.setstate(100) self.assertEqual(a.getstate(), 100) -class ClassPropertiesAndMethods(unittest.TestCase): - - def assertHasAttr(self, obj, name): - self.assertTrue(hasattr(obj, name), - '%r has no attribute %r' % (obj, name)) - - def assertNotHasAttr(self, obj, name): - self.assertFalse(hasattr(obj, name), - '%r has unexpected attribute %r' % (obj, name)) +class ClassPropertiesAndMethods(unittest.TestCase, unittest.ExtraAssertions): def test_python_dicts(self): # Testing Python subclass of dict... - self.assertTrue(issubclass(dict, dict)) + self.assertIsSubclass(dict, dict) self.assertIsInstance({}, dict) d = dict() self.assertEqual(d, {}) @@ -419,7 +411,7 @@ class ClassPropertiesAndMethods(unittest self.state = state def getstate(self): return self.state - self.assertTrue(issubclass(C, dict)) + self.assertIsSubclass(C, dict) a1 = C(12) self.assertEqual(a1.state, 12) a2 = C(foo=1, bar=2) @@ -1026,15 +1018,15 @@ order (MRO) for bases """ m = types.ModuleType("m") self.assertTrue(m.__class__ is types.ModuleType) - self.assertFalse(hasattr(m, "a")) + self.assertNotHasAttr(m, "a") m.__class__ = SubType self.assertTrue(m.__class__ is SubType) - self.assertTrue(hasattr(m, "a")) + self.assertHasAttr(m, "a") m.__class__ = types.ModuleType self.assertTrue(m.__class__ is types.ModuleType) - self.assertFalse(hasattr(m, "a")) + self.assertNotHasAttr(m, "a") # Make sure that builtin immutable objects don't support __class__ # assignment, because the object instances may be interned. @@ -1607,7 +1599,7 @@ order (MRO) for bases """ class E: # *not* subclassing from C foo = C.foo self.assertEqual(E().foo.__func__, C.foo) # i.e., unbound - self.assertTrue(repr(C.foo.__get__(C())).startswith(">") -class DictProxyTests(unittest.TestCase): +class DictProxyTests(unittest.TestCase, unittest.ExtraAssertions): def setUp(self): class C(object): def meth(self): @@ -4619,8 +4611,8 @@ class DictProxyTests(unittest.TestCase): # We can't blindly compare with the repr of another dict as ordering # of keys and values is arbitrary and may differ. r = repr(self.C.__dict__) - self.assertTrue(r.startswith('mappingproxy('), r) - self.assertTrue(r.endswith(')'), r) + self.assertStartsWith(r, 'mappingproxy(') + self.assertEndsWith(r, ')') for k, v in self.C.__dict__.items(): self.assertIn('{!r}: {!r}'.format(k, v), r) diff -r c95864a37ee2 Lib/test/test_dict.py --- a/Lib/test/test_dict.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_dict.py Sun May 29 18:15:14 2016 +0300 @@ -9,7 +9,7 @@ import weakref from test import support -class DictTest(unittest.TestCase): +class DictTest(unittest.TestCase, unittest.ExtraAssertions): def test_invalid_keyword_arguments(self): class Custom(dict): @@ -599,8 +599,8 @@ class DictTest(unittest.TestCase): def test_missing(self): # Make sure dict doesn't have a __missing__ method - self.assertFalse(hasattr(dict, "__missing__")) - self.assertFalse(hasattr({}, "__missing__")) + self.assertNotHasAttr(dict, "__missing__") + self.assertNotHasAttr({}, "__missing__") # Test several cases: # (D) subclass defines __missing__ method returning a value # (E) subclass defines __missing__ method raising RuntimeError diff -r c95864a37ee2 Lib/test/test_dynamicclassattribute.py --- a/Lib/test/test_dynamicclassattribute.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_dynamicclassattribute.py Sun May 29 18:15:14 2016 +0300 @@ -94,7 +94,7 @@ class ClassWithPropertyAbstractVirtual(m def color(): pass -class PropertyTests(unittest.TestCase): +class PropertyTests(unittest.TestCase, unittest.ExtraAssertions): def test_property_decorator_baseclass(self): # see #1620 base = BaseClass() @@ -104,8 +104,8 @@ class PropertyTests(unittest.TestCase): self.assertEqual(base.spam, 10) self.assertEqual(base._spam, 10) delattr(base, "spam") - self.assertTrue(not hasattr(base, "spam")) - self.assertTrue(not hasattr(base, "_spam")) + self.assertNotHasAttr(base, "spam") + self.assertNotHasAttr(base, "_spam") base.spam = 20 self.assertEqual(base.spam, 20) self.assertEqual(base._spam, 20) diff -r c95864a37ee2 Lib/test/test_email/test_contentmanager.py --- a/Lib/test/test_email/test_contentmanager.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_email/test_contentmanager.py Sun May 29 18:15:14 2016 +0300 @@ -133,7 +133,7 @@ class TestContentManager(TestEmailBase): @parameterize -class TestRawDataManager(TestEmailBase): +class TestRawDataManager(TestEmailBase, unittest.ExtraAssertions): # Note: these tests are dependent on the order in which headers are added # to the message objects by the code. There's no defined ordering in # RFC5322/MIME, so this makes the tests more fragile than the standards @@ -288,7 +288,7 @@ class TestRawDataManager(TestEmailBase): The real body is in another message. """)) - self.assertEqual(raw_data_manager.get_content(m)[:10], b'To: foo@ex') + self.assertStartsWith(raw_data_manager.get_content(m), b'To: foo@ex') def test_set_text_plain(self): m = self._make_message() diff -r c95864a37ee2 Lib/test/test_email/test_defect_handling.py --- a/Lib/test/test_email/test_defect_handling.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_email/test_defect_handling.py Sun May 29 18:15:14 2016 +0300 @@ -6,7 +6,7 @@ from email import errors from test.test_email import TestEmailBase -class TestDefectsBase: +class TestDefectsBase(unittest.ExtraAssertions): policy = policy.default raise_expected = False @@ -57,7 +57,7 @@ class TestDefectsBase: msg = self._str_msg(source) if self.raise_expected: return inner = msg.get_payload(0) - self.assertTrue(hasattr(inner, 'defects')) + self.assertHasAttr(inner, 'defects') self.assertEqual(len(self.get_defects(inner)), 1) self.assertIsInstance(self.get_defects(inner)[0], errors.StartBoundaryNotFoundDefect) @@ -151,7 +151,7 @@ class TestDefectsBase: with self._raise_point(errors.NoBoundaryInMultipartDefect): msg = self._str_msg(source) if self.raise_expected: return - self.assertTrue(hasattr(msg, 'defects')) + self.assertHasAttr(msg, 'defects') self.assertEqual(len(self.get_defects(msg)), 2) self.assertIsInstance(self.get_defects(msg)[0], errors.NoBoundaryInMultipartDefect) diff -r c95864a37ee2 Lib/test/test_email/test_email.py --- a/Lib/test/test_email/test_email.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_email/test_email.py Sun May 29 18:15:14 2016 +0300 @@ -51,7 +51,7 @@ SPACE = ' ' # Test various aspects of the Message class's API -class TestMessageAPI(TestEmailBase): +class TestMessageAPI(TestEmailBase, unittest.ExtraAssertions): def test_get_all(self): eq = self.assertEqual msg = self._msgobj('msg_20.txt') @@ -207,8 +207,8 @@ class TestMessageAPI(TestEmailBase): self.assertEqual(msg.items()[0][1], 'multipart/form-data') # Trigger creation of boundary msg.as_string() - self.assertEqual(msg.items()[0][1][:33], - 'multipart/form-data; boundary="==') + self.assertStartsWith(msg.items()[0][1], + 'multipart/form-data; boundary="==') # XXX: there ought to be tests of the uniqueness of the boundary, too. def test_message_rfc822_only(self): @@ -300,7 +300,7 @@ class TestMessageAPI(TestEmailBase): self.assertEqual(text, str(msg)) fullrepr = msg.as_string(unixfrom=True) lines = fullrepr.split('\n') - self.assertTrue(lines[0].startswith('From ')) + self.assertStartsWith(lines[0], 'From ') self.assertEqual(text, NL.join(lines[1:])) def test_as_string_policy(self): @@ -319,7 +319,7 @@ class TestMessageAPI(TestEmailBase): self.assertEqual(data, bytes(msg)) fullrepr = msg.as_bytes(unixfrom=True) lines = fullrepr.split(b'\n') - self.assertTrue(lines[0].startswith(b'From ')) + self.assertStartsWith(lines[0], b'From ') self.assertEqual(data, b'\n'.join(lines[1:])) def test_as_bytes_policy(self): @@ -2065,7 +2065,7 @@ YXNkZg== # Test some badly formatted messages -class TestNonConformant(TestEmailBase): +class TestNonConformant(TestEmailBase, unittest.ExtraAssertions): def test_parse_missing_minor_type(self): eq = self.assertEqual @@ -2079,7 +2079,7 @@ class TestNonConformant(TestEmailBase): msg = self._msgobj('msg_15.txt') # XXX We can probably eventually do better inner = msg.get_payload(0) - self.assertTrue(hasattr(inner, 'defects')) + self.assertHasAttr(inner, 'defects') self.assertEqual(len(inner.defects), 1) self.assertIsInstance(inner.defects[0], errors.StartBoundaryNotFoundDefect) @@ -2191,7 +2191,7 @@ counter to RFC 2822, there's no separati # test_defect_handling def test_lying_multipart(self): msg = self._msgobj('msg_41.txt') - self.assertTrue(hasattr(msg, 'defects')) + self.assertHasAttr(msg, 'defects') self.assertEqual(len(msg.defects), 2) self.assertIsInstance(msg.defects[0], errors.NoBoundaryInMultipartDefect) @@ -3464,7 +3464,7 @@ class TestFeedParsers(TestEmailBase): self.assertEqual(m.items(), [('a', ''), ('b', 'x'*M*N)]) -class TestParsers(TestEmailBase): +class TestParsers(TestEmailBase, unittest.ExtraAssertions): def test_header_parser(self): eq = self.assertEqual @@ -3663,7 +3663,7 @@ Here's the message body "--BOUNDARY--\n" ) msg = email.message_from_string(m) - self.assertTrue(msg.get_payload(0).get_payload().endswith('\r\n')) + self.assertEndsWith(msg.get_payload(0).get_payload(), '\r\n') class Test8BitBytesHandling(TestEmailBase): diff -r c95864a37ee2 Lib/test/test_ensurepip.py --- a/Lib/test/test_ensurepip.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_ensurepip.py Sun May 29 18:15:14 2016 +0300 @@ -271,7 +271,7 @@ class TestUninstall(EnsurepipMixin, unit self.assertEqual(self.os_environ["PIP_CONFIG_FILE"], os.devnull) -class TestMissingSSL(EnsurepipMixin, unittest.TestCase): +class TestMissingSSL(EnsurepipMixin, unittest.TestCase, unittest.ExtraAssertions): def setUp(self): sys.modules["ensurepip"] = ensurepip_no_ssl @@ -299,7 +299,7 @@ class TestMissingSSL(EnsurepipMixin, uni with test.support.captured_stderr() as stderr: ensurepip_no_ssl._main(["--version"]) warning = stderr.getvalue().strip() - self.assertTrue(warning.endswith("requires SSL/TLS"), warning) + self.assertEndsWith(warning, "requires SSL/TLS") self.assertFalse(self.run_pip.called) # Basic testing of the main functions and their argument parsing diff -r c95864a37ee2 Lib/test/test_enum.py --- a/Lib/test/test_enum.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_enum.py Sun May 29 18:15:14 2016 +0300 @@ -106,7 +106,7 @@ class TestHelpers(unittest.TestCase): self.assertFalse(enum._is_dunder(s)) -class TestEnum(unittest.TestCase): +class TestEnum(unittest.TestCase, unittest.ExtraAssertions): def setUp(self): class Season(Enum): @@ -243,9 +243,9 @@ class TestEnum(unittest.TestCase): def spam(cls): pass - self.assertTrue(hasattr(Season, 'spam')) + self.assertHasAttr(Season, 'spam') del Season.spam - self.assertFalse(hasattr(Season, 'spam')) + self.assertNotHasAttr(Season, 'spam') with self.assertRaises(AttributeError): del Season.SPRING diff -r c95864a37ee2 Lib/test/test_errno.py --- a/Lib/test/test_errno.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_errno.py Sun May 29 18:15:14 2016 +0300 @@ -7,19 +7,17 @@ import unittest std_c_errors = frozenset(['EDOM', 'ERANGE']) -class ErrnoAttributeTests(unittest.TestCase): +class ErrnoAttributeTests(unittest.TestCase, unittest.ExtraAssertions): def test_for_improper_attributes(self): # No unexpected attributes should be on the module. for error_code in std_c_errors: - self.assertTrue(hasattr(errno, error_code), - "errno is missing %s" % error_code) + self.assertHasAttr(errno, error_code) def test_using_errorcode(self): # Every key value in errno.errorcode should be on the module. for value in errno.errorcode.values(): - self.assertTrue(hasattr(errno, value), - 'no %s attr in errno' % value) + self.assertHasAttr(errno, value) class ErrorcodeTests(unittest.TestCase): diff -r c95864a37ee2 Lib/test/test_exceptions.py --- a/Lib/test/test_exceptions.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_exceptions.py Sun May 29 18:15:14 2016 +0300 @@ -26,7 +26,7 @@ class BrokenStrException(Exception): # XXX This is not really enough, each *operation* should be tested! -class ExceptionTests(unittest.TestCase): +class ExceptionTests(unittest.TestCase, unittest.ExtraAssertions): def raise_catch(self, exc, excname): try: @@ -188,7 +188,7 @@ class ExceptionTests(unittest.TestCase): exc, err, tb = sys.exc_info() co = tb.tb_frame.f_code self.assertEqual(co.co_name, "test_capi1") - self.assertTrue(co.co_filename.endswith('test_exceptions.py')) + self.assertEndsWith(co.co_filename, 'test_exceptions.py') else: self.fail("Expected exception") @@ -200,7 +200,7 @@ class ExceptionTests(unittest.TestCase): exc, err, tb = sys.exc_info() co = tb.tb_frame.f_code self.assertEqual(co.co_name, "__init__") - self.assertTrue(co.co_filename.endswith('test_exceptions.py')) + self.assertEndsWith(co.co_filename, 'test_exceptions.py') co2 = tb.tb_frame.f_back.f_code self.assertEqual(co2.co_name, "test_capi2") else: @@ -939,7 +939,7 @@ class ExceptionTests(unittest.TestCase): # test basic usage of PyErr_NewException error1 = _testcapi.make_exception_with_doc("_testcapi.error1") self.assertIs(type(error1), type) - self.assertTrue(issubclass(error1, Exception)) + self.assertIsSubclass(error1, Exception) self.assertIsNone(error1.__doc__) # test with given docstring @@ -949,21 +949,21 @@ class ExceptionTests(unittest.TestCase): # test with explicit base (without docstring) error3 = _testcapi.make_exception_with_doc("_testcapi.error3", base=error2) - self.assertTrue(issubclass(error3, error2)) + self.assertIsSubclass(error3, error2) # test with explicit base tuple class C(object): pass error4 = _testcapi.make_exception_with_doc("_testcapi.error4", doc4, (error3, C)) - self.assertTrue(issubclass(error4, error3)) - self.assertTrue(issubclass(error4, C)) + self.assertIsSubclass(error4, error3) + self.assertIsSubclass(error4, C) self.assertEqual(error4.__doc__, doc4) # test with explicit dictionary error5 = _testcapi.make_exception_with_doc("_testcapi.error5", "", error4, {'a': 1}) - self.assertTrue(issubclass(error5, error4)) + self.assertIsSubclass(error5, error4) self.assertEqual(error5.a, 1) self.assertEqual(error5.__doc__, "") @@ -1052,7 +1052,7 @@ class ExceptionTests(unittest.TestCase): else: self.assertIn("ValueError", report) self.assertIn("del is broken", report) - self.assertTrue(report.endswith("\n")) + self.assertEndsWith(report, "\n") def test_unhandled(self): # Check for sensible reporting of unhandled exceptions @@ -1073,7 +1073,7 @@ class ExceptionTests(unittest.TestCase): self.assertIn("", report) else: self.assertIn("test message", report) - self.assertTrue(report.endswith("\n")) + self.assertEndsWith(report, "\n") class ImportErrorTests(unittest.TestCase): diff -r c95864a37ee2 Lib/test/test_fileinput.py --- a/Lib/test/test_fileinput.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_fileinput.py Sun May 29 18:15:14 2016 +0300 @@ -186,7 +186,7 @@ class UnconditionallyRaise: self.invoked = True raise self.exception_type() -class FileInputTests(unittest.TestCase): +class FileInputTests(unittest.TestCase, unittest.ExtraAssertions): def test_zero_byte_files(self): t1 = t2 = t3 = t4 = None @@ -285,7 +285,7 @@ class FileInputTests(unittest.TestCase): orig_stdin = sys.stdin try: sys.stdin = BytesIO(b'spam, bacon, sausage, and spam') - self.assertFalse(hasattr(sys.stdin, 'buffer')) + self.assertNotHasAttr(sys.stdin, 'buffer') fi = FileInput(files=['-'], mode='rb') lines = list(fi) self.assertEqual(lines, [b'spam, bacon, sausage, and spam']) diff -r c95864a37ee2 Lib/test/test_functools.py --- a/Lib/test/test_functools.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_functools.py Sun May 29 18:15:14 2016 +0300 @@ -333,7 +333,7 @@ class TestPartialCSubclass(TestPartialC) test_nested_optimization = None -class TestPartialMethod(unittest.TestCase): +class TestPartialMethod(unittest.TestCase, unittest.ExtraAssertions): class A(object): nothing = functools.partialmethod(capture) @@ -399,11 +399,11 @@ class TestPartialMethod(unittest.TestCas def test_unbound_method_retrieval(self): obj = self.A - self.assertFalse(hasattr(obj.both, "__self__")) - self.assertFalse(hasattr(obj.nested, "__self__")) - self.assertFalse(hasattr(obj.over_partial, "__self__")) - self.assertFalse(hasattr(obj.static, "__self__")) - self.assertFalse(hasattr(self.a.static, "__self__")) + self.assertNotHasAttr(obj.both, "__self__") + self.assertNotHasAttr(obj.nested, "__self__") + self.assertNotHasAttr(obj.over_partial, "__self__") + self.assertNotHasAttr(obj.static, "__self__") + self.assertNotHasAttr(self.a.static, "__self__") def test_descriptors(self): for obj in [self.A, self.a]: @@ -447,7 +447,7 @@ class TestPartialMethod(unittest.TestCas self.assertFalse(getattr(func, '__isabstractmethod__', False)) -class TestUpdateWrapper(unittest.TestCase): +class TestUpdateWrapper(unittest.TestCase, unittest.ExtraAssertions): def check_wrapper(self, wrapper, wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, @@ -508,7 +508,7 @@ class TestUpdateWrapper(unittest.TestCas self.assertNotEqual(wrapper.__qualname__, f.__qualname__) self.assertEqual(wrapper.__doc__, None) self.assertEqual(wrapper.__annotations__, {}) - self.assertFalse(hasattr(wrapper, 'attr')) + self.assertNotHasAttr(wrapper, 'attr') def test_selective_update(self): def f(): @@ -557,7 +557,7 @@ class TestUpdateWrapper(unittest.TestCas pass functools.update_wrapper(wrapper, max) self.assertEqual(wrapper.__name__, 'max') - self.assertTrue(wrapper.__doc__.startswith('max(')) + self.assertStartsWith(wrapper.__doc__, 'max(') self.assertEqual(wrapper.__annotations__, {}) @@ -599,7 +599,7 @@ class TestWraps(TestUpdateWrapper): self.assertEqual(wrapper.__name__, 'wrapper') self.assertNotEqual(wrapper.__qualname__, f.__qualname__) self.assertEqual(wrapper.__doc__, None) - self.assertFalse(hasattr(wrapper, 'attr')) + self.assertNotHasAttr(wrapper, 'attr') def test_selective_update(self): def f(): diff -r c95864a37ee2 Lib/test/test_gdb.py --- a/Lib/test/test_gdb.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_gdb.py Sun May 29 18:15:14 2016 +0300 @@ -245,11 +245,6 @@ class DebuggerTests(unittest.TestCase): self.fail('Unexpected gdb output: %r\n%s' % (gdb_output, gdb_output)) return m.group(1), gdb_output - def assertEndsWith(self, actual, exp_end): - '''Ensure that the given "actual" string ends with "exp_end"''' - self.assertTrue(actual.endswith(exp_end), - msg='%r did not end with %r' % (actual, exp_end)) - def assertMultilineMatches(self, actual, pattern): m = re.match(pattern, actual, re.DOTALL) if not m: @@ -631,7 +626,7 @@ id(foo.__code__)''', @unittest.skipIf(python_is_optimized(), "Python was compiled with optimizations") -class PyListTests(DebuggerTests): +class PyListTests(DebuggerTests, unittest.ExtraAssertions): def assertListing(self, expected, actual): self.assertEndsWith(actual, expected) @@ -671,7 +666,7 @@ class PyListTests(DebuggerTests): ' 3 def foo(a, b, c):\n', bt) -class StackNavigationTests(DebuggerTests): +class StackNavigationTests(DebuggerTests, unittest.ExtraAssertions): @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands") @unittest.skipIf(python_is_optimized(), "Python was compiled with optimizations") diff -r c95864a37ee2 Lib/test/test_genericpath.py --- a/Lib/test/test_genericpath.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_genericpath.py Sun May 29 18:15:14 2016 +0300 @@ -15,7 +15,7 @@ def create_file(filename, data=b'foo'): fp.write(data) -class GenericTest: +class GenericTest(unittest.ExtraAssertions): common_attributes = ['commonprefix', 'getsize', 'getatime', 'getctime', 'getmtime', 'exists', 'isdir', 'isfile'] attributes = [] @@ -88,8 +88,8 @@ class GenericTest: for s1 in testlist: for s2 in testlist: p = commonprefix([s1, s2]) - self.assertTrue(s1.startswith(p)) - self.assertTrue(s2.startswith(p)) + self.assertStartsWith(s1, p) + self.assertStartsWith(s2, p) if s1 != s2: n = len(p) self.assertNotEqual(s1[n:n+1], s2[n:n+1]) diff -r c95864a37ee2 Lib/test/test_gzip.py --- a/Lib/test/test_gzip.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_gzip.py Sun May 29 18:15:14 2016 +0300 @@ -44,7 +44,7 @@ class BaseTest(unittest.TestCase): support.unlink(self.filename) -class TestGzip(BaseTest): +class TestGzip(BaseTest, unittest.ExtraAssertions): def write_and_read_back(self, data, mode='b'): b_data = bytes(data) with gzip.GzipFile(self.filename, 'w'+mode) as f: @@ -272,13 +272,13 @@ class TestGzip(BaseTest): def test_1647484(self): for mode in ('wb', 'rb'): with gzip.GzipFile(self.filename, mode) as f: - self.assertTrue(hasattr(f, "name")) + self.assertHasAttr(f, "name") self.assertEqual(f.name, self.filename) def test_paddedfile_getattr(self): self.test_write() with gzip.GzipFile(self.filename, 'rb') as f: - self.assertTrue(hasattr(f.fileobj, "name")) + self.assertHasAttr(f.fileobj, "name") self.assertEqual(f.fileobj.name, self.filename) def test_mtime(self): @@ -286,7 +286,7 @@ class TestGzip(BaseTest): with gzip.GzipFile(self.filename, 'w', mtime = mtime) as fWrite: fWrite.write(data1) with gzip.GzipFile(self.filename) as fRead: - self.assertTrue(hasattr(fRead, 'mtime')) + self.assertHasAttr(fRead, 'mtime') self.assertIsNone(fRead.mtime) dataRead = fRead.read() self.assertEqual(dataRead, data1) @@ -493,7 +493,7 @@ class TestGzip(BaseTest): with gzip.open(self.filename, "rb") as f: f._buffer.raw._fp.prepend() -class TestOpen(BaseTest): +class TestOpen(BaseTest, unittest.ExtraAssertions): def test_binary_modes(self): uncompressed = data1 * 50 diff -r c95864a37ee2 Lib/test/test_hashlib.py --- a/Lib/test/test_hashlib.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_hashlib.py Sun May 29 18:15:14 2016 +0300 @@ -35,7 +35,7 @@ def hexstr(s): return r -class HashLibTestCase(unittest.TestCase): +class HashLibTestCase(unittest.TestCase, unittest.ExtraAssertions): supported_hash_names = ( 'md5', 'MD5', 'sha1', 'SHA1', 'sha224', 'SHA224', 'sha256', 'SHA256', 'sha384', 'SHA384', 'sha512', 'SHA512') @@ -74,8 +74,8 @@ class HashLibTestCase(unittest.TestCase) if _hashlib: # These two algorithms should always be present when this module # is compiled. If not, something was compiled wrong. - self.assertTrue(hasattr(_hashlib, 'openssl_md5')) - self.assertTrue(hasattr(_hashlib, 'openssl_sha1')) + self.assertHasAttr(_hashlib, 'openssl_md5') + self.assertHasAttr(_hashlib, 'openssl_sha1') for algorithm, constructors in self.constructors_to_test.items(): constructor = getattr(_hashlib, 'openssl_'+algorithm, None) if constructor: diff -r c95864a37ee2 Lib/test/test_http_cookiejar.py --- a/Lib/test/test_http_cookiejar.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_http_cookiejar.py Sun May 29 18:15:14 2016 +0300 @@ -1150,7 +1150,7 @@ class CookieTests(unittest.TestCase): self.assertIsNone(cookie.expires) -class LWPCookieTests(unittest.TestCase): +class LWPCookieTests(unittest.TestCase, unittest.ExtraAssertions): # Tests taken from libwww-perl, with a few modifications and additions. def test_netscape_example_1(self): @@ -1242,7 +1242,7 @@ class LWPCookieTests(unittest.TestCase): h = req.get_header("Cookie") self.assertIn("PART_NUMBER=ROCKET_LAUNCHER_0001", h) self.assertIn("CUSTOMER=WILE_E_COYOTE", h) - self.assertTrue(h.startswith("SHIPPING=FEDEX;")) + self.assertStartsWith(h, "SHIPPING=FEDEX;") def test_netscape_example_2(self): # Second Example transaction sequence: diff -r c95864a37ee2 Lib/test/test_http_cookies.py --- a/Lib/test/test_http_cookies.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_http_cookies.py Sun May 29 18:15:14 2016 +0300 @@ -7,7 +7,7 @@ from http import cookies import pickle import warnings -class CookieTests(unittest.TestCase): +class CookieTests(unittest.TestCase, unittest.ExtraAssertions): def setUp(self): self._warnings_manager = check_warnings() @@ -105,7 +105,7 @@ class CookieTests(unittest.TestCase): C = cookies.SimpleCookie('Customer="WILE_E_COYOTE"') C['Customer']['expires'] = 0 # can't test exact output, it always depends on current date/time - self.assertTrue(C.output().endswith('GMT')) + self.assertEndsWith(C.output(), 'GMT') # loading 'expires' C = cookies.SimpleCookie() diff -r c95864a37ee2 Lib/test/test_httplib.py --- a/Lib/test/test_httplib.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_httplib.py Sun May 29 18:15:14 2016 +0300 @@ -124,7 +124,7 @@ class FakeSocketHTTPConnection(client.HT def create_connection(self, *pos, **kw): return FakeSocket(*self.fake_socket_args) -class HeaderTests(TestCase): +class HeaderTests(TestCase, unittest.ExtraAssertions): def test_auto_headers(self): # Some headers are added automatically, but should not be added by # .request() if they are explicitly set. @@ -263,7 +263,7 @@ class HeaderTests(TestCase): sock = FakeSocket('') conn.sock = sock conn.request('GET', '/foo') - self.assertTrue(sock.data.startswith(expected)) + self.assertStartsWith(sock.data, expected) expected = b'GET /foo HTTP/1.1\r\nHost: [2001:102A::]\r\n' \ b'Accept-Encoding: identity\r\n\r\n' @@ -271,7 +271,7 @@ class HeaderTests(TestCase): sock = FakeSocket('') conn.sock = sock conn.request('GET', '/foo') - self.assertTrue(sock.data.startswith(expected)) + self.assertStartsWith(sock.data, expected) def test_malformed_headers_coped_with(self): # Issue 19996 @@ -314,7 +314,7 @@ class HeaderTests(TestCase): conn.putheader(name, value) -class BasicTest(TestCase): +class BasicTest(TestCase, unittest.ExtraAssertions): def test_status_lines(self): # Test HTTP status lines @@ -541,8 +541,7 @@ class BasicTest(TestCase): sock = FakeSocket(body) conn.sock = sock conn.request('GET', '/foo', body) - self.assertTrue(sock.data.startswith(expected), '%r != %r' % - (sock.data[:len(expected)], expected)) + self.assertStartsWith(sock.data, expected) def test_send(self): expected = b'this is a test this is only a test' @@ -956,7 +955,7 @@ class BasicTest(TestCase): thread.join() self.assertEqual(result, b"proxied data\n") -class ExtendedReadTest(TestCase): +class ExtendedReadTest(TestCase, unittest.ExtraAssertions): """ Test peek(), read1(), readline() """ @@ -1015,7 +1014,7 @@ class ExtendedReadTest(TestCase): # then unbounded peek p2 = resp.peek() self.assertGreaterEqual(len(p2), len(p)) - self.assertTrue(p2.startswith(p)) + self.assertStartsWith(p2, p) next = resp.read(len(p2)) self.assertEqual(next, p2) else: @@ -1037,7 +1036,7 @@ class ExtendedReadTest(TestCase): line = readline(5) if line and line != b"foo": if len(line) < 5: - self.assertTrue(line.endswith(b"\n")) + self.assertEndsWith(line, b"\n") all.append(line) if not line: break @@ -1136,7 +1135,7 @@ class Readliner: raise -class OfflineTest(TestCase): +class OfflineTest(TestCase, unittest.ExtraAssertions): def test_all(self): # Documented objects defined in the module should be in __all__ expected = {"responses"} # White-list documented dict() object @@ -1213,7 +1212,7 @@ class OfflineTest(TestCase): ] for const in expected: with self.subTest(constant=const): - self.assertTrue(hasattr(client, const)) + self.assertHasAttr(client, const) class SourceAddressTest(TestCase): diff -r c95864a37ee2 Lib/test/test_httpservers.py --- a/Lib/test/test_httpservers.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_httpservers.py Sun May 29 18:15:14 2016 +0300 @@ -238,7 +238,7 @@ class BaseHTTPServerTestCase(BaseTestCas self.assertEqual(int(res.getheader('Content-Length')), len(data)) -class RequestHandlerLoggingTestCase(BaseTestCase): +class RequestHandlerLoggingTestCase(BaseTestCase, unittest.ExtraAssertions): class request_handler(BaseHTTPRequestHandler): protocol_version = 'HTTP/1.1' default_request_version = 'HTTP/1.1' @@ -258,8 +258,7 @@ class RequestHandlerLoggingTestCase(Base self.con.request('GET', '/') self.con.getresponse() - self.assertTrue( - err.getvalue().endswith('"GET / HTTP/1.1" 200 -\n')) + self.assertEndsWith(err.getvalue(), '"GET / HTTP/1.1" 200 -\n') def test_err(self): self.con = http.client.HTTPConnection(self.HOST, self.PORT) @@ -270,8 +269,8 @@ class RequestHandlerLoggingTestCase(Base self.con.getresponse() lines = err.getvalue().split('\n') - self.assertTrue(lines[0].endswith('code 404, message File not found')) - self.assertTrue(lines[1].endswith('"ERROR / HTTP/1.1" 404 -')) + self.assertEndsWith(lines[0], 'code 404, message File not found') + self.assertEndsWith(lines[1], '"ERROR / HTTP/1.1" 404 -') class SimpleHTTPServerTestCase(BaseTestCase): diff -r c95864a37ee2 Lib/test/test_imp.py --- a/Lib/test/test_imp.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_imp.py Sun May 29 18:15:14 2016 +0300 @@ -58,7 +58,7 @@ class LockTests(unittest.TestCase): self.fail("release_lock() without lock should raise " "RuntimeError") -class ImportTests(unittest.TestCase): +class ImportTests(unittest.TestCase, unittest.ExtraAssertions): def setUp(self): mod = importlib.import_module('test.encoded_modules') self.test_strings = mod.test_strings @@ -162,7 +162,7 @@ class ImportTests(unittest.TestCase): file, filename, info = imp.find_module(temp_mod_name) with file: self.assertIsNotNone(file) - self.assertTrue(filename[:-3].endswith(temp_mod_name)) + self.assertEndsWith(filename[:-3], temp_mod_name) self.assertEqual(info[0], '.py') self.assertEqual(info[1], 'r') self.assertEqual(info[2], imp.PY_SOURCE) diff -r c95864a37ee2 Lib/test/test_import/__init__.py --- a/Lib/test/test_import/__init__.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_import/__init__.py Sun May 29 18:15:14 2016 +0300 @@ -60,7 +60,7 @@ def _ready_to_import(name=None, source=" del sys.modules[name] -class ImportTests(unittest.TestCase): +class ImportTests(unittest.TestCase, unittest.ExtraAssertions): def setUp(self): remove_files(TESTFN) @@ -189,7 +189,7 @@ class ImportTests(unittest.TestCase): import test as x import test.support self.assertIs(x, test, x.__name__) - self.assertTrue(hasattr(test.support, "__file__")) + self.assertHasAttr(test.support, "__file__") # import x.y.z as w binds z as w import test.support as y @@ -243,7 +243,7 @@ class ImportTests(unittest.TestCase): sys.path.insert(0, os.curdir) try: mod = __import__(TESTFN) - self.assertTrue(mod.__file__.endswith('.py')) + self.assertEndsWith(mod.__file__, '.py') os.remove(source) del sys.modules[TESTFN] make_legacy_pyc(source) @@ -517,7 +517,7 @@ func_filename = func.__code__.co_filenam self.assertEqual(mod.constant.co_filename, foreign_code.co_filename) -class PathsTests(unittest.TestCase): +class PathsTests(unittest.TestCase, unittest.ExtraAssertions): SAMPLES = ('test', 'test\u00e4\u00f6\u00fc\u00df', 'test\u00e9\u00e8', 'test\u00b0\u00b3\u00b2') path = TESTFN @@ -566,11 +566,11 @@ class PathsTests(unittest.TestCase): self.fail("could not import 'test_unc_path' from %r: %r" % (unc, e)) self.assertEqual(mod.testdata, 'test_unc_path') - self.assertTrue(mod.__file__.startswith(unc), mod.__file__) + self.assertStartsWith(mod.__file__, unc) unload("test_unc_path") -class RelativeImportTests(unittest.TestCase): +class RelativeImportTests(unittest.TestCase, unittest.ExtraAssertions): def tearDown(self): unload("test.relimport") @@ -579,7 +579,7 @@ class RelativeImportTests(unittest.TestC def test_relimport_star(self): # This will import * from .test_import. from .. import relimport - self.assertTrue(hasattr(relimport, "RelativeImportTests")) + self.assertHasAttr(relimport, "RelativeImportTests") def test_issue3221(self): # Note for mergers: the 'absolute' tests from the 2.x branch @@ -845,7 +845,7 @@ class TestSymbolicallyLinkedPackage(unit @cpython_only -class ImportlibBootstrapTests(unittest.TestCase): +class ImportlibBootstrapTests(unittest.TestCase, unittest.ExtraAssertions): # These tests check that importlib is bootstrapped. def test_frozen_importlib(self): @@ -858,7 +858,7 @@ class ImportlibBootstrapTests(unittest.T self.assertIs(mod, _bootstrap) self.assertEqual(mod.__name__, 'importlib._bootstrap') self.assertEqual(mod.__package__, 'importlib') - self.assertTrue(mod.__file__.endswith('_bootstrap.py'), mod.__file__) + self.assertEndsWith(mod.__file__, '_bootstrap.py') def test_frozen_importlib_external_is_bootstrap_external(self): from importlib import _bootstrap_external @@ -866,7 +866,7 @@ class ImportlibBootstrapTests(unittest.T self.assertIs(mod, _bootstrap_external) self.assertEqual(mod.__name__, 'importlib._bootstrap_external') self.assertEqual(mod.__package__, 'importlib') - self.assertTrue(mod.__file__.endswith('_bootstrap_external.py'), mod.__file__) + self.assertEndsWith(mod.__file__, '_bootstrap_external.py') def test_there_can_be_only_one(self): # Issue #15386 revealed a tricky loophole in the bootstrapping diff -r c95864a37ee2 Lib/test/test_importlib/builtin/test_finder.py --- a/Lib/test/test_importlib/builtin/test_finder.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_importlib/builtin/test_finder.py Sun May 29 18:15:14 2016 +0300 @@ -51,7 +51,7 @@ class FindSpecTests(abc.FinderTests): @unittest.skipIf(util.BUILTINS.good_name is None, 'no reasonable builtin module') -class FinderTests(abc.FinderTests): +class FinderTests(abc.FinderTests, unittest.ExtraAssertions): """Test find_module() for built-in modules.""" @@ -60,7 +60,7 @@ class FinderTests(abc.FinderTests): with util.uncache(util.BUILTINS.good_name): found = self.machinery.BuiltinImporter.find_module(util.BUILTINS.good_name) self.assertTrue(found) - self.assertTrue(hasattr(found, 'load_module')) + self.assertHasAttr(found, 'load_module') # Built-in modules cannot be a package. test_package = test_package_in_package = test_package_over_module = None diff -r c95864a37ee2 Lib/test/test_importlib/extension/test_case_sensitivity.py --- a/Lib/test/test_importlib/extension/test_case_sensitivity.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_importlib/extension/test_case_sensitivity.py Sun May 29 18:15:14 2016 +0300 @@ -9,7 +9,7 @@ machinery = util.import_importlib('impor @unittest.skipIf(util.EXTENSIONS.filename is None, '_testcapi not available') @util.case_insensitive_tests -class ExtensionModuleCaseSensitivityTest: +class ExtensionModuleCaseSensitivityTest(unittest.ExtraAssertions): def find_module(self): good_name = util.EXTENSIONS.name @@ -36,7 +36,7 @@ class ExtensionModuleCaseSensitivityTest self.skipTest('os.environ changes not reflected in ' '_os.environ') loader = self.find_module() - self.assertTrue(hasattr(loader, 'load_module')) + self.assertHasAttr(loader, 'load_module') (Frozen_ExtensionCaseSensitivity, diff -r c95864a37ee2 Lib/test/test_importlib/extension/test_path_hook.py --- a/Lib/test/test_importlib/extension/test_path_hook.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_importlib/extension/test_path_hook.py Sun May 29 18:15:14 2016 +0300 @@ -5,7 +5,7 @@ machinery = util.import_importlib('impor import unittest -class PathHookTests: +class PathHookTests(unittest.ExtraAssertions): """Test the path hook for extension modules.""" # XXX Should it only succeed for pre-existing directories? @@ -19,7 +19,7 @@ class PathHookTests: def test_success(self): # Path hook should handle a directory where a known extension module # exists. - self.assertTrue(hasattr(self.hook(util.EXTENSIONS.path), 'find_module')) + self.assertHasAttr(self.hook(util.EXTENSIONS.path), 'find_module') (Frozen_PathHooksTests, diff -r c95864a37ee2 Lib/test/test_importlib/frozen/test_finder.py --- a/Lib/test/test_importlib/frozen/test_finder.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_importlib/frozen/test_finder.py Sun May 29 18:15:14 2016 +0300 @@ -43,7 +43,7 @@ class FindSpecTests(abc.FinderTests): ) = util.test_both(FindSpecTests, machinery=machinery) -class FinderTests(abc.FinderTests): +class FinderTests(abc.FinderTests, unittest.ExtraAssertions): """Test finding frozen modules.""" @@ -54,15 +54,15 @@ class FinderTests(abc.FinderTests): def test_module(self): name = '__hello__' loader = self.find(name) - self.assertTrue(hasattr(loader, 'load_module')) + self.assertHasAttr(loader, 'load_module') def test_package(self): loader = self.find('__phello__') - self.assertTrue(hasattr(loader, 'load_module')) + self.assertHasAttr(loader, 'load_module') def test_module_in_package(self): loader = self.find('__phello__.spam', ['__phello__']) - self.assertTrue(hasattr(loader, 'load_module')) + self.assertHasAttr(loader, 'load_module') # No frozen package within another package to test with. test_package_in_package = None diff -r c95864a37ee2 Lib/test/test_importlib/frozen/test_loader.py --- a/Lib/test/test_importlib/frozen/test_loader.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_importlib/frozen/test_loader.py Sun May 29 18:15:14 2016 +0300 @@ -9,7 +9,7 @@ import unittest import warnings -class ExecModuleTests(abc.LoaderTests): +class ExecModuleTests(abc.LoaderTests, unittest.ExtraAssertions): def exec_module(self, name): with util.uncache(name), captured_stdout() as stdout: @@ -21,7 +21,7 @@ class ExecModuleTests(abc.LoaderTests): assert not hasattr(module, 'initialized') self.machinery.FrozenImporter.exec_module(module) self.assertTrue(module.initialized) - self.assertTrue(hasattr(module, '__spec__')) + self.assertHasAttr(module, '__spec__') self.assertEqual(module.__spec__.origin, 'frozen') return module, stdout.getvalue() @@ -32,7 +32,7 @@ class ExecModuleTests(abc.LoaderTests): for attr, value in check.items(): self.assertEqual(getattr(module, attr), value) self.assertEqual(output, 'Hello world!\n') - self.assertTrue(hasattr(module, '__spec__')) + self.assertHasAttr(module, '__spec__') def test_package(self): name = '__phello__' @@ -89,7 +89,7 @@ class ExecModuleTests(abc.LoaderTests): ) = util.test_both(ExecModuleTests, machinery=machinery) -class LoaderTests(abc.LoaderTests): +class LoaderTests(abc.LoaderTests, unittest.ExtraAssertions): def test_module(self): with util.uncache('__hello__'), captured_stdout() as stdout: @@ -103,7 +103,7 @@ class LoaderTests(abc.LoaderTests): for attr, value in check.items(): self.assertEqual(getattr(module, attr), value) self.assertEqual(stdout.getvalue(), 'Hello world!\n') - self.assertFalse(hasattr(module, '__file__')) + self.assertNotHasAttr(module, '__file__') def test_package(self): with util.uncache('__phello__'), captured_stdout() as stdout: @@ -121,7 +121,7 @@ class LoaderTests(abc.LoaderTests): "for __phello__.%s, %r != %r" % (attr, attr_value, value)) self.assertEqual(stdout.getvalue(), 'Hello world!\n') - self.assertFalse(hasattr(module, '__file__')) + self.assertNotHasAttr(module, '__file__') def test_lacking_parent(self): with util.uncache('__phello__', '__phello__.spam'), \ @@ -139,7 +139,7 @@ class LoaderTests(abc.LoaderTests): "for __phello__.spam.%s, %r != %r" % (attr, attr_value, value)) self.assertEqual(stdout.getvalue(), 'Hello world!\n') - self.assertFalse(hasattr(module, '__file__')) + self.assertNotHasAttr(module, '__file__') def test_module_reuse(self): with util.uncache('__hello__'), captured_stdout() as stdout: @@ -181,7 +181,7 @@ class LoaderTests(abc.LoaderTests): ) = util.test_both(LoaderTests, machinery=machinery) -class InspectLoaderTests: +class InspectLoaderTests(unittest.ExtraAssertions): """Tests for the InspectLoader methods for FrozenImporter.""" @@ -192,7 +192,7 @@ class InspectLoaderTests: code = self.machinery.FrozenImporter.get_code(name) mod = types.ModuleType(name) exec(code, mod.__dict__) - self.assertTrue(hasattr(mod, 'initialized')) + self.assertHasAttr(mod, 'initialized') self.assertEqual(stdout.getvalue(), 'Hello world!\n') def test_get_source(self): diff -r c95864a37ee2 Lib/test/test_importlib/import_/test_caching.py --- a/Lib/test/test_importlib/import_/test_caching.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_importlib/import_/test_caching.py Sun May 29 18:15:14 2016 +0300 @@ -44,7 +44,7 @@ class UseCache: ) = util.test_both(UseCache, __import__=util.__import__) -class ImportlibUseCache(UseCache, unittest.TestCase): +class ImportlibUseCache(UseCache, unittest.TestCase, unittest.ExtraAssertions): # Pertinent only to PEP 302; exec_module() doesn't return a module. @@ -74,7 +74,7 @@ class ImportlibUseCache(UseCache, unitte with self.create_mock('pkg.__init__', 'pkg.module') as importer: with util.import_state(meta_path=[importer]): module = self.__import__('pkg.module') - self.assertTrue(hasattr(module, 'module')) + self.assertHasAttr(module, 'module') self.assertEqual(id(module.module), id(sys.modules['pkg.module'])) @@ -84,7 +84,7 @@ class ImportlibUseCache(UseCache, unitte with self.create_mock('pkg.__init__', 'pkg.module') as importer: with util.import_state(meta_path=[importer]): module = self.__import__('pkg', fromlist=['module']) - self.assertTrue(hasattr(module, 'module')) + self.assertHasAttr(module, 'module') self.assertEqual(id(module.module), id(sys.modules['pkg.module'])) diff -r c95864a37ee2 Lib/test/test_importlib/import_/test_fromlist.py --- a/Lib/test/test_importlib/import_/test_fromlist.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_importlib/import_/test_fromlist.py Sun May 29 18:15:14 2016 +0300 @@ -34,7 +34,7 @@ class ReturnValue: ) = util.test_both(ReturnValue, __import__=util.__import__) -class HandlingFromlist: +class HandlingFromlist(unittest.ExtraAssertions): """Using fromlist triggers different actions based on what is being asked of it. @@ -62,7 +62,7 @@ class HandlingFromlist: with util.import_state(meta_path=[importer]): module = self.__import__('module', fromlist=['non_existent']) self.assertEqual(module.__name__, 'module') - self.assertFalse(hasattr(module, 'non_existent')) + self.assertNotHasAttr(module, 'non_existent') def test_module_from_package(self): # [module] @@ -70,7 +70,7 @@ class HandlingFromlist: with util.import_state(meta_path=[importer]): module = self.__import__('pkg', fromlist=['module']) self.assertEqual(module.__name__, 'pkg') - self.assertTrue(hasattr(module, 'module')) + self.assertHasAttr(module, 'module') self.assertEqual(module.module.__name__, 'pkg.module') def test_module_from_package_triggers_ImportError(self): @@ -99,7 +99,7 @@ class HandlingFromlist: mock['pkg'].__all__ = ['module'] module = self.__import__('pkg', fromlist=fromlist) self.assertEqual(module.__name__, 'pkg') - self.assertTrue(hasattr(module, 'module')) + self.assertHasAttr(module, 'module') self.assertEqual(module.module.__name__, 'pkg.module') def test_using_star(self): @@ -117,8 +117,8 @@ class HandlingFromlist: mock['pkg'].__all__ = ['module1'] module = self.__import__('pkg', fromlist=['module2', '*']) self.assertEqual(module.__name__, 'pkg') - self.assertTrue(hasattr(module, 'module1')) - self.assertTrue(hasattr(module, 'module2')) + self.assertHasAttr(module, 'module1') + self.assertHasAttr(module, 'module2') self.assertEqual(module.module1.__name__, 'pkg.module1') self.assertEqual(module.module2.__name__, 'pkg.module2') diff -r c95864a37ee2 Lib/test/test_importlib/import_/test_meta_path.py --- a/Lib/test/test_importlib/import_/test_meta_path.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_importlib/import_/test_meta_path.py Sun May 29 18:15:14 2016 +0300 @@ -6,7 +6,7 @@ import unittest import warnings -class CallingOrder: +class CallingOrder(unittest.ExtraAssertions): """Calls to the importers on sys.meta_path happen in order that they are specified in the sequence, starting with the first importer @@ -43,7 +43,7 @@ class CallingOrder: self.assertIsNone(importlib._bootstrap._find_spec('nothing', None)) self.assertEqual(len(w), 1) - self.assertTrue(issubclass(w[-1].category, ImportWarning)) + self.assertIsSubclass(w[-1].category, ImportWarning) (Frozen_CallingOrder, diff -r c95864a37ee2 Lib/test/test_importlib/import_/test_path.py --- a/Lib/test/test_importlib/import_/test_path.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_importlib/import_/test_path.py Sun May 29 18:15:14 2016 +0300 @@ -12,7 +12,7 @@ import warnings import zipimport -class FinderTests: +class FinderTests(unittest.ExtraAssertions): """Tests for PathFinder.""" @@ -79,7 +79,7 @@ class FinderTests: self.assertIsNone(self.find('os')) self.assertIsNone(sys.path_importer_cache[path_entry]) self.assertEqual(len(w), 1) - self.assertTrue(issubclass(w[-1].category, ImportWarning)) + self.assertIsSubclass(w[-1].category, ImportWarning) def test_path_importer_cache_empty_string(self): # The empty string should create a finder using the cwd. diff -r c95864a37ee2 Lib/test/test_importlib/import_/test_relative_imports.py --- a/Lib/test/test_importlib/import_/test_relative_imports.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_importlib/import_/test_relative_imports.py Sun May 29 18:15:14 2016 +0300 @@ -4,7 +4,7 @@ import unittest import warnings -class RelativeImports: +class RelativeImports(unittest.ExtraAssertions): """PEP 328 introduced relative imports. This allows for imports to occur from within a package without having to specify the actual package name. @@ -81,7 +81,7 @@ class RelativeImports: self.__import__('pkg') # For __import__(). module = self.__import__('', global_, fromlist=['mod2'], level=1) self.assertEqual(module.__name__, 'pkg') - self.assertTrue(hasattr(module, 'mod2')) + self.assertHasAttr(module, 'mod2') self.assertEqual(module.mod2.attr, 'pkg.mod2') self.relative_import_test(create, globals_, callback) @@ -107,7 +107,7 @@ class RelativeImports: module = self.__import__('', global_, fromlist=['module'], level=1) self.assertEqual(module.__name__, 'pkg') - self.assertTrue(hasattr(module, 'module')) + self.assertHasAttr(module, 'module') self.assertEqual(module.module.attr, 'pkg.module') self.relative_import_test(create, globals_, callback) @@ -131,7 +131,7 @@ class RelativeImports: module = self.__import__('', global_, fromlist=['subpkg2'], level=2) self.assertEqual(module.__name__, 'pkg') - self.assertTrue(hasattr(module, 'subpkg2')) + self.assertHasAttr(module, 'subpkg2') self.assertEqual(module.subpkg2.attr, 'pkg.subpkg2.__init__') def test_deep_import(self): diff -r c95864a37ee2 Lib/test/test_importlib/source/test_finder.py --- a/Lib/test/test_importlib/source/test_finder.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_importlib/source/test_finder.py Sun May 29 18:15:14 2016 +0300 @@ -14,7 +14,7 @@ import unittest import warnings -class FinderTests(abc.FinderTests): +class FinderTests(abc.FinderTests, unittest.ExtraAssertions): """For a top-level module, it should just be found directly in the directory being searched. This is true for a directory with source @@ -75,7 +75,7 @@ class FinderTests(abc.FinderTests): if error.errno != errno.ENOENT: raise loader = self.import_(mapping['.root'], test) - self.assertTrue(hasattr(loader, 'load_module')) + self.assertHasAttr(loader, 'load_module') return loader def test_module(self): @@ -102,7 +102,7 @@ class FinderTests(abc.FinderTests): with util.create_modules('pkg.__init__', 'pkg.sub') as mapping: pkg_dir = os.path.dirname(mapping['pkg.__init__']) loader = self.import_(pkg_dir, 'pkg.sub') - self.assertTrue(hasattr(loader, 'load_module')) + self.assertHasAttr(loader, 'load_module') # [sub package] def test_package_in_package(self): @@ -110,7 +110,7 @@ class FinderTests(abc.FinderTests): with context as mapping: pkg_dir = os.path.dirname(mapping['pkg.__init__']) loader = self.import_(pkg_dir, 'pkg.sub') - self.assertTrue(hasattr(loader, 'load_module')) + self.assertHasAttr(loader, 'load_module') # [package over modules] def test_package_over_module(self): @@ -131,7 +131,7 @@ class FinderTests(abc.FinderTests): file.write("# test file for importlib") try: loader = self._find(finder, 'mod', loader_only=True) - self.assertTrue(hasattr(loader, 'load_module')) + self.assertHasAttr(loader, 'load_module') finally: os.unlink('mod.py') diff -r c95864a37ee2 Lib/test/test_importlib/source/test_path_hook.py --- a/Lib/test/test_importlib/source/test_path_hook.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_importlib/source/test_path_hook.py Sun May 29 18:15:14 2016 +0300 @@ -5,7 +5,7 @@ machinery = util.import_importlib('impor import unittest -class PathHookTest: +class PathHookTest(unittest.ExtraAssertions): """Test the path hook for source.""" @@ -15,21 +15,17 @@ class PathHookTest: def test_success(self): with util.create_modules('dummy') as mapping: - self.assertTrue(hasattr(self.path_hook()(mapping['.root']), - 'find_spec')) + self.assertHasAttr(self.path_hook()(mapping['.root']), + 'find_spec') def test_success_legacy(self): with util.create_modules('dummy') as mapping: - self.assertTrue(hasattr(self.path_hook()(mapping['.root']), - 'find_module')) + self.assertHasAttr(self.path_hook()(mapping['.root']), + 'find_module') def test_empty_string(self): # The empty string represents the cwd. - self.assertTrue(hasattr(self.path_hook()(''), 'find_spec')) - - def test_empty_string_legacy(self): - # The empty string represents the cwd. - self.assertTrue(hasattr(self.path_hook()(''), 'find_module')) + self.assertHasAttr(self.path_hook()(''), 'find_spec') (Frozen_PathHookTest, diff -r c95864a37ee2 Lib/test/test_importlib/test_abc.py --- a/Lib/test/test_importlib/test_abc.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_importlib/test_abc.py Sun May 29 18:15:14 2016 +0300 @@ -19,7 +19,7 @@ util = test_util.import_importlib('impor ##### Inheritance ############################################################## -class InheritanceTests: +class InheritanceTests(unittest.ExtraAssertions): """Test that the specified class is a subclass/superclass of the expected classes.""" @@ -45,13 +45,13 @@ class InheritanceTests: def test_subclasses(self): # Test that the expected subclasses inherit. for subclass in self.subclasses: - self.assertTrue(issubclass(subclass, self.__test), + self.assertIsSubclass(subclass, self.__test, "{0} is not a subclass of {1}".format(subclass, self.__test)) def test_superclasses(self): # Test that the class inherits from the expected superclasses. for superclass in self.superclasses: - self.assertTrue(issubclass(self.__test, superclass), + self.assertIsSubclass(self.__test, superclass, "{0} is not a superclass of {1}".format(superclass, self.__test)) @@ -432,7 +432,7 @@ class LoaderLoadModuleTests: ##### InspectLoader concrete methods ########################################### -class InspectLoaderSourceToCodeTests: +class InspectLoaderSourceToCodeTests(unittest.ExtraAssertions): def source_to_module(self, data, path=None): """Help with source_to_code() tests.""" @@ -449,14 +449,14 @@ class InspectLoaderSourceToCodeTests: # Since compile() can handle strings, so should source_to_code(). source = 'attr = 42' module = self.source_to_module(source) - self.assertTrue(hasattr(module, 'attr')) + self.assertHasAttr(module, 'attr') self.assertEqual(module.attr, 42) def test_source_to_code_bytes(self): # Since compile() can handle bytes, so should source_to_code(). source = b'attr = 42' module = self.source_to_module(source) - self.assertTrue(hasattr(module, 'attr')) + self.assertHasAttr(module, 'attr') self.assertEqual(module.attr, 42) def test_source_to_code_path(self): @@ -733,7 +733,7 @@ class SourceLoaderTestHarness: self.verify_module(module) -class SourceOnlyLoaderTests(SourceLoaderTestHarness): +class SourceOnlyLoaderTests(SourceLoaderTestHarness, unittest.ExtraAssertions): """Test importlib.abc.SourceLoader for source-only loading. @@ -794,7 +794,7 @@ class SourceOnlyLoaderTests(SourceLoader warnings.simplefilter('ignore', DeprecationWarning) module = self.loader.load_module(self.name) self.verify_module(module) - self.assertFalse(hasattr(module, '__path__')) + self.assertNotHasAttr(module, '__path__') def test_get_source_encoding(self): # Source is considered encoded in UTF-8 by default unless otherwise diff -r c95864a37ee2 Lib/test/test_importlib/test_api.py --- a/Lib/test/test_importlib/test_api.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_importlib/test_api.py Sun May 29 18:15:14 2016 +0300 @@ -415,15 +415,14 @@ class FrozenImportlibTests(unittest.Test 'FrozenImporter') -class StartupTests: +class StartupTests(unittest.ExtraAssertions): def test_everyone_has___loader__(self): # Issue #17098: all modules should have __loader__ defined. for name, module in sys.modules.items(): if isinstance(module, types.ModuleType): with self.subTest(name=name): - self.assertTrue(hasattr(module, '__loader__'), - '{!r} lacks a __loader__ attribute'.format(name)) + self.assertHasAttr(module, '__loader__') if self.machinery.BuiltinImporter.find_module(name): self.assertIsNot(module.__loader__, None) elif self.machinery.FrozenImporter.find_module(name): @@ -433,7 +432,7 @@ class StartupTests: for name, module in sys.modules.items(): if isinstance(module, types.ModuleType): with self.subTest(name=name): - self.assertTrue(hasattr(module, '__spec__')) + self.assertHasAttr(module, '__spec__') if self.machinery.BuiltinImporter.find_module(name): self.assertIsNot(module.__spec__, None) elif self.machinery.FrozenImporter.find_module(name): diff -r c95864a37ee2 Lib/test/test_importlib/test_lazy.py --- a/Lib/test/test_importlib/test_lazy.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_importlib/test_lazy.py Sun May 29 18:15:14 2016 +0300 @@ -50,7 +50,7 @@ class TestingImporter(abc.MetaPathFinder self.loaded = module -class LazyLoaderTests(unittest.TestCase): +class LazyLoaderTests(unittest.TestCase, unittest.ExtraAssertions): def test_init(self): with self.assertRaises(TypeError): @@ -114,12 +114,12 @@ class LazyLoaderTests(unittest.TestCase) # Deleting an attribute should stay deleted. module = self.new_module() del module.attr - self.assertFalse(hasattr(module, 'attr')) + self.assertNotHasAttr(module, 'attr') def test_delete_preexisting_attr(self): module = self.new_module() del module.__name__ - self.assertFalse(hasattr(module, '__name__')) + self.assertNotHasAttr(module, '__name__') def test_module_substitution_error(self): source_code = 'import sys; sys.modules[__name__] = 42' diff -r c95864a37ee2 Lib/test/test_importlib/test_spec.py --- a/Lib/test/test_importlib/test_spec.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_importlib/test_spec.py Sun May 29 18:15:14 2016 +0300 @@ -229,7 +229,7 @@ class ModuleSpecTests: ) = test_util.test_both(ModuleSpecTests, util=util, machinery=machinery) -class ModuleSpecMethodsTests: +class ModuleSpecMethodsTests(unittest.ExtraAssertions): @property def bootstrap(self): @@ -251,7 +251,7 @@ class ModuleSpecMethodsTests: self.spec.loader = NewLoader() module = self.util.module_from_spec(self.spec) sys.modules[self.name] = module - self.assertFalse(hasattr(module, 'eggs')) + self.assertNotHasAttr(module, 'eggs') self.bootstrap._exec(self.spec, module) self.assertEqual(module.eggs, 1) @@ -376,9 +376,9 @@ class ModuleSpecMethodsTests: self.assertIs(loaded.__loader__, self.spec.loader) self.assertEqual(loaded.__package__, self.spec.parent) self.assertIs(loaded.__spec__, self.spec) - self.assertFalse(hasattr(loaded, '__path__')) - self.assertFalse(hasattr(loaded, '__file__')) - self.assertFalse(hasattr(loaded, '__cached__')) + self.assertNotHasAttr(loaded, '__path__') + self.assertNotHasAttr(loaded, '__file__') + self.assertNotHasAttr(loaded, '__cached__') def test_reload_legacy(self): self.spec.loader = LegacyLoader() diff -r c95864a37ee2 Lib/test/test_importlib/test_util.py --- a/Lib/test/test_importlib/test_util.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_importlib/test_util.py Sun May 29 18:15:14 2016 +0300 @@ -39,7 +39,7 @@ class DecodeSourceBytesTests: ) = util.test_both(DecodeSourceBytesTests, util=importlib_util) -class ModuleFromSpecTests: +class ModuleFromSpecTests(unittest.ExtraAssertions): def test_no_create_module(self): class Loader: @@ -50,7 +50,7 @@ class ModuleFromSpecTests: warnings.simplefilter('always') module = self.util.module_from_spec(spec) self.assertEqual(1, len(w)) - self.assertTrue(issubclass(w[0].category, DeprecationWarning)) + self.assertIsSubclass(w[0].category, DeprecationWarning) self.assertIn('create_module', str(w[0].message)) self.assertIsInstance(module, types.ModuleType) self.assertEqual(module.__name__, spec.name) @@ -254,7 +254,7 @@ class ModuleForLoaderTests: ) = util.test_both(ModuleForLoaderTests, util=importlib_util) -class SetPackageTests: +class SetPackageTests(unittest.ExtraAssertions): """Tests for importlib.util.set_package.""" @@ -266,7 +266,7 @@ class SetPackageTests: with warnings.catch_warnings(): warnings.simplefilter('ignore', DeprecationWarning) wrapped() - self.assertTrue(hasattr(module, '__package__')) + self.assertHasAttr(module, '__package__') self.assertEqual(expect, module.__package__) def test_top_level(self): @@ -533,7 +533,7 @@ class FindSpecTests: machinery=machinery) -class MagicNumberTests: +class MagicNumberTests(unittest.ExtraAssertions): def test_length(self): # Should be 4 bytes. @@ -541,7 +541,7 @@ class MagicNumberTests: def test_incorporates_rn(self): # The magic number uses \r\n to come out wrong when splitting on lines. - self.assertTrue(self.util.MAGIC_NUMBER.endswith(b'\r\n')) + self.assertEndsWith(self.util.MAGIC_NUMBER, b'\r\n') (Frozen_MagicNumberTests, diff -r c95864a37ee2 Lib/test/test_inspect.py --- a/Lib/test/test_inspect.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_inspect.py Sun May 29 18:15:14 2016 +0300 @@ -1813,7 +1813,7 @@ class MyParameter(inspect.Parameter): -class TestSignatureObject(unittest.TestCase): +class TestSignatureObject(unittest.TestCase, unittest.ExtraAssertions): @staticmethod def signature(func, **kw): sig = inspect.signature(func, **kw) @@ -1870,7 +1870,7 @@ class TestSignatureObject(unittest.TestC with self.assertRaisesRegex(ValueError, 'follows default argument'): S((pkd, pk)) - self.assertTrue(repr(sig).startswith('(2)]', f.format(self.records)) -class ExceptionTest(BaseTest): +class ExceptionTest(BaseTest, unittest.ExtraAssertions): def test_formatting(self): r = self.root_logger h = RecordingHandler() @@ -3162,14 +3162,14 @@ class ExceptionTest(BaseTest): r.removeHandler(h) h.close() r = h.records[0] - self.assertTrue(r.exc_text.startswith('Traceback (most recent ' - 'call last):\n')) - self.assertTrue(r.exc_text.endswith('\nRuntimeError: ' - 'deliberate mistake')) - self.assertTrue(r.stack_info.startswith('Stack (most recent ' - 'call last):\n')) - self.assertTrue(r.stack_info.endswith('logging.exception(\'failed\', ' - 'stack_info=True)')) + self.assertStartsWith(r.exc_text, + 'Traceback (most recent call last):\n') + self.assertEndsWith(r.exc_text, + '\nRuntimeError: deliberate mistake') + self.assertStartsWith(r.stack_info, + 'Stack (most recent call last):\n') + self.assertEndsWith(r.stack_info, + "logging.exception('failed', stack_info=True)") class LastResortTest(BaseTest): @@ -3407,12 +3407,12 @@ class ModuleLevelMiscTest(BaseTest): self.assertIn("ValueError: some error", err) -class LogRecordTest(BaseTest): +class LogRecordTest(BaseTest, unittest.ExtraAssertions): def test_str_rep(self): r = logging.makeLogRecord({}) s = str(r) - self.assertTrue(s.startswith('')) + self.assertStartsWith(s, '') def test_dict_arg(self): h = RecordingHandler() diff -r c95864a37ee2 Lib/test/test_lzma.py --- a/Lib/test/test_lzma.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_lzma.py Sun May 29 18:15:14 2016 +0300 @@ -469,7 +469,7 @@ class TempFile: unlink(self.filename) -class FileTestCase(unittest.TestCase): +class FileTestCase(unittest.TestCase, unittest.ExtraAssertions): def test_init(self): with LZMAFile(BytesIO(COMPRESSED_XZ)) as f: @@ -886,12 +886,12 @@ class FileTestCase(unittest.TestCase): with LZMAFile(BytesIO(COMPRESSED_XZ)) as f: result = f.peek() self.assertGreater(len(result), 0) - self.assertTrue(INPUT.startswith(result)) + self.assertStartsWith(INPUT, result) self.assertEqual(f.read(), INPUT) with LZMAFile(BytesIO(COMPRESSED_XZ)) as f: result = f.peek(10) self.assertGreater(len(result), 0) - self.assertTrue(INPUT.startswith(result)) + self.assertStartsWith(INPUT, result) self.assertEqual(f.read(), INPUT) def test_peek_bad_args(self): diff -r c95864a37ee2 Lib/test/test_mailbox.py --- a/Lib/test/test_mailbox.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_mailbox.py Sun May 29 18:15:14 2016 +0300 @@ -1087,7 +1087,7 @@ class _TestMboxMMDF(_TestSingleFile): self._box.close() -class TestMbox(_TestMboxMMDF, unittest.TestCase): +class TestMbox(_TestMboxMMDF, unittest.TestCase, unittest.ExtraAssertions): _factory = lambda self, path, factory=None: mailbox.mbox(path, factory) @@ -1126,12 +1126,12 @@ class TestMbox(_TestMboxMMDF, unittest.T self._box.add('From: foo\n\n0') # No newline at the end with open(self._path) as f: data = f.read() - self.assertEqual(data[-3:], '0\n\n') + self.assertEndsWith(data, '0\n\n') self._box.add('From: foo\n\n0\n') # Newline at the end with open(self._path) as f: data = f.read() - self.assertEqual(data[-3:], '0\n\n') + self.assertEndsWith(data, '0\n\n') class TestMMDF(_TestMboxMMDF, unittest.TestCase): @@ -2102,7 +2102,7 @@ Subject: Simple Test This is a dummy message. """ -class MaildirTestCase(unittest.TestCase): +class MaildirTestCase(unittest.TestCase, unittest.ExtraAssertions): def setUp(self): # create a new maildir mailbox to work with: @@ -2150,7 +2150,7 @@ class MaildirTestCase(unittest.TestCase) # Test for regression on bug #117490: # Make sure the boxes attribute actually gets set. self.mbox = mailbox.Maildir(support.TESTFN) - #self.assertTrue(hasattr(self.mbox, "boxes")) + #self.assertHasAttr(self.mbox, "boxes") #self.assertEqual(len(self.mbox.boxes), 0) self.assertIsNone(self.mbox.next()) self.assertIsNone(self.mbox.next()) diff -r c95864a37ee2 Lib/test/test_memoryio.py --- a/Lib/test/test_memoryio.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_memoryio.py Sun May 29 18:15:14 2016 +0300 @@ -56,7 +56,7 @@ class MemorySeekTestMixin: self.assertEqual(10000, bytesIo.tell()) -class MemoryTestMixin: +class MemoryTestMixin(unittest.ExtraAssertions): def test_detach(self): buf = self.ioclass() @@ -235,8 +235,8 @@ class MemoryTestMixin: memio = self.ioclass(buf * 10) self.assertEqual(iter(memio), memio) - self.assertTrue(hasattr(memio, '__iter__')) - self.assertTrue(hasattr(memio, '__next__')) + self.assertHasAttr(memio, '__iter__') + self.assertHasAttr(memio, '__next__') i = 0 for line in memio: self.assertEqual(line, buf) diff -r c95864a37ee2 Lib/test/test_nntplib.py --- a/Lib/test/test_nntplib.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_nntplib.py Sun May 29 18:15:14 2016 +0300 @@ -28,7 +28,7 @@ certfile = os.path.join(os.path.dirname( # - test auth and `usenetrc` -class NetworkedNNTPTestsMixin: +class NetworkedNNTPTestsMixin(unittest.ExtraAssertions): def test_welcome(self): welcome = self.server.getwelcome() @@ -36,7 +36,7 @@ class NetworkedNNTPTestsMixin: def test_help(self): resp, lines = self.server.help() - self.assertTrue(resp.startswith("100 "), resp) + self.assertStartsWith(resp, "100 ") for line in lines: self.assertEqual(str, type(line)) @@ -56,7 +56,7 @@ class NetworkedNNTPTestsMixin: with self.assertRaises(nntplib.NNTPPermanentError) as cm: self.server._shortcmd("XYZZY") resp = cm.exception.response - self.assertTrue(resp.startswith("500 "), resp) + self.assertStartsWith(resp, "500 ") def test_newgroups(self): # gmane gets a constant influx of new groups. In order not to stress @@ -101,7 +101,7 @@ class NetworkedNNTPTestsMixin: self.assertIsInstance(first, int) self.assertIsInstance(last, int) self.assertLessEqual(first, last) - self.assertTrue(resp.startswith("211 "), resp) + self.assertStartsWith(resp, "211 ") def test_date(self): resp, date = self.server.date() @@ -178,13 +178,13 @@ class NetworkedNNTPTestsMixin: break else: self.skipTest("could not find a suitable article number") - self.assertTrue(resp.startswith("221 "), resp) + self.assertStartsWith(resp, "221 ") self.check_article_resp(resp, head, art_num) resp, body = self.server.body(art_num) - self.assertTrue(resp.startswith("222 "), resp) + self.assertStartsWith(resp, "222 ") self.check_article_resp(resp, body, art_num) resp, article = self.server.article(art_num) - self.assertTrue(resp.startswith("220 "), resp) + self.assertStartsWith(resp, "220 ") self.check_article_resp(resp, article, art_num) # Tolerate running the tests from behind a NNTP virus checker blacklist = lambda line: line.startswith(b'X-Antivirus') @@ -782,7 +782,7 @@ class ModeSwitchingNNTPv2Handler(NNTPv2H self.push_lit('200 Posting allowed') -class NNTPv1v2TestsMixin: +class NNTPv1v2TestsMixin(unittest.ExtraAssertions): def setUp(self): super().setUp() @@ -883,7 +883,7 @@ class NNTPv1v2TestsMixin: def test_group(self): resp, count, first, last, group = self.server.group("fr.comp.lang.python") - self.assertTrue(resp.startswith("211 "), resp) + self.assertStartsWith(resp, "211 ") self.assertEqual(first, 761) self.assertEqual(last, 1265) self.assertEqual(count, 486) @@ -891,8 +891,7 @@ class NNTPv1v2TestsMixin: with self.assertRaises(nntplib.NNTPTemporaryError) as cm: self.server.group("comp.lang.python.devel") exc = cm.exception - self.assertTrue(exc.response.startswith("411 No such group"), - exc.response) + self.assertStartsWith(exc.response, "411 No such group") def test_newnews(self): # NEWNEWS comp.lang.python [20]100913 082004 @@ -968,16 +967,16 @@ class NNTPv1v2TestsMixin: self.assertEqual(message_id, "<45223423@example.com>") self.assertEqual(lines, []) data = f.getvalue() - self.assertTrue(data.startswith( + self.assertStartsWith(data, b'From: "Demo User" \r\n' b'Subject: I am just a test article\r\n' - ), ascii(data)) - self.assertTrue(data.endswith( + ) + self.assertEndsWith(data, b'This is just a test article.\r\n' b'.Here is a dot-starting line.\r\n' b'\r\n' b'-- Signed by Andr\xc3\xa9.\r\n' - ), ascii(data)) + ) def test_head(self): # HEAD @@ -1015,10 +1014,10 @@ class NNTPv1v2TestsMixin: self.assertEqual(message_id, "<45223423@example.com>") self.assertEqual(lines, []) data = f.getvalue() - self.assertTrue(data.startswith( + self.assertStartsWith(data, b'From: "Demo User" \r\n' b'Subject: I am just a test article\r\n' - ), ascii(data)) + ) self.assertFalse(data.endswith( b'This is just a test article.\r\n' b'.Here is a dot-starting line.\r\n' @@ -1066,15 +1065,15 @@ class NNTPv1v2TestsMixin: b'From: "Demo User" \r\n' b'Subject: I am just a test article\r\n' ), ascii(data)) - self.assertTrue(data.endswith( + self.assertEndsWith(data, b'This is just a test article.\r\n' b'.Here is a dot-starting line.\r\n' b'\r\n' b'-- Signed by Andr\xc3\xa9.\r\n' - ), ascii(data)) + ) def check_over_xover_resp(self, resp, overviews): - self.assertTrue(resp.startswith("224 "), resp) + self.assertStartsWith(resp, "224 ") self.assertEqual(len(overviews), 3) art_num, over = overviews[0] self.assertEqual(art_num, 57) @@ -1245,7 +1244,7 @@ class SendReaderNNTPv2Tests(MockedNNTPWi self.assertIn('READER', self.server._caps) -class MiscTests(unittest.TestCase): +class MiscTests(unittest.TestCase, unittest.ExtraAssertions): def test_decode_header(self): def gives(a, b): @@ -1404,14 +1403,14 @@ class MiscTests(unittest.TestCase): @unittest.skipUnless(ssl, 'requires SSL support') def test_ssl_support(self): - self.assertTrue(hasattr(nntplib, 'NNTP_SSL')) + self.assertHasAttr(nntplib, 'NNTP_SSL') -class PublicAPITests(unittest.TestCase): +class PublicAPITests(unittest.TestCase, unittest.ExtraAssertions): """Ensures that the correct values are exposed in the public API.""" def test_module_all_attribute(self): - self.assertTrue(hasattr(nntplib, '__all__')) + self.assertHasAttr(nntplib, '__all__') target_api = ['NNTP', 'NNTPError', 'NNTPReplyError', 'NNTPTemporaryError', 'NNTPPermanentError', 'NNTPProtocolError', 'NNTPDataError', 'decode_header'] diff -r c95864a37ee2 Lib/test/test_ordered_dict.py --- a/Lib/test/test_ordered_dict.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_ordered_dict.py Sun May 29 18:15:14 2016 +0300 @@ -25,7 +25,7 @@ def replaced_module(name, replacement): sys.modules[name] = original_module -class OrderedDictTests: +class OrderedDictTests(unittest.ExtraAssertions): def test_init(self): OrderedDict = self.OrderedDict @@ -109,7 +109,7 @@ class OrderedDictTests: def test_abc(self): OrderedDict = self.OrderedDict self.assertIsInstance(OrderedDict(), MutableMapping) - self.assertTrue(issubclass(OrderedDict, MutableMapping)) + self.assertIsSubclass(OrderedDict, MutableMapping) def test_clear(self): OrderedDict = self.OrderedDict diff -r c95864a37ee2 Lib/test/test_os.py --- a/Lib/test/test_os.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_os.py Sun May 29 18:15:14 2016 +0300 @@ -246,7 +246,7 @@ class FileTests(unittest.TestCase): # Test attributes on return values from os.*stat* family. -class StatAttributeTests(unittest.TestCase): +class StatAttributeTests(unittest.TestCase, unittest.ExtraAssertions): def setUp(self): self.fname = support.TESTFN self.addCleanup(support.unlink, self.fname) @@ -426,7 +426,7 @@ class StatAttributeTests(unittest.TestCa self.assertEqual(ctx.exception.errno, errno.EBADF) def check_file_attributes(self, result): - self.assertTrue(hasattr(result, 'st_file_attributes')) + self.assertHasAttr(result, 'st_file_attributes') self.assertTrue(isinstance(result.st_file_attributes, int)) self.assertTrue(0 <= result.st_file_attributes <= 0xFFFFFFFF) diff -r c95864a37ee2 Lib/test/test_pathlib.py --- a/Lib/test/test_pathlib.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_pathlib.py Sun May 29 18:15:14 2016 +0300 @@ -161,7 +161,7 @@ class NTFlavourTest(_BaseFlavourTest, un # Tests for the pure classes # -class _BasePurePathTest(object): +class _BasePurePathTest(unittest.ExtraAssertions): # keys are canonical paths, values are list of tuples of arguments # supposed to produce equal paths @@ -284,8 +284,8 @@ class _BasePurePathTest(object): clsname = p.__class__.__name__ r = repr(p) # The repr() is in the form ClassName("forward-slashes path") - self.assertTrue(r.startswith(clsname + '('), r) - self.assertTrue(r.endswith(')'), r) + self.assertStartsWith(r, clsname + '(') + self.assertEndsWith(r, ')') inner = r[len(clsname) + 1 : -1] self.assertEqual(eval(inner), p.as_posix()) # The repr() roundtrips diff -r c95864a37ee2 Lib/test/test_pep247.py --- a/Lib/test/test_pep247.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_pep247.py Sun May 29 18:15:14 2016 +0300 @@ -7,10 +7,10 @@ import hmac import unittest from hashlib import md5, sha1, sha224, sha256, sha384, sha512 -class Pep247Test(unittest.TestCase): +class Pep247Test(unittest.TestCase, unittest.ExtraAssertions): def check_module(self, module, key=None): - self.assertTrue(hasattr(module, 'digest_size')) + self.assertHasAttr(module, 'digest_size') self.assertTrue(module.digest_size is None or module.digest_size > 0) self.check_object(module.new, module.digest_size, key) @@ -32,7 +32,7 @@ class Pep247Test(unittest.TestCase): obj3.update(b'string') h2 = obj3.digest() self.assertEqual(h1, h2) - self.assertTrue(hasattr(obj1, 'digest_size')) + self.assertHasAttr(obj1, 'digest_size') if digest_size is not None: self.assertEqual(obj1.digest_size, digest_size) diff -r c95864a37ee2 Lib/test/test_pep352.py --- a/Lib/test/test_pep352.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_pep352.py Sun May 29 18:15:14 2016 +0300 @@ -4,19 +4,17 @@ import os from platform import system as platform_system -class ExceptionClassTests(unittest.TestCase): +class ExceptionClassTests(unittest.TestCase, unittest.ExtraAssertions): """Tests for anything relating to exception objects themselves (e.g., inheritance hierarchy)""" def test_builtins_new_style(self): - self.assertTrue(issubclass(Exception, object)) + self.assertIsSubclass(Exception, object) def verify_instance_interface(self, ins): for attr in ("args", "__str__", "__repr__"): - self.assertTrue(hasattr(ins, attr), - "%s missing %s attribute" % - (ins.__class__.__name__, attr)) + self.assertHasAttr(ins, attr) def test_inheritance(self): # Make sure the inheritance hierarchy matches the documentation @@ -64,7 +62,7 @@ class ExceptionClassTests(unittest.TestC elif last_depth > depth: while superclasses[-1][0] >= depth: superclasses.pop() - self.assertTrue(issubclass(exc, superclasses[-1][1]), + self.assertIsSubclass(exc, superclasses[-1][1], "%s is not a subclass of %s" % (exc.__name__, superclasses[-1][1].__name__)) try: # Some exceptions require arguments; just skip them diff -r c95864a37ee2 Lib/test/test_pickle.py --- a/Lib/test/test_pickle.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_pickle.py Sun May 29 18:15:14 2016 +0300 @@ -292,7 +292,7 @@ def get_exceptions(mod): if isinstance(attr, type) and issubclass(attr, BaseException): yield name, attr -class CompatPickleTests(unittest.TestCase): +class CompatPickleTests(unittest.TestCase, unittest.ExtraAssertions): def test_import(self): modules = set(IMPORT_MAPPING.values()) modules |= set(REVERSE_IMPORT_MAPPING) @@ -320,7 +320,7 @@ class CompatPickleTests(unittest.TestCas with self.subTest(((module3, name3), (module2, name2))): if (module2, name2) == ('exceptions', 'OSError'): attr = getattribute(module3, name3) - self.assertTrue(issubclass(attr, OSError)) + self.assertIsSubclass(attr, OSError) else: module, name = mapping(module2, name2) if module3[:1] != '_': diff -r c95864a37ee2 Lib/test/test_pkgimport.py --- a/Lib/test/test_pkgimport.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_pkgimport.py Sun May 29 18:15:14 2016 +0300 @@ -9,7 +9,7 @@ import unittest from importlib.util import cache_from_source from test.support import create_empty_file -class TestImport(unittest.TestCase): +class TestImport(unittest.TestCase, unittest.ExtraAssertions): def __init__(self, *args, **kw): self.package_name = 'PACKAGE_' @@ -55,7 +55,7 @@ class TestImport(unittest.TestCase): except SyntaxError: pass else: raise RuntimeError('Failed to induce SyntaxError') # self.fail()? self.assertNotIn(self.module_name, sys.modules) - self.assertFalse(hasattr(sys.modules[self.package_name], 'foo')) + self.assertNotHasAttr(sys.modules[self.package_name], 'foo') # ...make up a variable name that isn't bound in __builtins__ var = 'a' diff -r c95864a37ee2 Lib/test/test_poplib.py --- a/Lib/test/test_poplib.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_poplib.py Sun May 29 18:15:14 2016 +0300 @@ -10,7 +10,7 @@ import socket import os import errno -from unittest import TestCase, skipUnless +from unittest import TestCase, ExtraAssertions, skipUnless from test import support as test_support threading = test_support.import_module('threading') @@ -240,9 +240,9 @@ class DummyPOP3Server(asyncore.dispatche raise -class TestPOP3Class(TestCase): +class TestPOP3Class(TestCase, ExtraAssertions): def assertOK(self, resp): - self.assertTrue(resp.startswith(b"+OK")) + self.assertStartsWith(resp, b"+OK") def setUp(self): self.server = DummyPOP3Server((HOST, PORT)) @@ -275,7 +275,7 @@ class TestPOP3Class(TestCase): self.assertEqual(self.client.list()[1:], ([b'1 1', b'2 2', b'3 3', b'4 4', b'5 5'], 25)) - self.assertTrue(self.client.list('1').endswith(b"OK 1 1")) + self.assertEndsWith(self.client.list('1'), b"OK 1 1") def test_retr(self): expected = (b'+OK 116 bytes', @@ -402,7 +402,7 @@ class TestPOP3_SSLClass(TestPOP3Class): context=ctx) self.assertIsInstance(self.client.sock, ssl.SSLSocket) self.assertIs(self.client.sock.context, ctx) - self.assertTrue(self.client.noop().startswith(b'+OK')) + self.assertStartsWith(self.client.noop(), b'+OK') def test_stls(self): self.assertRaises(poplib.error_proto, self.client.stls) diff -r c95864a37ee2 Lib/test/test_posix.py --- a/Lib/test/test_posix.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_posix.py Sun May 29 18:15:14 2016 +0300 @@ -19,7 +19,7 @@ import warnings _DUMMY_SYMLINK = os.path.join(tempfile.gettempdir(), support.TESTFN + '-dummy-symlink') -class PosixTester(unittest.TestCase): +class PosixTester(unittest.TestCase, unittest.ExtraAssertions): def setUp(self): # create empty file @@ -673,7 +673,7 @@ class PosixTester(unittest.TestCase): def _test_chflags_regular_file(self, chflags_func, target_file, **kwargs): st = os.stat(target_file) - self.assertTrue(hasattr(st, 'st_flags')) + self.assertHasAttr(st, 'st_flags') # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE. flags = st.st_flags | stat.UF_IMMUTABLE @@ -708,7 +708,7 @@ class PosixTester(unittest.TestCase): def test_lchflags_symlink(self): testfn_st = os.stat(support.TESTFN) - self.assertTrue(hasattr(testfn_st, 'st_flags')) + self.assertHasAttr(testfn_st, 'st_flags') os.symlink(support.TESTFN, _DUMMY_SYMLINK) self.teardown_files.append(_DUMMY_SYMLINK) diff -r c95864a37ee2 Lib/test/test_property.py --- a/Lib/test/test_property.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_property.py Sun May 29 18:15:14 2016 +0300 @@ -76,7 +76,7 @@ class PropertyNewGetter(object): """new docstring""" return 8 -class PropertyTests(unittest.TestCase): +class PropertyTests(unittest.TestCase, unittest.ExtraAssertions): def test_property_decorator_baseclass(self): # see #1620 base = BaseClass() @@ -86,8 +86,8 @@ class PropertyTests(unittest.TestCase): self.assertEqual(base.spam, 10) self.assertEqual(base._spam, 10) delattr(base, "spam") - self.assertTrue(not hasattr(base, "spam")) - self.assertTrue(not hasattr(base, "_spam")) + self.assertNotHasAttr(base, "spam") + self.assertNotHasAttr(base, "_spam") base.spam = 20 self.assertEqual(base.spam, 20) self.assertEqual(base._spam, 20) diff -r c95864a37ee2 Lib/test/test_pulldom.py --- a/Lib/test/test_pulldom.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_pulldom.py Sun May 29 18:15:14 2016 +0300 @@ -21,7 +21,7 @@ SMALL_SAMPLE = """ """ -class PullDOMTestCase(unittest.TestCase): +class PullDOMTestCase(unittest.TestCase, unittest.ExtraAssertions): def test_parse(self): """Minimal test of DOMEventStream.parse()""" @@ -45,7 +45,7 @@ class PullDOMTestCase(unittest.TestCase) items = pulldom.parseString(SMALL_SAMPLE) evt, node = next(items) # Just check the node is a Document: - self.assertTrue(hasattr(node, "createElement")) + self.assertHasAttr(node, "createElement") self.assertEqual(pulldom.START_DOCUMENT, evt) evt, node = next(items) self.assertEqual(pulldom.START_ELEMENT, evt) @@ -160,7 +160,7 @@ class PullDOMTestCase(unittest.TestCase) "Ran out of events, but should have received END_DOCUMENT") -class ThoroughTestCase(unittest.TestCase): +class ThoroughTestCase(unittest.TestCase, unittest.ExtraAssertions): """Test the hard-to-reach parts of pulldom.""" def test_thorough_parse(self): @@ -185,7 +185,7 @@ class ThoroughTestCase(unittest.TestCase evt, node = next(pd) self.assertEqual(pulldom.START_DOCUMENT, evt) # Just check the node is a Document: - self.assertTrue(hasattr(node, "createElement")) + self.assertHasAttr(node, "createElement") if before_root: evt, node = next(pd) diff -r c95864a37ee2 Lib/test/test_pyclbr.py --- a/Lib/test/test_pyclbr.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_pyclbr.py Sun May 29 18:15:14 2016 +0300 @@ -5,7 +5,7 @@ import sys from types import FunctionType, MethodType, BuiltinFunctionType import pyclbr -from unittest import TestCase, main as unittest_main +from unittest import TestCase, ExtraAssertions, main as unittest_main StaticMethodType = type(staticmethod(lambda: None)) ClassMethodType = type(classmethod(lambda c: None)) @@ -17,7 +17,7 @@ ClassMethodType = type(classmethod(lambd # is imperfect (as designed), testModule is called with a set of # members to ignore. -class PyclbrTest(TestCase): +class PyclbrTest(TestCase, ExtraAssertions): def assertListEq(self, l1, l2, ignore): ''' succeed iff {l1} - {ignore} == {l2} - {ignore} ''' @@ -30,8 +30,7 @@ class PyclbrTest(TestCase): ''' succeed iff hasattr(obj,attr) or attr in ignore. ''' if attr in ignore: return if not hasattr(obj, attr): print("???", attr) - self.assertTrue(hasattr(obj, attr), - 'expected hasattr(%r, %r)' % (obj, attr)) + self.assertHasAttr(obj, attr) def assertHaskey(self, obj, key, ignore): diff -r c95864a37ee2 Lib/test/test_pydoc.py --- a/Lib/test/test_pydoc.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_pydoc.py Sun May 29 18:15:14 2016 +0300 @@ -631,7 +631,7 @@ class PydocDocTest(unittest.TestCase): self.assertDictEqual(methods, expected) -class PydocImportTest(PydocBaseTest): +class PydocImportTest(PydocBaseTest, unittest.ExtraAssertions): def setUp(self): self.test_dir = os.mkdir(TESTFN) @@ -773,7 +773,7 @@ class PydocImportTest(PydocBaseTest): helper('modules garbage') result = help_io.getvalue() - self.assertTrue(result.startswith(expected)) + self.assertStartsWith(result, expected) def test_importfile(self): loaded_pydoc = pydoc.importfile(pydoc.__file__) diff -r c95864a37ee2 Lib/test/test_re.py --- a/Lib/test/test_re.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_re.py Sun May 29 18:15:14 2016 +0300 @@ -1672,7 +1672,7 @@ SUBPATTERN None self.checkPatternError(r'(?', 'unexpected end of pattern', 2) -class PatternReprTests(unittest.TestCase): +class PatternReprTests(unittest.TestCase, unittest.ExtraAssertions): def check(self, pattern, expected): self.assertEqual(repr(re.compile(pattern)), expected) @@ -1731,11 +1731,11 @@ class PatternReprTests(unittest.TestCase pattern = 'Very %spattern' % ('long ' * 1000) r = repr(re.compile(pattern)) self.assertLess(len(r), 300) - self.assertEqual(r[:30], "re.compile('Very long long lon") + self.assertStartsWith(r, "re.compile('Very long long lon") r = repr(re.compile(pattern, re.I)) self.assertLess(len(r), 300) - self.assertEqual(r[:30], "re.compile('Very long long lon") - self.assertEqual(r[-16:], ", re.IGNORECASE)") + self.assertStartsWith(r, "re.compile('Very long long lon") + self.assertEndsWith(r, ", re.IGNORECASE)") class ImplementationTest(unittest.TestCase): diff -r c95864a37ee2 Lib/test/test_reprlib.py --- a/Lib/test/test_reprlib.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_reprlib.py Sun May 29 18:15:14 2016 +0300 @@ -22,7 +22,7 @@ def nestedTuple(nesting): t = (t,) return t -class ReprTests(unittest.TestCase): +class ReprTests(unittest.TestCase, unittest.ExtraAssertions): def test_string(self): eq = self.assertEqual @@ -140,13 +140,13 @@ class ReprTests(unittest.TestCase): eq(r(i3), (""%id(i3))) s = r(ClassWithFailingRepr) - self.assertTrue(s.startswith("")) + self.assertStartsWith(s, "") self.assertIn(s.find("..."), [12, 13]) def test_lambda(self): r = repr(lambda x: x) - self.assertTrue(r.startswith("..') # Methods - self.assertTrue(repr(''.split).startswith( - '", "exec") expected = "'ascii' codec can't decode byte 0xe2 in position 16: " \ "ordinal not in range(128)" - self.assertTrue(c.exception.args[0].startswith(expected), - msg=c.exception.args[0]) + self.assertStartsWith(c.exception.args[0], expected) class AbstractSourceEncodingTest: diff -r c95864a37ee2 Lib/test/test_ssl.py --- a/Lib/test/test_ssl.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_ssl.py Sun May 29 18:15:14 2016 +0300 @@ -132,7 +132,7 @@ def skip_if_broken_ubuntu_ssl(func): needs_sni = unittest.skipUnless(ssl.HAS_SNI, "SNI support needed for this test") -class BasicSocketTests(unittest.TestCase): +class BasicSocketTests(unittest.TestCase, unittest.ExtraAssertions): def test_constants(self): ssl.CERT_NONE @@ -320,11 +320,9 @@ class BasicSocketTests(unittest.TestCase self.assertLessEqual(status, 15) # Version string as returned by {Open,Libre}SSL, the format might change if "LibreSSL" in s: - self.assertTrue(s.startswith("LibreSSL {:d}.{:d}".format(major, minor)), - (s, t, hex(n))) + self.assertStartsWith(s, "LibreSSL {:d}.{:d}".format(major, minor)) else: - self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)), - (s, t, hex(n))) + self.assertStartsWith(s, "OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)) @support.cpython_only def test_refcycle(self): @@ -1287,7 +1285,7 @@ class ContextTests(unittest.TestCase): self.assertFalse(ctx.check_hostname) -class SSLErrorTests(unittest.TestCase): +class SSLErrorTests(unittest.TestCase, unittest.ExtraAssertions): def test_str(self): # The str() of a SSLError doesn't include the errno @@ -1307,7 +1305,7 @@ class SSLErrorTests(unittest.TestCase): self.assertEqual(cm.exception.library, 'PEM') self.assertEqual(cm.exception.reason, 'NO_START_LINE') s = str(cm.exception) - self.assertTrue(s.startswith("[PEM: NO_START_LINE] no start line"), s) + self.assertStartsWith(s, "[PEM: NO_START_LINE] no start line") def test_subclass(self): # Check that the appropriate SSLError subclass is raised @@ -1323,7 +1321,7 @@ class SSLErrorTests(unittest.TestCase): with self.assertRaises(ssl.SSLWantReadError) as cm: c.do_handshake() s = str(cm.exception) - self.assertTrue(s.startswith("The operation did not complete (read)"), s) + self.assertStartsWith(s, "The operation did not complete (read)") # For compatibility self.assertEqual(cm.exception.errno, ssl.SSL_ERROR_WANT_READ) diff -r c95864a37ee2 Lib/test/test_stat.py --- a/Lib/test/test_stat.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_stat.py Sun May 29 18:15:14 2016 +0300 @@ -6,7 +6,7 @@ from test.support import TESTFN, import_ c_stat = import_fresh_module('stat', fresh=['_stat']) py_stat = import_fresh_module('stat', blocked=['_stat']) -class TestFilemode: +class TestFilemode(unittest.ExtraAssertions): statmod = None file_flags = {'SF_APPEND', 'SF_ARCHIVED', 'SF_IMMUTABLE', 'SF_NOUNLINK', @@ -141,7 +141,7 @@ class TestFilemode: else: os.chmod(TESTFN, 0o700) st_mode, modestr = self.get_mode() - self.assertEqual(modestr[:3], '-rw') + self.assertStartsWith(modestr, '-rw') self.assertS_IS("REG", st_mode) self.assertEqual(self.statmod.S_IFMT(st_mode), self.statmod.S_IFREG) @@ -210,7 +210,7 @@ class TestFilemode: "FILE_ATTRIBUTE_* constants are Win32 specific") def test_file_attribute_constants(self): for key, value in sorted(self.file_attributes.items()): - self.assertTrue(hasattr(self.statmod, key), key) + self.assertHasAttr(self.statmod, key) modvalue = getattr(self.statmod, key) self.assertEqual(value, modvalue, key) diff -r c95864a37ee2 Lib/test/test_statistics.py --- a/Lib/test/test_statistics.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_statistics.py Sun May 29 18:15:14 2016 +0300 @@ -588,7 +588,7 @@ class TestApproxEqualErrors(unittest.Tes # The formatting routine that generates the error messages is complex enough # that it too needs testing. -class TestNumericTestCase(unittest.TestCase): +class TestNumericTestCase(unittest.TestCase, unittest.ExtraAssertions): # The exact wording of NumericTestCase error messages is *not* guaranteed, # but we need to give them some sort of test to ensure that they are # generated correctly. As a compromise, we look for specific substrings @@ -602,7 +602,7 @@ class TestNumericTestCase(unittest.TestC def test_numerictestcase_is_testcase(self): # Ensure that NumericTestCase actually is a TestCase. - self.assertTrue(issubclass(NumericTestCase, unittest.TestCase)) + self.assertIsSubclass(NumericTestCase, unittest.TestCase) def test_error_msg_numeric(self): # Test the error message generated for numeric comparisons. @@ -633,15 +633,14 @@ class TestNumericTestCase(unittest.TestC # ======================================= -class GlobalsTest(unittest.TestCase): +class GlobalsTest(unittest.TestCase, unittest.ExtraAssertions): module = statistics expected_metadata = ["__doc__", "__all__"] def test_meta(self): # Test for the existence of metadata. for meta in self.expected_metadata: - self.assertTrue(hasattr(self.module, meta), - "%s not present" % meta) + self.assertHasAttr(self.module, meta) def test_check_all(self): # Check everything in __all__ exists and is public. @@ -651,8 +650,7 @@ class GlobalsTest(unittest.TestCase): self.assertFalse(name.startswith("_"), 'private name "%s" in __all__' % name) # And anything in __all__ must exist: - self.assertTrue(hasattr(module, name), - 'missing name "%s" in __all__' % name) + self.assertHasAttr(module, name) class DocTests(unittest.TestCase): @@ -663,17 +661,10 @@ class DocTests(unittest.TestCase): self.assertGreater(tried, 0) self.assertEqual(failed, 0) -class StatisticsErrorTest(unittest.TestCase): +class StatisticsErrorTest(unittest.TestCase, unittest.ExtraAssertions): def test_has_exception(self): - errmsg = ( - "Expected StatisticsError to be a ValueError, but got a" - " subclass of %r instead." - ) - self.assertTrue(hasattr(statistics, 'StatisticsError')) - self.assertTrue( - issubclass(statistics.StatisticsError, ValueError), - errmsg % statistics.StatisticsError.__base__ - ) + self.assertHasAttr(statistics, 'StatisticsError') + self.assertIsSubclass(statistics.StatisticsError, ValueError) # === Tests for private utility functions === diff -r c95864a37ee2 Lib/test/test_structseq.py --- a/Lib/test/test_structseq.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_structseq.py Sun May 29 18:15:14 2016 +0300 @@ -3,7 +3,7 @@ import time import unittest -class StructSeqTest(unittest.TestCase): +class StructSeqTest(unittest.TestCase, unittest.ExtraAssertions): def test_tuple(self): t = time.gmtime() @@ -37,7 +37,7 @@ class StructSeqTest(unittest.TestCase): # os.stat() gives a complicated struct sequence. st = os.stat(__file__) rep = repr(st) - self.assertTrue(rep.startswith("os.stat_result")) + self.assertStartsWith(rep, "os.stat_result") self.assertIn("st_mode=", rep) self.assertIn("st_ino=", rep) self.assertIn("st_dev=", rep) diff -r c95864a37ee2 Lib/test/test_subprocess.py --- a/Lib/test/test_subprocess.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_subprocess.py Sun May 29 18:15:14 2016 +0300 @@ -67,7 +67,7 @@ class PopenExecuteChildRaises(subprocess raise PopenTestException("Forced Exception for Test") -class ProcessTestCase(BaseTestCase): +class ProcessTestCase(BaseTestCase, unittest.ExtraAssertions): def test_io_buffered_by_default(self): p = subprocess.Popen([sys.executable, "-c", "import sys; sys.exit(0)"], @@ -881,7 +881,7 @@ class ProcessTestCase(BaseTestCase): # Python debug build push something like "[42442 refs]\n" # to stderr at exit of subprocess. # Don't use assertStderrEqual because it strips CR and LF from output. - self.assertTrue(stderr.startswith("eline2\neline6\neline7\n")) + self.assertStartsWith(stderr, "eline2\neline6\neline7\n") def test_universal_newlines_communicate_encodings(self): # Check that universal newlines mode works for various encodings, @@ -1153,7 +1153,7 @@ class ProcessTestCase(BaseTestCase): "[sys.executable, '-c', 'print(\"Hello World!\")'])", 'assert retcode == 0')) output = subprocess.check_output([sys.executable, '-c', code]) - self.assertTrue(output.startswith(b'Hello World!'), ascii(output)) + self.assertStartsWith(output, b'Hello World!') def test_handles_closed_on_exception(self): # If CreateProcess exits with an error, ensure the diff -r c95864a37ee2 Lib/test/test_sys.py --- a/Lib/test/test_sys.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_sys.py Sun May 29 18:15:14 2016 +0300 @@ -20,7 +20,7 @@ try: except ImportError: threading = None -class SysModuleTest(unittest.TestCase): +class SysModuleTest(unittest.TestCase, unittest.ExtraAssertions): def setUp(self): self.orig_stdout = sys.stdout @@ -46,7 +46,7 @@ class SysModuleTest(unittest.TestCase): dh(None) self.assertEqual(out.getvalue(), "") - self.assertTrue(not hasattr(builtins, "_")) + self.assertNotHasAttr(builtins, "_") dh(42) self.assertEqual(out.getvalue(), "42\n") self.assertEqual(builtins._, 42) @@ -78,7 +78,7 @@ class SysModuleTest(unittest.TestCase): except ValueError as exc: eh(*sys.exc_info()) - self.assertTrue(err.getvalue().endswith("ValueError: 42\n")) + self.assertEndsWith(err.getvalue(), "ValueError: 42\n") def test_excepthook(self): with test.support.captured_output("stderr") as stderr: @@ -134,8 +134,7 @@ class SysModuleTest(unittest.TestCase): rc, out, err = assert_python_failure('-c', code, **env_vars) self.assertEqual(rc, 1) self.assertEqual(out, b'') - self.assertTrue(err.startswith(expected), - "%s doesn't start with %s" % (ascii(err), ascii(expected))) + self.assertStartsWith(err, expected) # test that stderr buffer is flushed before the exit message is written # into stderr @@ -315,7 +314,7 @@ class SysModuleTest(unittest.TestCase): @unittest.skipUnless(hasattr(sys, "setdlopenflags"), 'test needs sys.setdlopenflags()') def test_dlopenflags(self): - self.assertTrue(hasattr(sys, "getdlopenflags")) + self.assertHasAttr(sys, "getdlopenflags") self.assertRaises(TypeError, sys.getdlopenflags, 42) oldflags = sys.getdlopenflags() self.assertRaises(TypeError, sys.setdlopenflags) @@ -553,7 +552,7 @@ class SysModuleTest(unittest.TestCase): "no_user_site", "no_site", "ignore_environment", "verbose", "bytes_warning", "quiet", "hash_randomization", "isolated") for attr in attrs: - self.assertTrue(hasattr(sys.flags, attr), attr) + self.assertHasAttr(sys.flags, attr) self.assertEqual(type(getattr(sys.flags, attr)), int, attr) self.assertTrue(repr(sys.flags)) self.assertEqual(len(sys.flags), len(attrs)) @@ -746,10 +745,10 @@ class SysModuleTest(unittest.TestCase): levels = {'alpha': 0xA, 'beta': 0xB, 'candidate': 0xC, 'final': 0xF} - self.assertTrue(hasattr(sys.implementation, 'name')) - self.assertTrue(hasattr(sys.implementation, 'version')) - self.assertTrue(hasattr(sys.implementation, 'hexversion')) - self.assertTrue(hasattr(sys.implementation, 'cache_tag')) + self.assertHasAttr(sys.implementation, 'name') + self.assertHasAttr(sys.implementation, 'version') + self.assertHasAttr(sys.implementation, 'hexversion') + self.assertHasAttr(sys.implementation, 'cache_tag') version = sys.implementation.version self.assertEqual(version[:2], (version.major, version.minor)) diff -r c95864a37ee2 Lib/test/test_sysconfig.py --- a/Lib/test/test_sysconfig.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_sysconfig.py Sun May 29 18:15:14 2016 +0300 @@ -15,7 +15,7 @@ from sysconfig import (get_paths, get_pl get_scheme_names, get_config_var, _main) import _osx_support -class TestSysConfig(unittest.TestCase): +class TestSysConfig(unittest.TestCase, unittest.ExtraAssertions): def setUp(self): super(TestSysConfig, self).setUp() @@ -398,12 +398,12 @@ class TestSysConfig(unittest.TestCase): or suffix.endswith('x86_64-linux-gnux32.so'), suffix) else: # 8 byte pointer size - self.assertTrue(suffix.endswith('x86_64-linux-gnu.so'), suffix) + self.assertEndsWith(suffix, 'x86_64-linux-gnu.so') @unittest.skipUnless(sys.platform == 'darwin', 'OS X-specific test') def test_osx_ext_suffix(self): suffix = sysconfig.get_config_var('EXT_SUFFIX') - self.assertTrue(suffix.endswith('-darwin.so'), suffix) + self.assertEndsWith(suffix, '-darwin.so') class MakefileTests(unittest.TestCase): diff -r c95864a37ee2 Lib/test/test_tarfile.py --- a/Lib/test/test_tarfile.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_tarfile.py Sun May 29 18:15:14 2016 +0300 @@ -1019,7 +1019,7 @@ class WriteTestBase(TarTest): self.assertEqual(len(fobj.read()), tarfile.RECORDSIZE * 2) -class WriteTest(WriteTestBase, unittest.TestCase): +class WriteTest(WriteTestBase, unittest.TestCase, unittest.ExtraAssertions): prefix = "w:" @@ -1301,7 +1301,7 @@ class WriteTest(WriteTestBase, unittest. try: for t in tar: if t.name != ".": - self.assertTrue(t.name.startswith("./"), t.name) + self.assertStartsWith(t.name, "./") finally: tar.close() diff -r c95864a37ee2 Lib/test/test_telnetlib.py --- a/Lib/test/test_telnetlib.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_telnetlib.py Sun May 29 18:15:14 2016 +0300 @@ -176,7 +176,7 @@ class ExpectAndReadTestCase(unittest.Tes def tearDown(self): telnetlib._TelnetSelector = self.old_selector -class ReadTests(ExpectAndReadTestCase): +class ReadTests(ExpectAndReadTestCase, unittest.ExtraAssertions): def test_read_until(self): """ read_until(expected, timeout=None) @@ -271,7 +271,7 @@ class ReadTests(ExpectAndReadTestCase): telnet.fill_rawq() except EOFError: break - self.assertTrue(want.startswith(data)) + self.assertStartsWith(want, data) self.assertEqual(data, want) class nego_collector(object): diff -r c95864a37ee2 Lib/test/test_tempfile.py --- a/Lib/test/test_tempfile.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_tempfile.py Sun May 29 18:15:14 2016 +0300 @@ -350,7 +350,7 @@ class TestBadTempdir: self.make_temp() -class TestMkstempInner(TestBadTempdir, BaseTestCase): +class TestMkstempInner(TestBadTempdir, BaseTestCase, unittest.ExtraAssertions): """Test the internal function _mkstemp_inner.""" class mkstemped: @@ -505,11 +505,11 @@ class TestMkstempInner(TestBadTempdir, B _mock_candidate_names('aaa', 'aaa', 'bbb'): (fd1, name1) = self.make_temp() os.close(fd1) - self.assertTrue(name1.endswith('aaa')) + self.assertEndsWith(name1, 'aaa') (fd2, name2) = self.make_temp() os.close(fd2) - self.assertTrue(name2.endswith('bbb')) + self.assertEndsWith(name2, 'bbb') def test_collision_with_existing_directory(self): # _mkstemp_inner tries another name when a directory with @@ -517,11 +517,11 @@ class TestMkstempInner(TestBadTempdir, B with _inside_empty_temp_dir(), \ _mock_candidate_names('aaa', 'aaa', 'bbb'): dir = tempfile.mkdtemp() - self.assertTrue(dir.endswith('aaa')) + self.assertEndsWith(dir, 'aaa') (fd, name) = self.make_temp() os.close(fd) - self.assertTrue(name.endswith('bbb')) + self.assertEndsWith(name, 'bbb') class TestGetTempPrefix(BaseTestCase): @@ -665,7 +665,7 @@ class TestMkstemp(BaseTestCase): os.rmdir(dir) -class TestMkdtemp(TestBadTempdir, BaseTestCase): +class TestMkdtemp(TestBadTempdir, BaseTestCase, unittest.ExtraAssertions): """Test mkdtemp().""" def make_temp(self): @@ -758,9 +758,9 @@ class TestMkdtemp(TestBadTempdir, BaseTe _mock_candidate_names('aaa', 'aaa', 'bbb'): file = tempfile.NamedTemporaryFile(delete=False) file.close() - self.assertTrue(file.name.endswith('aaa')) + self.assertEndsWith(file.name, 'aaa') dir = tempfile.mkdtemp() - self.assertTrue(dir.endswith('bbb')) + self.assertEndsWith(dir, 'bbb') def test_collision_with_existing_directory(self): # mkdtemp tries another name when a directory with @@ -768,9 +768,9 @@ class TestMkdtemp(TestBadTempdir, BaseTe with _inside_empty_temp_dir(), \ _mock_candidate_names('aaa', 'aaa', 'bbb'): dir1 = tempfile.mkdtemp() - self.assertTrue(dir1.endswith('aaa')) + self.assertEndsWith(dir1, 'aaa') dir2 = tempfile.mkdtemp() - self.assertTrue(dir2.endswith('bbb')) + self.assertEndsWith(dir2, 'bbb') class TestMktemp(BaseTestCase): diff -r c95864a37ee2 Lib/test/test_time.py --- a/Lib/test/test_time.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_time.py Sun May 29 18:15:14 2016 +0300 @@ -618,23 +618,23 @@ class TestStrftime4dyear(_TestStrftimeYe pass -class TestPytime(unittest.TestCase): +class TestPytime(unittest.TestCase, unittest.ExtraAssertions): @unittest.skipUnless(time._STRUCT_TM_ITEMS == 11, "needs tm_zone support") def test_localtime_timezone(self): # Get the localtime and examine it for the offset and zone. lt = time.localtime() - self.assertTrue(hasattr(lt, "tm_gmtoff")) - self.assertTrue(hasattr(lt, "tm_zone")) + self.assertHasAttr(lt, "tm_gmtoff") + self.assertHasAttr(lt, "tm_zone") # See if the offset and zone are similar to the module # attributes. if lt.tm_gmtoff is None: - self.assertTrue(not hasattr(time, "timezone")) + self.assertNotHasAttr(time, "timezone") else: self.assertEqual(lt.tm_gmtoff, -[time.timezone, time.altzone][lt.tm_isdst]) if lt.tm_zone is None: - self.assertTrue(not hasattr(time, "tzname")) + self.assertNotHasAttr(time, "tzname") else: self.assertEqual(lt.tm_zone, time.tzname[lt.tm_isdst]) diff -r c95864a37ee2 Lib/test/test_timeit.py --- a/Lib/test/test_timeit.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_timeit.py Sun May 29 18:15:14 2016 +0300 @@ -42,7 +42,7 @@ class FakeTimer: self.saved_timer = timer return self -class TestTimeit(unittest.TestCase): +class TestTimeit(unittest.TestCase, unittest.ExtraAssertions): def tearDown(self): try: @@ -214,8 +214,8 @@ class TestTimeit(unittest.TestCase): def assert_exc_string(self, exc_string, expected_exc_name): exc_lines = exc_string.splitlines() self.assertGreater(len(exc_lines), 2) - self.assertTrue(exc_lines[0].startswith('Traceback')) - self.assertTrue(exc_lines[-1].startswith(expected_exc_name)) + self.assertStartsWith(exc_lines[0], 'Traceback') + self.assertStartsWith(exc_lines[-1], expected_exc_name) def test_print_exc(self): s = io.StringIO() diff -r c95864a37ee2 Lib/test/test_tools/test_md5sum.py --- a/Lib/test/test_tools/test_md5sum.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_tools/test_md5sum.py Sun May 29 18:15:14 2016 +0300 @@ -9,7 +9,7 @@ from test.test_tools import scriptsdir, skip_if_missing() -class MD5SumTests(unittest.TestCase): +class MD5SumTests(unittest.TestCase, unittest.ExtraAssertions): @classmethod def setUpClass(cls): cls.script = os.path.join(scriptsdir, 'md5sum.py') @@ -34,7 +34,7 @@ class MD5SumTests(unittest.TestCase): def test_checksum_fodder(self): rc, out, err = assert_python_ok(self.script, self.fodder) self.assertEqual(rc, 0) - self.assertTrue(out.startswith(self.fodder_md5)) + self.assertStartsWith(out, self.fodder_md5) for part in self.fodder.split(os.path.sep): self.assertIn(part.encode(), out) self.assertFalse(err) @@ -50,7 +50,7 @@ class MD5SumTests(unittest.TestCase): def test_dash_t(self): rc, out, err = assert_python_ok(self.script, '-t', self.fodder) self.assertEqual(rc, 0) - self.assertTrue(out.startswith(self.fodder_textmode_md5)) + self.assertStartsWith(out, self.fodder_textmode_md5) self.assertNotIn(self.fodder_md5, out) def test_dash_s(self): diff -r c95864a37ee2 Lib/test/test_traceback.py --- a/Lib/test/test_traceback.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_traceback.py Sun May 29 18:15:14 2016 +0300 @@ -19,7 +19,7 @@ test_frame = namedtuple('frame', ['f_cod test_tb = namedtuple('tb', ['tb_frame', 'tb_lineno', 'tb_next']) -class SyntaxTracebackCases(unittest.TestCase): +class SyntaxTracebackCases(unittest.TestCase, unittest.ExtraAssertions): # For now, a very minimal set of tests. I want to be sure that # formatting of SyntaxErrors works based on changes for 2.1. @@ -154,9 +154,7 @@ class SyntaxTracebackCases(unittest.Test self.assertIn(("line %s" % lineno), stdout[1], "Invalid line number: {0!r} instead of {1}".format( stdout[1], lineno)) - self.assertTrue(stdout[2].endswith(err_line), - "Invalid traceback line: {0!r} instead of {1!r}".format( - stdout[2], err_line)) + self.assertEndsWith(stdout[2], err_line) self.assertTrue(stdout[3] == err_msg, "Invalid error message: {0!r} instead of {1!r}".format( stdout[3], err_msg)) @@ -217,7 +215,7 @@ class SyntaxTracebackCases(unittest.Test self.assertEqual(output.getvalue(), "Exception: projector\n") -class TracebackFormatTests(unittest.TestCase): +class TracebackFormatTests(unittest.TestCase, unittest.ExtraAssertions): def some_exception(self): raise KeyError('blah') @@ -263,9 +261,9 @@ class TracebackFormatTests(unittest.Test self.assertEqual(len(tb_lines), 5) banner = tb_lines[0] location, source_line = tb_lines[-2:] - self.assertTrue(banner.startswith('Traceback')) - self.assertTrue(location.startswith(' File')) - self.assertTrue(source_line.startswith(' raise')) + self.assertStartsWith(banner, 'Traceback') + self.assertStartsWith(location, ' File') + self.assertStartsWith(source_line, ' raise') def test_traceback_format(self): self.check_traceback_format() @@ -327,7 +325,7 @@ boundaries = re.compile( '(%s|%s)' % (re.escape(cause_message), re.escape(context_message))) -class BaseExceptionReportingTests: +class BaseExceptionReportingTests(unittest.ExtraAssertions): def get_exception(self, exception_or_callable): if isinstance(exception_or_callable, Exception): @@ -342,9 +340,9 @@ class BaseExceptionReportingTests: def check_zero_div(self, msg): lines = msg.splitlines() - self.assertTrue(lines[-3].startswith(' File')) + self.assertStartsWith(lines[-3], ' File') self.assertIn('1/0 # In zero_div', lines[-2]) - self.assertTrue(lines[-1].startswith('ZeroDivisionError'), lines[-1]) + self.assertStartsWith(lines[-1], 'ZeroDivisionError') def test_simple(self): try: @@ -353,10 +351,10 @@ class BaseExceptionReportingTests: e = _ lines = self.get_report(e).splitlines() self.assertEqual(len(lines), 4) - self.assertTrue(lines[0].startswith('Traceback')) - self.assertTrue(lines[1].startswith(' File')) + self.assertStartsWith(lines[0], 'Traceback') + self.assertStartsWith(lines[1], ' File') self.assertIn('1/0 # Marker', lines[2]) - self.assertTrue(lines[3].startswith('ZeroDivisionError')) + self.assertStartsWith(lines[3], 'ZeroDivisionError') def test_cause(self): def inner_raise(): @@ -396,10 +394,10 @@ class BaseExceptionReportingTests: e = _ lines = self.get_report(e).splitlines() self.assertEqual(len(lines), 4) - self.assertTrue(lines[0].startswith('Traceback')) - self.assertTrue(lines[1].startswith(' File')) + self.assertStartsWith(lines[0], 'Traceback') + self.assertStartsWith(lines[1], ' File') self.assertIn('ZeroDivisionError from None', lines[2]) - self.assertTrue(lines[3].startswith('ZeroDivisionError')) + self.assertStartsWith(lines[3], 'ZeroDivisionError') def test_cause_and_context(self): # When both a cause and a context are set, only the cause should be diff -r c95864a37ee2 Lib/test/test_types.py --- a/Lib/test/test_types.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_types.py Sun May 29 18:15:14 2016 +0300 @@ -752,7 +752,7 @@ class MappingProxyTests(unittest.TestCas self.assertEqual(copy['key1'], 27) -class ClassCreationTests(unittest.TestCase): +class ClassCreationTests(unittest.TestCase, unittest.ExtraAssertions): class Meta(type): def __init__(cls, name, bases, ns, **kw): @@ -774,7 +774,7 @@ class ClassCreationTests(unittest.TestCa def test_new_class_subclass(self): C = types.new_class("C", (int,)) - self.assertTrue(issubclass(C, int)) + self.assertIsSubclass(C, int) def test_new_class_meta(self): Meta = self.Meta @@ -819,7 +819,7 @@ class ClassCreationTests(unittest.TestCa bases=(int,), kwds=dict(metaclass=Meta, z=2), exec_body=func) - self.assertTrue(issubclass(C, int)) + self.assertIsSubclass(C, int) self.assertIsInstance(C, Meta) self.assertEqual(C.x, 0) self.assertEqual(C.y, 1) diff -r c95864a37ee2 Lib/test/test_typing.py --- a/Lib/test/test_typing.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_typing.py Sun May 29 18:15:14 2016 +0300 @@ -3,7 +3,7 @@ import collections import pickle import re import sys -from unittest import TestCase, main, skipUnless +from unittest import TestCase, ExtraAssertions, main, skipUnless from typing import Any from typing import TypeVar, AnyStr @@ -22,21 +22,8 @@ from typing import Pattern, Match import typing -class BaseTestCase(TestCase): - - def assertIsSubclass(self, cls, class_or_tuple, msg=None): - if not issubclass(cls, class_or_tuple): - message = '%r is not a subclass of %r' % (cls, class_or_tuple) - if msg is not None: - message += ' : %s' % msg - raise self.failureException(message) - - def assertNotIsSubclass(self, cls, class_or_tuple, msg=None): - if issubclass(cls, class_or_tuple): - message = '%r is a subclass of %r' % (cls, class_or_tuple) - if msg is not None: - message += ' : %s' % msg - raise self.failureException(message) +class BaseTestCase(TestCase, ExtraAssertions): + pass class Employee: @@ -62,17 +49,17 @@ class AnyTests(BaseTestCase): isinstance(42, Any) def test_any_subclass(self): - self.assertTrue(issubclass(Employee, Any)) - self.assertTrue(issubclass(int, Any)) - self.assertTrue(issubclass(type(None), Any)) - self.assertTrue(issubclass(object, Any)) + self.assertIsSubclass(Employee, Any) + self.assertIsSubclass(int, Any) + self.assertIsSubclass(type(None), Any) + self.assertIsSubclass(object, Any) def test_others_any(self): - self.assertFalse(issubclass(Any, Employee)) - self.assertFalse(issubclass(Any, int)) - self.assertFalse(issubclass(Any, type(None))) + self.assertNotIsSubclass(Any, Employee) + self.assertNotIsSubclass(Any, int) + self.assertNotIsSubclass(Any, type(None)) # However, Any is a subclass of object (this can't be helped). - self.assertTrue(issubclass(Any, object)) + self.assertIsSubclass(Any, object) def test_repr(self): self.assertEqual(repr(Any), 'typing.Any') @@ -186,16 +173,16 @@ class TypeVarTests(BaseTestCase): def test_subclass_as_unions(self): # None of these are true -- each type var is its own world. - self.assertFalse(issubclass(TypeVar('T', int, str), - TypeVar('T', int, str))) - self.assertFalse(issubclass(TypeVar('T', int, float), - TypeVar('T', int, float, str))) - self.assertFalse(issubclass(TypeVar('T', int, str), - TypeVar('T', str, int))) + self.assertNotIsSubclass(TypeVar('T', int, str), + TypeVar('T', int, str)) + self.assertNotIsSubclass(TypeVar('T', int, float), + TypeVar('T', int, float, str)) + self.assertNotIsSubclass(TypeVar('T', int, str), + TypeVar('T', str, int)) A = TypeVar('A', int, str) B = TypeVar('B', int, str, float) - self.assertFalse(issubclass(A, B)) - self.assertFalse(issubclass(B, A)) + self.assertNotIsSubclass(A, B) + self.assertNotIsSubclass(B, A) def test_cannot_subclass_vars(self): with self.assertRaises(TypeError): @@ -229,8 +216,8 @@ class UnionTests(BaseTestCase): def test_basics(self): u = Union[int, float] self.assertNotEqual(u, Union) - self.assertTrue(issubclass(int, u)) - self.assertTrue(issubclass(float, u)) + self.assertIsSubclass(int, u) + self.assertIsSubclass(float, u) def test_union_any(self): u = Union[Any] @@ -261,15 +248,15 @@ class UnionTests(BaseTestCase): def test_subclass(self): u = Union[int, Employee] - self.assertTrue(issubclass(Manager, u)) + self.assertIsSubclass(Manager, u) def test_self_subclass(self): - self.assertTrue(issubclass(Union[KT, VT], Union)) - self.assertFalse(issubclass(Union, Union[KT, VT])) + self.assertIsSubclass(Union[KT, VT], Union) + self.assertNotIsSubclass(Union, Union[KT, VT]) def test_multiple_inheritance(self): u = Union[int, Employee] - self.assertTrue(issubclass(ManagingFounder, u)) + self.assertIsSubclass(ManagingFounder, u) def test_single_class_disappears(self): t = Union[Employee] @@ -286,9 +273,9 @@ class UnionTests(BaseTestCase): def test_weird_subclasses(self): u = Union[Employee, int, float] v = Union[int, float] - self.assertTrue(issubclass(v, u)) + self.assertIsSubclass(v, u) w = Union[int, Manager] - self.assertTrue(issubclass(w, u)) + self.assertIsSubclass(w, u) def test_union_union(self): u = Union[int, float] @@ -357,8 +344,8 @@ class TypeVarUnionTests(BaseTestCase): self.assertNotIsSubclass(A, Union[int, str]) def test_var_union_subclass(self): - self.assertTrue(issubclass(T, Union[int, T])) - self.assertTrue(issubclass(KT, Union[KT, VT])) + self.assertIsSubclass(T, Union[int, T]) + self.assertIsSubclass(KT, Union[KT, VT]) def test_var_union(self): TU = TypeVar('TU', Union[int, float], None) @@ -369,14 +356,14 @@ class TypeVarUnionTests(BaseTestCase): class TupleTests(BaseTestCase): def test_basics(self): - self.assertTrue(issubclass(Tuple[int, str], Tuple)) - self.assertTrue(issubclass(Tuple[int, str], Tuple[int, str])) - self.assertFalse(issubclass(int, Tuple)) - self.assertFalse(issubclass(Tuple[float, str], Tuple[int, str])) - self.assertFalse(issubclass(Tuple[int, str, int], Tuple[int, str])) - self.assertFalse(issubclass(Tuple[int, str], Tuple[int, str, int])) - self.assertTrue(issubclass(tuple, Tuple)) - self.assertFalse(issubclass(Tuple, tuple)) # Can't have it both ways. + self.assertIsSubclass(Tuple[int, str], Tuple) + self.assertIsSubclass(Tuple[int, str], Tuple[int, str]) + self.assertNotIsSubclass(int, Tuple) + self.assertNotIsSubclass(Tuple[float, str], Tuple[int, str]) + self.assertNotIsSubclass(Tuple[int, str, int], Tuple[int, str]) + self.assertNotIsSubclass(Tuple[int, str], Tuple[int, str, int]) + self.assertIsSubclass(tuple, Tuple) + self.assertNotIsSubclass(Tuple, tuple) # Can't have it both ways. def test_equality(self): self.assertEqual(Tuple[int], Tuple[int]) @@ -387,7 +374,7 @@ class TupleTests(BaseTestCase): def test_tuple_subclass(self): class MyTuple(tuple): pass - self.assertTrue(issubclass(MyTuple, Tuple)) + self.assertIsSubclass(MyTuple, Tuple) def test_tuple_instance_type_error(self): with self.assertRaises(TypeError): @@ -424,17 +411,17 @@ class TupleTests(BaseTestCase): class CallableTests(BaseTestCase): def test_self_subclass(self): - self.assertTrue(issubclass(Callable[[int], int], Callable)) - self.assertFalse(issubclass(Callable, Callable[[int], int])) - self.assertTrue(issubclass(Callable[[int], int], Callable[[int], int])) - self.assertFalse(issubclass(Callable[[Employee], int], - Callable[[Manager], int])) - self.assertFalse(issubclass(Callable[[Manager], int], - Callable[[Employee], int])) - self.assertFalse(issubclass(Callable[[int], Employee], - Callable[[int], Manager])) - self.assertFalse(issubclass(Callable[[int], Manager], - Callable[[int], Employee])) + self.assertIsSubclass(Callable[[int], int], Callable) + self.assertNotIsSubclass(Callable, Callable[[int], int]) + self.assertIsSubclass(Callable[[int], int], Callable[[int], int]) + self.assertNotIsSubclass(Callable[[Employee], int], + Callable[[Manager], int]) + self.assertNotIsSubclass(Callable[[Manager], int], + Callable[[Employee], int]) + self.assertNotIsSubclass(Callable[[int], Employee], + Callable[[int], Manager]) + self.assertNotIsSubclass(Callable[[int], Manager], + Callable[[int], Employee]) def test_eq_hash(self): self.assertEqual(Callable[[int], int], Callable[[int], int]) @@ -632,8 +619,8 @@ class GenericTests(BaseTestCase): self.assertNotEqual(Z, Y[int]) self.assertNotEqual(Z, Y[T]) - self.assertTrue(str(Z).endswith( - '.C<~T>[typing.Tuple[~S, ~T]]<~S, ~T>[~T, int]<~T>[str]')) + self.assertEndsWith(str(Z), + '.C<~T>[typing.Tuple[~S, ~T]]<~S, ~T>[~T, int]<~T>[str]') def test_dict(self): T = TypeVar('T') diff -r c95864a37ee2 Lib/test/test_urllib.py --- a/Lib/test/test_urllib.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_urllib.py Sun May 29 18:15:14 2016 +0300 @@ -124,7 +124,7 @@ class FakeFTPMixin(object): urllib.request.ftpwrapper = self._ftpwrapper_class -class urlopen_FileTests(unittest.TestCase): +class urlopen_FileTests(unittest.TestCase, unittest.ExtraAssertions): """Test urlopen() opening a temporary file. Try to test as much functionality as possible so as to cut down on reliance @@ -153,9 +153,7 @@ class urlopen_FileTests(unittest.TestCas # Make sure object returned by urlopen() has the specified methods for attr in ("read", "readline", "readlines", "fileno", "close", "info", "geturl", "getcode", "__iter__"): - self.assertTrue(hasattr(self.returned_obj, attr), - "object returned by urlopen() lacks %s attribute" % - attr) + self.assertHasAttr(self.returned_obj, attr) def test_read(self): self.assertEqual(self.text, self.returned_obj.read()) @@ -462,7 +460,7 @@ Connection: close "https://localhost", cafile="/nonexistent/path", context=context ) -class urlopen_DataTests(unittest.TestCase): +class urlopen_DataTests(unittest.TestCase, unittest.ExtraAssertions): """Test urlopen() opening a data URL.""" def setUp(self): @@ -497,9 +495,7 @@ class urlopen_DataTests(unittest.TestCas # Make sure object returned by urlopen() has the specified methods for attr in ("read", "readline", "readlines", "close", "info", "geturl", "getcode", "__iter__"): - self.assertTrue(hasattr(self.text_url_resp, attr), - "object returned by urlopen() lacks %s attribute" % - attr) + self.assertHasAttr(self.text_url_resp, attr) def test_info(self): self.assertIsInstance(self.text_url_resp.info(), email.message.Message) diff -r c95864a37ee2 Lib/test/test_urllib2.py --- a/Lib/test/test_urllib2.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_urllib2.py Sun May 29 18:15:14 2016 +0300 @@ -682,7 +682,7 @@ def sanepathname2url(path): return urlpath -class HandlerTests(unittest.TestCase): +class HandlerTests(unittest.TestCase, unittest.ExtraAssertions): def test_ftp(self): class MockFTPWrapper: @@ -1043,15 +1043,15 @@ class HandlerTests(unittest.TestCase): r = MockResponse(200, "OK", {}, "", url) newr = h.http_response(req, r) self.assertIs(r, newr) - self.assertFalse(hasattr(o, "proto")) # o.error not called + self.assertNotHasAttr(o, "proto") # o.error not called r = MockResponse(202, "Accepted", {}, "", url) newr = h.http_response(req, r) self.assertIs(r, newr) - self.assertFalse(hasattr(o, "proto")) # o.error not called + self.assertNotHasAttr(o, "proto") # o.error not called r = MockResponse(206, "Partial content", {}, "", url) newr = h.http_response(req, r) self.assertIs(r, newr) - self.assertFalse(hasattr(o, "proto")) # o.error not called + self.assertNotHasAttr(o, "proto") # o.error not called # anything else calls o.error (and MockOpener returns None, here) r = MockResponse(502, "Bad gateway", {}, "", url) self.assertIsNone(h.http_response(req, r)) @@ -1257,7 +1257,7 @@ class HandlerTests(unittest.TestCase): response = opener.open('http://example.com/') expected = b'GET ' + result + b' ' request = handler.last_buf - self.assertTrue(request.startswith(expected), repr(request)) + self.assertStartsWith(request, expected) def test_proxy(self): o = OpenerDirector() @@ -1618,7 +1618,7 @@ class HandlerTests(unittest.TestCase): -class MiscTests(unittest.TestCase): +class MiscTests(unittest.TestCase, unittest.ExtraAssertions): def opener_has_handler(self, opener, handler_class): self.assertTrue(any(h.__class__ == handler_class @@ -1693,9 +1693,9 @@ class MiscTests(unittest.TestCase): url = code = fp = None hdrs = 'Content-Length: 42' err = urllib.error.HTTPError(url, code, msg, hdrs, fp) - self.assertTrue(hasattr(err, 'reason')) + self.assertHasAttr(err, 'reason') self.assertEqual(err.reason, 'something bad happened') - self.assertTrue(hasattr(err, 'headers')) + self.assertHasAttr(err, 'headers') self.assertEqual(err.headers, 'Content-Length: 42') expected_errmsg = 'HTTP Error %s: %s' % (err.code, err.msg) self.assertEqual(str(err), expected_errmsg) diff -r c95864a37ee2 Lib/test/test_urllib2_localnet.py --- a/Lib/test/test_urllib2_localnet.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_urllib2_localnet.py Sun May 29 18:15:14 2016 +0300 @@ -427,7 +427,7 @@ def GetRequestHandler(responses): @unittest.skipUnless(threading, "Threading required for this test.") -class TestUrlopen(unittest.TestCase): +class TestUrlopen(unittest.TestCase, unittest.ExtraAssertions): """Tests urllib.request.urlopen using the network. These tests are not exhaustive. Assuming that testing using files does a @@ -597,8 +597,7 @@ class TestUrlopen(unittest.TestCase): handler = self.start_server() open_url = urllib.request.urlopen("http://localhost:%s" % handler.port) for attr in ("read", "close", "info", "geturl"): - self.assertTrue(hasattr(open_url, attr), "object returned from " - "urlopen lacks the %s attribute" % attr) + self.assertHasAttr(open_url, attr) try: self.assertTrue(open_url.read(), "calling 'read' failed") finally: diff -r c95864a37ee2 Lib/test/test_urllibnet.py --- a/Lib/test/test_urllibnet.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_urllibnet.py Sun May 29 18:15:14 2016 +0300 @@ -28,7 +28,7 @@ class URLTimeoutTest(unittest.TestCase): x = f.read() -class urlopenNetworkTests(unittest.TestCase): +class urlopenNetworkTests(unittest.TestCase, unittest.ExtraAssertions): """Tests urllib.reqest.urlopen using the network. These tests are not exhaustive. Assuming that testing using files does a @@ -60,8 +60,7 @@ class urlopenNetworkTests(unittest.TestC with self.urlopen(self.url) as open_url: for attr in ("read", "readline", "readlines", "fileno", "close", "info", "geturl"): - self.assertTrue(hasattr(open_url, attr), "object returned from " - "urlopen lacks the %s attribute" % attr) + self.assertHasAttr(open_url, attr) self.assertTrue(open_url.read(), "calling 'read' failed") def test_readlines(self): diff -r c95864a37ee2 Lib/test/test_urlparse.py --- a/Lib/test/test_urlparse.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_urlparse.py Sun May 29 18:15:14 2016 +0300 @@ -75,7 +75,7 @@ parse_qs_test_cases = [ (b"a=1;a=2", {b'a': [b'1', b'2']}), ] -class UrlParseTestCase(unittest.TestCase): +class UrlParseTestCase(unittest.TestCase, unittest.ExtraAssertions): def checkRoundtrips(self, url, parsed, split): result = urllib.parse.urlparse(url) @@ -767,7 +767,7 @@ class UrlParseTestCase(unittest.TestCase with self.subTest(url=url, function=func): result = func(url, allow_fragments=False) self.assertEqual(result.fragment, "") - self.assertTrue(getattr(result, attr).endswith("#frag")) + self.assertEndsWith(getattr(result, attr), "#frag") self.assertEqual(func(url, "", False).fragment, "") result = func(url, allow_fragments=True) diff -r c95864a37ee2 Lib/test/test_userdict.py --- a/Lib/test/test_userdict.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_userdict.py Sun May 29 18:15:14 2016 +0300 @@ -11,7 +11,7 @@ d3 = {"one": 1, "two": 3, "three": 5} d4 = {"one": None, "two": None} d5 = {"one": 1, "two": 1} -class UserDictTest(mapping_tests.TestHashMappingProtocol): +class UserDictTest(mapping_tests.TestHashMappingProtocol, unittest.ExtraAssertions): type2test = collections.UserDict def test_all(self): @@ -167,7 +167,7 @@ class UserDictTest(mapping_tests.TestHas def test_missing(self): # Make sure UserDict doesn't have a __missing__ method - self.assertEqual(hasattr(collections.UserDict, "__missing__"), False) + self.assertNotHasAttr(collections.UserDict, "__missing__") # Test several cases: # (D) subclass defines __missing__ method returning a value # (E) subclass defines __missing__ method raising RuntimeError diff -r c95864a37ee2 Lib/test/test_venv.py --- a/Lib/test/test_venv.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_venv.py Sun May 29 18:15:14 2016 +0300 @@ -283,7 +283,7 @@ class BasicTest(BaseTest): @skipInVenv -class EnsurePipTest(BaseTest): +class EnsurePipTest(BaseTest, unittest.ExtraAssertions): """Test venv module installation of pip.""" def assert_pip_not_installed(self): envpy = os.path.join(os.path.realpath(self.env_dir), @@ -385,7 +385,7 @@ class EnsurePipTest(BaseTest): self.assertEqual(err, "") out = out.decode("latin-1") # Force to text, prevent decoding errors expected_version = "pip {}".format(ensurepip.version()) - self.assertEqual(out[:len(expected_version)], expected_version) + self.assertStartsWith(out, expected_version) env_dir = os.fsencode(self.env_dir).decode("latin-1") self.assertIn(env_dir, out) diff -r c95864a37ee2 Lib/test/test_warnings/__init__.py --- a/Lib/test/test_warnings/__init__.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_warnings/__init__.py Sun May 29 18:15:14 2016 +0300 @@ -69,14 +69,14 @@ class BaseTest: unittest.case.warnings = self.old_unittest_module super(BaseTest, self).tearDown() -class PublicAPITests(BaseTest): +class PublicAPITests(BaseTest, unittest.ExtraAssertions): """Ensures that the correct values are exposed in the public API. """ def test_module_all_attribute(self): - self.assertTrue(hasattr(self.module, '__all__')) + self.assertHasAttr(self.module, '__all__') target_api = ["warn", "warn_explicit", "showwarning", "formatwarning", "filterwarnings", "simplefilter", "resetwarnings", "catch_warnings"] @@ -329,7 +329,7 @@ class PyFilterTests(FilterTests, unittes module = py_warnings -class WarnTests(BaseTest): +class WarnTests(BaseTest, unittest.ExtraAssertions): """Test warnings.warn() and warnings.warn_explicit().""" @@ -564,7 +564,7 @@ class CWarnTests(WarnTests, unittest.Tes # test.support.import_fresh_module utility function def test_accelerated(self): self.assertFalse(original_warnings is self.module) - self.assertFalse(hasattr(self.module.warn, '__code__')) + self.assertNotHasAttr(self.module.warn, '__code__') class PyWarnTests(WarnTests, unittest.TestCase): module = py_warnings @@ -573,7 +573,7 @@ class PyWarnTests(WarnTests, unittest.Te # test.support.import_fresh_module utility function def test_pure_python(self): self.assertFalse(original_warnings is self.module) - self.assertTrue(hasattr(self.module.warn, '__code__')) + self.assertHasAttr(self.module.warn, '__code__') class WCmdLineTests(BaseTest): @@ -1034,7 +1034,7 @@ class BootstrapTest(unittest.TestCase): assert_python_ok('-c', 'pass', '-W', 'always', PYTHONPATH=cwd) -class FinalizationTest(unittest.TestCase): +class FinalizationTest(unittest.TestCase, unittest.ExtraAssertions): def test_finalization(self): # Issue #19421: warnings.warn() should not crash # during Python finalization @@ -1063,12 +1063,12 @@ a=A() # (_warnings will try to import it) code = "f = open(%a)" % __file__ rc, out, err = assert_python_ok("-Wd", "-c", code) - self.assertTrue(err.startswith(expected), ascii(err)) + self.assertStartsWith(err, expected) # import the warnings module code = "import warnings; f = open(%a)" % __file__ rc, out, err = assert_python_ok("-Wd", "-c", code) - self.assertTrue(err.startswith(expected), ascii(err)) + self.assertStartsWith(err, expected) def setUpModule(): diff -r c95864a37ee2 Lib/test/test_weakref.py --- a/Lib/test/test_weakref.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_weakref.py Sun May 29 18:15:14 2016 +0300 @@ -72,7 +72,7 @@ class TestBase(unittest.TestCase): self.cbcalled += 1 -class ReferencesTestCase(TestBase): +class ReferencesTestCase(TestBase, unittest.ExtraAssertions): def test_basic_ref(self): self.check_basic_ref(C) @@ -321,7 +321,7 @@ class ReferencesTestCase(TestBase): self.assertEqual(proxy.foo, 2, "proxy does not reflect attribute modification") del o.foo - self.assertFalse(hasattr(proxy, 'foo'), + self.assertNotHasAttr(proxy, 'foo', "proxy does not reflect attribute removal") proxy.foo = 1 @@ -331,7 +331,7 @@ class ReferencesTestCase(TestBase): self.assertEqual(o.foo, 2, "object does not reflect attribute modification via proxy") del proxy.foo - self.assertFalse(hasattr(o, 'foo'), + self.assertNotHasAttr(o, 'foo', "object does not reflect attribute removal via proxy") def test_proxy_deletion(self): @@ -845,7 +845,7 @@ class ReferencesTestCase(TestBase): ref1.__callback__ = lambda ref: None -class SubclassableWeakrefTestCase(TestBase): +class SubclassableWeakrefTestCase(TestBase, unittest.ExtraAssertions): def test_subclass_refs(self): class MyRef(weakref.ref): @@ -907,7 +907,7 @@ class SubclassableWeakrefTestCase(TestBa self.assertEqual(r.slot1, "abc") self.assertEqual(r.slot2, "def") self.assertEqual(r.meth(), "abcdef") - self.assertFalse(hasattr(r, "__dict__")) + self.assertNotHasAttr(r, "__dict__") def test_subclass_refs_with_cycle(self): # Bug #3110 diff -r c95864a37ee2 Lib/test/test_with.py --- a/Lib/test/test_with.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_with.py Sun May 29 18:15:14 2016 +0300 @@ -594,7 +594,7 @@ class NonLocalFlowControlTestCase(unitte self.fail("Didn't raise RuntimeError") -class AssignmentTargetTestCase(unittest.TestCase): +class AssignmentTargetTestCase(unittest.TestCase, unittest.ExtraAssertions): def testSingleComplexTarget(self): targets = {1: [0, 1, 2]} @@ -611,7 +611,7 @@ class AssignmentTargetTestCase(unittest. class C: pass blah = C() with mock_contextmanager_generator() as blah.foo: - self.assertEqual(hasattr(blah, "foo"), True) + self.assertHasAttr(blah, "foo") def testMultipleComplexTargets(self): class C: diff -r c95864a37ee2 Lib/test/test_wsgiref.py --- a/Lib/test/test_wsgiref.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_wsgiref.py Sun May 29 18:15:14 2016 +0300 @@ -111,7 +111,7 @@ def compare_generic_iter(make_it,match): raise AssertionError("Too many items from .__next__()", it) -class IntegrationTests(TestCase): +class IntegrationTests(TestCase, unittest.ExtraAssertions): def check_hello(self, out, has_length=True): pyver = (python_implementation() + "/" + @@ -158,9 +158,9 @@ class IntegrationTests(TestCase): start_response("200 OK", ('Content-Type','text/plain')) return ["Hello, world!"] out, err = run_amock(validator(bad_app)) - self.assertTrue(out.endswith( + self.assertEndsWith(out, b"A server error occurred. Please contact the administrator." - )) + ) self.assertEqual( err.splitlines()[-2], "AssertionError: Headers (('Content-Type', 'text/plain')) must" @@ -183,9 +183,9 @@ class IntegrationTests(TestCase): for status, exc_message in tests: with self.subTest(status=status): out, err = run_amock(create_bad_app(status)) - self.assertTrue(out.endswith( + self.assertEndsWith(out, b"A server error occurred. Please contact the administrator." - )) + ) self.assertEqual(err.splitlines()[-2], exc_message) def test_wsgi_input(self): @@ -194,9 +194,9 @@ class IntegrationTests(TestCase): s("200 OK", [("Content-Type", "text/plain; charset=utf-8")]) return [b"data"] out, err = run_amock(validator(bad_app)) - self.assertTrue(out.endswith( + self.assertEndsWith(out, b"A server error occurred. Please contact the administrator." - )) + ) self.assertEqual( err.splitlines()[-2], "AssertionError" ) @@ -209,7 +209,7 @@ class IntegrationTests(TestCase): ]) return [b"data"] out, err = run_amock(validator(app)) - self.assertTrue(err.endswith('"GET / HTTP/1.0" 200 4\n')) + self.assertEndsWith(err, '"GET / HTTP/1.0" 200 4\n') ver = sys.version.split()[0].encode('ascii') py = python_implementation().encode('ascii') pyver = py + b"/" + ver diff -r c95864a37ee2 Lib/test/test_xml_etree.py --- a/Lib/test/test_xml_etree.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_xml_etree.py Sun May 29 18:15:14 2016 +0300 @@ -155,7 +155,7 @@ class ElementTestCase: # -------------------------------------------------------------------- # element tree tests -class ElementTreeTest(unittest.TestCase): +class ElementTreeTest(unittest.TestCase, unittest.ExtraAssertions): def serialize_check(self, elem, expected): self.assertEqual(serialize(elem), expected) @@ -186,8 +186,7 @@ class ElementTreeTest(unittest.TestCase) self.assertTrue(ET.iselement(element), msg="not an element") direlem = dir(element) for attr in 'tag', 'attrib', 'text', 'tail': - self.assertTrue(hasattr(element, attr), - msg='no %s member' % attr) + self.assertHasAttr(element, attr) self.assertIn(attr, direlem, msg='no %s visible by dir' % attr) @@ -212,7 +211,7 @@ class ElementTreeTest(unittest.TestCase) # Make sure all standard element methods exist. def check_method(method): - self.assertTrue(hasattr(method, '__call__'), + self.assertHasAttr(method, '__call__', msg="%s not callable" % method) check_method(element.append) @@ -1007,7 +1006,7 @@ class ElementTreeTest(unittest.TestCase) self.assertEqual(serialized, expected) -class XMLPullParserTest(unittest.TestCase): +class XMLPullParserTest(unittest.TestCase, unittest.ExtraAssertions): def _feed(self, parser, data, chunk_size=None): if chunk_size is None: diff -r c95864a37ee2 Lib/test/test_zipapp.py --- a/Lib/test/test_zipapp.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_zipapp.py Sun May 29 18:15:14 2016 +0300 @@ -11,7 +11,7 @@ import zipfile from unittest.mock import patch -class ZipAppTest(unittest.TestCase): +class ZipAppTest(unittest.TestCase, unittest.ExtraAssertions): """Test zipapp module functionality.""" @@ -151,7 +151,7 @@ class ZipAppTest(unittest.TestCase): (source / '__main__.py').touch() target = io.BytesIO() zipapp.create_archive(str(source), target, interpreter='python') - self.assertTrue(target.getvalue().startswith(b'#!python\n')) + self.assertStartsWith(target.getvalue(), b'#!python\n') def test_read_shebang(self): # Test that we can read the shebang line correctly. @@ -192,7 +192,7 @@ class ZipAppTest(unittest.TestCase): zipapp.create_archive(str(source), str(target), interpreter='python') new_target = io.BytesIO() zipapp.create_archive(str(target), new_target, interpreter='python2.7') - self.assertTrue(new_target.getvalue().startswith(b'#!python2.7\n')) + self.assertStartsWith(new_target.getvalue(), b'#!python2.7\n') def test_read_from_pathobj(self): # Test that we can copy an archive using a pathlib.Path object @@ -217,7 +217,7 @@ class ZipAppTest(unittest.TestCase): new_target = io.BytesIO() temp_archive.seek(0) zipapp.create_archive(temp_archive, new_target, interpreter='python2.7') - self.assertTrue(new_target.getvalue().startswith(b'#!python2.7\n')) + self.assertStartsWith(new_target.getvalue(), b'#!python2.7\n') def test_remove_shebang(self): # Test that we can remove the shebang from a file. diff -r c95864a37ee2 Lib/test/test_zipfile.py --- a/Lib/test/test_zipfile.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_zipfile.py Sun May 29 18:15:14 2016 +0300 @@ -1946,7 +1946,7 @@ class TestsWithMultipleOpens(unittest.Te unlink(TESTFN2) -class TestWithDirectory(unittest.TestCase): +class TestWithDirectory(unittest.TestCase, unittest.ExtraAssertions): def setUp(self): os.mkdir(TESTFN2) @@ -1969,7 +1969,7 @@ class TestWithDirectory(unittest.TestCas with zipfile.ZipFile(TESTFN, "w") as zipf: zipf.write(dirpath) zinfo = zipf.filelist[0] - self.assertTrue(zinfo.filename.endswith("/x/")) + self.assertEndsWith(zinfo.filename, "/x/") self.assertEqual(zinfo.external_attr, (mode << 16) | 0x10) zipf.write(dirpath, "y") zinfo = zipf.filelist[1] @@ -1977,7 +1977,7 @@ class TestWithDirectory(unittest.TestCas self.assertEqual(zinfo.external_attr, (mode << 16) | 0x10) with zipfile.ZipFile(TESTFN, "r") as zipf: zinfo = zipf.filelist[0] - self.assertTrue(zinfo.filename.endswith("/x/")) + self.assertEndsWith(zinfo.filename, "/x/") self.assertEqual(zinfo.external_attr, (mode << 16) | 0x10) zinfo = zipf.filelist[1] self.assertTrue(zinfo.filename, "y/") @@ -1997,7 +1997,7 @@ class TestWithDirectory(unittest.TestCas self.assertEqual(zinfo.external_attr, (0o40775 << 16) | 0x10) with zipfile.ZipFile(TESTFN, "r") as zipf: zinfo = zipf.filelist[0] - self.assertTrue(zinfo.filename.endswith("x/")) + self.assertEndsWith(zinfo.filename, "x/") self.assertEqual(zinfo.external_attr, (0o40775 << 16) | 0x10) target = os.path.join(TESTFN2, "target") os.mkdir(target) diff -r c95864a37ee2 Lib/test/test_zipimport.py --- a/Lib/test/test_zipimport.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/test/test_zipimport.py Sun May 29 18:15:14 2016 +0300 @@ -73,7 +73,7 @@ class ImportHooksBaseTestCase(unittest.T support.modules_cleanup(*self.modules_before) -class UncompressedZipImportTestCase(ImportHooksBaseTestCase): +class UncompressedZipImportTestCase(ImportHooksBaseTestCase, unittest.ExtraAssertions): compression = ZIP_STORED @@ -597,7 +597,7 @@ class UncompressedZipImportTestCase(Impo s = io.StringIO() print_tb(tb, 1, s) - self.assertTrue(s.getvalue().endswith(raise_src)) + self.assertEndsWith(s.getvalue(), raise_src) else: raise AssertionError("This ought to be impossible") diff -r c95864a37ee2 Lib/unittest/__init__.py --- a/Lib/unittest/__init__.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/unittest/__init__.py Sun May 29 18:15:14 2016 +0300 @@ -48,7 +48,8 @@ SUPPORT, UPDATES, ENHANCEMENTS, OR MODIF 'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main', 'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless', 'expectedFailure', 'TextTestResult', 'installHandler', - 'registerResult', 'removeResult', 'removeHandler'] + 'registerResult', 'removeResult', 'removeHandler', + 'ExtraAssertions'] # Expose obsolete functions for backwards compatibility __all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases']) @@ -57,7 +58,7 @@ SUPPORT, UPDATES, ENHANCEMENTS, OR MODIF from .result import TestResult from .case import (TestCase, FunctionTestCase, SkipTest, skip, skipIf, - skipUnless, expectedFailure) + skipUnless, expectedFailure, ExtraAssertions) from .suite import BaseTestSuite, TestSuite from .loader import (TestLoader, defaultTestLoader, makeSuite, getTestCaseNames, findTestCases) diff -r c95864a37ee2 Lib/unittest/case.py --- a/Lib/unittest/case.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/unittest/case.py Sun May 29 18:15:14 2016 +0300 @@ -10,6 +10,7 @@ import warnings import collections import contextlib import traceback +import types from . import result from .util import (strclass, safe_repr, _count_diff_all_purpose, @@ -332,8 +333,96 @@ class _AssertLogsContext(_BaseTestCaseCo "no logs of level {} or higher triggered on {}" .format(logging.getLevelName(self.level), self.logger.name)) +class ExtraAssertions: + def assertHasAttr(self, obj, name, msg=None): + if not hasattr(obj, name): + if isinstance(obj, types.ModuleType): + self.fail(self._formatMessage(msg, + 'module %r has no attribute %r' % + (obj.__name__, name))) + else: + self.fail(self._formatMessage(msg, + '%s instance has no attribute %r' % + (type(obj).__name__, name))) -class TestCase(object): + def assertNotHasAttr(self, obj, name, msg=None): + if hasattr(obj, name): + if isinstance(obj, types.ModuleType): + self.fail(self._formatMessage(msg, + 'module %r has unexpected attribute %r' % + (obj.__name__, name))) + else: + self.fail(self._formatMessage(msg, + '%s instance has unexpected attribute %r' % + (type(obj).__name__, name))) + + def assertIsSubclass(self, cls, superclass, msg=None): + try: + r = issubclass(cls, superclass) + except TypeError: + if not isinstance(cls, type): + self.fail(self._formatMessage(msg, + '%r is not a class' % (cls,))) + raise + if not r: + self.fail(self._formatMessage(msg, + '%r is not a subclass of %r' % (cls, superclass))) + + def assertNotIsSubclass(self, cls, superclass, msg=None): + try: + r = issubclass(cls, superclass) + except TypeError: + if not isinstance(cls, type): + self.fail(self._formatMessage(msg, + '%r is not a class' % (cls,))) + raise + if r: + self.fail(self._formatMessage(msg, + '%r is a subclass of %r' % (cls, superclass))) + + def assertStartsWith(self, s, prefix, msg=None): + if not isinstance(prefix, (str, bytes, bytearray)): + raise TypeError('prefix should be str or bytes, not %s' % type(prefix)) + try: + r = s.startswith(prefix) + except (AttributeError, TypeError): + if isinstance(prefix, str) and not isinstance(s, str): + self.fail(self._formatMessage(msg, + 'Expected str, not %s' % (type(s).__name__,))) + if (isinstance(prefix, (bytes, bytearray)) and + not isinstance(s, (bytes, bytearray))): + self.fail(self._formatMessage(msg, + 'Expected bytes, not %s' % (type(s).__name__,))) + raise + if not r: + a, b = _common_shorten_repr(s[:len(prefix) + 10], prefix) + if len(a) > len(prefix) + 10: + a += '...' + self.fail(self._formatMessage(msg, + "%s doesn't starts with %s" % (a, b))) + + def assertEndsWith(self, s, suffix, msg=None): + if not isinstance(suffix, (str, bytes, bytearray)): + raise TypeError('suffix should be str or bytes') + try: + r = s.endswith(suffix) + except (AttributeError, TypeError): + if isinstance(suffix, str) and not isinstance(s, str): + self.fail(self._formatMessage(msg, + 'Expected str, not %s' % (type(s).__name__,))) + if (isinstance(suffix, (bytes, bytearray)) and + not isinstance(s, (bytes, bytearray))): + self.fail(self._formatMessage(msg, + 'Expected bytes, not %s' % (type(s).__name__,))) + raise + if not r: + a, b = _common_shorten_repr(s[-len(suffix) - 10:], suffix) + if len(a) > len(suffix) + 10: + a = '...' + a + self.fail(self._formatMessage(msg, + "%s doesn't starts with %s" % (a, b))) + +class TestCase: """A class whose instances are single test cases. By default, the test code itself should be placed in a method named diff -r c95864a37ee2 Lib/unittest/test/test_case.py --- a/Lib/unittest/test/test_case.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/unittest/test/test_case.py Sun May 29 18:15:14 2016 +0300 @@ -53,7 +53,11 @@ class Test(object): self.events.append('tearDown') -class Test_TestCase(unittest.TestCase, TestEquality, TestHashing): +class List(list): + pass + + +class Test_TestCase(unittest.TestCase, TestEquality, TestHashing, unittest.ExtraAssertions): ### Set up attributes used by inherited tests ################################################################ @@ -84,7 +88,7 @@ class Test_TestCase(unittest.TestCase, T def runTest(self): raise MyException() def test(self): pass - self.assertEqual(Test().id()[-13:], '.Test.runTest') + self.assertEndsWith(Test().id(), '.Test.runTest') # test that TestCase can be instantiated with no args # primarily for use at the interactive interpreter @@ -105,7 +109,7 @@ class Test_TestCase(unittest.TestCase, T def runTest(self): raise MyException() def test(self): pass - self.assertEqual(Test('test').id()[-10:], '.Test.test') + self.assertEndsWith(Test('test').id(), '.Test.test') # "class TestCase([methodName])" # ... @@ -1816,5 +1820,91 @@ test case self.assertEqual(MyException.ninstance, 0) +class Test_ExtraAssertions(unittest.TestCase, unittest.ExtraAssertions): + def testAssertHasAttr(self): + a = List() + a.x = 1 + self.assertHasAttr(a, 'x') + with self.assertRaises(self.failureException): + self.assertHasAttr(a, 'y') + with self.assertRaisesRegex(self.failureException, 'ababahalamaha'): + self.assertHasAttr(a, 'y', 'ababahalamaha') + with self.assertRaisesRegex(self.failureException, 'ababahalamaha'): + self.assertHasAttr(a, 'y', msg='ababahalamaha') + + def testAssertNotHasAttr(self): + a = List() + a.x = 1 + self.assertNotHasAttr(a, 'y') + with self.assertRaises(self.failureException): + self.assertNotHasAttr(a, 'x') + with self.assertRaisesRegex(self.failureException, 'ababahalamaha'): + self.assertNotHasAttr(a, 'x', 'ababahalamaha') + with self.assertRaisesRegex(self.failureException, 'ababahalamaha'): + self.assertNotHasAttr(a, 'x', msg='ababahalamaha') + + def testAssertIsSubclass(self): + self.assertIsSubclass(List, list) + self.assertIsSubclass(List, (int, list)) + with self.assertRaises(self.failureException): + self.assertIsSubclass(List, int) + with self.assertRaises(self.failureException): + self.assertIsSubclass(List, (int, float)) + with self.assertRaises(self.failureException): + self.assertIsSubclass(1, int) + with self.assertRaisesRegex(self.failureException, 'ababahalamaha'): + self.assertIsSubclass(List, int, 'ababahalamaha') + with self.assertRaisesRegex(self.failureException, 'ababahalamaha'): + self.assertIsSubclass(List, int, msg='ababahalamaha') + + def testAssertNotIsSubclass(self): + self.assertNotIsSubclass(List, int) + self.assertNotIsSubclass(List, (int, float)) + with self.assertRaises(self.failureException): + self.assertNotIsSubclass(List, list) + with self.assertRaises(self.failureException): + self.assertNotIsSubclass(List, (int, list)) + with self.assertRaises(self.failureException): + self.assertNotIsSubclass(1, int) + with self.assertRaisesRegex(self.failureException, 'ababahalamaha'): + self.assertNotIsSubclass(List, list, 'ababahalamaha') + with self.assertRaisesRegex(self.failureException, 'ababahalamaha'): + self.assertNotIsSubclass(List, list, msg='ababahalamaha') + + def testAssertStartsWith(self): + self.assertStartsWith('ababahalamaha', 'ababa') + self.assertStartsWith(b'ababahalamaha', bytearray(b'ababa')) + self.assertStartsWith(bytearray(b'ababahalamaha'), b'ababa') + with self.assertRaises(self.failureException): + self.assertStartsWith('ababahalamaha', 'amaha') + with self.assertRaises(self.failureException): + self.assertStartsWith('ababahalamaha', b'ababa') + with self.assertRaises(self.failureException): + self.assertStartsWith(b'ababahalamaha', 'ababa') + with self.assertRaises(TypeError): + self.assertStartsWith('ababahalamaha', ord('a')) + with self.assertRaisesRegex(self.failureException, 'abracadabra'): + self.assertStartsWith('ababahalamaha', 'amaha', 'abracadabra') + with self.assertRaisesRegex(self.failureException, 'abracadabra'): + self.assertStartsWith('ababahalamaha', 'amaha', msg='abracadabra') + + def testAssertEndsWith(self): + self.assertEndsWith('ababahalamaha', 'amaha') + self.assertEndsWith(b'ababahalamaha', bytearray(b'amaha')) + self.assertEndsWith(bytearray(b'ababahalamaha'), b'amaha') + with self.assertRaises(self.failureException): + self.assertEndsWith('ababahalamaha', 'ababa') + with self.assertRaises(self.failureException): + self.assertEndsWith('ababahalamaha', b'amaha') + with self.assertRaises(self.failureException): + self.assertEndsWith(b'ababahalamaha', 'amaha') + with self.assertRaises(TypeError): + self.assertEndsWith('ababahalamaha', ord('a')) + with self.assertRaisesRegex(self.failureException, 'abracadabra'): + self.assertEndsWith('ababahalamaha', 'ababa', 'abracadabra') + with self.assertRaisesRegex(self.failureException, 'abracadabra'): + self.assertEndsWith('ababahalamaha', 'ababa', msg='abracadabra') + + if __name__ == "__main__": unittest.main() diff -r c95864a37ee2 Lib/unittest/test/test_program.py --- a/Lib/unittest/test/test_program.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/unittest/test/test_program.py Sun May 29 18:15:14 2016 +0300 @@ -7,7 +7,7 @@ import unittest import unittest.test -class Test_TestProgram(unittest.TestCase): +class Test_TestProgram(unittest.TestCase, unittest.ExtraAssertions): def test_discovery_from_dotted_path(self): loader = unittest.TestLoader() @@ -107,7 +107,7 @@ class Test_TestProgram(unittest.TestCase argv=["foobar"], testRunner=unittest.TextTestRunner(stream=io.StringIO()), testLoader=self.FooBarLoader()) - self.assertTrue(hasattr(program, 'result')) + self.assertHasAttr(program, 'result') def test_Exit(self): diff -r c95864a37ee2 Lib/unittest/test/testmock/testcallable.py --- a/Lib/unittest/test/testmock/testcallable.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/unittest/test/testmock/testcallable.py Sun May 29 18:15:14 2016 +0300 @@ -13,7 +13,7 @@ from unittest.mock import ( -class TestCallable(unittest.TestCase): +class TestCallable(unittest.TestCase, unittest.ExtraAssertions): def assertNotCallable(self, mock): self.assertTrue(is_instance(mock, NonCallableMagicMock)) @@ -23,21 +23,21 @@ class TestCallable(unittest.TestCase): def test_non_callable(self): for mock in NonCallableMagicMock(), NonCallableMock(): self.assertRaises(TypeError, mock) - self.assertFalse(hasattr(mock, '__call__')) + self.assertNotHasAttr(mock, '__call__') self.assertIn(mock.__class__.__name__, repr(mock)) def test_heirarchy(self): - self.assertTrue(issubclass(MagicMock, Mock)) - self.assertTrue(issubclass(NonCallableMagicMock, NonCallableMock)) + self.assertIsSubclass(MagicMock, Mock) + self.assertIsSubclass(NonCallableMagicMock, NonCallableMock) def test_attributes(self): one = NonCallableMock() - self.assertTrue(issubclass(type(one.one), Mock)) + self.assertIsSubclass(type(one.one), Mock) two = NonCallableMagicMock() - self.assertTrue(issubclass(type(two.two), MagicMock)) + self.assertIsSubclass(type(two.two), MagicMock) def test_subclasses(self): @@ -45,13 +45,13 @@ class TestCallable(unittest.TestCase): pass one = MockSub() - self.assertTrue(issubclass(type(one.one), MockSub)) + self.assertIsSubclass(type(one.one), MockSub) class MagicSub(MagicMock): pass two = MagicSub() - self.assertTrue(issubclass(type(two.two), MagicSub)) + self.assertIsSubclass(type(two.two), MagicSub) def test_patch_spec(self): diff -r c95864a37ee2 Lib/unittest/test/testmock/testmagicmethods.py --- a/Lib/unittest/test/testmock/testmagicmethods.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/unittest/test/testmock/testmagicmethods.py Sun May 29 18:15:14 2016 +0300 @@ -4,17 +4,17 @@ from unittest.mock import Mock, MagicMoc -class TestMockingMagicMethods(unittest.TestCase): +class TestMockingMagicMethods(unittest.TestCase, unittest.ExtraAssertions): def test_deleting_magic_methods(self): mock = Mock() - self.assertFalse(hasattr(mock, '__getitem__')) + self.assertNotHasAttr(mock, '__getitem__') mock.__getitem__ = Mock() - self.assertTrue(hasattr(mock, '__getitem__')) + self.assertHasAttr(mock, '__getitem__') del mock.__getitem__ - self.assertFalse(hasattr(mock, '__getitem__')) + self.assertNotHasAttr(mock, '__getitem__') def test_magicmock_del(self): @@ -250,12 +250,12 @@ class TestMockingMagicMethods(unittest.T self.assertEqual(list(mock), [1, 2, 3]) getattr(mock, '__bool__').return_value = False - self.assertFalse(hasattr(mock, '__nonzero__')) + self.assertNotHasAttr(mock, '__nonzero__') self.assertFalse(bool(mock)) for entry in _magics: - self.assertTrue(hasattr(mock, entry)) - self.assertFalse(hasattr(mock, '__imaginery__')) + self.assertHasAttr(mock, entry) + self.assertNotHasAttr(mock, '__imaginery__') def test_magic_mock_equality(self): diff -r c95864a37ee2 Lib/unittest/test/testmock/testmock.py --- a/Lib/unittest/test/testmock/testmock.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/unittest/test/testmock/testmock.py Sun May 29 18:15:14 2016 +0300 @@ -39,7 +39,7 @@ class Something(object): pass -class MockTest(unittest.TestCase): +class MockTest(unittest.TestCase, unittest.ExtraAssertions): def test_all(self): # if __all__ is badly defined then import * will raise an error @@ -1517,13 +1517,13 @@ class MockTest(unittest.TestCase): def test_attribute_deletion(self): for mock in (Mock(), MagicMock(), NonCallableMagicMock(), NonCallableMock()): - self.assertTrue(hasattr(mock, 'm')) + self.assertHasAttr(mock, 'm') del mock.m - self.assertFalse(hasattr(mock, 'm')) + self.assertNotHasAttr(mock, 'm') del mock.f - self.assertFalse(hasattr(mock, 'f')) + self.assertNotHasAttr(mock, 'f') self.assertRaises(AttributeError, getattr, mock, 'f') diff -r c95864a37ee2 Lib/unittest/test/testmock/testpatch.py --- a/Lib/unittest/test/testmock/testpatch.py Sun May 29 01:40:22 2016 -0400 +++ b/Lib/unittest/test/testmock/testpatch.py Sun May 29 18:15:14 2016 +0300 @@ -79,7 +79,7 @@ class Container(object): -class PatchTest(unittest.TestCase): +class PatchTest(unittest.TestCase, unittest.ExtraAssertions): def assertNotCallable(self, obj, magic=True): MockClass = NonCallableMagicMock @@ -357,7 +357,7 @@ class PatchTest(unittest.TestCase): self.assertEqual(SomeClass.frooble, sentinel.Frooble) test() - self.assertFalse(hasattr(SomeClass, 'frooble')) + self.assertNotHasAttr(SomeClass, 'frooble') def test_patch_wont_create_by_default(self): @@ -386,7 +386,7 @@ class PatchTest(unittest.TestCase): pass else: self.fail('Patching non existent attributes should fail') - self.assertFalse(hasattr(SomeClass, 'ord')) + self.assertNotHasAttr(SomeClass, 'ord') def test_patch_builtins_without_create(self): @@ -1393,7 +1393,7 @@ class PatchTest(unittest.TestCase): finally: patcher.stop() - self.assertFalse(hasattr(Foo, 'blam')) + self.assertNotHasAttr(Foo, 'blam') def test_patch_multiple_spec_set(self):