I tried to define my own exception class in python 2.7, deriving from BaseException
.
class NestedCommentException(BaseException):
"""
Exception for nested comments
"""
def __init__(self, file_path, list_lines):
self.file_path = file_path
self.list_lines = list_lines
def __repr__(self):
return self.__str__()
def __str__(self):
return 'File {0} contains nested comments at lines {1}'.format(self.file_path, ', '.join(self.list_lines))
But when throwing it, it cannot be printed: raise NestedCommentException(file_path, list_lines)
triggers
Traceback (most recent call last):
File "D:\DATA\FP12210\My Documents\Outils\SVN\05_impl\2_tools\svn_tag_setup.py", line 85, in <module>
tag_checks()
File "D:\DATA\FP12210\My Documents\Outils\SVN\05_impl\2_tools\svn_tag_setup.py", line 66, in tag_checks
check_nested_comments(ddl_path)
File "D:\DATA\FP12210\My Documents\Outils\SVN\05_impl\2_tools\svn_tag_setup.py", line 54, in check_nested_comments
raise NestedCommentException(file_path, list_lines)
NestedCommentException: <unprintable NestedCommentException object>
Can you please explain why this happens, even if I defined __str__
and __repr__
methods ?
Best Answer
TL;DR
When you see this thing, it basically means that some kind of exception has been raised in
__str__()
of your object. So unless the problem is trivial enough to see at the first sight (e.g. forgotten "%s"), eitherwrap the
__str__
body in a try/except clause as Anurag advices, orinstantiate your exception and call the
__str__
(or any methods you may have overridden) manually, outside the traceback module, so that you get the full description of the exception.Analysis
Actually this
<unprintable MyException object>
can come from various functions in traceback module, which, when trying to get a string (i.e. "printable") version of a value (exception), itcalls
str()
on it, and if anything goes wrong,tries to treat it as unicode and convert it to ASCII, and if still anything goes wrong
simply prints the above representation.
Responsible code (same in 2.6 and 2.7):
As you can see, any exceptions coming from the
str()
call or theunicode.encode()
call are ceased in the process and only the "cryptic" representation is given.Note on traceback module vs. Python interpreter
Contrary to what
traceback
documentation tells us:the representation given by Python interpreter is slightly different here. As opposed to the "unprintable" message, the interpreter would simply display the name of the exception, ceasing any actual exceptions as well.
Here is a simple script that demonstrates all three approaches: leaving the exception to Python interpreter, using traceback module, or calling the function by hand.