Python Exception - How Does The Args Attribute Get Automatically Set?
Solution 1:
args is implemented as a data descriptor with __get__ and __set__ methods. 
This takes place inside BaseException.__new__ like @bakatrouble mentioned. Among other things, what happens inside BaseException.__new__ is roughly like the Python code below: 
classBaseException:
    def__new__(cls, *args): 
        # self = create object of type cls
        self.args = args  # This calls: BaseException.args.__set__(self, args) 
        ...
        return self
In C code of Python 3.7.0 alpha 1, the above Python code looks like this (inspect Python's C code for any past or future differences):
BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    # other things omitted... self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
    # many things follow... if (args) {
        self->args = args;
        Py_INCREF(args);
        return (PyObject *)self;
    }
    # many more things follow
}
Experimenting interactively:
>>>e = Exception('aaa')>>>e
Exception('aaa',)
>>>BaseException.args.__set__(e, ('bbb',))>>>e
Exception('bbb',)
>>>BaseException.args.__get__(e)
('bbb',)
Hence, the magical inspiration of args that makes your eyes look heavenward takes place in BaseException.__new__, when an object of BaseException or any of its sub-classes is created. 
Solution 2:
It is being set in the BaseException.__new__() method, which could be seen here: source code
Note: in Python 2.7 it is being set in the BaseException.__init__() method, so the override makes .args dict always empty (not sure if pointing to the correct line): source code
Post a Comment for "Python Exception - How Does The Args Attribute Get Automatically Set?"