Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Class method decorator with arguments

So, here’s a method:

def evaluate(self): return self.left ** self.right

And it can raise an OverflowError if the result is too big.
To fix it (or convert to a different exception), you can e.g. decorate it:

def overflow_adapter(method):
    def wrapper(self):
        try:
            return method(self)
        except OverflowError:
            raise ValueError("Result is too big!")
    return wrapper


@overflow_adapter
def evaluate(self): return self.left ** self.right

What I want to achieve is to be able to decorate methods with a specific decorator, which converts multiple different exceptions to one specific:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

@exception_adapter(aware=[OverflowError,], response=ValueError("Result is too big!"))
def evaluate(self): return self.left ** self.right

I would write something like this (… are places I don’t know how to complete:

def exception_adapter(...):
    def wrapper(...):
        try:
            return method(self)
        except BaseException as e:
            if e in aware: raise response
    return wrapper

How can I make this work?

>Solution :

Something like this:

from functools import wraps


def exception_adapter(
    aware: tuple[type[BaseException]],
    response: BaseException,
):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except aware as e:
                raise response from e

        return wrapper

    return decorator


@exception_adapter(
    aware=(OverflowError,),
    response=ValueError("Result is too big!"),
)
def evaluate(a, b):
    if a > 3:
        raise OverflowError("foo")
    return a ** b


print(evaluate(2, 7))
print(evaluate(5, 7))

The output is

Traceback (most recent call last):
  File "scratch_625.py", line 9, in wrapper
    return func(*args, **kwargs)
  File "scratch_625.py", line 21, in evaluate
    raise OverflowError("foo")
OverflowError: foo

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "scratch_625.py", line 26, in <module>
    print(evaluate(5, 7))
  File "scratch_625.py", line 11, in wrapper
    raise response from e
ValueError: Result is too big!
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading