2

While creating a custom Exception class, I encountered an unexpected situation how the base Exception class handles parameters. Specifically, with how it sets the 'message' attribute.

When you pass more than one parameter to the Exception.__init__(), it does not initialize the message attribute. For example, this works

>>> e = Exception('msg')
>>> e.message
'msg'

BUT This does NOT set the message attribute

>>> e = Exception('msg', 'extra')
>>> e.message
''

It does of course store all the parameters in the args attribute:

>>> e = Exception('msg', 'extra')
>>> e.args
('msg', 'extra')

Can anyone shed light on this? I've scoured the Exception docs, but I'm at a loss to understand why the Exception class does this. In case it matters, this is python 2.7

1 Answer 1

5

Use the source, Luke!

BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
{
    if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
        return -1;

    Py_DECREF(self->args);
    self->args = args;
    Py_INCREF(self->args);

    if (PyTuple_GET_SIZE(self->args) == 1) {
        Py_CLEAR(self->message);
        self->message = PyTuple_GET_ITEM(self->args, 0);
        Py_INCREF(self->message);
    }
    return 0;
}

So message is only set if the args is length 1.

The reason for this behaviour is for backwards compatibility. Exception.message is deprecated since python 2.6, and the implementation for BaseException.__str__ doesn't look at message at all - it only uses the args tuple.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the code -- but I'm curious about why this behavior is true?
Thanks...I'll accept this as the correct answer (need to wait 6 minutes for SO to allow this). Do you have a reference to the deprecated statement? I'd like to read up.
See PEP-352. The message attribute was actually a short-lived addition to the BaseException class, added in 2.5 but immediately deprecated in 2.6.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.