testtools-dev team mailing list archive
-
testtools-dev team
-
Mailing list archive
-
Message #00869
[Bug 804127] Re: assertThat sometimes generates unprintable AssertionErrors
This test seems to reproduce:
def test_assertThat_unicode(self):
crazy_char = _u("\xa7")
e = self.assertRaises(
self.failureException,
self.assertThat, crazy_char, Equals(_u("a")), verbose=True)
str_exception = _exception_to_text(e)
self.assertIsNotNone(str_exception)
Also, see this discussion:
<jml> mgz: around?
<mgz> aha, I was considering pinging you
<mgz> I've got an idea that might help some of the assertThat issues
<mgz> how about just putting the Mismatch object in the AssertionError rather than stringifying it? avoids a bunch of __str__ vs __unicode__ issues
<mgz> also puts the formatting entirely in the hands of the Mismatch rather than printing the Matcher at all
<mgz> I don't think there are any bad side effects from having a non-string type argument to an exception
<mgz> jml: anything in particular?
<jml> mgz: oh huh
<jml> mgz: just wanted your feedback on a bug
<jml> mgz: https://bugs.launchpad.net/testtools/+bug/675323
<ubot5> Ubuntu bug 675323 in testtools "assertThat style gives overly verbose output" [Wishlist,Triaged]
<mgz> how would you feel about just printing the "Difference" portion and none of the rest?
<mgz> in cases like assertThat(something_long, DoctestMatches(pattern, doctest.REPORT_UDIFF)) that'll be much better anyway
<mgz> and trivial things like assertEqual(1, 2) are clear anyway without being explicit about what the Matcher and matchee are
<jml> mgz: basically, that's my plan.
<jml> mgz: maybe adding a verbose option to assertThat to print its current output
<jml> mgz: patch up.
<jml> mgz: regarding your earlier comment, you mean doing something like 'raise AssertionError(mismatch)' and relying on AssertionError to call __str__ (and thus, describe)
<mgz> I do.
<mgz> Then we can get the logic right on the Mismatch classes, and avoid the python version variations on exception instances
<jml> Hmm.
<jml> mgz: That would change the API for mismatches, not sure that would be a problem.
<mgz> In which respect?
<jml> we don't currently insist on inheriting from Mismatch
<jml> and we don't currently use mismatch.__str__
<jml> so third-party mismatches that don't inherit will break
<mgz> hm.
<jml> where 'break' means, "<testtools.matchers.Mismatch object at %x attributes=%r>" % (id(self), self.__dict__)
<mgz> the other option is raising an AssertionError subclass on some python versions.
<mgz> which is also a tricky api change.
<jml> well, we could _always_ raise an AssertionError subclass
<jml> that would only break people who were expecting an exact class
<jml> but would still go alright w/ 'except AssertionError' or isinstance() checks
<jml> mgz: in some ways, I wouldn't mind raising a specialized exception for assertThat anyway. I think it would be nice to attach the matchee & matcher objects explictly and make them programatically available
<mgz> that sounds reasonable.
<jml> hmm.
<jml> I guess the break there is that if someone sets failureException, assertThat failures become errors.
<jml> I think that's as unlikely to be a problem in practice as third-party mismatches that don't inherit from Mismatch.
** Description changed:
The assertThat method for use with matchers creates AssertionError
instances that don't stringify on Python 2.4, 2.5, and some 2.6 minor
versions when used with a non-ascii unicode argument. The
testtools.testresults code has some robustness that means the failure is
still printed, but other runners may break if the UnicodeEncodeError
from trying to stringify the exception propagates.
Instead of the expected output, these older Pythons get:
Traceback (most recent call last):
- ...
- self.assertThat(u"\xa7", Equals(u"a"))
- File "C:\Python24\Lib\site-packages\testtools\testcase.py", line 351, in assertThat
- self.fail('Match failed. Matchee: "%s"\nMatcher: %s\nDifference: %s\n'
+ ...
+ self.assertThat(u"\xa7", Equals(u"a"), verbose=True)
+ File "C:\Python24\Lib\site-packages\testtools\testcase.py", line 351, in assertThat
+ self.fail('Match failed. Matchee: "%s"\nMatcher: %s\nDifference: %s\n'
AssertionError: <unprintable AssertionError object>
--
You received this bug notification because you are a member of testtools
developers, which is subscribed to testtools.
https://bugs.launchpad.net/bugs/804127
Title:
assertThat sometimes generates unprintable AssertionErrors
Status in testtools:
Triaged
Bug description:
The assertThat method for use with matchers creates AssertionError
instances that don't stringify on Python 2.4, 2.5, and some 2.6 minor
versions when used with a non-ascii unicode argument. The
testtools.testresults code has some robustness that means the failure
is still printed, but other runners may break if the
UnicodeEncodeError from trying to stringify the exception propagates.
Instead of the expected output, these older Pythons get:
Traceback (most recent call last):
...
self.assertThat(u"\xa7", Equals(u"a"), verbose=True)
File "C:\Python24\Lib\site-packages\testtools\testcase.py", line 351, in assertThat
self.fail('Match failed. Matchee: "%s"\nMatcher: %s\nDifference: %s\n'
AssertionError: <unprintable AssertionError object>
To manage notifications about this bug go to:
https://bugs.launchpad.net/testtools/+bug/804127/+subscriptions
References