-
Notifications
You must be signed in to change notification settings - Fork 659
Better handling of tracebacks #4696
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
base: master
Are you sure you want to change the base?
Changes from 14 commits
d26760c
61a5635
8ef357d
3c5cd86
9723a5b
fafeff1
3711e6e
376ef5e
de47cd6
f8fee4d
5d5c4ce
30422cb
f090b6d
d5a8f04
acc81da
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| RELEASE_TYPE: patch | ||
|
|
||
| This release fixes (:issue:`4681`), which would cause line numbers to frequently be wrong in tracebacks for | ||
| errors found by Hypothesis. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1619,6 +1619,12 @@ def shortlex_key(error): | |
| return result | ||
|
|
||
|
|
||
| # Exists solely to insert a line in the traceback where we need to. | ||
| def _reraise_exception_group(the_error_hypothesis_found): | ||
| __tracebackhide__ = False | ||
| raise the_error_hypothesis_found | ||
|
|
||
|
|
||
| def _raise_to_user( | ||
| errors_to_report, settings, target_lines, trailer="", *, unsound_backend=None | ||
| ): | ||
|
|
@@ -2248,19 +2254,16 @@ def wrapped_test(*arguments, **kwargs): | |
| f"{pytest_extra_msg}." | ||
| ) | ||
| report(msg) | ||
| # The dance here is to avoid showing users long tracebacks | ||
| # full of Hypothesis internals they don't care about. | ||
| # We have to do this inline, to avoid adding another | ||
| # internal stack frame just when we've removed the rest. | ||
| # | ||
| # Using a variable for our trimmed error ensures that the line | ||
| # which will actually appear in tracebacks is as clear as | ||
| # possible - "raise the_error_hypothesis_found". | ||
| # Trim the traceback to remove hypothesis internals | ||
| the_error_hypothesis_found = e.with_traceback( | ||
| None | ||
| if isinstance(e, BaseExceptionGroup) | ||
| else get_trimmed_traceback() | ||
| ) | ||
| if isinstance(e, BaseExceptionGroup): | ||
| # Insert a frame here as otherwise all base frames are | ||
| # trimmed which causes pytest problems | ||
| _reraise_exception_group(the_error_hypothesis_found) | ||
|
Comment on lines
+2263
to
+2266
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd rather fix this in Pytest than Hypothesis, optionally keeping a version-gated workaround here. |
||
| raise the_error_hypothesis_found | ||
|
|
||
| if not (ran_explicit_examples or state.ever_executed): | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -80,14 +80,27 @@ def get_trimmed_traceback( | |
| ) | ||
| ): | ||
| return tb | ||
| while tb.tb_next is not None and ( | ||
| # If the frame is from one of our files, it's been added by Hypothesis. | ||
| is_hypothesis_file(getsourcefile(tb.tb_frame) or getfile(tb.tb_frame)) | ||
| # But our `@proxies` decorator overrides the source location, | ||
| # so we check for an attribute it injects into the frame too. | ||
| or tb.tb_frame.f_globals.get("__hypothesistracebackhide__") is True | ||
| ): | ||
|
|
||
| def _is_hypothesis_frame(frame): | ||
| return ( | ||
| is_hypothesis_file(getsourcefile(frame) or getfile(frame)) | ||
| or frame.f_globals.get("__hypothesistracebackhide__") is True | ||
| ) | ||
|
|
||
| # Strip leading hypothesis frames | ||
| while tb.tb_next is not None and _is_hypothesis_frame(tb.tb_frame): | ||
| tb = tb.tb_next | ||
|
|
||
| # Strip any remaining hypothesis frames from the middle of the traceback | ||
| prev = tb | ||
| current = tb.tb_next | ||
| while current is not None: | ||
| if current.tb_next is not None and _is_hypothesis_frame(current.tb_frame): | ||
| prev.tb_next = current.tb_next | ||
| else: | ||
| prev = current | ||
| current = prev.tb_next | ||
|
Comment on lines
+94
to
+102
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unlike stripping leading frames, this modifies the traceback object in place and will thus affect anyone else who has a copy for whatever reason. Avoiding that is necessarily more expensive though, so maybe we just leave a comment? |
||
|
|
||
| return tb | ||
|
|
||
|
|
||
|
|
||
|
Zac-HD marked this conversation as resolved.
Outdated
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # This file is part of Hypothesis, which may be found at | ||
| # https://github.com/HypothesisWorks/hypothesis/ | ||
| # | ||
| # Copyright the Hypothesis Authors. | ||
| # Individual contributors are listed in AUTHORS.rst and the git log. | ||
| # | ||
| # This Source Code Form is subject to the terms of the Mozilla Public License, | ||
| # v. 2.0. If a copy of the MPL was not distributed with this file, You can | ||
| # obtain one at https://mozilla.org/MPL/2.0/. |
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 disagree with removing this useful comment (did claude do this?)