-
-
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
Draft: Add very basic implementation of PEP657 style expression markers in tracebacks #13102
base: main
Are you sure you want to change the base?
Conversation
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 think I'll have time to finish this out fully
Thanks for taking it this far! Whether or not you keep going, this is a neat contribution 😄
There's some interesting problems here like
mypy
complaining because typeshed doesn't have some of the newertraceback.FrameSummary
attrs likecolno
.
It looks like typeshed does have them, so I think we're probably seeing mypy pointing out that we need to version-guard those accesses; see comment below.
Additionally, since the python offsets are from the start of the line, we have to know the line before it gets de-dented in
Source
.
I think we could fetch it with linecache
(as used by the traceback
module), and then correct for the different length of leading whitespace? Alternatively we could ast.parse()
the Source
line, and see if there's an expression which matches the expected start and end colnos for various candidate dedents; it's a heuristic but likely to be unambiguous almost all the time.
src/_pytest/_code/code.py
Outdated
def end_lineno(self) -> int: | ||
return self.get_python_framesummary().end_lineno - 1 |
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.
Here, and in end_colno
below, we'll need to handle the case where on earlier Python versions these attributes don't exist. I'd consider defining the properties differently based on version, so that we can easily remove the backwards-compatibility code once we're ready to drop support for Python 3.10
assert reprtb.lines[0] == " return 1 / 0" | ||
assert reprtb.lines[1] == " ^^^^^" |
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.
It's not the full fledged python traceback.py implementation where we try to differentiate which parts contain operators.
That would be very nice to have, but I'd be happy to merge something without that and open a follow-up issue: this is already a nice improvement on the status quo!
Oh yup, you're totally right about them being behind a version check in typeshed, I missed that. Added a version guard and now mypy seems happy with it. Also added version guards for the one unit test I added and changed. |
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.
Thanks again @ammaraskar!
I think the only thing left is to add yourself to the AUTHORS file, and create changelog/10224.improvement.rst
containing something like "Partial support for PEP-657 precise traceback locations in Pytest's alternative traceback formatting."
Hey folks this is just a proof of concept for #10224 to serve as a reference for if any contributor wants to give this a full shot.
This adds a very basic implementation of the PEP657 style expression highlighting in the short and long traceback modes. It's not the full fledged python
traceback.py
implementation where we try to differentiate which parts contain operators.I don't think I'll have time to finish this out fully, there's some interesting problems here like
mypy
complaining because typeshed doesn't have some of the newertraceback
FrameSummary
attrs likecolno
. Additionally, since the python offsets are from the start of the line, we have to know the line before it gets de-dented inSource
.Example of what it looks like:
and with tb short: