Reputation: 1212
I'm confused by how the following exception in Python 3 gets initialized.
class MyException( Exception ):
def __init__(self,msg,foo):
self.foo = foo
raise MyException('this is msg',123)
In Python 3, this outputs:
Traceback (most recent call last):
File "exceptionTest.py", line 7, in <module>
raise MyException('this is msg',123)
__main__.MyException: ('this is msg', 123)
How are the arguments getting initialized? I'm surprised that the trackback shows the args since I'm not calling the super class initializer.
In Python 2, I get the following output, which makes more sense to me since the args aren't included in the traceback.
Traceback (most recent call last):
File "exceptionTest.py", line 7, in <module>
raise MyException('this is msg',123)
__main__.MyException
Upvotes: 0
Views: 41
Reputation: 1122352
The Python BaseException
class is special in that it has a __new__
method that is put there specifically to handle this common case of errors.
So no, BaseException.__init__
is not being called, but BaseException.__new__
is. You can override __new__
and ignore the arguments passed in to suppress the setting of self.args
:
>>> class MyException(Exception):
... def __new__(cls, *args, **kw):
... return super().__new__(cls) # ignoring arguments
... def __init__(self,msg,foo):
... self.foo = foo
...
>>> MyException('this is msg', 123) # no need to raise to see the result
MyException()
This addition is specific to Python 3 and is not present in Python 2. See issue #1692335 for the motivations and details.
Upvotes: 3