_compare_eq_iterable: use AlwaysDispatchingPrettyPrinter
This fixes/removes the previous hack of re-trying with minimum width,
which fails short when it splits strings.
This inherits from `pprint.PrettyPrinter` to override `_format` in a
minimal way to always dispatch, regardless of the given width.
Code ref: 5c0c325453/Lib/pprint.py (L170-L178)
			
			
This commit is contained in:
		
							parent
							
								
									6ad95716da
								
							
						
					
					
						commit
						cc503c1821
					
				| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,",
 | 
			
		||||
            "  }",
 | 
			
		||||
        ]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue