diff options
author | nkozlovskiy <nmk@ydb.tech> | 2023-09-29 12:24:06 +0300 |
---|---|---|
committer | nkozlovskiy <nmk@ydb.tech> | 2023-09-29 12:41:34 +0300 |
commit | e0e3e1717e3d33762ce61950504f9637a6e669ed (patch) | |
tree | bca3ff6939b10ed60c3d5c12439963a1146b9711 /contrib/python/contextlib2 | |
parent | 38f2c5852db84c7b4d83adfcb009eb61541d1ccd (diff) | |
download | ydb-e0e3e1717e3d33762ce61950504f9637a6e669ed.tar.gz |
add ydb deps
Diffstat (limited to 'contrib/python/contextlib2')
-rw-r--r-- | contrib/python/contextlib2/py2/.dist-info/METADATA | 70 | ||||
-rw-r--r-- | contrib/python/contextlib2/py2/.dist-info/top_level.txt | 1 | ||||
-rw-r--r-- | contrib/python/contextlib2/py2/LICENSE.txt | 122 | ||||
-rw-r--r-- | contrib/python/contextlib2/py2/README.rst | 48 | ||||
-rw-r--r-- | contrib/python/contextlib2/py2/contextlib2.py | 518 | ||||
-rw-r--r-- | contrib/python/contextlib2/py2/ya.make | 22 | ||||
-rw-r--r-- | contrib/python/contextlib2/py3/.dist-info/METADATA | 113 | ||||
-rw-r--r-- | contrib/python/contextlib2/py3/.dist-info/top_level.txt | 1 | ||||
-rw-r--r-- | contrib/python/contextlib2/py3/LICENSE.txt | 124 | ||||
-rw-r--r-- | contrib/python/contextlib2/py3/README.rst | 90 | ||||
-rw-r--r-- | contrib/python/contextlib2/py3/contextlib2/__init__.py | 798 | ||||
-rw-r--r-- | contrib/python/contextlib2/py3/contextlib2/py.typed | 0 | ||||
-rw-r--r-- | contrib/python/contextlib2/py3/ya.make | 24 | ||||
-rw-r--r-- | contrib/python/contextlib2/ya.make | 18 |
14 files changed, 1949 insertions, 0 deletions
diff --git a/contrib/python/contextlib2/py2/.dist-info/METADATA b/contrib/python/contextlib2/py2/.dist-info/METADATA new file mode 100644 index 0000000000..c44f02deb5 --- /dev/null +++ b/contrib/python/contextlib2/py2/.dist-info/METADATA @@ -0,0 +1,70 @@ +Metadata-Version: 2.1 +Name: contextlib2 +Version: 0.6.0.post1 +Summary: Backports and enhancements for the contextlib module +Home-page: http://contextlib2.readthedocs.org +Author: Nick Coghlan +Author-email: ncoghlan@gmail.com +License: PSF License +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: License :: OSI Approved :: Python Software Foundation License +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* + +.. image:: https://jazzband.co/static/img/badge.svg + :target: https://jazzband.co/ + :alt: Jazzband + +.. image:: https://readthedocs.org/projects/contextlib2/badge/?version=latest + :target: https://contextlib2.readthedocs.org/ + :alt: Latest Docs + +.. image:: https://img.shields.io/travis/jazzband/contextlib2/master.svg + :target: http://travis-ci.org/jazzband/contextlib2 + +.. image:: https://coveralls.io/repos/github/jazzband/contextlib2/badge.svg?branch=master + :target: https://coveralls.io/github/jazzband/contextlib2?branch=master + +.. image:: https://landscape.io/github/jazzband/contextlib2/master/landscape.svg + :target: https://landscape.io/github/jazzband/contextlib2/ + +contextlib2 is a backport of the `standard library's contextlib +module <https://docs.python.org/3.5/library/contextlib.html>`_ to +earlier Python versions. + +It also serves as a real world proving ground for possible future +enhancements to the standard library version. + +Development +----------- + +contextlib2 has no runtime dependencies, but requires ``unittest2`` for testing +on Python 2.x, as well as ``setuptools`` and ``wheel`` to generate universal +wheel archives. + +Local testing is just a matter of running ``python test_contextlib2.py``. + +You can test against multiple versions of Python with +`tox <https://tox.testrun.org/>`_:: + + pip install tox + tox + +Versions currently tested in both tox and Travis CI are: + +* CPython 2.7 +* CPython 3.4 +* CPython 3.5 +* CPython 3.6 +* CPython 3.7 +* PyPy +* PyPy3 + + diff --git a/contrib/python/contextlib2/py2/.dist-info/top_level.txt b/contrib/python/contextlib2/py2/.dist-info/top_level.txt new file mode 100644 index 0000000000..03fdf8ed24 --- /dev/null +++ b/contrib/python/contextlib2/py2/.dist-info/top_level.txt @@ -0,0 +1 @@ +contextlib2 diff --git a/contrib/python/contextlib2/py2/LICENSE.txt b/contrib/python/contextlib2/py2/LICENSE.txt new file mode 100644 index 0000000000..5de20277df --- /dev/null +++ b/contrib/python/contextlib2/py2/LICENSE.txt @@ -0,0 +1,122 @@ + + +A. HISTORY OF THE SOFTWARE +========================== + +contextlib2 is a derivative of the contextlib module distributed by the PSF +as part of the Python standard library. According, it is itself redistributed +under the PSF license (reproduced in full below). As the contextlib module +was added only in Python 2.5, the licenses for earlier Python versions are +not applicable and have not been included. + +Python was created in the early 1990s by Guido van Rossum at Stichting +Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands +as a successor of a language called ABC. Guido remains Python's +principal author, although it includes many contributions from others. + +In 1995, Guido continued his work on Python at the Corporation for +National Research Initiatives (CNRI, see http://www.cnri.reston.va.us) +in Reston, Virginia where he released several versions of the +software. + +In May 2000, Guido and the Python core development team moved to +BeOpen.com to form the BeOpen PythonLabs team. In October of the same +year, the PythonLabs team moved to Digital Creations (now Zope +Corporation, see http://www.zope.com). In 2001, the Python Software +Foundation (PSF, see http://www.python.org/psf/) was formed, a +non-profit organization created specifically to own Python-related +Intellectual Property. Zope Corporation is a sponsoring member of +the PSF. + +All Python releases are Open Source (see http://www.opensource.org for +the Open Source Definition). Historically, most, but not all, Python +releases have also been GPL-compatible; the table below summarizes +the various releases that included the contextlib module. + + Release Derived Year Owner GPL- + from compatible? (1) + + 2.5 2.4 2006 PSF yes + 2.5.1 2.5 2007 PSF yes + 2.5.2 2.5.1 2008 PSF yes + 2.5.3 2.5.2 2008 PSF yes + 2.6 2.5 2008 PSF yes + 2.6.1 2.6 2008 PSF yes + 2.6.2 2.6.1 2009 PSF yes + 2.6.3 2.6.2 2009 PSF yes + 2.6.4 2.6.3 2009 PSF yes + 2.6.5 2.6.4 2010 PSF yes + 3.0 2.6 2008 PSF yes + 3.0.1 3.0 2009 PSF yes + 3.1 3.0.1 2009 PSF yes + 3.1.1 3.1 2009 PSF yes + 3.1.2 3.1.1 2010 PSF yes + 3.1.3 3.1.2 2010 PSF yes + 3.1.4 3.1.3 2011 PSF yes + 3.2 3.1 2011 PSF yes + 3.2.1 3.2 2011 PSF yes + 3.2.2 3.2.1 2011 PSF yes + 3.3 3.2 2012 PSF yes + +Footnotes: + +(1) GPL-compatible doesn't mean that we're distributing Python under + the GPL. All Python licenses, unlike the GPL, let you distribute + a modified version without making your changes open source. The + GPL-compatible licenses make it possible to combine Python with + other software that is released under the GPL; the others don't. + +Thanks to the many outside volunteers who have worked under Guido's +direction to make these releases possible. + + +B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON +=============================================================== + +PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 +-------------------------------------------- + +1. This LICENSE AGREEMENT is between the Python Software Foundation +("PSF"), and the Individual or Organization ("Licensee") accessing and +otherwise using this software ("Python") in source or binary form and +its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, PSF hereby +grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, +analyze, test, perform and/or display publicly, prepare derivative works, +distribute, and otherwise use Python alone or in any derivative version, +provided, however, that PSF's License Agreement and PSF's notice of copyright, +i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +2011 Python Software Foundation; All Rights Reserved" are retained in Python +alone or in any derivative version prepared by Licensee. + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python. + +4. PSF is making Python available to Licensee on an "AS IS" +basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. Nothing in this License Agreement shall be deemed to create any +relationship of agency, partnership, or joint venture between PSF and +Licensee. This License Agreement does not grant permission to use PSF +trademarks or trade name in a trademark sense to endorse or promote +products or services of Licensee, or any third party. + +8. By copying, installing or otherwise using Python, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. diff --git a/contrib/python/contextlib2/py2/README.rst b/contrib/python/contextlib2/py2/README.rst new file mode 100644 index 0000000000..7fe170f1ff --- /dev/null +++ b/contrib/python/contextlib2/py2/README.rst @@ -0,0 +1,48 @@ +.. image:: https://jazzband.co/static/img/badge.svg + :target: https://jazzband.co/ + :alt: Jazzband + +.. image:: https://readthedocs.org/projects/contextlib2/badge/?version=latest + :target: https://contextlib2.readthedocs.org/ + :alt: Latest Docs + +.. image:: https://img.shields.io/travis/jazzband/contextlib2/master.svg + :target: http://travis-ci.org/jazzband/contextlib2 + +.. image:: https://coveralls.io/repos/github/jazzband/contextlib2/badge.svg?branch=master + :target: https://coveralls.io/github/jazzband/contextlib2?branch=master + +.. image:: https://landscape.io/github/jazzband/contextlib2/master/landscape.svg + :target: https://landscape.io/github/jazzband/contextlib2/ + +contextlib2 is a backport of the `standard library's contextlib +module <https://docs.python.org/3.5/library/contextlib.html>`_ to +earlier Python versions. + +It also serves as a real world proving ground for possible future +enhancements to the standard library version. + +Development +----------- + +contextlib2 has no runtime dependencies, but requires ``unittest2`` for testing +on Python 2.x, as well as ``setuptools`` and ``wheel`` to generate universal +wheel archives. + +Local testing is just a matter of running ``python test_contextlib2.py``. + +You can test against multiple versions of Python with +`tox <https://tox.testrun.org/>`_:: + + pip install tox + tox + +Versions currently tested in both tox and Travis CI are: + +* CPython 2.7 +* CPython 3.4 +* CPython 3.5 +* CPython 3.6 +* CPython 3.7 +* PyPy +* PyPy3 diff --git a/contrib/python/contextlib2/py2/contextlib2.py b/contrib/python/contextlib2/py2/contextlib2.py new file mode 100644 index 0000000000..3aae8f4117 --- /dev/null +++ b/contrib/python/contextlib2/py2/contextlib2.py @@ -0,0 +1,518 @@ +"""contextlib2 - backports and enhancements to the contextlib module""" + +import abc +import sys +import warnings +from collections import deque +from functools import wraps + +__all__ = ["contextmanager", "closing", "nullcontext", + "AbstractContextManager", + "ContextDecorator", "ExitStack", + "redirect_stdout", "redirect_stderr", "suppress"] + +# Backwards compatibility +__all__ += ["ContextStack"] + + +# Backport abc.ABC +if sys.version_info[:2] >= (3, 4): + _abc_ABC = abc.ABC +else: + _abc_ABC = abc.ABCMeta('ABC', (object,), {'__slots__': ()}) + + +# Backport classic class MRO +def _classic_mro(C, result): + if C in result: + return + result.append(C) + for B in C.__bases__: + _classic_mro(B, result) + return result + + +# Backport _collections_abc._check_methods +def _check_methods(C, *methods): + try: + mro = C.__mro__ + except AttributeError: + mro = tuple(_classic_mro(C, [])) + + for method in methods: + for B in mro: + if method in B.__dict__: + if B.__dict__[method] is None: + return NotImplemented + break + else: + return NotImplemented + return True + + +class AbstractContextManager(_abc_ABC): + """An abstract base class for context managers.""" + + def __enter__(self): + """Return `self` upon entering the runtime context.""" + return self + + @abc.abstractmethod + def __exit__(self, exc_type, exc_value, traceback): + """Raise any exception triggered within the runtime context.""" + return None + + @classmethod + def __subclasshook__(cls, C): + """Check whether subclass is considered a subclass of this ABC.""" + if cls is AbstractContextManager: + return _check_methods(C, "__enter__", "__exit__") + return NotImplemented + + +class ContextDecorator(object): + """A base class or mixin that enables context managers to work as decorators.""" + + def refresh_cm(self): + """Returns the context manager used to actually wrap the call to the + decorated function. + + The default implementation just returns *self*. + + Overriding this method allows otherwise one-shot context managers + like _GeneratorContextManager to support use as decorators via + implicit recreation. + + DEPRECATED: refresh_cm was never added to the standard library's + ContextDecorator API + """ + warnings.warn("refresh_cm was never added to the standard library", + DeprecationWarning) + return self._recreate_cm() + + def _recreate_cm(self): + """Return a recreated instance of self. + + Allows an otherwise one-shot context manager like + _GeneratorContextManager to support use as + a decorator via implicit recreation. + + This is a private interface just for _GeneratorContextManager. + See issue #11647 for details. + """ + return self + + def __call__(self, func): + @wraps(func) + def inner(*args, **kwds): + with self._recreate_cm(): + return func(*args, **kwds) + return inner + + +class _GeneratorContextManager(ContextDecorator): + """Helper for @contextmanager decorator.""" + + def __init__(self, func, args, kwds): + self.gen = func(*args, **kwds) + self.func, self.args, self.kwds = func, args, kwds + # Issue 19330: ensure context manager instances have good docstrings + doc = getattr(func, "__doc__", None) + if doc is None: + doc = type(self).__doc__ + self.__doc__ = doc + # Unfortunately, this still doesn't provide good help output when + # inspecting the created context manager instances, since pydoc + # currently bypasses the instance docstring and shows the docstring + # for the class instead. + # See http://bugs.python.org/issue19404 for more details. + + def _recreate_cm(self): + # _GCM instances are one-shot context managers, so the + # CM must be recreated each time a decorated function is + # called + return self.__class__(self.func, self.args, self.kwds) + + def __enter__(self): + try: + return next(self.gen) + except StopIteration: + raise RuntimeError("generator didn't yield") + + def __exit__(self, type, value, traceback): + if type is None: + try: + next(self.gen) + except StopIteration: + return + else: + raise RuntimeError("generator didn't stop") + else: + if value is None: + # Need to force instantiation so we can reliably + # tell if we get the same exception back + value = type() + try: + self.gen.throw(type, value, traceback) + raise RuntimeError("generator didn't stop after throw()") + except StopIteration as exc: + # Suppress StopIteration *unless* it's the same exception that + # was passed to throw(). This prevents a StopIteration + # raised inside the "with" statement from being suppressed. + return exc is not value + except RuntimeError as exc: + # Don't re-raise the passed in exception + if exc is value: + return False + # Likewise, avoid suppressing if a StopIteration exception + # was passed to throw() and later wrapped into a RuntimeError + # (see PEP 479). + if _HAVE_EXCEPTION_CHAINING and exc.__cause__ is value: + return False + raise + except: + # only re-raise if it's *not* the exception that was + # passed to throw(), because __exit__() must not raise + # an exception unless __exit__() itself failed. But throw() + # has to raise the exception to signal propagation, so this + # fixes the impedance mismatch between the throw() protocol + # and the __exit__() protocol. + # + if sys.exc_info()[1] is not value: + raise + + +def contextmanager(func): + """@contextmanager decorator. + + Typical usage: + + @contextmanager + def some_generator(<arguments>): + <setup> + try: + yield <value> + finally: + <cleanup> + + This makes this: + + with some_generator(<arguments>) as <variable>: + <body> + + equivalent to this: + + <setup> + try: + <variable> = <value> + <body> + finally: + <cleanup> + + """ + @wraps(func) + def helper(*args, **kwds): + return _GeneratorContextManager(func, args, kwds) + return helper + + +class closing(object): + """Context to automatically close something at the end of a block. + + Code like this: + + with closing(<module>.open(<arguments>)) as f: + <block> + + is equivalent to this: + + f = <module>.open(<arguments>) + try: + <block> + finally: + f.close() + + """ + def __init__(self, thing): + self.thing = thing + + def __enter__(self): + return self.thing + + def __exit__(self, *exc_info): + self.thing.close() + + +class _RedirectStream(object): + + _stream = None + + def __init__(self, new_target): + self._new_target = new_target + # We use a list of old targets to make this CM re-entrant + self._old_targets = [] + + def __enter__(self): + self._old_targets.append(getattr(sys, self._stream)) + setattr(sys, self._stream, self._new_target) + return self._new_target + + def __exit__(self, exctype, excinst, exctb): + setattr(sys, self._stream, self._old_targets.pop()) + + +class redirect_stdout(_RedirectStream): + """Context manager for temporarily redirecting stdout to another file. + + # How to send help() to stderr + with redirect_stdout(sys.stderr): + help(dir) + + # How to write help() to a file + with open('help.txt', 'w') as f: + with redirect_stdout(f): + help(pow) + """ + + _stream = "stdout" + + +class redirect_stderr(_RedirectStream): + """Context manager for temporarily redirecting stderr to another file.""" + + _stream = "stderr" + + +class suppress(object): + """Context manager to suppress specified exceptions + + After the exception is suppressed, execution proceeds with the next + statement following the with statement. + + with suppress(FileNotFoundError): + os.remove(somefile) + # Execution still resumes here if the file was already removed + """ + + def __init__(self, *exceptions): + self._exceptions = exceptions + + def __enter__(self): + pass + + def __exit__(self, exctype, excinst, exctb): + # Unlike isinstance and issubclass, CPython exception handling + # currently only looks at the concrete type hierarchy (ignoring + # the instance and subclass checking hooks). While Guido considers + # that a bug rather than a feature, it's a fairly hard one to fix + # due to various internal implementation details. suppress provides + # the simpler issubclass based semantics, rather than trying to + # exactly reproduce the limitations of the CPython interpreter. + # + # See http://bugs.python.org/issue12029 for more details + return exctype is not None and issubclass(exctype, self._exceptions) + + +# Context manipulation is Python 3 only +_HAVE_EXCEPTION_CHAINING = sys.version_info[0] >= 3 +if _HAVE_EXCEPTION_CHAINING: + def _make_context_fixer(frame_exc): + def _fix_exception_context(new_exc, old_exc): + # Context may not be correct, so find the end of the chain + while 1: + exc_context = new_exc.__context__ + if exc_context is old_exc: + # Context is already set correctly (see issue 20317) + return + if exc_context is None or exc_context is frame_exc: + break + new_exc = exc_context + # Change the end of the chain to point to the exception + # we expect it to reference + new_exc.__context__ = old_exc + return _fix_exception_context + + def _reraise_with_existing_context(exc_details): + try: + # bare "raise exc_details[1]" replaces our carefully + # set-up context + fixed_ctx = exc_details[1].__context__ + raise exc_details[1] + except BaseException: + exc_details[1].__context__ = fixed_ctx + raise +else: + # No exception context in Python 2 + def _make_context_fixer(frame_exc): + return lambda new_exc, old_exc: None + + # Use 3 argument raise in Python 2, + # but use exec to avoid SyntaxError in Python 3 + def _reraise_with_existing_context(exc_details): + exc_type, exc_value, exc_tb = exc_details + exec("raise exc_type, exc_value, exc_tb") + +# Handle old-style classes if they exist +try: + from types import InstanceType +except ImportError: + # Python 3 doesn't have old-style classes + _get_type = type +else: + # Need to handle old-style context managers on Python 2 + def _get_type(obj): + obj_type = type(obj) + if obj_type is InstanceType: + return obj.__class__ # Old-style class + return obj_type # New-style class + + +# Inspired by discussions on http://bugs.python.org/issue13585 +class ExitStack(object): + """Context manager for dynamic management of a stack of exit callbacks + + For example: + + with ExitStack() as stack: + files = [stack.enter_context(open(fname)) for fname in filenames] + # All opened files will automatically be closed at the end of + # the with statement, even if attempts to open files later + # in the list raise an exception + + """ + def __init__(self): + self._exit_callbacks = deque() + + def pop_all(self): + """Preserve the context stack by transferring it to a new instance""" + new_stack = type(self)() + new_stack._exit_callbacks = self._exit_callbacks + self._exit_callbacks = deque() + return new_stack + + def _push_cm_exit(self, cm, cm_exit): + """Helper to correctly register callbacks to __exit__ methods""" + def _exit_wrapper(*exc_details): + return cm_exit(cm, *exc_details) + _exit_wrapper.__self__ = cm + self.push(_exit_wrapper) + + def push(self, exit): + """Registers a callback with the standard __exit__ method signature + + Can suppress exceptions the same way __exit__ methods can. + + Also accepts any object with an __exit__ method (registering a call + to the method instead of the object itself) + """ + # We use an unbound method rather than a bound method to follow + # the standard lookup behaviour for special methods + _cb_type = _get_type(exit) + try: + exit_method = _cb_type.__exit__ + except AttributeError: + # Not a context manager, so assume its a callable + self._exit_callbacks.append(exit) + else: + self._push_cm_exit(exit, exit_method) + return exit # Allow use as a decorator + + def callback(self, callback, *args, **kwds): + """Registers an arbitrary callback and arguments. + + Cannot suppress exceptions. + """ + def _exit_wrapper(exc_type, exc, tb): + callback(*args, **kwds) + # We changed the signature, so using @wraps is not appropriate, but + # setting __wrapped__ may still help with introspection + _exit_wrapper.__wrapped__ = callback + self.push(_exit_wrapper) + return callback # Allow use as a decorator + + def enter_context(self, cm): + """Enters the supplied context manager + + If successful, also pushes its __exit__ method as a callback and + returns the result of the __enter__ method. + """ + # We look up the special methods on the type to match the with statement + _cm_type = _get_type(cm) + _exit = _cm_type.__exit__ + result = _cm_type.__enter__(cm) + self._push_cm_exit(cm, _exit) + return result + + def close(self): + """Immediately unwind the context stack""" + self.__exit__(None, None, None) + + def __enter__(self): + return self + + def __exit__(self, *exc_details): + received_exc = exc_details[0] is not None + + # We manipulate the exception state so it behaves as though + # we were actually nesting multiple with statements + frame_exc = sys.exc_info()[1] + _fix_exception_context = _make_context_fixer(frame_exc) + + # Callbacks are invoked in LIFO order to match the behaviour of + # nested context managers + suppressed_exc = False + pending_raise = False + while self._exit_callbacks: + cb = self._exit_callbacks.pop() + try: + if cb(*exc_details): + suppressed_exc = True + pending_raise = False + exc_details = (None, None, None) + except: + new_exc_details = sys.exc_info() + # simulate the stack of exceptions by setting the context + _fix_exception_context(new_exc_details[1], exc_details[1]) + pending_raise = True + exc_details = new_exc_details + if pending_raise: + _reraise_with_existing_context(exc_details) + return received_exc and suppressed_exc + + +# Preserve backwards compatibility +class ContextStack(ExitStack): + """Backwards compatibility alias for ExitStack""" + + def __init__(self): + warnings.warn("ContextStack has been renamed to ExitStack", + DeprecationWarning) + super(ContextStack, self).__init__() + + def register_exit(self, callback): + return self.push(callback) + + def register(self, callback, *args, **kwds): + return self.callback(callback, *args, **kwds) + + def preserve(self): + return self.pop_all() + + +class nullcontext(AbstractContextManager): + """Context manager that does no additional processing. + Used as a stand-in for a normal context manager, when a particular + block of code is only sometimes used with a normal context manager: + cm = optional_cm if condition else nullcontext() + with cm: + # Perform operation, using optional_cm if condition is True + """ + + def __init__(self, enter_result=None): + self.enter_result = enter_result + + def __enter__(self): + return self.enter_result + + def __exit__(self, *excinfo): + pass diff --git a/contrib/python/contextlib2/py2/ya.make b/contrib/python/contextlib2/py2/ya.make new file mode 100644 index 0000000000..34e15ca73e --- /dev/null +++ b/contrib/python/contextlib2/py2/ya.make @@ -0,0 +1,22 @@ +# Generated by devtools/yamaker (pypi). + +PY2_LIBRARY() + +VERSION(0.6.0.post1) + +LICENSE(PSF-2.0) + +NO_LINT() + +PY_SRCS( + TOP_LEVEL + contextlib2.py +) + +RESOURCE_FILES( + PREFIX contrib/python/contextlib2/py2/ + .dist-info/METADATA + .dist-info/top_level.txt +) + +END() diff --git a/contrib/python/contextlib2/py3/.dist-info/METADATA b/contrib/python/contextlib2/py3/.dist-info/METADATA new file mode 100644 index 0000000000..b2427d0476 --- /dev/null +++ b/contrib/python/contextlib2/py3/.dist-info/METADATA @@ -0,0 +1,113 @@ +Metadata-Version: 2.1 +Name: contextlib2 +Version: 21.6.0 +Summary: Backports and enhancements for the contextlib module +Home-page: http://contextlib2.readthedocs.org +Author: Nick Coghlan +Author-email: ncoghlan@gmail.com +License: PSF License +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: License :: OSI Approved :: Apache Software License +Classifier: License :: OSI Approved :: Python Software Foundation License +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Requires-Python: >=3.6 +License-File: LICENSE.txt + +.. image:: https://jazzband.co/static/img/badge.svg + :target: https://jazzband.co/ + :alt: Jazzband + +.. image:: https://github.com/jazzband/contextlib2/workflows/Test/badge.svg + :target: https://github.com/jazzband/contextlib2/actions + :alt: Tests + +.. image:: https://codecov.io/gh/jazzband/contextlib2/branch/master/graph/badge.svg + :target: https://codecov.io/gh/jazzband/contextlib2 + :alt: Coverage + +.. image:: https://readthedocs.org/projects/contextlib2/badge/?version=latest + :target: https://contextlib2.readthedocs.org/ + :alt: Latest Docs + +contextlib2 is a backport of the `standard library's contextlib +module <https://docs.python.org/3/library/contextlib.html>`_ to +earlier Python versions. + +It also sometimes serves as a real world proving ground for possible future +enhancements to the standard library version. + +Licensing +--------- + +As a backport of Python standard library software, the implementation, test +suite and other supporting files for this project are distributed under the +Python Software License used for the CPython reference implementation. + +The one exception is the included type hints file, which comes from the +``typeshed`` project, and is hence distributed under the Apache License 2.0. + +Development +----------- + +contextlib2 has no runtime dependencies, but requires ``setuptools`` and +``wheel`` at build time to generate universal wheel archives. + +Local testing is a matter of running:: + + python3 -m unittest discover -t . -s test + +You can test against multiple versions of Python with +`tox <https://tox.testrun.org/>`_:: + + pip install tox + tox + +Versions currently tested in both tox and GitHub Actions are: + +* CPython 3.6 +* CPython 3.7 +* CPython 3.8 +* CPython 3.9 +* CPython 3.10 +* PyPy3 + +Updating to a new stdlib reference version +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +As of Python 3.10, 4 files needed to be copied from the CPython reference +implementation to contextlib2: + +* ``Doc/contextlib.rst`` -> ``docs/contextlib2.rst`` +* ``Lib/contextlib.py`` -> ``contextlib2/__init__.py`` +* ``Lib/test/test_contextlib.py`` -> ``test/test_contextlib.py`` +* ``Lib/test/test_contextlib_async.py`` -> ``test/test_contextlib_async.py`` + +The corresponding version of ``contextlib2/__init__.pyi`` also needs to be +retrieved from the ``typeshed`` project:: + + wget https://raw.githubusercontent.com/python/typeshed/master/stdlib/contextlib.pyi + +For the 3.10 sync, the only changes needed to the test files were to import from +``contextlib2`` rather than ``contextlib``. The test directory is laid out so +that the test suite's imports from ``test.support`` work the same way they do in +the main CPython test suite. + +The following patch files are saved in the ``dev`` directory: + +* changes made to ``contextlib2/__init__.py`` to get it to run on the older + versions (and to add back in the deprecated APIs that never graduated to + the standard library version) +* changes made to ``contextlib2/__init__.pyi`` to make the Python version + guards unconditional (since the ``contextlib2`` API is the same on all + supported versions) +* changes made to ``docs/contextlib2.rst`` to use ``contextlib2`` version + numbers in the version added/changed notes and to integrate the module + documentation with the rest of the project documentation + + diff --git a/contrib/python/contextlib2/py3/.dist-info/top_level.txt b/contrib/python/contextlib2/py3/.dist-info/top_level.txt new file mode 100644 index 0000000000..03fdf8ed24 --- /dev/null +++ b/contrib/python/contextlib2/py3/.dist-info/top_level.txt @@ -0,0 +1 @@ +contextlib2 diff --git a/contrib/python/contextlib2/py3/LICENSE.txt b/contrib/python/contextlib2/py3/LICENSE.txt new file mode 100644 index 0000000000..e40caa18c3 --- /dev/null +++ b/contrib/python/contextlib2/py3/LICENSE.txt @@ -0,0 +1,124 @@ +Note: The type hints included in this package come from the typeshed project, +and are hence distributed under the Apache License 2.0 rather than under the +Python Software License that covers the module implementation and test suite. + +A. HISTORY OF THE SOFTWARE +========================== + +contextlib2 is a derivative of the contextlib module distributed by the PSF +as part of the Python standard library. According, it is itself redistributed +under the PSF license (reproduced in full below). As the contextlib module +was added only in Python 2.5, the licenses for earlier Python versions are +not applicable and have not been included. + +Python was created in the early 1990s by Guido van Rossum at Stichting +Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands +as a successor of a language called ABC. Guido remains Python's +principal author, although it includes many contributions from others. + +In 1995, Guido continued his work on Python at the Corporation for +National Research Initiatives (CNRI, see http://www.cnri.reston.va.us) +in Reston, Virginia where he released several versions of the +software. + +In May 2000, Guido and the Python core development team moved to +BeOpen.com to form the BeOpen PythonLabs team. In October of the same +year, the PythonLabs team moved to Digital Creations (now Zope +Corporation, see http://www.zope.com). In 2001, the Python Software +Foundation (PSF, see http://www.python.org/psf/) was formed, a +non-profit organization created specifically to own Python-related +Intellectual Property. Zope Corporation is a sponsoring member of +the PSF. + +All Python releases are Open Source (see http://www.opensource.org for +the Open Source Definition). Historically, most, but not all, Python +releases have also been GPL-compatible; the table below summarizes +the various releases that included the contextlib module. + + Release Derived Year Owner GPL- + from compatible? (1) + + 2.5 2.4 2006 PSF yes + 2.5.1 2.5 2007 PSF yes + 2.5.2 2.5.1 2008 PSF yes + 2.5.3 2.5.2 2008 PSF yes + 2.6 2.5 2008 PSF yes + 2.6.1 2.6 2008 PSF yes + 2.6.2 2.6.1 2009 PSF yes + 2.6.3 2.6.2 2009 PSF yes + 2.6.4 2.6.3 2009 PSF yes + 2.6.5 2.6.4 2010 PSF yes + 3.0 2.6 2008 PSF yes + 3.0.1 3.0 2009 PSF yes + 3.1 3.0.1 2009 PSF yes + 3.1.1 3.1 2009 PSF yes + 3.1.2 3.1.1 2010 PSF yes + 3.1.3 3.1.2 2010 PSF yes + 3.1.4 3.1.3 2011 PSF yes + 3.2 3.1 2011 PSF yes + 3.2.1 3.2 2011 PSF yes + 3.2.2 3.2.1 2011 PSF yes + 3.3 3.2 2012 PSF yes + +Footnotes: + +(1) GPL-compatible doesn't mean that we're distributing Python under + the GPL. All Python licenses, unlike the GPL, let you distribute + a modified version without making your changes open source. The + GPL-compatible licenses make it possible to combine Python with + other software that is released under the GPL; the others don't. + +Thanks to the many outside volunteers who have worked under Guido's +direction to make these releases possible. + + +B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON +=============================================================== + +PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 +-------------------------------------------- + +1. This LICENSE AGREEMENT is between the Python Software Foundation +("PSF"), and the Individual or Organization ("Licensee") accessing and +otherwise using this software ("Python") in source or binary form and +its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, PSF hereby +grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, +analyze, test, perform and/or display publicly, prepare derivative works, +distribute, and otherwise use Python alone or in any derivative version, +provided, however, that PSF's License Agreement and PSF's notice of copyright, +i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +2011 Python Software Foundation; All Rights Reserved" are retained in Python +alone or in any derivative version prepared by Licensee. + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python. + +4. PSF is making Python available to Licensee on an "AS IS" +basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. Nothing in this License Agreement shall be deemed to create any +relationship of agency, partnership, or joint venture between PSF and +Licensee. This License Agreement does not grant permission to use PSF +trademarks or trade name in a trademark sense to endorse or promote +products or services of Licensee, or any third party. + +8. By copying, installing or otherwise using Python, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. diff --git a/contrib/python/contextlib2/py3/README.rst b/contrib/python/contextlib2/py3/README.rst new file mode 100644 index 0000000000..6274896e95 --- /dev/null +++ b/contrib/python/contextlib2/py3/README.rst @@ -0,0 +1,90 @@ +.. image:: https://jazzband.co/static/img/badge.svg + :target: https://jazzband.co/ + :alt: Jazzband + +.. image:: https://github.com/jazzband/contextlib2/workflows/Test/badge.svg + :target: https://github.com/jazzband/contextlib2/actions + :alt: Tests + +.. image:: https://codecov.io/gh/jazzband/contextlib2/branch/master/graph/badge.svg + :target: https://codecov.io/gh/jazzband/contextlib2 + :alt: Coverage + +.. image:: https://readthedocs.org/projects/contextlib2/badge/?version=latest + :target: https://contextlib2.readthedocs.org/ + :alt: Latest Docs + +contextlib2 is a backport of the `standard library's contextlib +module <https://docs.python.org/3/library/contextlib.html>`_ to +earlier Python versions. + +It also sometimes serves as a real world proving ground for possible future +enhancements to the standard library version. + +Licensing +--------- + +As a backport of Python standard library software, the implementation, test +suite and other supporting files for this project are distributed under the +Python Software License used for the CPython reference implementation. + +The one exception is the included type hints file, which comes from the +``typeshed`` project, and is hence distributed under the Apache License 2.0. + +Development +----------- + +contextlib2 has no runtime dependencies, but requires ``setuptools`` and +``wheel`` at build time to generate universal wheel archives. + +Local testing is a matter of running:: + + python3 -m unittest discover -t . -s test + +You can test against multiple versions of Python with +`tox <https://tox.testrun.org/>`_:: + + pip install tox + tox + +Versions currently tested in both tox and GitHub Actions are: + +* CPython 3.6 +* CPython 3.7 +* CPython 3.8 +* CPython 3.9 +* CPython 3.10 +* PyPy3 + +Updating to a new stdlib reference version +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +As of Python 3.10, 4 files needed to be copied from the CPython reference +implementation to contextlib2: + +* ``Doc/contextlib.rst`` -> ``docs/contextlib2.rst`` +* ``Lib/contextlib.py`` -> ``contextlib2/__init__.py`` +* ``Lib/test/test_contextlib.py`` -> ``test/test_contextlib.py`` +* ``Lib/test/test_contextlib_async.py`` -> ``test/test_contextlib_async.py`` + +The corresponding version of ``contextlib2/__init__.pyi`` also needs to be +retrieved from the ``typeshed`` project:: + + wget https://raw.githubusercontent.com/python/typeshed/master/stdlib/contextlib.pyi + +For the 3.10 sync, the only changes needed to the test files were to import from +``contextlib2`` rather than ``contextlib``. The test directory is laid out so +that the test suite's imports from ``test.support`` work the same way they do in +the main CPython test suite. + +The following patch files are saved in the ``dev`` directory: + +* changes made to ``contextlib2/__init__.py`` to get it to run on the older + versions (and to add back in the deprecated APIs that never graduated to + the standard library version) +* changes made to ``contextlib2/__init__.pyi`` to make the Python version + guards unconditional (since the ``contextlib2`` API is the same on all + supported versions) +* changes made to ``docs/contextlib2.rst`` to use ``contextlib2`` version + numbers in the version added/changed notes and to integrate the module + documentation with the rest of the project documentation diff --git a/contrib/python/contextlib2/py3/contextlib2/__init__.py b/contrib/python/contextlib2/py3/contextlib2/__init__.py new file mode 100644 index 0000000000..d6c0c4ac4a --- /dev/null +++ b/contrib/python/contextlib2/py3/contextlib2/__init__.py @@ -0,0 +1,798 @@ +"""contextlib2 - backports and enhancements to the contextlib module""" + +import abc +import sys +import warnings +import _collections_abc +from collections import deque +from functools import wraps +from types import MethodType + +# Python 3.6/3.7/3.8 compatibility: GenericAlias may not be defined +try: + from types import GenericAlias +except ImportError: + # If the real GenericAlias type doesn't exist, __class_getitem__ won't be used, + # so the fallback placeholder doesn't need to provide any meaningful behaviour + class GenericAlias: + pass + + +__all__ = ["asynccontextmanager", "contextmanager", "closing", "nullcontext", + "AbstractContextManager", "AbstractAsyncContextManager", + "AsyncExitStack", "ContextDecorator", "ExitStack", + "redirect_stdout", "redirect_stderr", "suppress", "aclosing"] + +# Backwards compatibility +__all__ += ["ContextStack"] + +class AbstractContextManager(abc.ABC): + """An abstract base class for context managers.""" + + __class_getitem__ = classmethod(GenericAlias) + + def __enter__(self): + """Return `self` upon entering the runtime context.""" + return self + + @abc.abstractmethod + def __exit__(self, exc_type, exc_value, traceback): + """Raise any exception triggered within the runtime context.""" + return None + + @classmethod + def __subclasshook__(cls, C): + if cls is AbstractContextManager: + return _collections_abc._check_methods(C, "__enter__", "__exit__") + return NotImplemented + + +class AbstractAsyncContextManager(abc.ABC): + + """An abstract base class for asynchronous context managers.""" + + __class_getitem__ = classmethod(GenericAlias) + + async def __aenter__(self): + """Return `self` upon entering the runtime context.""" + return self + + @abc.abstractmethod + async def __aexit__(self, exc_type, exc_value, traceback): + """Raise any exception triggered within the runtime context.""" + return None + + @classmethod + def __subclasshook__(cls, C): + if cls is AbstractAsyncContextManager: + return _collections_abc._check_methods(C, "__aenter__", + "__aexit__") + return NotImplemented + + +class ContextDecorator(object): + "A base class or mixin that enables context managers to work as decorators." + + def refresh_cm(self): + """Returns the context manager used to actually wrap the call to the + decorated function. + + The default implementation just returns *self*. + + Overriding this method allows otherwise one-shot context managers + like _GeneratorContextManager to support use as decorators via + implicit recreation. + + DEPRECATED: refresh_cm was never added to the standard library's + ContextDecorator API + """ + warnings.warn("refresh_cm was never added to the standard library", + DeprecationWarning) + return self._recreate_cm() + + def _recreate_cm(self): + """Return a recreated instance of self. + + Allows an otherwise one-shot context manager like + _GeneratorContextManager to support use as + a decorator via implicit recreation. + + This is a private interface just for _GeneratorContextManager. + See issue #11647 for details. + """ + return self + + def __call__(self, func): + @wraps(func) + def inner(*args, **kwds): + with self._recreate_cm(): + return func(*args, **kwds) + return inner + + +class AsyncContextDecorator(object): + "A base class or mixin that enables async context managers to work as decorators." + + def _recreate_cm(self): + """Return a recreated instance of self. + """ + return self + + def __call__(self, func): + @wraps(func) + async def inner(*args, **kwds): + async with self._recreate_cm(): + return await func(*args, **kwds) + return inner + + +class _GeneratorContextManagerBase: + """Shared functionality for @contextmanager and @asynccontextmanager.""" + + def __init__(self, func, args, kwds): + self.gen = func(*args, **kwds) + self.func, self.args, self.kwds = func, args, kwds + # Issue 19330: ensure context manager instances have good docstrings + doc = getattr(func, "__doc__", None) + if doc is None: + doc = type(self).__doc__ + self.__doc__ = doc + # Unfortunately, this still doesn't provide good help output when + # inspecting the created context manager instances, since pydoc + # currently bypasses the instance docstring and shows the docstring + # for the class instead. + # See http://bugs.python.org/issue19404 for more details. + + +class _GeneratorContextManager(_GeneratorContextManagerBase, + AbstractContextManager, + ContextDecorator): + """Helper for @contextmanager decorator.""" + + def _recreate_cm(self): + # _GCM instances are one-shot context managers, so the + # CM must be recreated each time a decorated function is + # called + return self.__class__(self.func, self.args, self.kwds) + + def __enter__(self): + # do not keep args and kwds alive unnecessarily + # they are only needed for recreation, which is not possible anymore + del self.args, self.kwds, self.func + try: + return next(self.gen) + except StopIteration: + raise RuntimeError("generator didn't yield") from None + + def __exit__(self, type, value, traceback): + if type is None: + try: + next(self.gen) + except StopIteration: + return False + else: + raise RuntimeError("generator didn't stop") + else: + if value is None: + # Need to force instantiation so we can reliably + # tell if we get the same exception back + value = type() + try: + self.gen.throw(type, value, traceback) + except StopIteration as exc: + # Suppress StopIteration *unless* it's the same exception that + # was passed to throw(). This prevents a StopIteration + # raised inside the "with" statement from being suppressed. + return exc is not value + except RuntimeError as exc: + # Don't re-raise the passed in exception. (issue27122) + if exc is value: + return False + # Likewise, avoid suppressing if a StopIteration exception + # was passed to throw() and later wrapped into a RuntimeError + # (see PEP 479). + if type is StopIteration and exc.__cause__ is value: + return False + raise + except: + # only re-raise if it's *not* the exception that was + # passed to throw(), because __exit__() must not raise + # an exception unless __exit__() itself failed. But throw() + # has to raise the exception to signal propagation, so this + # fixes the impedance mismatch between the throw() protocol + # and the __exit__() protocol. + # + # This cannot use 'except BaseException as exc' (as in the + # async implementation) to maintain compatibility with + # Python 2, where old-style class exceptions are not caught + # by 'except BaseException'. + if sys.exc_info()[1] is value: + return False + raise + raise RuntimeError("generator didn't stop after throw()") + + +class _AsyncGeneratorContextManager(_GeneratorContextManagerBase, + AbstractAsyncContextManager, + AsyncContextDecorator): + """Helper for @asynccontextmanager.""" + + def _recreate_cm(self): + # _AGCM instances are one-shot context managers, so the + # ACM must be recreated each time a decorated function is + # called + return self.__class__(self.func, self.args, self.kwds) + + async def __aenter__(self): + try: + return await self.gen.__anext__() + except StopAsyncIteration: + raise RuntimeError("generator didn't yield") from None + + async def __aexit__(self, typ, value, traceback): + if typ is None: + try: + await self.gen.__anext__() + except StopAsyncIteration: + return + else: + raise RuntimeError("generator didn't stop") + else: + if value is None: + value = typ() + # See _GeneratorContextManager.__exit__ for comments on subtleties + # in this implementation + try: + await self.gen.athrow(typ, value, traceback) + raise RuntimeError("generator didn't stop after athrow()") + except StopAsyncIteration as exc: + return exc is not value + except RuntimeError as exc: + if exc is value: + return False + # Avoid suppressing if a StopIteration exception + # was passed to throw() and later wrapped into a RuntimeError + # (see PEP 479 for sync generators; async generators also + # have this behavior). But do this only if the exception wrapped + # by the RuntimeError is actually Stop(Async)Iteration (see + # issue29692). + if isinstance(value, (StopIteration, StopAsyncIteration)): + if exc.__cause__ is value: + return False + raise + except BaseException as exc: + if exc is not value: + raise + + +def contextmanager(func): + """@contextmanager decorator. + + Typical usage: + + @contextmanager + def some_generator(<arguments>): + <setup> + try: + yield <value> + finally: + <cleanup> + + This makes this: + + with some_generator(<arguments>) as <variable>: + <body> + + equivalent to this: + + <setup> + try: + <variable> = <value> + <body> + finally: + <cleanup> + """ + @wraps(func) + def helper(*args, **kwds): + return _GeneratorContextManager(func, args, kwds) + return helper + + +def asynccontextmanager(func): + """@asynccontextmanager decorator. + + Typical usage: + + @asynccontextmanager + async def some_async_generator(<arguments>): + <setup> + try: + yield <value> + finally: + <cleanup> + + This makes this: + + async with some_async_generator(<arguments>) as <variable>: + <body> + + equivalent to this: + + <setup> + try: + <variable> = <value> + <body> + finally: + <cleanup> + """ + @wraps(func) + def helper(*args, **kwds): + return _AsyncGeneratorContextManager(func, args, kwds) + return helper + + +class closing(AbstractContextManager): + """Context to automatically close something at the end of a block. + + Code like this: + + with closing(<module>.open(<arguments>)) as f: + <block> + + is equivalent to this: + + f = <module>.open(<arguments>) + try: + <block> + finally: + f.close() + + """ + def __init__(self, thing): + self.thing = thing + def __enter__(self): + return self.thing + def __exit__(self, *exc_info): + self.thing.close() + + +class aclosing(AbstractAsyncContextManager): + """Async context manager for safely finalizing an asynchronously cleaned-up + resource such as an async generator, calling its ``aclose()`` method. + + Code like this: + + async with aclosing(<module>.fetch(<arguments>)) as agen: + <block> + + is equivalent to this: + + agen = <module>.fetch(<arguments>) + try: + <block> + finally: + await agen.aclose() + + """ + def __init__(self, thing): + self.thing = thing + async def __aenter__(self): + return self.thing + async def __aexit__(self, *exc_info): + await self.thing.aclose() + + +class _RedirectStream(AbstractContextManager): + + _stream = None + + def __init__(self, new_target): + self._new_target = new_target + # We use a list of old targets to make this CM re-entrant + self._old_targets = [] + + def __enter__(self): + self._old_targets.append(getattr(sys, self._stream)) + setattr(sys, self._stream, self._new_target) + return self._new_target + + def __exit__(self, exctype, excinst, exctb): + setattr(sys, self._stream, self._old_targets.pop()) + + +class redirect_stdout(_RedirectStream): + """Context manager for temporarily redirecting stdout to another file. + + # How to send help() to stderr + with redirect_stdout(sys.stderr): + help(dir) + + # How to write help() to a file + with open('help.txt', 'w') as f: + with redirect_stdout(f): + help(pow) + """ + + _stream = "stdout" + + +class redirect_stderr(_RedirectStream): + """Context manager for temporarily redirecting stderr to another file.""" + + _stream = "stderr" + + +class suppress(AbstractContextManager): + """Context manager to suppress specified exceptions + + After the exception is suppressed, execution proceeds with the next + statement following the with statement. + + with suppress(FileNotFoundError): + os.remove(somefile) + # Execution still resumes here if the file was already removed + """ + + def __init__(self, *exceptions): + self._exceptions = exceptions + + def __enter__(self): + pass + + def __exit__(self, exctype, excinst, exctb): + # Unlike isinstance and issubclass, CPython exception handling + # currently only looks at the concrete type hierarchy (ignoring + # the instance and subclass checking hooks). While Guido considers + # that a bug rather than a feature, it's a fairly hard one to fix + # due to various internal implementation details. suppress provides + # the simpler issubclass based semantics, rather than trying to + # exactly reproduce the limitations of the CPython interpreter. + # + # See http://bugs.python.org/issue12029 for more details + return exctype is not None and issubclass(exctype, self._exceptions) + + +class _BaseExitStack: + """A base class for ExitStack and AsyncExitStack.""" + + @staticmethod + def _create_exit_wrapper(cm, cm_exit): + return MethodType(cm_exit, cm) + + @staticmethod + def _create_cb_wrapper(*args, **kwds): + # Python 3.6/3.7 compatibility: no native positional-only args syntax + callback, *args = args + def _exit_wrapper(exc_type, exc, tb): + callback(*args, **kwds) + return _exit_wrapper + + def __init__(self): + self._exit_callbacks = deque() + + def pop_all(self): + """Preserve the context stack by transferring it to a new instance.""" + new_stack = type(self)() + new_stack._exit_callbacks = self._exit_callbacks + self._exit_callbacks = deque() + return new_stack + + def push(self, exit): + """Registers a callback with the standard __exit__ method signature. + + Can suppress exceptions the same way __exit__ method can. + Also accepts any object with an __exit__ method (registering a call + to the method instead of the object itself). + """ + # We use an unbound method rather than a bound method to follow + # the standard lookup behaviour for special methods. + _cb_type = type(exit) + + try: + exit_method = _cb_type.__exit__ + except AttributeError: + # Not a context manager, so assume it's a callable. + self._push_exit_callback(exit) + else: + self._push_cm_exit(exit, exit_method) + return exit # Allow use as a decorator. + + def enter_context(self, cm): + """Enters the supplied context manager. + + If successful, also pushes its __exit__ method as a callback and + returns the result of the __enter__ method. + """ + # We look up the special methods on the type to match the with + # statement. + _cm_type = type(cm) + _exit = _cm_type.__exit__ + result = _cm_type.__enter__(cm) + self._push_cm_exit(cm, _exit) + return result + + def callback(*args, **kwds): + """Registers an arbitrary callback and arguments. + + Cannot suppress exceptions. + """ + # Python 3.6/3.7 compatibility: no native positional-only args syntax + try: + self, callback, *args = args + except ValueError as exc: + exc_details = str(exc).partition("(")[2] + msg = "Not enough positional arguments {}".format(exc_details) + raise TypeError(msg) from None + _exit_wrapper = self._create_cb_wrapper(callback, *args, **kwds) + + # We changed the signature, so using @wraps is not appropriate, but + # setting __wrapped__ may still help with introspection. + _exit_wrapper.__wrapped__ = callback + self._push_exit_callback(_exit_wrapper) + return callback # Allow use as a decorator + + def _push_cm_exit(self, cm, cm_exit): + """Helper to correctly register callbacks to __exit__ methods.""" + _exit_wrapper = self._create_exit_wrapper(cm, cm_exit) + self._push_exit_callback(_exit_wrapper, True) + + def _push_exit_callback(self, callback, is_sync=True): + self._exit_callbacks.append((is_sync, callback)) + + +# Inspired by discussions on http://bugs.python.org/issue13585 +class ExitStack(_BaseExitStack, AbstractContextManager): + """Context manager for dynamic management of a stack of exit callbacks. + + For example: + with ExitStack() as stack: + files = [stack.enter_context(open(fname)) for fname in filenames] + # All opened files will automatically be closed at the end of + # the with statement, even if attempts to open files later + # in the list raise an exception. + """ + + def __enter__(self): + return self + + def __exit__(self, *exc_details): + received_exc = exc_details[0] is not None + + # We manipulate the exception state so it behaves as though + # we were actually nesting multiple with statements + frame_exc = sys.exc_info()[1] + def _fix_exception_context(new_exc, old_exc): + # Context may not be correct, so find the end of the chain + while 1: + exc_context = new_exc.__context__ + if exc_context is old_exc: + # Context is already set correctly (see issue 20317) + return + if exc_context is None or exc_context is frame_exc: + break + new_exc = exc_context + # Change the end of the chain to point to the exception + # we expect it to reference + new_exc.__context__ = old_exc + + # Callbacks are invoked in LIFO order to match the behaviour of + # nested context managers + suppressed_exc = False + pending_raise = False + while self._exit_callbacks: + is_sync, cb = self._exit_callbacks.pop() + assert is_sync + try: + if cb(*exc_details): + suppressed_exc = True + pending_raise = False + exc_details = (None, None, None) + except: + new_exc_details = sys.exc_info() + # simulate the stack of exceptions by setting the context + _fix_exception_context(new_exc_details[1], exc_details[1]) + pending_raise = True + exc_details = new_exc_details + if pending_raise: + try: + # bare "raise exc_details[1]" replaces our carefully + # set-up context + fixed_ctx = exc_details[1].__context__ + raise exc_details[1] + except BaseException: + exc_details[1].__context__ = fixed_ctx + raise + return received_exc and suppressed_exc + + def close(self): + """Immediately unwind the context stack.""" + self.__exit__(None, None, None) + + +# Inspired by discussions on https://bugs.python.org/issue29302 +class AsyncExitStack(_BaseExitStack, AbstractAsyncContextManager): + """Async context manager for dynamic management of a stack of exit + callbacks. + + For example: + async with AsyncExitStack() as stack: + connections = [await stack.enter_async_context(get_connection()) + for i in range(5)] + # All opened connections will automatically be released at the + # end of the async with statement, even if attempts to open a + # connection later in the list raise an exception. + """ + + @staticmethod + def _create_async_exit_wrapper(cm, cm_exit): + return MethodType(cm_exit, cm) + + @staticmethod + def _create_async_cb_wrapper(*args, **kwds): + # Python 3.6/3.7 compatibility: no native positional-only args syntax + callback, *args = args + async def _exit_wrapper(exc_type, exc, tb): + await callback(*args, **kwds) + return _exit_wrapper + + async def enter_async_context(self, cm): + """Enters the supplied async context manager. + + If successful, also pushes its __aexit__ method as a callback and + returns the result of the __aenter__ method. + """ + _cm_type = type(cm) + _exit = _cm_type.__aexit__ + result = await _cm_type.__aenter__(cm) + self._push_async_cm_exit(cm, _exit) + return result + + def push_async_exit(self, exit): + """Registers a coroutine function with the standard __aexit__ method + signature. + + Can suppress exceptions the same way __aexit__ method can. + Also accepts any object with an __aexit__ method (registering a call + to the method instead of the object itself). + """ + _cb_type = type(exit) + try: + exit_method = _cb_type.__aexit__ + except AttributeError: + # Not an async context manager, so assume it's a coroutine function + self._push_exit_callback(exit, False) + else: + self._push_async_cm_exit(exit, exit_method) + return exit # Allow use as a decorator + + def push_async_callback(*args, **kwds): + """Registers an arbitrary coroutine function and arguments. + + Cannot suppress exceptions. + """ + # Python 3.6/3.7 compatibility: no native positional-only args syntax + try: + self, callback, *args = args + except ValueError as exc: + exc_details = str(exc).partition("(")[2] + msg = "Not enough positional arguments {}".format(exc_details) + raise TypeError(msg) from None + _exit_wrapper = self._create_async_cb_wrapper(callback, *args, **kwds) + + # We changed the signature, so using @wraps is not appropriate, but + # setting __wrapped__ may still help with introspection. + _exit_wrapper.__wrapped__ = callback + self._push_exit_callback(_exit_wrapper, False) + return callback # Allow use as a decorator + + async def aclose(self): + """Immediately unwind the context stack.""" + await self.__aexit__(None, None, None) + + def _push_async_cm_exit(self, cm, cm_exit): + """Helper to correctly register coroutine function to __aexit__ + method.""" + _exit_wrapper = self._create_async_exit_wrapper(cm, cm_exit) + self._push_exit_callback(_exit_wrapper, False) + + async def __aenter__(self): + return self + + async def __aexit__(self, *exc_details): + received_exc = exc_details[0] is not None + + # We manipulate the exception state so it behaves as though + # we were actually nesting multiple with statements + frame_exc = sys.exc_info()[1] + def _fix_exception_context(new_exc, old_exc): + # Context may not be correct, so find the end of the chain + while 1: + exc_context = new_exc.__context__ + if exc_context is old_exc: + # Context is already set correctly (see issue 20317) + return + if exc_context is None or exc_context is frame_exc: + break + new_exc = exc_context + # Change the end of the chain to point to the exception + # we expect it to reference + new_exc.__context__ = old_exc + + # Callbacks are invoked in LIFO order to match the behaviour of + # nested context managers + suppressed_exc = False + pending_raise = False + while self._exit_callbacks: + is_sync, cb = self._exit_callbacks.pop() + try: + if is_sync: + cb_suppress = cb(*exc_details) + else: + cb_suppress = await cb(*exc_details) + + if cb_suppress: + suppressed_exc = True + pending_raise = False + exc_details = (None, None, None) + except: + new_exc_details = sys.exc_info() + # simulate the stack of exceptions by setting the context + _fix_exception_context(new_exc_details[1], exc_details[1]) + pending_raise = True + exc_details = new_exc_details + if pending_raise: + try: + # bare "raise exc_details[1]" replaces our carefully + # set-up context + fixed_ctx = exc_details[1].__context__ + raise exc_details[1] + except BaseException: + exc_details[1].__context__ = fixed_ctx + raise + return received_exc and suppressed_exc + + +class nullcontext(AbstractContextManager, AbstractAsyncContextManager): + """Context manager that does no additional processing. + + Used as a stand-in for a normal context manager, when a particular + block of code is only sometimes used with a normal context manager: + + cm = optional_cm if condition else nullcontext() + with cm: + # Perform operation, using optional_cm if condition is True + """ + + def __init__(self, enter_result=None): + self.enter_result = enter_result + + def __enter__(self): + return self.enter_result + + def __exit__(self, *excinfo): + pass + + async def __aenter__(self): + return self.enter_result + + async def __aexit__(self, *excinfo): + pass + + +# Preserve backwards compatibility +class ContextStack(ExitStack): + """Backwards compatibility alias for ExitStack""" + + def __init__(self): + warnings.warn("ContextStack has been renamed to ExitStack", + DeprecationWarning) + super(ContextStack, self).__init__() + + def register_exit(self, callback): + return self.push(callback) + + def register(self, callback, *args, **kwds): + return self.callback(callback, *args, **kwds) + + def preserve(self): + return self.pop_all() diff --git a/contrib/python/contextlib2/py3/contextlib2/py.typed b/contrib/python/contextlib2/py3/contextlib2/py.typed new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/contrib/python/contextlib2/py3/contextlib2/py.typed diff --git a/contrib/python/contextlib2/py3/ya.make b/contrib/python/contextlib2/py3/ya.make new file mode 100644 index 0000000000..9674bb12d4 --- /dev/null +++ b/contrib/python/contextlib2/py3/ya.make @@ -0,0 +1,24 @@ +# Generated by devtools/yamaker (pypi). + +PY3_LIBRARY() + +VERSION(21.6.0) + +LICENSE(PSF-2.0) + +NO_LINT() + +PY_SRCS( + TOP_LEVEL + contextlib2/__init__.py + contextlib2/__init__.pyi +) + +RESOURCE_FILES( + PREFIX contrib/python/contextlib2/py3/ + .dist-info/METADATA + .dist-info/top_level.txt + contextlib2/py.typed +) + +END() diff --git a/contrib/python/contextlib2/ya.make b/contrib/python/contextlib2/ya.make new file mode 100644 index 0000000000..00b1b55ba1 --- /dev/null +++ b/contrib/python/contextlib2/ya.make @@ -0,0 +1,18 @@ +PY23_LIBRARY() + +LICENSE(Service-Py23-Proxy) + +IF (PYTHON2) + PEERDIR(contrib/python/contextlib2/py2) +ELSE() + PEERDIR(contrib/python/contextlib2/py3) +ENDIF() + +NO_LINT() + +END() + +RECURSE( + py2 + py3 +) |