-
-
Notifications
You must be signed in to change notification settings - Fork 32k
bpo-45249: Ensure the traceback module prints correctly syntax errors with ranges #28575
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
Changes from all commits
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 |
---|---|---|
|
@@ -622,10 +622,14 @@ class TracebackException: | |
occurred. | ||
- :attr:`lineno` For syntax errors - the linenumber where the error | ||
occurred. | ||
- :attr:`end_lineno` For syntax errors - the end linenumber where the error | ||
occurred. Can be `None` if not present. | ||
- :attr:`text` For syntax errors - the text where the error | ||
occurred. | ||
- :attr:`offset` For syntax errors - the offset into the text where the | ||
error occurred. | ||
- :attr:`end_offset` For syntax errors - the offset into the text where the | ||
error occurred. Can be `None` if not present. | ||
- :attr:`msg` For syntax errors - the compiler error message. | ||
""" | ||
|
||
|
@@ -655,8 +659,11 @@ def __init__(self, exc_type, exc_value, exc_traceback, *, limit=None, | |
self.filename = exc_value.filename | ||
lno = exc_value.lineno | ||
self.lineno = str(lno) if lno is not None else None | ||
end_lno = exc_value.end_lineno | ||
self.end_lineno = str(end_lno) if end_lno is not None else None | ||
self.text = exc_value.text | ||
self.offset = exc_value.offset | ||
self.end_offset = exc_value.end_offset | ||
self.msg = exc_value.msg | ||
if lookup_lines: | ||
self._load_lines() | ||
|
@@ -771,12 +778,20 @@ def _format_syntax_error(self, stype): | |
ltext = rtext.lstrip(' \n\f') | ||
spaces = len(rtext) - len(ltext) | ||
yield ' {}\n'.format(ltext) | ||
# Convert 1-based column offset to 0-based index into stripped text | ||
caret = (self.offset or 0) - 1 - spaces | ||
if caret >= 0: | ||
# non-space whitespace (likes tabs) must be kept for alignment | ||
caretspace = ((c if c.isspace() else ' ') for c in ltext[:caret]) | ||
yield ' {}^\n'.format(''.join(caretspace)) | ||
|
||
if self.offset is not None: | ||
offset = self.offset | ||
end_offset = self.end_offset if self.end_offset is not None else offset | ||
if offset == end_offset or end_offset == -1: | ||
end_offset = offset + 1 | ||
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've noticed that 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. Addressed in #28855 |
||
|
||
# Convert 1-based column offset to 0-based index into stripped text | ||
colno = offset - 1 - spaces | ||
end_colno = end_offset - 1 - spaces | ||
if colno >= 0: | ||
# non-space whitespace (likes tabs) must be kept for alignment | ||
caretspace = ((c if c.isspace() else ' ') for c in ltext[:colno]) | ||
yield ' {}{}'.format("".join(caretspace), ('^' * (end_colno - colno) + "\n")) | ||
msg = self.msg or "<no detail available>" | ||
yield "{}: {}{}\n".format(stype, msg, filename_suffix) | ||
|
||
|
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 is not
None
, but an unset attribute for non-SyntaxErrors, since it gets set forif exc_type and issubclass(exc_type, SyntaxError)
only.I think it should either get initialized always (to
None
), or at least the doc should get fixed (both places above).Uh oh!
There was an error while loading. Please reload this page.
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. The text is the same as for other syntax errors fields. It says:
the same way offset is also for syntax errors:
The thing here is that end_offset can be None if not present even for syntax errors.