__init__.py (7288B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\contextlib2\__init__.py 2 import sys 3 import warnings 4 from collections import deque 5 from functools import wraps 6 __all__ = ['contextmanager', 7 'closing', 8 'ContextDecorator', 9 'ExitStack', 10 'redirect_stdout', 11 'redirect_stderr', 12 'suppress'] 13 __all__ += ['ContextStack'] 14 15 class ContextDecorator(object): 16 17 def refresh_cm(self): 18 warnings.warn('refresh_cm was never added to the standard library', DeprecationWarning) 19 return self._recreate_cm() 20 21 def _recreate_cm(self): 22 return self 23 24 def __call__(self, func): 25 26 @wraps(func) 27 def inner(*args, **kwds): 28 with self._recreate_cm(): 29 return func(*args, **kwds) 30 31 return inner 32 33 34 class _GeneratorContextManager(ContextDecorator): 35 36 def __init__(self, func, args, kwds): 37 self.gen = func(*args, **kwds) 38 self.func, self.args, self.kwds = func, args, kwds 39 doc = getattr(func, '__doc__', None) 40 if doc is None: 41 doc = type(self).__doc__ 42 self.__doc__ = doc 43 44 def _recreate_cm(self): 45 return self.__class__(self.func, self.args, self.kwds) 46 47 def __enter__(self): 48 try: 49 return next(self.gen) 50 except StopIteration: 51 raise RuntimeError("generator didn't yield") 52 53 def __exit__(self, type, value, traceback): 54 if type is None: 55 try: 56 next(self.gen) 57 except StopIteration: 58 return 59 60 raise RuntimeError("generator didn't stop") 61 else: 62 if value is None: 63 value = type() 64 try: 65 self.gen.throw(type, value, traceback) 66 raise RuntimeError("generator didn't stop after throw()") 67 except StopIteration as exc: 68 return exc is not value 69 except RuntimeError as exc: 70 if exc is value: 71 return False 72 if _HAVE_EXCEPTION_CHAINING and exc.__cause__ is value: 73 return False 74 raise 75 except: 76 if sys.exc_info()[1] is not value: 77 raise 78 79 80 def contextmanager(func): 81 82 @wraps(func) 83 def helper(*args, **kwds): 84 return _GeneratorContextManager(func, args, kwds) 85 86 return helper 87 88 89 class closing(object): 90 91 def __init__(self, thing): 92 self.thing = thing 93 94 def __enter__(self): 95 return self.thing 96 97 def __exit__(self, *exc_info): 98 self.thing.close() 99 100 101 class _RedirectStream(object): 102 _stream = None 103 104 def __init__(self, new_target): 105 self._new_target = new_target 106 self._old_targets = [] 107 108 def __enter__(self): 109 self._old_targets.append(getattr(sys, self._stream)) 110 setattr(sys, self._stream, self._new_target) 111 return self._new_target 112 113 def __exit__(self, exctype, excinst, exctb): 114 setattr(sys, self._stream, self._old_targets.pop()) 115 116 117 class redirect_stdout(_RedirectStream): 118 _stream = 'stdout' 119 120 121 class redirect_stderr(_RedirectStream): 122 _stream = 'stderr' 123 124 125 class suppress(object): 126 127 def __init__(self, *exceptions): 128 self._exceptions = exceptions 129 130 def __enter__(self): 131 pass 132 133 def __exit__(self, exctype, excinst, exctb): 134 return exctype is not None and issubclass(exctype, self._exceptions) 135 136 137 _HAVE_EXCEPTION_CHAINING = sys.version_info[0] >= 3 138 if _HAVE_EXCEPTION_CHAINING: 139 140 def _make_context_fixer(frame_exc): 141 142 def _fix_exception_context(new_exc, old_exc): 143 while 1: 144 exc_context = new_exc.__context__ 145 if exc_context is old_exc: 146 return 147 if exc_context is None or exc_context is frame_exc: 148 break 149 new_exc = exc_context 150 151 new_exc.__context__ = old_exc 152 153 return _fix_exception_context 154 155 156 def _reraise_with_existing_context(exc_details): 157 try: 158 fixed_ctx = exc_details[1].__context__ 159 raise exc_details[1] 160 except BaseException: 161 exc_details[1].__context__ = fixed_ctx 162 raise 163 164 165 else: 166 167 def _make_context_fixer(frame_exc): 168 return lambda new_exc, old_exc: None 169 170 171 def _reraise_with_existing_context(exc_details): 172 exc_type, exc_value, exc_tb = exc_details 173 exec 'raise exc_type, exc_value, exc_tb' 174 175 176 try: 177 from types import InstanceType 178 except ImportError: 179 _get_type = type 180 else: 181 182 def _get_type(obj): 183 obj_type = type(obj) 184 if obj_type is InstanceType: 185 return obj.__class__ 186 return obj_type 187 188 189 class ExitStack(object): 190 191 def __init__(self): 192 self._exit_callbacks = deque() 193 194 def pop_all(self): 195 new_stack = type(self)() 196 new_stack._exit_callbacks = self._exit_callbacks 197 self._exit_callbacks = deque() 198 return new_stack 199 200 def _push_cm_exit(self, cm, cm_exit): 201 202 def _exit_wrapper(*exc_details): 203 return cm_exit(cm, *exc_details) 204 205 _exit_wrapper.__self__ = cm 206 self.push(_exit_wrapper) 207 208 def push(self, exit): 209 _cb_type = _get_type(exit) 210 try: 211 exit_method = _cb_type.__exit__ 212 except AttributeError: 213 self._exit_callbacks.append(exit) 214 else: 215 self._push_cm_exit(exit, exit_method) 216 217 return exit 218 219 def callback(self, callback, *args, **kwds): 220 221 def _exit_wrapper(exc_type, exc, tb): 222 callback(*args, **kwds) 223 224 _exit_wrapper.__wrapped__ = callback 225 self.push(_exit_wrapper) 226 return callback 227 228 def enter_context(self, cm): 229 _cm_type = _get_type(cm) 230 _exit = _cm_type.__exit__ 231 result = _cm_type.__enter__(cm) 232 self._push_cm_exit(cm, _exit) 233 return result 234 235 def close(self): 236 self.__exit__(None, None, None) 237 238 def __enter__(self): 239 return self 240 241 def __exit__(self, *exc_details): 242 received_exc = exc_details[0] is not None 243 frame_exc = sys.exc_info()[1] 244 _fix_exception_context = _make_context_fixer(frame_exc) 245 suppressed_exc = False 246 pending_raise = False 247 while self._exit_callbacks: 248 cb = self._exit_callbacks.pop() 249 try: 250 if cb(*exc_details): 251 suppressed_exc = True 252 pending_raise = False 253 exc_details = (None, None, None) 254 except: 255 new_exc_details = sys.exc_info() 256 _fix_exception_context(new_exc_details[1], exc_details[1]) 257 pending_raise = True 258 exc_details = new_exc_details 259 260 if pending_raise: 261 _reraise_with_existing_context(exc_details) 262 return received_exc and suppressed_exc 263 264 265 class ContextStack(ExitStack): 266 267 def __init__(self): 268 warnings.warn('ContextStack has been renamed to ExitStack', DeprecationWarning) 269 super(ContextStack, self).__init__() 270 271 def register_exit(self, callback): 272 return self.push(callback) 273 274 def register(self, callback, *args, **kwds): 275 return self.callback(callback, *args, **kwds) 276 277 def preserve(self): 278 return self.pop_all()