1class CtxMgr: 2 3 def __enter__(self): 4 print("__enter__") 5 return self 6 7 def __exit__(self, a, b, c): 8 print("__exit__", repr(a), repr(b)) 9 10 11with CtxMgr() as a: 12 print(isinstance(a, CtxMgr)) 13 14try: 15 with CtxMgr() as a: 16 raise ValueError 17except ValueError: 18 print("ValueError") 19 20 21class CtxMgr2: 22 23 def __enter__(self): 24 print("__enter__") 25 return self 26 27 def __exit__(self, a, b, c): 28 print("__exit__", repr(a), repr(b)) 29 return True 30 31try: 32 with CtxMgr2() as a: 33 raise ValueError 34 print("No ValueError2") 35except ValueError: 36 print("ValueError2") 37 38 39# These recursive try-finally tests are attempt to get some interpretation 40# of last phrase in http://docs.python.org/3.4/library/dis.html#opcode-WITH_CLEANUP 41# "If the stack represents an exception, and the function call returns a 'true' 42# value, this information is "zapped" and replaced with a single WHY_SILENCED 43# to prevent END_FINALLY from re-raising the exception. (But non-local gotos 44# will still be resumed.)" 45print("===") 46with CtxMgr2() as a: 47 try: 48 try: 49 raise ValueError 50 print("No ValueError3") 51 finally: 52 print("finally1") 53 finally: 54 print("finally2") 55 56print("===") 57try: 58 try: 59 with CtxMgr2() as a: 60 try: 61 try: 62 raise ValueError 63 print("No ValueError3") 64 finally: 65 print("finally1") 66 finally: 67 print("finally2") 68 finally: 69 print("finally3") 70finally: 71 print("finally4") 72