_compare_eq_iterable: use AlwaysDispatchingPrettyPrinter (#6151)

This commit is contained in:
Daniel Hahler 2019-11-10 14:08:25 +01:00 committed by GitHub
commit abcedd6095
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 15 deletions

View File

@ -28,6 +28,27 @@ _reprcompare = None # type: Optional[Callable[[str, object, object], Optional[s
_assertion_pass = None # type: Optional[Callable[[int, str, str], None]]
class AlwaysDispatchingPrettyPrinter(pprint.PrettyPrinter):
"""PrettyPrinter that always dispatches (regardless of width)."""
def _format(self, object, stream, indent, allowance, context, level):
p = self._dispatch.get(type(object).__repr__, None)
objid = id(object)
if objid in context or p is None:
return super()._format(object, stream, indent, allowance, context, level)
context[objid] = 1
p(self, object, stream, indent, allowance, context, level + 1)
del context[objid]
def _pformat_dispatch(object, indent=1, width=80, depth=None, *, compact=False):
return AlwaysDispatchingPrettyPrinter(
indent=1, width=80, depth=None, compact=False
).pformat(object)
def format_explanation(explanation: str) -> str:
"""This formats an explanation
@ -270,15 +291,8 @@ def _compare_eq_iterable(
lines_left = len(left_formatting)
lines_right = len(right_formatting)
if lines_left != lines_right:
if lines_left > lines_right:
max_width = min(len(x) for x in left_formatting)
else:
max_width = min(len(x) for x in right_formatting)
right_formatting = pprint.pformat(right, width=max_width).splitlines()
lines_right = len(right_formatting)
left_formatting = pprint.pformat(left, width=max_width).splitlines()
lines_left = len(left_formatting)
left_formatting = _pformat_dispatch(left).splitlines()
right_formatting = _pformat_dispatch(right).splitlines()
if lines_left > 1 or lines_right > 1:
_surrounding_parens_on_own_lines(left_formatting)

View File

@ -462,6 +462,29 @@ class TestAssert_reprcompare:
" ]",
]
def test_list_dont_wrap_strings(self):
long_a = "a" * 10
l1 = ["a"] + [long_a for _ in range(0, 7)]
l2 = ["should not get wrapped"]
diff = callequal(l1, l2, verbose=True)
assert diff == [
"['a', 'aaaaaa...aaaaaaa', ...] == ['should not get wrapped']",
"At index 0 diff: 'a' != 'should not get wrapped'",
"Left contains 7 more items, first extra item: 'aaaaaaaaaa'",
"Full diff:",
" [",
"+ 'should not get wrapped',",
"- 'a',",
"- 'aaaaaaaaaa',",
"- 'aaaaaaaaaa',",
"- 'aaaaaaaaaa',",
"- 'aaaaaaaaaa',",
"- 'aaaaaaaaaa',",
"- 'aaaaaaaaaa',",
"- 'aaaaaaaaaa',",
" ]",
]
def test_dict_wrap(self):
d1 = {"common": 1, "env": {"env1": 1}}
d2 = {"common": 1, "env": {"env1": 1, "env2": 2}}
@ -479,22 +502,20 @@ class TestAssert_reprcompare:
]
long_a = "a" * 80
sub = {"long_a": long_a, "sub1": {"long_a": "substring that gets wrapped"}}
sub = {"long_a": long_a, "sub1": {"long_a": "substring that gets wrapped " * 2}}
d1 = {"env": {"sub": sub}}
d2 = {"env": {"sub": sub}, "new": 1}
diff = callequal(d1, d2, verbose=True)
assert diff == [
"{'env': {'sub...s wrapped'}}}} == {'env': {'sub...}}}, 'new': 1}",
"{'env': {'sub... wrapped '}}}} == {'env': {'sub...}}}, 'new': 1}",
"Omitting 1 identical items, use -vv to show",
"Right contains 1 more item:",
"{'new': 1}",
"Full diff:",
" {",
" 'env': {'sub': {'long_a': '" + long_a + "',",
" 'sub1': {'long_a': 'substring '",
" 'that '",
" 'gets '",
" 'wrapped'}}},",
" 'sub1': {'long_a': 'substring that gets wrapped substring '",
" 'that gets wrapped '}}},",
"+ 'new': 1,",
" }",
]