-
-
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
Show full repr with assert a==b and -vv #4607
Conversation
Thanks, please add a test for this - (maybe only by adjusting the now failing test(s)?!) |
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'd also note that this was introduced to prevent various denial of service issues triggered by broken reprs - i suggest to use a higher verbosity level to trigger the behaviour,
left_lines = repr(left).splitlines(keepends) | ||
right_lines = repr(right).splitlines(keepends) | ||
|
||
explanation = [] |
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.
unified_diff
imported but not used
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.
Okay I've removed that now
It might be worth controlling this through some additional setting. I for example would like to see full diffs always, without turning pytest verbose in general. |
What verbosity level should I use? It's already easy to make arbitrarily long output with import random
def test_f():
linesa = '\n'.join('foobar' + random.choice('wer') for n in range(10000))
linesb = '\n'.join('foobar' + random.choice('wer') for n in range(10000))
assert linesa == linesb ( The behaviour I've gone for here is intended to match what already happens with strings. |
df52dd0
to
e503c03
Compare
Codecov Report
@@ Coverage Diff @@
## master #4607 +/- ##
==========================================
- Coverage 95.75% 95.74% -0.01%
==========================================
Files 111 111
Lines 24678 24706 +28
Branches 2446 2449 +3
==========================================
+ Hits 23630 23655 +25
Misses 740 740
- Partials 308 311 +3
Continue to review full report at Codecov.
|
e503c03
to
f0496f9
Compare
I also have the same feeling. How about |
We also need a new CHANGELOG entry |
Adding a new option will require this to target |
f0496f9
to
d751634
Compare
I agree there should be a separate option, but I would argue it should still be controlled by |
d751634
to
2596cb9
Compare
I think I've addressed all issues (removed unused import, added changelog, fixed it so no tests fail, added a new test) apart from the question of the command line option to use. I don't understand why there should be a separate option unless it is intended to apply to all the cases. The behaviour of this patch matches what already happens for list, set, string etc. If you try this you can see the effect of def test_f():
class Nums:
def __init__(self, nums):
self.nums = nums
def __repr__(self):
return str(self.nums)
x = list(range(500))
y = list(range(500))
y[len(y)//2] = 3
x = Nums(x)
y = Nums(y)
assert x == y
def test_g():
x = list(range(500))
y = list(range(500))
y[len(y)//2] = -1
assert x == y
def test_h():
x = set(range(500))
y = set(range(500))
y.remove(200)
assert x == y
def test_i():
lines = ['qwerty'*5 for n in range(20)]
x = '\n'.join(lines)
lines[10] += 'zxc'
y = '\n'.join(lines)
assert x == y
def test_j():
x = list(range(500))
y = list(range(500))
y[len(y)//2] = 3
x = str(x)
y = str(y)
assert x == y You can see that If there is to be a separate command line option why should it only apply to this case and not the others? Likewise I don't see how this case can cause a new DOS issue given that it matches the other cases. |
Well, as a first interaction we can keep it as |
2596cb9
to
85055a9
Compare
@@ -151,6 +151,8 @@ def isiterable(obj): | |||
elif type(left) == type(right) and (isdatacls(left) or isattrs(left)): | |||
type_fn = (isdatacls, isattrs) | |||
explanation = _compare_eq_cls(left, right, verbose, type_fn) | |||
elif verbose: | |||
explanation = _compare_eq_verbose(left, right) |
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.
This uses it with -v
already, no?
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.
Yes. That's also what happens in the case of e.g. strings: https://github.com/pytest-dev/pytest/blob/master/src/_pytest/assertion/util.py#L176
The filtering based on -vv happens down the line somewhere else (in all cases).
So with -v this function will generate full output but pytest won't ultimately show the whole of it unless -vv is given.
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.
That's confusing - especially when looking at the test.
Can this be fixed here (in this PR) also?
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.
The test is showing the output of call_equal
which calls these functions directly. Shortening (without -vv) takes place here I think: https://github.com/pytest-dev/pytest/blob/master/src/_pytest/assertion/truncate.py
That looks like a deliberate design and seems reasonable to me so I'm not sure what needs fixing.
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 it makes sense that truncation happens later down the line, otherwise every implementation would need to implement or call truncation (IIUC).
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.
But yeah, I was also confused for this same reason, I had to look at the rest of the code to understand what was going on.
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.
@nicoddemus
I think we should create a follow-up issue/PR for this.
Have you looked closer at it already?
So is this patch okay? Happy to make changes but I think I've addressed all requests so far... |
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.
LGTM, thank you @oscarbenjamin, we appreciate the PR and your patience. 👍
Thanks again @oscarbenjamin for the PR! |
1 similar comment
Thanks again @oscarbenjamin for the PR! |
Thanks all! |
Fixes #2256
Adds a new explanation handler to show reprs of arbitrary objects. The handler shows the full
repr
in test failure output forassert x==y
when-vv
is given on the command line.Here's a test case:
Running on master this gives:
With this patch there is a short output given by:
Running with
-vv
shows the wholerepr
(which is very long so I won't paste it here).