contextlib.py (2192B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\contextlib.py 2 import sys 3 from functools import wraps 4 from warnings import warn 5 __all__ = ['contextmanager', 'nested', 'closing'] 6 7 class GeneratorContextManager(object): 8 9 def __init__(self, gen): 10 self.gen = gen 11 12 def __enter__(self): 13 try: 14 return self.gen.next() 15 except StopIteration: 16 raise RuntimeError("generator didn't yield") 17 18 def __exit__(self, type, value, traceback): 19 if type is None: 20 try: 21 self.gen.next() 22 except StopIteration: 23 return 24 25 raise RuntimeError("generator didn't stop") 26 else: 27 if value is None: 28 value = type() 29 try: 30 self.gen.throw(type, value, traceback) 31 raise RuntimeError("generator didn't stop after throw()") 32 except StopIteration as exc: 33 return exc is not value 34 except: 35 if sys.exc_info()[1] is not value: 36 raise 37 38 39 def contextmanager(func): 40 41 @wraps(func) 42 def helper(*args, **kwds): 43 return GeneratorContextManager(func(*args, **kwds)) 44 45 return helper 46 47 48 @contextmanager 49 def nested(*managers): 50 warn('With-statements now directly support multiple context managers', DeprecationWarning, 3) 51 exits = [] 52 vars = [] 53 exc = (None, None, None) 54 try: 55 for mgr in managers: 56 exit = mgr.__exit__ 57 enter = mgr.__enter__ 58 vars.append(enter()) 59 exits.append(exit) 60 61 yield vars 62 except: 63 exc = sys.exc_info() 64 finally: 65 while exits: 66 exit = exits.pop() 67 try: 68 if exit(*exc): 69 exc = (None, None, None) 70 except: 71 exc = sys.exc_info() 72 73 if exc != (None, None, None): 74 raise exc[0], exc[1], exc[2] 75 76 77 class closing(object): 78 79 def __init__(self, thing): 80 self.thing = thing 81 82 def __enter__(self): 83 return self.thing 84 85 def __exit__(self, *exc_info): 86 self.thing.close()