with1.py 1.6 KB

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