Question

I need to know WHY this fails:

class ConfigurationError(Exception):
    def __init__(self, *args):
        super(ConfigurationError, self).__init__(self, args)

        self.args = list(args)
        # Do some formatting on the message string stored in self.args[0]
        self.args[0]=self.__prettyfi(self.args[0])

    def __prettyfi(self, arg):
        pass
        # Actual function splits message at word
        # boundaries at pos rfind(arg[1:78]) if len(arg) >78
        # it does this by converting a whitespace char to a \n

When I run the code, i receive the following msg: <snip> ConfigurationError.py", line 7, in __init__ self.args[0]=self.__prettyfi(self.args[0]) TypeError: 'tuple' object does not support item assignment

I edited the line no. to match this code sample.

I do not understand why self.args = list(args) does not correctly unpack the tuple into the list at line 5.

(I have a sneaking suspicion I am failing to remember something super-basic...)

Was it helpful?

Solution

Exception.args is a descriptor; it hooks __set__ to turn anything you assign to self.args into a tuple.

So, as soon as you assign your list to self.args, the descriptor converts it back to a tuple. It's not that your list() call failed, it's just that Exception.args is special.

BaseException.args is documented to be a tuple, and in Python 2, exception objects support slicing:

>>> ex = Exception(1, 2)
>>> ex.args
(1, 2)
>>> ex[0]
1

Exceptions are also supposed to be immutable; keeping the .args attribute a tuple helps keep them so. Moreover, the __str__ handler for exceptions expects .args to be a tuple, and setting it to something else has led to strange bugs in the past.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top