1import sys 2 3 4def typename(t): 5 name = type(t).__name__ 6 if sys.version_info < (2,5): 7 if name == 'classobj' and issubclass(t, MyException): 8 name = 'type' 9 elif name == 'instance' and isinstance(t, MyException): 10 name = 'MyException' 11 return "<type '%s'>" % name 12 13 14class MyException(Exception): 15 pass 16 17 18class ContextManager(object): 19 def __init__(self, value, exit_ret = None): 20 self.value = value 21 self.exit_ret = exit_ret 22 23 def __exit__(self, a, b, tb): 24 print("exit %s %s %s" % (typename(a), typename(b), typename(tb))) 25 return self.exit_ret 26 27 def __enter__(self): 28 print("enter") 29 return self.value 30 31 32def no_as(): 33 """ 34 >>> no_as() 35 enter 36 hello 37 exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'> 38 """ 39 with ContextManager("value"): 40 print("hello") 41 42 43def basic(): 44 """ 45 >>> basic() 46 enter 47 value 48 exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'> 49 """ 50 with ContextManager("value") as x: 51 print(x) 52 53 54def with_pass(): 55 """ 56 >>> with_pass() 57 enter 58 exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'> 59 """ 60 with ContextManager("value") as x: 61 pass 62 63 64def with_return(): 65 """ 66 >>> print(with_return()) 67 enter 68 exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'> 69 value 70 """ 71 with ContextManager("value") as x: 72 return x 73 74 75def with_break(): 76 """ 77 >>> print(with_break()) 78 enter 79 exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'> 80 a 81 """ 82 for c in list("abc"): 83 with ContextManager("value") as x: 84 break 85 print("FAILED") 86 return c 87 88 89def with_continue(): 90 """ 91 >>> print(with_continue()) 92 enter 93 exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'> 94 enter 95 exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'> 96 enter 97 exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'> 98 c 99 """ 100 for c in list("abc"): 101 with ContextManager("value") as x: 102 continue 103 print("FAILED") 104 return c 105 106 107def with_exception(exit_ret): 108 """ 109 >>> with_exception(None) 110 enter 111 value 112 exit <type 'type'> <type 'MyException'> <type 'traceback'> 113 outer except 114 >>> with_exception(True) 115 enter 116 value 117 exit <type 'type'> <type 'MyException'> <type 'traceback'> 118 """ 119 try: 120 with ContextManager("value", exit_ret=exit_ret) as value: 121 print(value) 122 raise MyException() 123 except: 124 print("outer except") 125 126 127def with_real_lock(): 128 """ 129 >>> with_real_lock() 130 about to acquire lock 131 holding lock 132 lock no longer held 133 """ 134 from threading import Lock 135 lock = Lock() 136 137 print("about to acquire lock") 138 139 with lock: 140 print("holding lock") 141 142 print("lock no longer held") 143 144 145def functions_in_with(): 146 """ 147 >>> f = functions_in_with() 148 enter 149 exit <type 'type'> <type 'MyException'> <type 'traceback'> 150 outer except 151 >>> f(1)[0] 152 1 153 >>> print(f(1)[1]) 154 value 155 """ 156 try: 157 with ContextManager("value") as value: 158 def f(x): return x, value 159 make = lambda x:x() 160 raise make(MyException) 161 except: 162 print("outer except") 163 return f 164 165 166def multitarget(): 167 """ 168 >>> multitarget() 169 enter 170 1 2 3 4 5 171 exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'> 172 """ 173 with ContextManager((1, 2, (3, (4, 5)))) as (a, b, (c, (d, e))): 174 print('%s %s %s %s %s' % (a, b, c, d, e)) 175 176 177def tupletarget(): 178 """ 179 >>> tupletarget() 180 enter 181 (1, 2, (3, (4, 5))) 182 exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'> 183 """ 184 with ContextManager((1, 2, (3, (4, 5)))) as t: 185 print(t) 186 187 188class GetManager(object): 189 def get(self, *args): 190 return ContextManager(*args) 191 192 193def manager_from_expression(): 194 """ 195 >>> manager_from_expression() 196 enter 197 1 198 exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'> 199 enter 200 2 201 exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'> 202 """ 203 with GetManager().get(1) as x: 204 print(x) 205 g = GetManager() 206 with g.get(2) as x: 207 print(x) 208