How is base Exception getting initialized?
<p>I'm confused by how the following exception in Python 3 gets initialized.</p>

<pre><code>class MyException( Exception ):

    def __init__(self,msg,foo):
        self.foo = foo

raise MyException('this is msg',123)
</code></pre>

<p>In Python 3, this outputs:</p>

<pre><code>Traceback (most recent call last):
  File "exceptionTest.py", line 7, in &lt;module&gt;
    raise MyException('this is msg',123)
__main__.MyException: ('this is msg', 123)
</code></pre>

<p>How are the arguments getting initialized?  I'm surprised that the trackback shows the args since I'm not calling the super class initializer. </p>

<p>In Python 2, I get the following output, which makes more sense to me since the args aren't included in the traceback.</p>

<pre><code>Traceback (most recent call last):
  File "exceptionTest.py", line 7, in &lt;module&gt;
    raise MyException('this is msg',123)
__main__.MyException
</code></pre>

<p>The Python <code>BaseException</code> class is special in that it has a <code>__new__</code> method that is put there specifically to handle this common case of errors.</p>

<p>So no, <code>BaseException.__init__</code> is not being called, but <code>BaseException.__new__</code> <em>is</em>. You can override <code>__new__</code> and ignore the arguments passed in to suppress the setting of <code>self.args</code>:</p>

<pre><code>&gt;&gt;&gt; class MyException(Exception):
...     def __new__(cls, *args, **kw):
...         return super().__new__(cls)  # ignoring arguments
...     def __init__(self,msg,foo):
...         self.foo = foo
...
&gt;&gt;&gt; MyException('this is msg', 123)  # no need to raise to see the result
MyException()
</code></pre>

<p>This addition is specific to Python 3 and is not present in Python 2. See <a href="https://bugs.python.org/issue1692335" rel="nofollow">issue #1692335</a> for the motivations and details.</p>

python python-3.x exception python-2.x