Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove newlines from left/right operands with '-vv' #9743

Merged
merged 4 commits into from Mar 19, 2022

Conversation

samuelcolvin
Copy link
Member

@samuelcolvin samuelcolvin commented Mar 8, 2022

fix #9742

I've done this in the least intrusive way possible, a cleaner solution would be to alter saferepr to behave like the new saferepr_unlimited method when maxsize=None, but that might effect some other code (though I think use of saferepr() with maxsize=None is very rare).

@samuelcolvin samuelcolvin changed the title improve -vv repr improve -vv AssertionError message Mar 8, 2022
@Zac-HD
Copy link
Member

Zac-HD commented Mar 15, 2022

Thanks @samuelcolvin - this looks good to me, though I'll leave merging to another maintainer to be sure 🙂

@nicoddemus
Copy link
Member

Here's the output of main:

 λ pytest .tmp\test_foo.py -vv --no-header
======================== test session starts ========================
collected 1 item

.tmp\test_foo.py::test_foobar FAILED                           [100%]

============================= FAILURES ==============================
____________________________ test_foobar ____________________________

    def test_foobar():
        a = {string.ascii_letters[i]: i for i in range(26)}
        b = a.copy()
        a.pop('g')
>       assert a == b
E       AssertionError: assert {'a': 0,\n 'b': 1,\n 'c': 2,\n 'd': 3,\n 'e': 4,\n 'f': 5,\n 'h': 7,\n 'i': 8,\n 'j': 9,\n 'k': 10,\n 'l': 11,\n 'm': 12,\n 'n': 13,\n 'o': 14,\n 'p': 15,\n 'q': 16,\n 'r': 17,\n 's': 18,\n 't': 19,\n 'u': 20,\n 'v': 21,\n 'w': 22,\n 'x': 23,\n 'y': 24,\n 'z': 25} == {'a': 0,\n 'b': 1,\n 'c': 2,\n 'd': 3,\n 'e': 4,\n 'f': 5,\n 'g': 6,\n 'h': 7,\n 'i': 8,\n 'j': 9,\n 'k': 10,\n 'l': 11,\n 'm': 12,\n 'n': 13,\n 'o': 14,\n 'p': 15,\n 'q': 16,\n 'r': 17,\n 's': 18,\n 't': 19,\n 'u': 20,\n 'v': 21,\n 'w': 22,\n 'x': 23,\n 'y': 24,\n 'z': 25}
E         Common items:
E         {'a': 0,
E          'b': 1,
E          'c': 2,
E          'd': 3,
E          'e': 4,
E          'f': 5,
E          'h': 7,
E          'i': 8,
E          'j': 9,
E          'k': 10,
E          'l': 11,
E          'm': 12,
E          'n': 13,
E          'o': 14,
E          'p': 15,
E          'q': 16,
E          'r': 17,
E          's': 18,
E          't': 19,
E          'u': 20,
E          'v': 21,
E          'w': 22,
E          'x': 23,
E          'y': 24,
E          'z': 25}
E         Right contains 1 more item:
E         {'g': 6}
E         Full diff:
E           {
E            'a': 0,
E            'b': 1,
E            'c': 2,
E            'd': 3,
E            'e': 4,
E            'f': 5,
E         -  'g': 6,
E            'h': 7,
E            'i': 8,
E            'j': 9,
E            'k': 10,
E            'l': 11,
E            'm': 12,
E            'n': 13,
E            'o': 14,
E            'p': 15,
E            'q': 16,
E            'r': 17,
E            's': 18,
E            't': 19,
E            'u': 20,
E            'v': 21,
E            'w': 22,
E            'x': 23,
E            'y': 24,
E            'z': 25,
E           }

