In [19]:
class ShouldHaveFailed(Exception):
    pass

class IncorrectException(Exception):
    pass

class ExpectFailure:
    def __init__(self, err):
        self.err = err

    def __enter__(self):
        return self.err

    def __exit__(self, exc_type, exc_value, traceback):
        if isinstance(exc_value, self.err):
            print('The correct error was raised')
            return True
        elif isinstance(exc_value, Exception):
            raise IncorrectException('Incorrect exception occurred.')
        raise ShouldHaveFailed('This should have failed!!!')

with ExpectFailure(NameError):
    foo
The correct error was raised
In [20]:
with ExpectFailure(ValueError):
    print('nice')
nice
---------------------------------------------------------------------------
ShouldHaveFailed                          Traceback (most recent call last)
Cell In [20], line 1
----> 1 with ExpectFailure(ValueError):
      2     print('nice')

Cell In [19], line 20, in ExpectFailure.__exit__(self, exc_type, exc_value, traceback)
     18 elif isinstance(exc_value, Exception):
     19     raise IncorrectException('Incorrect exception occurred.')
---> 20 raise ShouldHaveFailed('This should have failed!!!')

ShouldHaveFailed: This should have failed!!!
In [ ]:
with ExpectFailure(Exception):
    asdf
In [ ]:
!jupyter nbconvert --to html *.ipynb --output-dir="../../../static/notebooks"