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?

Was it helpful?

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top