Mercurial > repos > guerler > hhblits
comparison lib/python3.8/site-packages/pip/_vendor/contextlib2.py @ 0:9e54283cc701 draft
"planemo upload commit d12c32a45bcd441307e632fca6d9af7d60289d44"
| author | guerler |
|---|---|
| date | Mon, 27 Jul 2020 03:47:31 -0400 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:9e54283cc701 |
|---|---|
| 1 """contextlib2 - backports and enhancements to the contextlib module""" | |
| 2 | |
| 3 import abc | |
| 4 import sys | |
| 5 import warnings | |
| 6 from collections import deque | |
| 7 from functools import wraps | |
| 8 | |
| 9 __all__ = ["contextmanager", "closing", "nullcontext", | |
| 10 "AbstractContextManager", | |
| 11 "ContextDecorator", "ExitStack", | |
| 12 "redirect_stdout", "redirect_stderr", "suppress"] | |
| 13 | |
| 14 # Backwards compatibility | |
| 15 __all__ += ["ContextStack"] | |
| 16 | |
| 17 | |
| 18 # Backport abc.ABC | |
| 19 if sys.version_info[:2] >= (3, 4): | |
| 20 _abc_ABC = abc.ABC | |
| 21 else: | |
| 22 _abc_ABC = abc.ABCMeta('ABC', (object,), {'__slots__': ()}) | |
| 23 | |
| 24 | |
| 25 # Backport classic class MRO | |
| 26 def _classic_mro(C, result): | |
| 27 if C in result: | |
| 28 return | |
| 29 result.append(C) | |
| 30 for B in C.__bases__: | |
| 31 _classic_mro(B, result) | |
| 32 return result | |
| 33 | |
| 34 | |
| 35 # Backport _collections_abc._check_methods | |
| 36 def _check_methods(C, *methods): | |
| 37 try: | |
| 38 mro = C.__mro__ | |
| 39 except AttributeError: | |
| 40 mro = tuple(_classic_mro(C, [])) | |
| 41 | |
| 42 for method in methods: | |
| 43 for B in mro: | |
| 44 if method in B.__dict__: | |
| 45 if B.__dict__[method] is None: | |
| 46 return NotImplemented | |
| 47 break | |
| 48 else: | |
| 49 return NotImplemented | |
| 50 return True | |
| 51 | |
| 52 | |
| 53 class AbstractContextManager(_abc_ABC): | |
| 54 """An abstract base class for context managers.""" | |
| 55 | |
| 56 def __enter__(self): | |
| 57 """Return `self` upon entering the runtime context.""" | |
| 58 return self | |
| 59 | |
| 60 @abc.abstractmethod | |
| 61 def __exit__(self, exc_type, exc_value, traceback): | |
| 62 """Raise any exception triggered within the runtime context.""" | |
| 63 return None | |
| 64 | |
| 65 @classmethod | |
| 66 def __subclasshook__(cls, C): | |
| 67 """Check whether subclass is considered a subclass of this ABC.""" | |
| 68 if cls is AbstractContextManager: | |
| 69 return _check_methods(C, "__enter__", "__exit__") | |
| 70 return NotImplemented | |
| 71 | |
| 72 | |
| 73 class ContextDecorator(object): | |
| 74 """A base class or mixin that enables context managers to work as decorators.""" | |
| 75 | |
| 76 def refresh_cm(self): | |
| 77 """Returns the context manager used to actually wrap the call to the | |
| 78 decorated function. | |
| 79 | |
| 80 The default implementation just returns *self*. | |
| 81 | |
| 82 Overriding this method allows otherwise one-shot context managers | |
| 83 like _GeneratorContextManager to support use as decorators via | |
| 84 implicit recreation. | |
| 85 | |
| 86 DEPRECATED: refresh_cm was never added to the standard library's | |
| 87 ContextDecorator API | |
| 88 """ | |
| 89 warnings.warn("refresh_cm was never added to the standard library", | |
| 90 DeprecationWarning) | |
| 91 return self._recreate_cm() | |
| 92 | |
| 93 def _recreate_cm(self): | |
| 94 """Return a recreated instance of self. | |
| 95 | |
| 96 Allows an otherwise one-shot context manager like | |
| 97 _GeneratorContextManager to support use as | |
| 98 a decorator via implicit recreation. | |
| 99 | |
| 100 This is a private interface just for _GeneratorContextManager. | |
| 101 See issue #11647 for details. | |
| 102 """ | |
| 103 return self | |
| 104 | |
| 105 def __call__(self, func): | |
| 106 @wraps(func) | |
| 107 def inner(*args, **kwds): | |
| 108 with self._recreate_cm(): | |
| 109 return func(*args, **kwds) | |
| 110 return inner | |
| 111 | |
| 112 | |
| 113 class _GeneratorContextManager(ContextDecorator): | |
| 114 """Helper for @contextmanager decorator.""" | |
| 115 | |
| 116 def __init__(self, func, args, kwds): | |
| 117 self.gen = func(*args, **kwds) | |
| 118 self.func, self.args, self.kwds = func, args, kwds | |
| 119 # Issue 19330: ensure context manager instances have good docstrings | |
| 120 doc = getattr(func, "__doc__", None) | |
| 121 if doc is None: | |
| 122 doc = type(self).__doc__ | |
| 123 self.__doc__ = doc | |
| 124 # Unfortunately, this still doesn't provide good help output when | |
| 125 # inspecting the created context manager instances, since pydoc | |
| 126 # currently bypasses the instance docstring and shows the docstring | |
| 127 # for the class instead. | |
| 128 # See http://bugs.python.org/issue19404 for more details. | |
| 129 | |
| 130 def _recreate_cm(self): | |
| 131 # _GCM instances are one-shot context managers, so the | |
| 132 # CM must be recreated each time a decorated function is | |
| 133 # called | |
| 134 return self.__class__(self.func, self.args, self.kwds) | |
| 135 | |
| 136 def __enter__(self): | |
| 137 try: | |
| 138 return next(self.gen) | |
| 139 except StopIteration: | |
| 140 raise RuntimeError("generator didn't yield") | |
| 141 | |
| 142 def __exit__(self, type, value, traceback): | |
| 143 if type is None: | |
| 144 try: | |
| 145 next(self.gen) | |
| 146 except StopIteration: | |
| 147 return | |
| 148 else: | |
| 149 raise RuntimeError("generator didn't stop") | |
| 150 else: | |
| 151 if value is None: | |
| 152 # Need to force instantiation so we can reliably | |
| 153 # tell if we get the same exception back | |
| 154 value = type() | |
| 155 try: | |
| 156 self.gen.throw(type, value, traceback) | |
| 157 raise RuntimeError("generator didn't stop after throw()") | |
| 158 except StopIteration as exc: | |
| 159 # Suppress StopIteration *unless* it's the same exception that | |
| 160 # was passed to throw(). This prevents a StopIteration | |
| 161 # raised inside the "with" statement from being suppressed. | |
| 162 return exc is not value | |
| 163 except RuntimeError as exc: | |
| 164 # Don't re-raise the passed in exception | |
| 165 if exc is value: | |
| 166 return False | |
| 167 # Likewise, avoid suppressing if a StopIteration exception | |
| 168 # was passed to throw() and later wrapped into a RuntimeError | |
| 169 # (see PEP 479). | |
| 170 if _HAVE_EXCEPTION_CHAINING and exc.__cause__ is value: | |
| 171 return False | |
| 172 raise | |
| 173 except: | |
| 174 # only re-raise if it's *not* the exception that was | |
| 175 # passed to throw(), because __exit__() must not raise | |
| 176 # an exception unless __exit__() itself failed. But throw() | |
| 177 # has to raise the exception to signal propagation, so this | |
| 178 # fixes the impedance mismatch between the throw() protocol | |
| 179 # and the __exit__() protocol. | |
| 180 # | |
| 181 if sys.exc_info()[1] is not value: | |
| 182 raise | |
| 183 | |
| 184 | |
| 185 def contextmanager(func): | |
| 186 """@contextmanager decorator. | |
| 187 | |
| 188 Typical usage: | |
| 189 | |
| 190 @contextmanager | |
| 191 def some_generator(<arguments>): | |
| 192 <setup> | |
| 193 try: | |
| 194 yield <value> | |
| 195 finally: | |
| 196 <cleanup> | |
| 197 | |
| 198 This makes this: | |
| 199 | |
| 200 with some_generator(<arguments>) as <variable>: | |
| 201 <body> | |
| 202 | |
| 203 equivalent to this: | |
| 204 | |
| 205 <setup> | |
| 206 try: | |
| 207 <variable> = <value> | |
| 208 <body> | |
| 209 finally: | |
| 210 <cleanup> | |
| 211 | |
| 212 """ | |
| 213 @wraps(func) | |
| 214 def helper(*args, **kwds): | |
| 215 return _GeneratorContextManager(func, args, kwds) | |
| 216 return helper | |
| 217 | |
| 218 | |
| 219 class closing(object): | |
| 220 """Context to automatically close something at the end of a block. | |
| 221 | |
| 222 Code like this: | |
| 223 | |
| 224 with closing(<module>.open(<arguments>)) as f: | |
| 225 <block> | |
| 226 | |
| 227 is equivalent to this: | |
| 228 | |
| 229 f = <module>.open(<arguments>) | |
| 230 try: | |
| 231 <block> | |
| 232 finally: | |
| 233 f.close() | |
| 234 | |
| 235 """ | |
| 236 def __init__(self, thing): | |
| 237 self.thing = thing | |
| 238 | |
| 239 def __enter__(self): | |
| 240 return self.thing | |
| 241 | |
| 242 def __exit__(self, *exc_info): | |
| 243 self.thing.close() | |
| 244 | |
| 245 | |
| 246 class _RedirectStream(object): | |
| 247 | |
| 248 _stream = None | |
| 249 | |
| 250 def __init__(self, new_target): | |
| 251 self._new_target = new_target | |
| 252 # We use a list of old targets to make this CM re-entrant | |
| 253 self._old_targets = [] | |
| 254 | |
| 255 def __enter__(self): | |
| 256 self._old_targets.append(getattr(sys, self._stream)) | |
| 257 setattr(sys, self._stream, self._new_target) | |
| 258 return self._new_target | |
| 259 | |
| 260 def __exit__(self, exctype, excinst, exctb): | |
| 261 setattr(sys, self._stream, self._old_targets.pop()) | |
| 262 | |
| 263 | |
| 264 class redirect_stdout(_RedirectStream): | |
| 265 """Context manager for temporarily redirecting stdout to another file. | |
| 266 | |
| 267 # How to send help() to stderr | |
| 268 with redirect_stdout(sys.stderr): | |
| 269 help(dir) | |
| 270 | |
| 271 # How to write help() to a file | |
| 272 with open('help.txt', 'w') as f: | |
| 273 with redirect_stdout(f): | |
| 274 help(pow) | |
| 275 """ | |
| 276 | |
| 277 _stream = "stdout" | |
| 278 | |
| 279 | |
| 280 class redirect_stderr(_RedirectStream): | |
| 281 """Context manager for temporarily redirecting stderr to another file.""" | |
| 282 | |
| 283 _stream = "stderr" | |
| 284 | |
| 285 | |
| 286 class suppress(object): | |
| 287 """Context manager to suppress specified exceptions | |
| 288 | |
| 289 After the exception is suppressed, execution proceeds with the next | |
| 290 statement following the with statement. | |
| 291 | |
| 292 with suppress(FileNotFoundError): | |
| 293 os.remove(somefile) | |
| 294 # Execution still resumes here if the file was already removed | |
| 295 """ | |
| 296 | |
| 297 def __init__(self, *exceptions): | |
| 298 self._exceptions = exceptions | |
| 299 | |
| 300 def __enter__(self): | |
| 301 pass | |
| 302 | |
| 303 def __exit__(self, exctype, excinst, exctb): | |
| 304 # Unlike isinstance and issubclass, CPython exception handling | |
| 305 # currently only looks at the concrete type hierarchy (ignoring | |
| 306 # the instance and subclass checking hooks). While Guido considers | |
| 307 # that a bug rather than a feature, it's a fairly hard one to fix | |
| 308 # due to various internal implementation details. suppress provides | |
| 309 # the simpler issubclass based semantics, rather than trying to | |
| 310 # exactly reproduce the limitations of the CPython interpreter. | |
| 311 # | |
| 312 # See http://bugs.python.org/issue12029 for more details | |
| 313 return exctype is not None and issubclass(exctype, self._exceptions) | |
| 314 | |
| 315 | |
| 316 # Context manipulation is Python 3 only | |
| 317 _HAVE_EXCEPTION_CHAINING = sys.version_info[0] >= 3 | |
| 318 if _HAVE_EXCEPTION_CHAINING: | |
| 319 def _make_context_fixer(frame_exc): | |
| 320 def _fix_exception_context(new_exc, old_exc): | |
| 321 # Context may not be correct, so find the end of the chain | |
| 322 while 1: | |
| 323 exc_context = new_exc.__context__ | |
| 324 if exc_context is old_exc: | |
| 325 # Context is already set correctly (see issue 20317) | |
| 326 return | |
| 327 if exc_context is None or exc_context is frame_exc: | |
| 328 break | |
| 329 new_exc = exc_context | |
| 330 # Change the end of the chain to point to the exception | |
| 331 # we expect it to reference | |
| 332 new_exc.__context__ = old_exc | |
| 333 return _fix_exception_context | |
| 334 | |
| 335 def _reraise_with_existing_context(exc_details): | |
| 336 try: | |
| 337 # bare "raise exc_details[1]" replaces our carefully | |
| 338 # set-up context | |
| 339 fixed_ctx = exc_details[1].__context__ | |
| 340 raise exc_details[1] | |
| 341 except BaseException: | |
| 342 exc_details[1].__context__ = fixed_ctx | |
| 343 raise | |
| 344 else: | |
| 345 # No exception context in Python 2 | |
| 346 def _make_context_fixer(frame_exc): | |
| 347 return lambda new_exc, old_exc: None | |
| 348 | |
| 349 # Use 3 argument raise in Python 2, | |
| 350 # but use exec to avoid SyntaxError in Python 3 | |
| 351 def _reraise_with_existing_context(exc_details): | |
| 352 exc_type, exc_value, exc_tb = exc_details | |
| 353 exec("raise exc_type, exc_value, exc_tb") | |
| 354 | |
| 355 # Handle old-style classes if they exist | |
| 356 try: | |
| 357 from types import InstanceType | |
| 358 except ImportError: | |
| 359 # Python 3 doesn't have old-style classes | |
| 360 _get_type = type | |
| 361 else: | |
| 362 # Need to handle old-style context managers on Python 2 | |
| 363 def _get_type(obj): | |
| 364 obj_type = type(obj) | |
| 365 if obj_type is InstanceType: | |
| 366 return obj.__class__ # Old-style class | |
| 367 return obj_type # New-style class | |
| 368 | |
| 369 | |
| 370 # Inspired by discussions on http://bugs.python.org/issue13585 | |
| 371 class ExitStack(object): | |
| 372 """Context manager for dynamic management of a stack of exit callbacks | |
| 373 | |
| 374 For example: | |
| 375 | |
| 376 with ExitStack() as stack: | |
| 377 files = [stack.enter_context(open(fname)) for fname in filenames] | |
| 378 # All opened files will automatically be closed at the end of | |
| 379 # the with statement, even if attempts to open files later | |
| 380 # in the list raise an exception | |
| 381 | |
| 382 """ | |
| 383 def __init__(self): | |
| 384 self._exit_callbacks = deque() | |
| 385 | |
| 386 def pop_all(self): | |
| 387 """Preserve the context stack by transferring it to a new instance""" | |
| 388 new_stack = type(self)() | |
| 389 new_stack._exit_callbacks = self._exit_callbacks | |
| 390 self._exit_callbacks = deque() | |
| 391 return new_stack | |
| 392 | |
| 393 def _push_cm_exit(self, cm, cm_exit): | |
| 394 """Helper to correctly register callbacks to __exit__ methods""" | |
| 395 def _exit_wrapper(*exc_details): | |
| 396 return cm_exit(cm, *exc_details) | |
| 397 _exit_wrapper.__self__ = cm | |
| 398 self.push(_exit_wrapper) | |
| 399 | |
| 400 def push(self, exit): | |
| 401 """Registers a callback with the standard __exit__ method signature | |
| 402 | |
| 403 Can suppress exceptions the same way __exit__ methods can. | |
| 404 | |
| 405 Also accepts any object with an __exit__ method (registering a call | |
| 406 to the method instead of the object itself) | |
| 407 """ | |
| 408 # We use an unbound method rather than a bound method to follow | |
| 409 # the standard lookup behaviour for special methods | |
| 410 _cb_type = _get_type(exit) | |
| 411 try: | |
| 412 exit_method = _cb_type.__exit__ | |
| 413 except AttributeError: | |
| 414 # Not a context manager, so assume its a callable | |
| 415 self._exit_callbacks.append(exit) | |
| 416 else: | |
| 417 self._push_cm_exit(exit, exit_method) | |
| 418 return exit # Allow use as a decorator | |
| 419 | |
| 420 def callback(self, callback, *args, **kwds): | |
| 421 """Registers an arbitrary callback and arguments. | |
| 422 | |
| 423 Cannot suppress exceptions. | |
| 424 """ | |
| 425 def _exit_wrapper(exc_type, exc, tb): | |
| 426 callback(*args, **kwds) | |
| 427 # We changed the signature, so using @wraps is not appropriate, but | |
| 428 # setting __wrapped__ may still help with introspection | |
| 429 _exit_wrapper.__wrapped__ = callback | |
| 430 self.push(_exit_wrapper) | |
| 431 return callback # Allow use as a decorator | |
| 432 | |
| 433 def enter_context(self, cm): | |
| 434 """Enters the supplied context manager | |
| 435 | |
| 436 If successful, also pushes its __exit__ method as a callback and | |
| 437 returns the result of the __enter__ method. | |
| 438 """ | |
| 439 # We look up the special methods on the type to match the with statement | |
| 440 _cm_type = _get_type(cm) | |
| 441 _exit = _cm_type.__exit__ | |
| 442 result = _cm_type.__enter__(cm) | |
| 443 self._push_cm_exit(cm, _exit) | |
| 444 return result | |
| 445 | |
| 446 def close(self): | |
| 447 """Immediately unwind the context stack""" | |
| 448 self.__exit__(None, None, None) | |
| 449 | |
| 450 def __enter__(self): | |
| 451 return self | |
| 452 | |
| 453 def __exit__(self, *exc_details): | |
| 454 received_exc = exc_details[0] is not None | |
| 455 | |
| 456 # We manipulate the exception state so it behaves as though | |
| 457 # we were actually nesting multiple with statements | |
| 458 frame_exc = sys.exc_info()[1] | |
| 459 _fix_exception_context = _make_context_fixer(frame_exc) | |
| 460 | |
| 461 # Callbacks are invoked in LIFO order to match the behaviour of | |
| 462 # nested context managers | |
| 463 suppressed_exc = False | |
| 464 pending_raise = False | |
| 465 while self._exit_callbacks: | |
| 466 cb = self._exit_callbacks.pop() | |
| 467 try: | |
| 468 if cb(*exc_details): | |
| 469 suppressed_exc = True | |
| 470 pending_raise = False | |
| 471 exc_details = (None, None, None) | |
| 472 except: | |
| 473 new_exc_details = sys.exc_info() | |
| 474 # simulate the stack of exceptions by setting the context | |
| 475 _fix_exception_context(new_exc_details[1], exc_details[1]) | |
| 476 pending_raise = True | |
| 477 exc_details = new_exc_details | |
| 478 if pending_raise: | |
| 479 _reraise_with_existing_context(exc_details) | |
| 480 return received_exc and suppressed_exc | |
| 481 | |
| 482 | |
| 483 # Preserve backwards compatibility | |
| 484 class ContextStack(ExitStack): | |
| 485 """Backwards compatibility alias for ExitStack""" | |
| 486 | |
| 487 def __init__(self): | |
| 488 warnings.warn("ContextStack has been renamed to ExitStack", | |
| 489 DeprecationWarning) | |
| 490 super(ContextStack, self).__init__() | |
| 491 | |
| 492 def register_exit(self, callback): | |
| 493 return self.push(callback) | |
| 494 | |
| 495 def register(self, callback, *args, **kwds): | |
| 496 return self.callback(callback, *args, **kwds) | |
| 497 | |
| 498 def preserve(self): | |
| 499 return self.pop_all() | |
| 500 | |
| 501 | |
| 502 class nullcontext(AbstractContextManager): | |
| 503 """Context manager that does no additional processing. | |
| 504 Used as a stand-in for a normal context manager, when a particular | |
| 505 block of code is only sometimes used with a normal context manager: | |
| 506 cm = optional_cm if condition else nullcontext() | |
| 507 with cm: | |
| 508 # Perform operation, using optional_cm if condition is True | |
| 509 """ | |
| 510 | |
| 511 def __init__(self, enter_result=None): | |
| 512 self.enter_result = enter_result | |
| 513 | |
| 514 def __enter__(self): | |
| 515 return self.enter_result | |
| 516 | |
| 517 def __exit__(self, *excinfo): | |
| 518 pass |
