Merge pull request #786 from edisongustavo/pytest-2.7

Fix Python2 bug with PrettyPrinter raising with sets of unsortable elements
This commit is contained in:
Bruno Oliveira 2015-06-19 08:39:15 -03:00
commit 02421790bf
4 changed files with 52 additions and 4 deletions

View File

@ -24,6 +24,7 @@ Daniel Grana
Daniel Nuri Daniel Nuri
Dave Hunt Dave Hunt
David Mohr David Mohr
Edison Gustavo Muenz
Floris Bruynooghe Floris Bruynooghe
Graham Horler Graham Horler
Grig Gheorghiu Grig Gheorghiu

View File

@ -16,6 +16,9 @@
- fix issue748: unittest.SkipTest reports to internal pytest unittest plugin. - fix issue748: unittest.SkipTest reports to internal pytest unittest plugin.
Thanks Thomas De Schampheleire for reporting and Bruno Oliveira for the PR. Thanks Thomas De Schampheleire for reporting and Bruno Oliveira for the PR.
- fix issue718: failed to create representation of sets containing unsortable
elements in python 2. Thanks Edison Gustavo Muenz
2.7.1 (compared to 2.7.0) 2.7.1 (compared to 2.7.0)
----------------------------- -----------------------------

View File

@ -225,10 +225,18 @@ def _compare_eq_iterable(left, right, verbose=False):
# dynamic import to speedup pytest # dynamic import to speedup pytest
import difflib import difflib
left = pprint.pformat(left).splitlines() try:
right = pprint.pformat(right).splitlines() left_formatting = pprint.pformat(left).splitlines()
explanation = [u('Full diff:')] right_formatting = pprint.pformat(right).splitlines()
explanation.extend(line.strip() for line in difflib.ndiff(left, right)) explanation = [u('Full diff:')]
except Exception:
# hack: PrettyPrinter.pformat() in python 2 fails when formatting items that can't be sorted(), ie, calling
# sorted() on a list would raise. See issue #718.
# As a workaround, the full diff is generated by using the repr() string of each item of each container.
left_formatting = sorted(repr(x) for x in left)
right_formatting = sorted(repr(x) for x in right)
explanation = [u('Full diff (fallback to calling repr on each item):')]
explanation.extend(line.strip() for line in difflib.ndiff(left_formatting, right_formatting))
return explanation return explanation

View File

@ -569,3 +569,39 @@ def test_AssertionError_message(testdir):
*assert 0, (x,y)* *assert 0, (x,y)*
*AssertionError: (1, 2)* *AssertionError: (1, 2)*
""") """)
@pytest.mark.skipif(PY3, reason='This bug does not exist on PY3')
def test_set_with_unsortable_elements():
# issue #718
class UnsortableKey(object):
def __init__(self, name):
self.name = name
def __lt__(self, other):
raise RuntimeError()
def __repr__(self):
return 'repr({0})'.format(self.name)
def __eq__(self, other):
return self.name == other.name
def __hash__(self):
return hash(self.name)
left_set = set(UnsortableKey(str(i)) for i in range(1, 3))
right_set = set(UnsortableKey(str(i)) for i in range(2, 4))
expl = callequal(left_set, right_set, verbose=True)
# skip first line because it contains the "construction" of the set, which does not have a guaranteed order
expl = expl[1:]
dedent = textwrap.dedent("""
Extra items in the left set:
repr(1)
Extra items in the right set:
repr(3)
Full diff (fallback to calling repr on each item):
- repr(1)
repr(2)
+ repr(3)
""").strip()
assert '\n'.join(expl) == dedent