-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Show full repr with assert a==b and -vv #4607
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
Conversation
|
Thanks, please add a test for this - (maybe only by adjusting the now failing test(s)?!) |
RonnyPfannschmidt
left a comment
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 == yYou 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
| 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... |
nicoddemus
left a comment
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
reprin test failure output forassert x==ywhen-vvis 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
-vvshows the wholerepr(which is very long so I won't paste it here).