0

I'm writing a context manager allowing to catch a certain type of exception.

class AssertRaises(object):
    def __init__(self, exc_type):
        self.exc_type = exc_type

    def __enter__(self):
        pass

    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_type == self.exc_type:
            raise AssertionError
        return True

This manager works fine when built-in exception raises but fails with such usage:

class MyTypeError(TypeError):
    pass


try:
    with AssertRaises(TypeError):
        raise MyTypeError()
except Exception as e:
    print(type(e).__name__)

In this example the user-defined excepton raises, but this exception is equivalent to TypeError and I want it to be processed by context manager as TypeError. I checked that `isinstance(MyTypeError(), TypeError) == True' and want

__exit__(...)

to work in the same way (to consider inheritance). Is there any solution?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Coconut
  • 3
  • 1
  • 1
    Equality can't test for subclasses no, that's what `issubclass()` is for. – Martijn Pieters May 20 '16 at 07:21
  • Note that you should not use `==` to test for classes; `issubclass(Class, Class)` will also return true (a class is deemed a subclass of itself). And don't use `== True` in tests; that is already implied. So instead of `if some_test == True:` use `if some_test:`, and the inverse is `if not some_test:`. – Martijn Pieters May 20 '16 at 07:28
  • Thank you for help. I think this is the function i was looking for/ – Coconut May 20 '16 at 07:31

1 Answers1

0

Either check the exception itself (exc_val) as you've done with isinstance(), or use issubclass():

def __exit__(self, exc_type, exc_val, exc_tb):
    if issubclass(exc_type, self.exc_type):
        raise AssertionError
    return True
Ilja Everilä
  • 50,538
  • 7
  • 126
  • 127