Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove "__main__." from the beginning of user-created exception classes in Python

Is there a way to get a "prettier" exception rather than one prefaced with __main__MyExceptionTitle?

Example:

>>> class BadThings(Exception):
...     def __init__(self, msg):
...         self.msg = msg
...         return
... 
>>> class BadThings(Exception):
...     def __init__(self, msg):
...         self.msg = msg
...         return
...     def __str__(self):
...         return self.msg
... 
>>> raise BadThings("This is really, really bad")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
__main__.BadThings: This is really, really bad

I would like it to just say:

BadThings: This is really, really bad

Just as if one types:

>>> raise Exception("This, too, is really, really bad")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Exception: This, too, is really, really bad

I would like the __main__. gone!

Thanks, Narnie

like image 726
narnie Avatar asked Sep 11 '10 03:09

narnie


People also ask

How do you catch an instance of a specific exception type in Python?

Catching Exceptions in Python In Python, exceptions can be handled using a try statement. The critical operation which can raise an exception is placed inside the try clause. The code that handles the exceptions is written in the except clause.

How does Python handle user defined exceptions?

In Python, users can define custom exceptions by creating a new class. This exception class has to be derived, either directly or indirectly, from the built-in Exception class. Most of the built-in exceptions are also derived from this class.

What is BaseException in Python?

The BaseException is the base class of all other exceptions. User defined classes cannot be directly derived from this class, to derive user defied class, we need to use Exception class. The Python Exception Hierarchy is like below. BaseException.


2 Answers

class MyException(Exception):
    __module__ = Exception.__module__

This way looks/works better than sys.excepthook


Source Code Reference

Python2

See PyErr_Display

There're two ways to bypass the module name part:

class A(Exception):
    __module__ = None

class B(Exception):
    __module__ = 'exceptions'

But if you need to play with threading.Thread, the first one will introduce a TypeError.

Python 3

See PyErr_WriteUnraisable

class C(Exception):
    __module__ = 'builtins'
like image 183
youfu Avatar answered Oct 17 '22 05:10

youfu


I am not sure why you want to remove __main__ because that is the module name and when your exception would be in a appropriately named module, it would look beautiful not ugly e.g. myexceptions.BadException

Alternatively you can catch exception and print as you wish.

But if you want the uncaught exceptions to be printed as per your wish, try to set sys.excepthook e.g.

class BadThings(Exception): pass 

import traceback
def myexcepthook(type, value, tb):
    l = ''.join(traceback.format_exception(type, value, tb))
    print l

import sys
sys.excepthook = myexcepthook

raise BadThings("bad bad")

Output:

Traceback (most recent call last):
  File "untitled-1.py", line 12, in <module>
    raise BadThings("bad bad")
BadThings: bad bad

So in sys.excepthook you can modify exception, format it etc

like image 44
Anurag Uniyal Avatar answered Oct 17 '22 07:10

Anurag Uniyal