issue 9815 assertraises should avoid keeping local variables in a traceback alive test that the individual asserts honour longmessage this actually tests all the message behaviour for asserts that use longmessage def setupself class testabletestfalseunittest testcase longmessage false failureexception self failureexception def testtestself pass class testabletesttrueunittest testcase longmessage true failureexception self failureexception def testtestself pass self testabletrue testabletesttrue testtest self testablefalse testabletestfalse testtest def testdefaultself self asserttrueunittest testcase longmessage def testformatmsgself self assertequalself testablefalse formatmessagenone foo foo self assertequalself testablefalse formatmessagefoo bar foo self assertequalself testabletrue formatmessagenone foo foo self assertequalself testabletrue formatmessagefoo bar bar foo this blows up if formatmessage uses string concatenation self testabletrue formatmessageobject foo def testformatmessageunicodeerrorself one joinchri for i in range255 this used to cause a unicodedecodeerror constructing msg self testabletrue formatmessageone ufffd def assertmessagesself methodname args errors def getmethodi usetestablefalse i 2 if usetestablefalse test self testablefalse else test self testabletrue return getattrtest methodname for i expectedregex in enumerateerrors testmethod getmethodi kwargs withmsg i 2 if withmsg kwargs msg oops with self assertraisesregexself failureexception expectedregexexpectedregex testmethodargs kwargs def testasserttrueself self assertmessages asserttrue false false is not true oops false is not true false is not true oops def testassertfalseself self assertmessages assertfalse true true is not false oops true is not false true is not false oops def testnotequalself self assertmessages assertnotequal 1 1 1 1 oops 1 1 1 1 oops def testalmostequalself self assertmessages assertalmostequal 1 2 r1 2 within 7 places 1 difference oops r1 2 within 7 places 1 difference r1 2 within 7 places 1 difference oops def testnotalmostequalself self assertmessages assertnotalmostequal 1 1 1 1 within 7 places oops 1 1 within 7 places 1 1 within 7 places oops def testbaseassertequalself self assertmessages baseassertequal 1 2 1 2 oops 1 2 1 2 oops def testassertsequenceequalself error messages are multiline so not testing on full message asserttupleequal and assertlistequal delegate to this method self assertmessages assertsequenceequal none r none oops r none r none oops def testassertsetequalself self assertmessages assertsetequal set setnone none oops none none oops def testassertinself self assertmessages assertin none r none not found in oops r none not found in r none not found in oops def testassertnotinself self assertmessages assertnotin none none r none unexpectedly found in none oops r none unexpectedly found in none r none unexpectedly found in none oops def testassertdictequalself self assertmessages assertdictequal key value r key value oops r key value r key value oops def testassertmultilineequalself self assertmessages assertmultilineequal foo r foon oops r foon r foon oops def testassertlessself self assertmessages assertless 2 1 2 not less than 1 oops 2 not less than 1 2 not less than 1 oops def testassertlessequalself self assertmessages assertlessequal 2 1 2 not less than or equal to 1 oops 2 not less than or equal to 1 2 not less than or equal to 1 oops def testassertgreaterself self assertmessages assertgreater 1 2 1 not greater than 2 oops 1 not greater than 2 1 not greater than 2 oops def testassertgreaterequalself self assertmessages assertgreaterequal 1 2 1 not greater than or equal to 2 oops 1 not greater than or equal to 2 1 not greater than or equal to 2 oops def testassertisnoneself self assertmessages assertisnone not none not none is not none oops not none is not none not none is not none oops def testassertisnotnoneself self assertmessages assertisnotnone none unexpectedly none oops unexpectedly none unexpectedly none oops def testassertisself self assertmessages assertis none foo none is not foo oops none is not foo none is not foo oops def testassertisnotself self assertmessages assertisnot none none unexpectedly identical none oops unexpectedly identical none unexpectedly identical none oops def testassertregexself self assertmessages assertregex foo bar regex didn t match oops regex didn t match regex didn t match oops def testassertnotregexself self assertmessages assertnotregex foo foo regex matched oops regex matched regex matched oops def assertmessagescmself methodname args func errors p productself testablefalse self testabletrue msg oops for cls kwargs err in zipp errors method getattrcls methodname with self assertraisesregexcls failureexception err with methodargs kwargs as cm func def testassertraisesself self assertmessagescm assertraises typeerror lambda none typeerror not raised oops typeerror not raised typeerror not raised oops def testassertraisesregexself test error not raised self assertmessagescm assertraisesregex typeerror unused regex lambda none typeerror not raised oops typeerror not raised typeerror not raised oops test error raised but with wrong message def raisewrongmessage raise typeerror foo self assertmessagescm assertraisesregex typeerror regex raisewrongmessage regex does not match foo oops regex does not match foo regex does not match foo oops def testassertwarnsself self assertmessagescm assertwarns userwarning lambda none userwarning not triggered oops userwarning not triggered userwarning not triggered oops def testassertwarnsregexself test error not raised self assertmessagescm assertwarnsregex userwarning unused regex lambda none userwarning not triggered oops userwarning not triggered userwarning not triggered oops test warning raised but with wrong message def raisewrongmessage warnings warn foo self assertmessagescm assertwarnsregex userwarning regex raisewrongmessage regex does not match foo oops regex does not match foo regex does not match foo oops if name main unittest main issue 9815 assertraises should avoid keeping local variables in a traceback alive for pypy or other gcs for pypy or other gcs test that the individual asserts honour longmessage this actually tests all the message behaviour for asserts that use longmessage this blows up if _formatmessage uses string concatenation this used to cause a unicodedecodeerror constructing msg check that methodname args raises the correct error messages errors should be a list of 4 regex that match the error when 1 longmessage false and no msg passed 2 longmessage false and msg passed 3 longmessage true and no msg passed 4 longmessage true and msg passed error messages are multiline so not testing on full message asserttupleequal and assertlistequal delegate to this method check that the correct error messages are raised while executing with method args func errors should be a list of 4 regex that match the error when 1 longmessage false and no msg passed 2 longmessage false and msg passed 3 longmessage true and no msg passed 4 longmessage true and msg passed test error not raised test error raised but with wrong message test error not raised test warning raised but with wrong message
import datetime
import warnings
import weakref
import unittest
from test.support import gc_collect
from itertools import product


