-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Color the full diff that pytest shows as a diff #11530
Color the full diff that pytest shows as a diff #11530
Conversation
Previously, it would get printed all in red, which makes it hard to read and actually understand. However, the diffs shown are standard and have a supported lexer in Pygments. As such, use this to color the output when pygments is available.
Thanks a lot @BenjaminSchubert, this looks great!
Yeah this seems fine to me. 👍
Yeah, I agree. Perhaps we can do some really shallow testing there: we don't need to test the full diff coloring, we just need to ensure that diff coloring has been applied. So we can check that some coloring has been applied in a diff output in a normal run, and then no diff coloring in a 2nd run of the same code but with |
@nicoddemus thanks for the quick feedback :)
I have pushed a fixup to reduce the amount of checks, which should make it easier to maintain on the long run. I can still trim it down more by just matchin we have a green I just need to figure out why the CI is failing in some cases only now, which I am currently unable to reproduce locally |
I was thinking of testing a single sample code, but I think this is better now and good to go now. 👍
Yeah me neither. I noticed however the failures happen in runs using xdist, but I also was unable to reproduce locally (using xdist too). |
No worries, I'll investigate more in depth, it does seem triggered by my change, as a run of the main branch does indeed pass |
It is really a head scratcher. Because this cannot be reproduced this locally it seems, to debug/investigate this I would push a series of commits:
Hopefully at some point this approach will point out to a small change that causes the other tests to break, and from there it might facilitate discovering what's going on. |
@nicoddemus That's a weird one. 7cbe6ef is enough to fix it. I am unsure why it breaks otherwise but don't think it's worth investigating more? Let me know if you want me to squash the commits or if anything else needs updating :) |
Apologies for the noise, this was not it |
Oh OK, thanks for the investigation!
Don't worry about squashing, we can do so before merging. 👍 |
I have a reproduction for the bug... I have no idea what's going on there. main...BenjaminSchubert:pytest:test-me-bug-repro has most cases of python<3.11 failing (except some??) and barely does any changes. The changes to the Which is basically: import pytest
# To fail you need at least:
# - 2 parametrize, with at least 2 value each. Content of the value does not
# seem to matter
# - use pytester
@pytest.mark.parametrize("foo", [True, False])
@pytest.mark.parametrize("bar", [True, False])
def test_bug(pytester, foo, bar) -> None:
pass And this is the check run: https://github.com/BenjaminSchubert/pytest/actions/runs/6597999568 I'll see if I can write the tests differently without them becoming non-sensical |
The only thing that all the failing tests have in common is xdist. It looks like running this test under xdist fails. |
I can reproduce locally. Running |
Found the problematic test, this fails locally:
This also fails on main, so unrelated to this PR. I will work on another PR fixing this, and then we can rebase yours to fix this. Thanks for the patience. Note: I used https://github.com/esss/pytest-replay to get the list of tests running in a specific node (because of xdist), and then manually bisected the failure (I tried using https://github.com/asottile/detect-test-pollution but got an error). |
Logging has many global states, and we did foresee this by creating a ``cleanup_disabled_logging`` fixture, however one might still forget to use it and failures leak later -- sometimes not even in the same PR, because the order of the tests might change in the future, specially when running under xdist. This problem surfaced during pytest-dev#11530, where tests unrelated to the change started to fail.
Logging has many global states, and we did foresee this by creating a ``cleanup_disabled_logging`` fixture, however one might still forget to use it and failures leak later -- sometimes not even in the same PR, because the order of the tests might change in the future, specially when running under xdist. This problem surfaced during pytest-dev#11530, where tests unrelated to the change started to fail.
@nicoddemus good catch, I was still very far from finding it :D Thank you very much |
Sure thing! I opened #11531 also, we can rebase this branch once that gets merged. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this change a lot, thanks @BenjaminSchubert. The code looks good to me. As you said there are a few more places that can benefit from this, but can do it in follow up PRs.
src/_pytest/assertion/util.py
Outdated
@@ -189,7 +190,8 @@ def assertrepr_compare( | |||
explanation = None | |||
try: | |||
if op == "==": | |||
explanation = _compare_eq_any(left, right, verbose) | |||
writer = config.get_terminal_writer() | |||
explanation = _compare_eq_any(left, right, writer, verbose) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like that we pass the full TerminalWriter to these functions, because it makes it seem like the functions actually write to the terminal, while they only need it for the pure _highlight
function. But it's OK for now, not asking you to refactor :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you prefer, we could instead pass a highlight
function (Callable[[str], str]
) which would be TerminalWriter._highlight
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like that idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I have pushed a fixup for this. I wasn't sure where to add the type definition, feel free to update/let me know if there's a better place
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that looks great, thanks!
Logging has many global states, and we did foresee this by creating a ``cleanup_disabled_logging`` fixture, however one might still forget to use it and failures leak later -- sometimes not even in the same PR, because the order of the tests might change in the future, specially when running under xdist. This problem surfaced during pytest-dev#11530, where tests unrelated to the change started to fail.
Overview
Previously, it would get printed all in red, which makes it hard to read and actually understand.
However, the diffs shown are standard and have a supported lexer in Pygments. As such, use this to color the output when pygments is available.
This is a step towards #11520 but does not address all the discussion points yet.
Visual changes
Previously
With this change
Questions
I am unsure about two things here: