31

I'm trying to define my own (very simple) exception class in Python 2.6, but no matter how I do it I get some warning.

First, the simplest way:

class MyException(Exception):
    pass

This works, but prints out a warning at runtime: DeprecationWarning: BaseException.message has been deprecated as of Python 2.6 OK, so that's not the way. I then tried:

class MyException(Exception):
    def __init__(self, message):
        self.message = message

This also works, but PyLint reports a warning: W0231: MyException.__init__: __init__ method from base class 'Exception' is not called. So I tried calling it:

class MyException(Exception):
    def __init__(self, message):
        super(Exception, self).__init__(message)
        self.message = message

This works, too! But now PyLint reports an error: E1003: MyException.__init__: Bad first argument 'Exception' given to super class

How the hell do I do such a simple thing without any warnings?

Community
  • 1
  • 1
EMP
  • 59,148
  • 53
  • 164
  • 220
  • 7
    `*lint` has always erred on the side of warning thus generating warnings that you don't really care about and can prompt the unwary to do things like add unused methods to try to shut it up. Making any lint not complain is not a worthwhile goal, understanding all its complaints is. – msw May 24 '10 at 23:45
  • @msw: Any unresolved warnings are noise which might hide interesting messages. But there is always `noqa`/`# pylint: disable=line-too-long` to get rid of pure noise. And calling the base class `__init__`is generally a good idea. – ted Feb 09 '22 at 12:23

3 Answers3

45

When you call super, you need the subclass/derived class as the first argument, not the main/base class.

From the Python online documentation:

class C(B):
    def method(self, arg):
        super(C, self).method(arg)

So your exception would be defined as follows:

class MyException(Exception):
    def __init__(self, message):
        super(MyException, self).__init__(message)
        self.message = message
Dustin
  • 1,956
  • 14
  • 14
  • Ah, this was a live saver, although I would even go a bit further with the example, to show something like this you can do: super(MyException, self).__init__('MyException prefix: {0}'.format(message)), but either way, it is a great answer! – László Papp Oct 21 '13 at 17:50
7

Alright, I think I figured it out. This seems to keep PyLint happy:

class MyException(Exception):
    def __init__(self, message):
        Exception.__init__(self, message)
        self.message = message
EMP
  • 59,148
  • 53
  • 164
  • 220
0

Your first way should work. I use it myself all the time in Python 2.6.5. I don't use the "message" attribute, however; maybe that's why you're getting a runtime warning in the first example.

The following code, for example, runs without any errors or runtime warnings:

class MyException(Exception):
    pass

def thrower():
    error_value = 3
    raise MyException("My message", error_value)
    return 4

def catcher():
    try:
        print thrower()
    except MyException as (message, error_value):
        print message, "error value:", error_value

The result:

>>> catcher()
My message error value: 3

I don't know if PyLint would have a problem with the above.

Peter Milley
  • 2,768
  • 19
  • 18