.tmp\test_foo.py:8: AssertionError
====================== short test summary info ======================
FAILED .tmp\test_foo.py::test_foobar - AssertionError: assert {'a':...
========================= 1 failed in 0.11s =========================

And here's the output of this PR:

λ pytest .tmp\test_foo.py -vv --no-header
======================== test session starts ========================
collected 1 item

.tmp\test_foo.py::test_foobar FAILED                           [100%]

============================= FAILURES ==============================
____________________________ test_foobar ____________________________

    def test_foobar():
        a = {string.ascii_letters[i]: i for i in range(26)}
        b = a.copy()
        a.pop('g')
>       assert a == b
E       AssertionError: assert {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5, 'h': 7, 'i': 8, 'j': 9, 'k': 10, 'l': 11, 'm': 12, 'n': 13, 'o': 14, 'p': 15, 'q': 16, 'r': 17, 's': 18, 't': 19, 'u': 20, 'v': 21, 'w': 22, 'x': 23, 'y': 24, 'z': 25} == {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5, 'g': 6, 'h': 7, 'i': 8, 'j': 9, 'k': 10, 'l': 11, 'm': 12, 'n': 13, 'o': 14, 'p': 15, 'q': 16, 'r': 17, 's': 18, 't': 19, 'u': 20, 'v': 21, 'w': 22, 'x': 23, 'y': 24, 'z': 25}
E         Common items:
E         {'a': 0,
E          'b': 1,
E          'c': 2,
E          'd': 3,
E          'e': 4,
E          'f': 5,
E          'h': 7,
E          'i': 8,
E          'j': 9,
E          'k': 10,
E          'l': 11,
E          'm': 12,
E          'n': 13,
E          'o': 14,
E          'p': 15,
E          'q': 16,
E          'r': 17,
E          's': 18,
E          't': 19,
E          'u': 20,
E          'v': 21,
E          'w': 22,
E          'x': 23,
E          'y': 24,
E          'z': 25}
E         Right contains 1 more item:
E         {'g': 6}
E         Full diff:
E           {
E            'a': 0,
E            'b': 1,
E            'c': 2,
E            'd': 3,
E            'e': 4,
E            'f': 5,
E         -  'g': 6,
E            'h': 7,
E            'i': 8,
E            'j': 9,
E            'k': 10,
E            'l': 11,
E            'm': 12,
E            'n': 13,
E            'o': 14,
E            'p': 15,
E            'q': 16,
E            'r': 17,
E            's': 18,
E            't': 19,
E            'u': 20,
E            'v': 21,
E            'w': 22,
E            'x': 23,
E            'y': 24,
E            'z': 25,
E           }

.tmp\test_foo.py:8: AssertionError
====================== short test summary info ======================
FAILED .tmp\test_foo.py::test_foobar - AssertionError: assert {'a':...
========================= 1 failed in 0.09s =========================

So clearly an improvement! 👍

Copy link
Member

@nicoddemus nicoddemus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @samuelcolvin, appreciate a lot the PR! Very clean work. 👍

@@ -160,8 +160,8 @@ def assertrepr_compare(config, op: str, left: Any, right: Any) -> Optional[List[
"""Return specialised explanations for some operators/operands."""
verbose = config.getoption("verbose")
if verbose > 1:
left_repr = safeformat(left)
right_repr = safeformat(right)
left_repr = saferepr_unlimited(left)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed using safeformat for the left and right operands when verbose > 1 is not what is expected, because safeformat introduces newlines, and the result of assertrepr_compare is expected to be a list of lines; the string produced by safeformat (containing \n) is put as a single string in the result, which causes them to be escaped by the terminal later (I assume).

So the fix is entirely correct: use repr to produce the representation without \n, which is used to build the summary variable which is expected to be a single line.

@nicoddemus nicoddemus changed the title improve -vv AssertionError message Remove newlines from left/right operands with '-vv' Mar 19, 2022
@nicoddemus nicoddemus enabled auto-merge (squash) March 19, 2022 11:44
@nicoddemus nicoddemus merged commit b75cbee into pytest-dev:main Mar 19, 2022
@samuelcolvin samuelcolvin deleted the repr-9742 branch March 19, 2022 19:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

AssertionError message contains unnecessary newline characters in verbose mode
3 participants