Error exception must derive from BaseException even when it does (Python 2.7)
Question:
What’s wrong with the following code (under Python 2.7.1):
class TestFailed(BaseException):
def __new__(self, m):
self.message = m
def __str__(self):
return self.message
try:
raise TestFailed('Oops')
except TestFailed as x:
print x
When I run it, I get:
Traceback (most recent call last):
File "x.py", line 9, in <module>
raise TestFailed('Oops')
TypeError: exceptions must be old-style classes or derived from BaseException, not NoneType
But it looks to me that TestFailed
does derive from BaseException
.
Answers:
Use __init__()
instead of __new__()
to “initialize” classes. In most cases overriding __new__
is not necessary. It is called before __init__
during object creation.
The __new__
implementation should return an instance of the class, but it’s currently returning None
(by default).
However, it looks like you should be using __init__
here, rather than __new__
.
Others have shown you how to fix your implementation, but I feel it important to point out that the behavior you are implementing is already the standard behavior of exceptions in Python so most of your code is completely unnecessary. Just derive from Exception
(the appropriate base class for runtime exceptions) and put pass
as the body.
class TestFailed(Exception):
pass
What’s wrong with the following code (under Python 2.7.1):
class TestFailed(BaseException):
def __new__(self, m):
self.message = m
def __str__(self):
return self.message
try:
raise TestFailed('Oops')
except TestFailed as x:
print x
When I run it, I get:
Traceback (most recent call last):
File "x.py", line 9, in <module>
raise TestFailed('Oops')
TypeError: exceptions must be old-style classes or derived from BaseException, not NoneType
But it looks to me that TestFailed
does derive from BaseException
.
Use __init__()
instead of __new__()
to “initialize” classes. In most cases overriding __new__
is not necessary. It is called before __init__
during object creation.
The __new__
implementation should return an instance of the class, but it’s currently returning None
(by default).
However, it looks like you should be using __init__
here, rather than __new__
.
Others have shown you how to fix your implementation, but I feel it important to point out that the behavior you are implementing is already the standard behavior of exceptions in Python so most of your code is completely unnecessary. Just derive from Exception
(the appropriate base class for runtime exceptions) and put pass
as the body.
class TestFailed(Exception):
pass