Skip to content

Commit 0f9cdeb

Browse files
authored
Fix formatting of possible notes added to an Exception (#980)
1 parent 91351df commit 0f9cdeb

File tree

5 files changed

+174
-2
lines changed

5 files changed

+174
-2
lines changed

CHANGELOG.rst

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
=============
33

44
- Add support for formatting of ``ExceptionGroup`` errors (`#805 <https://github.com/Delgan/loguru/issues/805>`_).
5+
- Fix formatting of possible ``__notes__`` attached to an ``Exception`` (`#980 <https://github.com/Delgan/loguru/issues/980>`_).
56

67

78
`0.7.1`_ (2023-09-04)

loguru/_better_exceptions.py

+12-2
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,17 @@ def _format_exception(
441441
)
442442
exception_only = traceback.format_exception_only(exc_type, exc_value)
443443

444-
error_message = exception_only[-1][:-1] # Remove last new line temporarily
444+
# Determining the correct index for the "Exception: message" part in the formatted exception
445+
# is challenging. This is because it might be preceded by multiple lines specific to
446+
# "SyntaxError" or followed by various notes. However, we can make an educated guess based
447+
# on the indentation; the preliminary context for "SyntaxError" is always indented, while
448+
# the Exception itself is not. This allows us to identify the correct index for the
449+
# exception message.
450+
for error_message_index, part in enumerate(exception_only): # noqa: B007
451+
if not part.startswith(" "):
452+
break
453+
454+
error_message = exception_only[error_message_index][:-1] # Remove last new line temporarily
445455

446456
if self._colorize:
447457
if ":" in error_message:
@@ -460,7 +470,7 @@ def _format_exception(
460470

461471
error_message = "\n" + error_message
462472

463-
exception_only[-1] = error_message + "\n"
473+
exception_only[error_message_index] = error_message + "\n"
464474

465475
if is_first:
466476
yield self._prefix
+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
2+
Traceback (most recent call last):
3+
File "tests/exceptions/source/modern/notes.py", line 13, in <module>
4+
raise e
5+
ValueError: invalid value
6+
Note
7+
8+
Traceback (most recent call last):
9+
10+
> File "tests/exceptions/source/modern/notes.py", line 13, in <module>
11+
raise e
12+
 └ ValueError('invalid value')
13+
14+
ValueError: invalid value
15+
Note
16+
17+
Traceback (most recent call last):
18+
File "tests/exceptions/source/modern/notes.py", line 20, in <module>
19+
raise e
20+
ValueError: invalid value
21+
Note1
22+
Note2
23+
Note3
24+
25+
26+
Traceback (most recent call last):
27+
28+
> File "tests/exceptions/source/modern/notes.py", line 20, in <module>
29+
raise e
30+
 └ ValueError('invalid value')
31+
32+
ValueError: invalid value
33+
Note1
34+
Note2
35+
Note3
36+
37+
38+
+ Exception Group Traceback (most recent call last):
39+
| File "tests/exceptions/source/modern/notes.py", line 27, in <module>
40+
| raise e
41+
| ExceptionGroup: Grouped (2 sub-exceptions)
42+
| Note 1
43+
| Note 2
44+
| Note 3
45+
+-+---------------- 1 ----------------
46+
| ValueError: 1
47+
+---------------- 2 ----------------
48+
| ValueError: 2
49+
+------------------------------------
50+
51+
+ Exception Group Traceback (most recent call last):
52+
|
53+
| > File "tests/exceptions/source/modern/notes.py", line 27, in <module>
54+
| raise e
55+
|  └ ExceptionGroup('Grouped', [ValueError(1), ValueError(2)])
56+
|
57+
| ExceptionGroup: Grouped (2 sub-exceptions)
58+
| Note 1
59+
| Note 2
60+
| Note 3
61+
+-+---------------- 1 ----------------
62+
| ValueError: 1
63+
+---------------- 2 ----------------
64+
| ValueError: 2
65+
+------------------------------------
66+
67+
Traceback (most recent call last):
68+
File "tests/exceptions/source/modern/notes.py", line 32, in <module>
69+
raise e
70+
TabError: tab error
71+
Note
72+
73+
Traceback (most recent call last):
74+
75+
> File "tests/exceptions/source/modern/notes.py", line 32, in <module>
76+
raise e
77+
 └ TabError('tab error')
78+
79+
TabError: tab error
80+
Note
81+
82+
Traceback (most recent call last):
83+
File "tests/exceptions/source/modern/notes.py", line 38, in <module>
84+
raise e
85+
File "<string>", line 1
86+
a = 7 *
87+
^
88+
SyntaxError: syntax error
89+
Note 1
90+
Note 2
91+
92+
Traceback (most recent call last):
93+
94+
> File "tests/exceptions/source/modern/notes.py", line 38, in <module>
95+
raise e
96+
 └ SyntaxError('syntax error', ('<string>', 1, 8, 'a = 7 *\n', 1, 8))
97+
98+
File "<string>", line 1
99+
a = 7 *
100+
^
101+
102+
SyntaxError: syntax error
103+
Note 1
104+
Note 2
105+
106+
Traceback (most recent call last):
107+
File "tests/exceptions/source/modern/notes.py", line 43, in <module>
108+
raise e
109+
TypeError: type error
110+
111+
Traceback (most recent call last):
112+
113+
> File "tests/exceptions/source/modern/notes.py", line 43, in <module>
114+
raise e
115+
 └ TypeError('type error')
116+
117+
TypeError: type error
+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from loguru import logger
2+
import sys
3+
4+
5+
logger.remove()
6+
logger.add(sys.stderr, format="", diagnose=False, backtrace=False, colorize=False)
7+
logger.add(sys.stderr, format="", diagnose=True, backtrace=True, colorize=True)
8+
9+
10+
with logger.catch():
11+
e = ValueError("invalid value")
12+
e.add_note("Note")
13+
raise e
14+
15+
16+
with logger.catch():
17+
e = ValueError("invalid value")
18+
e.add_note("Note1")
19+
e.add_note("Note2\nNote3\n")
20+
raise e
21+
22+
23+
with logger.catch():
24+
e = ExceptionGroup("Grouped", [ValueError(1), ValueError(2)])
25+
e.add_note("Note 1\nNote 2")
26+
e.add_note("Note 3")
27+
raise e
28+
29+
with logger.catch():
30+
e = TabError("tab error")
31+
e.add_note("Note")
32+
raise e
33+
34+
with logger.catch():
35+
e = SyntaxError("syntax error", ("<string>", 1, 8, "a = 7 *\n", 1, 8))
36+
e.add_note("Note 1")
37+
e.add_note("Note 2")
38+
raise e
39+
40+
with logger.catch():
41+
e = TypeError("type error")
42+
e.__notes__ = None
43+
raise e

tests/test_exceptions_formatting.py

+1
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ def test_exception_others(filename):
235235
("walrus_operator", (3, 8)),
236236
("match_statement", (3, 10)),
237237
("exception_group_catch", (3, 11)),
238+
("notes", (3, 11)),
238239
("grouped_simple", (3, 11)),
239240
("grouped_nested", (3, 11)),
240241
("grouped_with_cause_and_context", (3, 11)),

0 commit comments

Comments
 (0)