class Test_Assertions(unittest.TestCase):
    def test_AlmostEqual(self):
        self.assertAlmostEqual(1.00000001, 1.0)
        self.assertNotAlmostEqual(1.0000001, 1.0)
        self.assertRaises(self.failureException,
                          self.assertAlmostEqual, 1.0000001, 1.0)
        self.assertRaises(self.failureException,
                          self.assertNotAlmostEqual, 1.00000001, 1.0)

        self.assertAlmostEqual(1.1, 1.0, places=0)
        self.assertRaises(self.failureException,
                          self.assertAlmostEqual, 1.1, 1.0, places=1)

        self.assertAlmostEqual(0, .1+.1j, places=0)
        self.assertNotAlmostEqual(0, .1+.1j, places=1)
        self.assertRaises(self.failureException,
                          self.assertAlmostEqual, 0, .1+.1j, places=1)
        self.assertRaises(self.failureException,
                          self.assertNotAlmostEqual, 0, .1+.1j, places=0)

        self.assertAlmostEqual(float('inf'), float('inf'))
        self.assertRaises(self.failureException, self.assertNotAlmostEqual,
                          float('inf'), float('inf'))

    def test_AmostEqualWithDelta(self):
        self.assertAlmostEqual(1.1, 1.0, delta=0.5)
        self.assertAlmostEqual(1.0, 1.1, delta=0.5)
        self.assertNotAlmostEqual(1.1, 1.0, delta=0.05)
        self.assertNotAlmostEqual(1.0, 1.1, delta=0.05)

        self.assertAlmostEqual(1.0, 1.0, delta=0.5)
        self.assertRaises(self.failureException, self.assertNotAlmostEqual,
                          1.0, 1.0, delta=0.5)

        self.assertRaises(self.failureException, self.assertAlmostEqual,
                          1.1, 1.0, delta=0.05)
        self.assertRaises(self.failureException, self.assertNotAlmostEqual,
                          1.1, 1.0, delta=0.5)

        self.assertRaises(TypeError, self.assertAlmostEqual,
                          1.1, 1.0, places=2, delta=2)
        self.assertRaises(TypeError, self.assertNotAlmostEqual,
                          1.1, 1.0, places=2, delta=2)

        first = datetime.datetime.now()
        second = first + datetime.timedelta(seconds=10)
        self.assertAlmostEqual(first, second,
                               delta=datetime.timedelta(seconds=20))
        self.assertNotAlmostEqual(first, second,
                                  delta=datetime.timedelta(seconds=5))

    def test_assertRaises(self):
        def _raise(e):
            raise e
        self.assertRaises(KeyError, _raise, KeyError)
        self.assertRaises(KeyError, _raise, KeyError("key"))
        try:
            self.assertRaises(KeyError, lambda: None)
        except self.failureException as e:
            self.assertIn("KeyError not raised", str(e))
        else:
            self.fail("assertRaises() didn't fail")
        try:
            self.assertRaises(KeyError, _raise, ValueError)
        except ValueError:
            pass
        else:
            self.fail("assertRaises() didn't let exception pass through")
        with self.assertRaises(KeyError) as cm:
            try:
                raise KeyError
            except Exception as e:
                exc = e
                raise
        self.assertIs(cm.exception, exc)

        with self.assertRaises(KeyError):
            raise KeyError("key")
        try:
            with self.assertRaises(KeyError):
                pass
        except self.failureException as e:
            self.assertIn("KeyError not raised", str(e))
        else:
            self.fail("assertRaises() didn't fail")
        try:
            with self.assertRaises(KeyError):
                raise ValueError
        except ValueError:
            pass
        else:
            self.fail("assertRaises() didn't let exception pass through")

    def test_assertRaises_frames_survival(self):
        
        
        class A:
            pass
        wr = None

        class Foo(unittest.TestCase):

            def foo(self):
                nonlocal wr
                a = A()
                wr = weakref.ref(a)
                try:
                    raise OSError
                except OSError:
                    raise ValueError

            def test_functional(self):
                self.assertRaises(ValueError, self.foo)

            def test_with(self):
                with self.assertRaises(ValueError):
                    self.foo()

        Foo("test_functional").run()
        gc_collect()  
        self.assertIsNone(wr())
        Foo("test_with").run()
        gc_collect()  
        self.assertIsNone(wr())

    def testAssertNotRegex(self):
        self.assertNotRegex('Ala ma kota', r'r+')
        try:
            self.assertNotRegex('Ala ma kota', r'k.t', 'Message')
        except self.failureException as e:
            self.assertIn('Message', e.args[0])
        else:
            self.fail('assertNotRegex should have failed.')


