DeprecationWarning: BaseException.message has been deprecated as of Python 2.6 exception.__class__, exception.message,

PythonDev picture PythonDev · Oct 25, 2012 · Viewed 10.9k times · Source

Can anyone tell me the actual reason behind the warning I am getting in this Django middleware, and how can I solve this?

I am getting this message "DeprecationWarning: BaseException.message has been deprecated as of Python 2.6 exception.class, exception.message,"

class GeneralMiddleware(object):
    def process_exception(self, request, exception):
        if exception.__class__ is SandboxError:
            # someone is trying to access a sandbox that he has no
            # permission to
            return HttpResponseRedirect("/notpermitted/")

        exc_type, value, tb = sys.exc_info()
        data = traceback.format_tb(
                    tb, None) + traceback.format_exception_only(
                    exc_type, value)
        msg = (
            "Failure when calling method:\n"
            u"URL:'%s'\nMethod:'%s'\nException Type:'%s'\n"
            u"Error Message '%s'\nFull Message:\n%s"
            % (request.get_full_path(), request.method,
               exception.__class__, exception.message,

Answer

abarnert picture abarnert · Oct 25, 2012

If I remember correctly, when Python switched to the new raise syntax in 2.5(?), they got rid of the message member in favor of an args tuple. For backward compatibility, BaseException.message is effectively the same thing as BaseException.args[0] if BaseException.args else None, but you shouldn't use it in new code.

So, change message to either args (if you want all args) or args[0] (or, if you're worried there may be no args, the fancier version that protects against ()), depending on which you want.

The reason for this change is that with the new-style exceptions, there's no magic to raise or except anymore; you're just calling the exception class's constructor in the raise statement, and catching the exception in a variable in the except statement. So:

try:
  raise MyException('Out of cheese error', 42)
except Exception as x:
  print x.args

This will print ('Out of cheese error', 42). If you only had print x.message you'd just get 'Out of cheese error'. So, the Exception subclasses that used to have to do fancy things to carry around an error code as a separate member, etc., can be simplified; in fact, the whole thing comes down to this:

class BaseException(object):
  def __init__(self, *args):
    self.args = args