This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Add an assertBytesEqual to unittest and use it for bytes assertEqual
Type: enhancement Stage: patch review
Components: Versions: Python 3.2
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: rhettinger Nosy List: michael.foord, r.david.murray, rhettinger
Priority: low Keywords: patch

Created on 2010-10-21 12:48 by r.david.murray, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
bytes_multi_line_equal.diff r.david.murray, 2010-10-21 12:48 review
assertBytesEqual.diff r.david.murray, 2010-10-22 02:38 review
Messages (7)
msg119280 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2010-10-21 12:48
Just as with regular strings, when comparing failed output involving bytes strings it is really helpful to have a diff showing which bytes have changed.  The attached patch adds an assertMultiLineEqual method to unittest and uses it for comparing bytes in assertEqual.

The diff output is created by first breaking the byte strings into lines using 'splitlines(True)' just as in assertMultiLineEqual, but then each line is converted to a string using 'repr' before the lines sets are passed to ndiff.  This results in output containing escaped bytes, making it easier to compare the differences in the byte strings.

(NB: this patch is the end result of several attempts to make the unittest output more useful in the email package when testing bytes handling).
msg119360 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2010-10-22 02:38
After talking with Michael on #python-dev, I've revised the patch to make it a real assertBytesEqual method rather than a pretend-the-bytes-are-strings method.  This version allows the byte strings to be split on an arbitrary byte string, which makes it more useful for getting diffs of structured binary data if that data has a convenient break point.  And the default is no splitting, which is what assertEqual uses when comparing bytes.

One of the tests is failing, and it's late and I can't figure out where the extra space is coming from.  Maybe someone else will check it out and spot the problem before I get back to it.
msg119484 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2010-10-24 04:57
My best guess currently is that the failing test is a bug in difflib, but I haven't dug into that code yet to prove it.  It's still possible it's something stupid in my code, but as far as I can see there's no character over where that - is in the difflib output (that is, the two lines that it says are different appear identical when viewed with cat -A).
msg120034 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2010-10-31 03:45
Am discussing this with the OP on IRC and tabling it for a while so we can better think out the API.

The goal is to let assertEqual(a, b) do straight-comparions of raw bytes, but to give a nice looking diff (possibly translated with line breaks or somesuch) when the test fails.  This will be helpful in testing the email module. 

The current patch requires that assertBytesEqual be exposed and called directly so that a user can specify a split-at argument.  The purpose of that argument is to approximate the line breaking that occurs naturally in text.  The OP does not want to decode the bytes prior to the equality test, but does want a readable diff whenever the bytes represent ascii text.
msg120105 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2010-11-01 03:13
David - would you get a good approximation of what you want simply with:

    self.assertEqual(ascii(first), ascii(second))

(This actually returns "b'first'" "b'second'" so you may want a convenience function that chops the leading and trailing b'/')

As ascii returns unicode it would automatically delegate to assertMultilineEqual.

The obvious way to hook this up by default for assertEqual is having the split-character as '\n'. This would not be meaningful for using assertEqual to compare bytes that *aren't* text.
msg122030 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2010-11-22 00:07
Rejecting this one for reasons we discussed earlier.  The assertEqual() method needs to be the primary interface.  Everything else is starting to mix content and presentation (i.e. passing in separators).  The existing repr() works fine with bytes and Michael's suggested ascii() cast would be the preferred technique in the common cases.

What might be useful is a less specialized patch letting assertEqual() take an argument pointing to some repr or pre-processing function that would be called after an equality test fails but before it is diffed.  That would support a clear separation of concerns and be easily extendable by users would need something more than an ascii() cast.
msg122074 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2010-11-22 02:45
Agreed on the closing.  The pre-diff processing function would be a great addition.  For the record, I am currently satisfying my use case by doing this:

   self.assertEqual(bstr1.split(b'\n'), bstr2.split(b'\n'))

which produces a very readable diff.
History
Date User Action Args
2022-04-11 14:57:07adminsetgithub: 54373
2010-11-22 02:45:04r.david.murraysetmessages: + msg122074
2010-11-22 00:07:13rhettingersetstatus: open -> closed
resolution: later -> rejected
messages: + msg122030
2010-11-01 03:13:19michael.foordsetmessages: + msg120105
2010-10-31 03:45:07rhettingersetresolution: later
messages: + msg120034
2010-10-30 16:17:06rhettingersetpriority: normal -> low
assignee: rhettinger

nosy: + rhettinger
2010-10-24 04:57:21r.david.murraysetmessages: + msg119484
2010-10-22 12:14:06r.david.murraysettitle: Add an assertBytesMultiLineEqual to unittest and use it for bytes assertEqual -> Add an assertBytesEqual to unittest and use it for bytes assertEqual
2010-10-22 02:38:42r.david.murraysetfiles: + assertBytesEqual.diff

messages: + msg119360
2010-10-21 12:48:15r.david.murraycreate