class TestLongMessage(unittest.TestCase):
    

    def setUp(self):
        class TestableTestFalse(unittest.TestCase):
            longMessage = False
            failureException = self.failureException

            def testTest(self):
                pass

        class TestableTestTrue(unittest.TestCase):
            longMessage = True
            failureException = self.failureException

            def testTest(self):
                pass

        self.testableTrue = TestableTestTrue('testTest')
        self.testableFalse = TestableTestFalse('testTest')

    def testDefault(self):
        self.assertTrue(unittest.TestCase.longMessage)

    def test_formatMsg(self):
        self.assertEqual(self.testableFalse._formatMessage(None, "foo"), "foo")
        self.assertEqual(self.testableFalse._formatMessage("foo", "bar"), "foo")

        self.assertEqual(self.testableTrue._formatMessage(None, "foo"), "foo")
        self.assertEqual(self.testableTrue._formatMessage("foo", "bar"), "bar : foo")

        
        self.testableTrue._formatMessage(object(), 'foo')

    def test_formatMessage_unicode_error(self):
        one = ''.join(chr(i) for i in range(255))
        
        self.testableTrue._formatMessage(one, '\uFFFD')

    def assertMessages(self, methodName, args, errors):
        
        def getMethod(i):
            useTestableFalse  = i < 2
            if useTestableFalse:
                test = self.testableFalse
            else:
                test = self.testableTrue
            return getattr(test, methodName)

        for i, expected_regex in enumerate(errors):
            testMethod = getMethod(i)
            kwargs = {}
            withMsg = i % 2
            if withMsg:
                kwargs = {"msg": "oops"}

            with self.assertRaisesRegex(self.failureException,
                                        expected_regex=expected_regex):
                testMethod(*args, **kwargs)

    def testAssertTrue(self):
        self.assertMessages('assertTrue', (False,),
                            ["^False is not true$", "^oops$", "^False is not true$",
                             "^False is not true : oops$"])

    def testAssertFalse(self):
        self.assertMessages('assertFalse', (True,),
                            ["^True is not false$", "^oops$", "^True is not false$",
                             "^True is not false : oops$"])

    def testNotEqual(self):
        self.assertMessages('assertNotEqual', (1, 1),
                            ["^1 == 1$", "^oops$", "^1 == 1$",
                             "^1 == 1 : oops$"])

    def testAlmostEqual(self):
        self.assertMessages(
            'assertAlmostEqual', (1, 2),
            [r"^1 != 2 within 7 places \(1 difference\)$", "^oops$",
             r"^1 != 2 within 7 places \(1 difference\)$",
             r"^1 != 2 within 7 places \(1 difference\) : oops$"])

    def testNotAlmostEqual(self):
        self.assertMessages('assertNotAlmostEqual', (1, 1),
                            ["^1 == 1 within 7 places$", "^oops$",
                             "^1 == 1 within 7 places$", "^1 == 1 within 7 places : oops$"])

    def test_baseAssertEqual(self):
        self.assertMessages('_baseAssertEqual', (1, 2),
                            ["^1 != 2$", "^oops$", "^1 != 2$", "^1 != 2 : oops$"])

    def testAssertSequenceEqual(self):
        
        
        self.assertMessages('assertSequenceEqual', ([], [None]),
                            [r"\+ \[None\]$", "^oops$", r"\+ \[None\]$",
                             r"\+ \[None\] : oops$"])

    def testAssertSetEqual(self):
        self.assertMessages('assertSetEqual', (set(), set([None])),
                            ["None$", "^oops$", "None$",
                             "None : oops$"])

    def testAssertIn(self):
        self.assertMessages('assertIn', (None, []),
                            [r'^None not found in \[\]$', "^oops$",
                             r'^None not found in \[\]$',
                             r'^None not found in \[\] : oops$'])

    def testAssertNotIn(self):
        self.assertMessages('assertNotIn', (None, [None]),
                            [r'^None unexpectedly found in \[None\]$', "^oops$",
                             r'^None unexpectedly found in \[None\]$',
                             r'^None unexpectedly found in \[None\] : oops$'])

    def testAssertDictEqual(self):
        self.assertMessages('assertDictEqual', ({}, {'key': 'value'}),
                            [r"\+ \{'key': 'value'\}$", "^oops$",
                             r"\+ \{'key': 'value'\}$",
                             r"\+ \{'key': 'value'\} : oops$"])

    def testAssertMultiLineEqual(self):
        self.assertMessages('assertMultiLineEqual', ("", "foo"),
                            [r"\+ foo\n$", "^oops$",
                             r"\+ foo\n$",
                             r"\+ foo\n : oops$"])

    def testAssertLess(self):
        self.assertMessages('assertLess', (2, 1),
                            ["^2 not less than 1$", "^oops$",
                             "^2 not less than 1$", "^2 not less than 1 : oops$"])

    def testAssertLessEqual(self):
        self.assertMessages('assertLessEqual', (2, 1),
                            ["^2 not less than or equal to 1$", "^oops$",
                             "^2 not less than or equal to 1$",
                             "^2 not less than or equal to 1 : oops$"])

    def testAssertGreater(self):
        self.assertMessages('assertGreater', (1, 2),
                            ["^1 not greater than 2$", "^oops$",
                             "^1 not greater than 2$",
                             "^1 not greater than 2 : oops$"])

    def testAssertGreaterEqual(self):
        self.assertMessages('assertGreaterEqual', (1, 2),
                            ["^1 not greater than or equal to 2$", "^oops$",
                             "^1 not greater than or equal to 2$",
                             "^1 not greater than or equal to 2 : oops$"])

    def testAssertIsNone(self):
        self.assertMessages('assertIsNone', ('not None',),
                            ["^'not None' is not None$", "^oops$",
                             "^'not None' is not None$",
                             "^'not None' is not None : oops$"])

    def testAssertIsNotNone(self):
        self.assertMessages('assertIsNotNone', (None,),
                            ["^unexpectedly None$", "^oops$",
                             "^unexpectedly None$",
                             "^unexpectedly None : oops$"])

    def testAssertIs(self):
        self.assertMessages('assertIs', (None, 'foo'),
                            ["^None is not 'foo'$", "^oops$",
                             "^None is not 'foo'$",
                             "^None is not 'foo' : oops$"])

    def testAssertIsNot(self):
        self.assertMessages('assertIsNot', (None, None),
                            ["^unexpectedly identical: None$", "^oops$",
                             "^unexpectedly identical: None$",
                             "^unexpectedly identical: None : oops$"])

    def testAssertRegex(self):
        self.assertMessages('assertRegex', ('foo', 'bar'),
                            ["^Regex didn't match:",
                             "^oops$",
                             "^Regex didn't match:",
                             "^Regex didn't match: (.*) : oops$"])

    def testAssertNotRegex(self):
        self.assertMessages('assertNotRegex', ('foo', 'foo'),
                            ["^Regex matched:",
                             "^oops$",
                             "^Regex matched:",
                             "^Regex matched: (.*) : oops$"])


    def assertMessagesCM(self, methodName, args, func, errors):
        
        p = product((self.testableFalse, self.testableTrue),
                    ({}, {"msg": "oops"}))
        for (cls, kwargs), err in zip(p, errors):
            method = getattr(cls, methodName)
            with self.assertRaisesRegex(cls.failureException, err):
                with method(*args, **kwargs) as cm:
                    func()

    def testAssertRaises(self):
        self.assertMessagesCM('assertRaises', (TypeError,), lambda: None,
                              ['^TypeError not raised$', '^oops$',
                               '^TypeError not raised$',
                               '^TypeError not raised : oops$'])

    def testAssertRaisesRegex(self):
        
        self.assertMessagesCM('assertRaisesRegex', (TypeError, 'unused regex'),
                              lambda: None,
                              ['^TypeError not raised$', '^oops$',
                               '^TypeError not raised$',
                               '^TypeError not raised : oops$'])
        
        def raise_wrong_message():
            raise TypeError('foo')
        self.assertMessagesCM('assertRaisesRegex', (TypeError, 'regex'),
                              raise_wrong_message,
                              ['^"regex" does not match "foo"$', '^oops$',
                               '^"regex" does not match "foo"$',
                               '^"regex" does not match "foo" : oops$'])

    def testAssertWarns(self):
        self.assertMessagesCM('assertWarns', (UserWarning,), lambda: None,
                              ['^UserWarning not triggered$', '^oops$',
                               '^UserWarning not triggered$',
                               '^UserWarning not triggered : oops$'])

    def testAssertWarnsRegex(self):
        
        self.assertMessagesCM('assertWarnsRegex', (UserWarning, 'unused regex'),
                              lambda: None,
                              ['^UserWarning not triggered$', '^oops$',
                               '^UserWarning not triggered$',
                               '^UserWarning not triggered : oops$'])
        
        def raise_wrong_message():
            warnings.warn('foo')
        self.assertMessagesCM('assertWarnsRegex', (UserWarning, 'regex'),
                              raise_wrong_message,
                              ['^"regex" does not match "foo"$', '^oops$',
                               '^"regex" does not match "foo"$',
                               '^"regex" does not match "foo" : oops$'])


if __name__ == "__main__":
    unittest.main()