Python: Can I overload the raise statement with def __raise__(self):?
Question
Here's my exception class that is using raise:
class SCE(Exception):
"""
An error while performing SCE functions.
"""
def __init__(self, value=None):
"""
Message: A string message or an iterable of strings.
"""
if value is None:
self._values = []
elif isinstance(value, str):
self._values = [value]
else:
self._values = list(value)
def __raise__(self):
print('raising')
if not len(self._values):
return
def __str__(self):
return self.__repr__()
def __iter__(self):
return iter(self._values)
def __repr__(self):
return repr(self._values)
Currently if I raise this exception with no value I get traceback followed by:
__main__.SCE: []
Instead of what I expected which was:
raising
>>>
How do you overload raise
?
Solution
As the other answer says, there is no __raise__
special method. There was a thread in 2004 on comp.lang.python where someone suggested adding such a method, but I don't think there was any followup to that. The only way I can think of to hook exception raising is either by patching the interpreter, or some kind of source or bytecode rewriting that inserts a function call next to the raise operation.
OTHER TIPS
There is no such special method __raise__
(at least none that I have ever heard of or that I can find in the Python documentation).
Why do you want to do this? I can't think of any reason why you want custom code be be executed when the exception is raised (as opposed to either when the exception is constructed, which you can do with the __init__
method, or when the exception is caught, which you can do with an except
block). What is your use case for this behavior, and why do you expect that Python supports it?
As others have stated, there is no such private method __raise__
. Nothing prevents defining one. For example:
#!/usr/bin/env python3
class MyClass(object):
def __init__(self, raise_exceptions=False):
self.raise_exceptions = raise_exceptions
def __raise__(self, err=None):
print(err, flush=True)
if self.raise_exceptions:
raise err
def run(self):
try:
assert False, 'assertion False'
except Exception as err:
self.__raise__(err)
if __name__ == '__main__':
MyClass(raise_exceptions=False).run()
MyClass(raise_exceptions=True).run()
Here is the output:
$ python3 my_class.py
assertion False
assertion False
Traceback (most recent call last):
File "my_class.py", line 22, in <module>
MyClass(raise_exceptions=True).run()
File "my_class.py", line 17, in run
self.__raise__(err)
File "my_class.py", line 11, in __raise__
raise err
File "my_class.py", line 15, in run
assert False, 'assertion False'
AssertionError: assertion False
Process finished with exit code 1