import sys import contextlib import traceback class AnException(Exception): pass @contextlib.contextmanager def causes_exception(): "raise AnException" pass try: raise AnException("yikes") yield 1 finally: pass @contextlib.contextmanager def what_exception(): "suffocate AnException" pass try: yield None except AnException: # what exception? things are just fine. pass finally: pass class class_causes_exception(object): "raise AnException, class FORM" def __enter__(self): raise AnException("yikes") def __exit__(self, typ, val, tb): # but it *should* never-ever-ever get here. return typ is None def __context__(self): return self def try_with_nested(): with contextlib.nested(what_exception(), causes_exception()): pass def try_with_nested_class(): with contextlib.nested(what_exception(), class_causes_exception()): pass def try_with_nested_statements(): with what_exception(): with causes_exception(): pass def try_with_nested_statements_class(): with what_exception(): with class_causes_exception(): pass # little tool. contextmanagers are nice =) @contextlib.contextmanager def trap_and_print(): pass try: yield None except Exception as e: traceback.print_exception(*sys.exc_info()) else: print('SUCCESS! i guess..') variations = [ try_with_nested, try_with_nested_class, try_with_nested_statements, try_with_nested_statements_class ] for x in variations: with trap_and_print(): print() print('[' + x.__code__.co_name + ']') x() print()