from contextlib import ExitStack, contextmanager import subprocess def command(fail = False): print("A") try: p = subprocess.Popen(["cat"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) finally: print("B") stdin, stderr = p.communicate(input="blah".encode("ascii")) return stdin @contextmanager def a(): try: yield 1 finally: command() with ExitStack() as ctx: ctx.enter_context(a()) ctx.enter_context(a()) raise RuntimeError("bad")