Description
Bug report
When notes on an exception cannot be shown because the repr
and str
raise exceptions, a <note str() failed>
message is shown instead. In the case where exception.__notes__
is not a sequence and cannot be shown, a <__notes__ repr() failed>
is shown. In the second case, the message does not include a trailing newline.
__notes__
is a list containing a broken "note" - output includes a newline:
class A:
def __repr__(self):
raise Exception()
e = Exception()
e.__notes__ = [A()] # !!!
raise e
user@host $ ./repro.py
Traceback (most recent call last):
File "./repro.py", line 8, in <module>
raise e
Exception
<note str() failed>
user@host $
__notes__
is just a single broken "note" - output does not include a newline:
class A:
def __repr__(self):
raise Exception()
e = Exception()
e.__notes__ = A() # !!!
raise e
user@host $ ./repro.py
Traceback (most recent call last):
File "./repro.py", line 8, in <module>
raise e
Exception
<__notes__ repr() failed>user@host $
Additionally, when __notes__
is a string/bytes, the contents are expoded over multiple lines because of an isinstance(__notes__, Sequence)
check.
String:
e = Exception()
e.__notes__ = "a note"
raise e
user@host $ ./repro.py
Traceback (most recent call last):
File "./repro.py", line 8, in <module>
raise e
Exception
a
n
o
t
e
user@host $
Bytes:
e = Exception()
e.__notes__ = b"a note"
raise e
user@host $ ./repro.py
Traceback (most recent call last):
File "./repro.py", line 8, in <module>
raise e
Exception
97
32
110
111
116
101
user@host $
Even though the above are all edge cases, since there are some checks that handle these cases already, it makes sense to handle them more gracefully.
Your environment
- CPython versions tested on: 3.12.0a7+
- Operating system and architecture: macOS Mojave (x86)