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

Use tb_lineno to point to correct line in traceback #17

Merged
merged 4 commits into from
Sep 27, 2023

Conversation

alexmojaki
Copy link
Contributor

Tracebacks should generally use tb_lineno/lasti instead of f_lineno/lasti. From https://docs.python.org/3/reference/datamodel.html#traceback-objects:

tb_lineno gives the line number where the exception occurred; tb_lasti indicates the precise instruction. The line number and last instruction in the traceback may differ from the line number of its frame object if the exception occurred in a try statement with no matching except clause or with a finally clause.

try:
return x / y
finally:
str(y)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the line where the traceback would point without the change, as it's the last line the frame executed. tb_lineno points to where the exception happened, two lines up.

Copy link
Member

@samuelcolvin samuelcolvin left a comment

Choose a reason for hiding this comment

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

Otherwise LGTM.

pytest_examples/traceback.py Show resolved Hide resolved
@@ -54,7 +54,7 @@ def test_find_run_examples(example: CodeExample, eval_example: EvalExample):

# assert 'my_file_9_13.py:12: AssertionError' in '\n'.join(result.outlines)
assert result.outlines[-8:-3] == [
'',
' b = 2',
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is caused by changing to f_code.co_firstlineno, which seems to help pytest include more context from the original markdown file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I understand this properly now. Previously, setting co_firstlineno to frame.f_lineno + example.start_line was saying that the code started at the problematic line (ignoring the nuance about f_lineno vs tb_lineno) so pytest would show the failing line (so things appeared to work) but it thought that was the start of the code so it didn't show any context before that.

Leaving co_firstlineno unchanged meant it included more context, but too much.

f_code.co_firstlineno + example.start_line works correctly as you'd expect. That's the only way that this expanded test passes, with pytest showing the exact correct context.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

#19 doesn't pass this test because the code in line_adjusted_source still starts at the first line, even if it's just padding comments, so the full example file gets included as context for the top level frame.

Copy link
Member

@sydney-runkle sydney-runkle left a comment

Choose a reason for hiding this comment

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

LGTM 👍 thanks for the contribution!

@samuelcolvin samuelcolvin merged commit 3bef5d6 into pydantic:main Sep 27, 2023
8 checks passed
@samuelcolvin
Copy link
Member

great, thanks so much. We urgently need to fix #20 and #18 and do a new release.

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.

None yet

3 participants