aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/deprecated/python/backports-abc/backports_abc.py
diff options
context:
space:
mode:
authornkozlovskiy <nmk@ydb.tech>2023-10-02 18:57:38 +0300
committernkozlovskiy <nmk@ydb.tech>2023-10-02 19:39:06 +0300
commit6295ef4d23465c11296e898b9dc4524ad9592b5d (patch)
treefc0c852877b2c52f365a1f6ed0710955844338c2 /contrib/deprecated/python/backports-abc/backports_abc.py
parentde63c80b75948ecc13894854514d147840ff8430 (diff)
downloadydb-6295ef4d23465c11296e898b9dc4524ad9592b5d.tar.gz
oss ydb: fix dstool building and test run
Diffstat (limited to 'contrib/deprecated/python/backports-abc/backports_abc.py')
-rw-r--r--contrib/deprecated/python/backports-abc/backports_abc.py216
1 files changed, 216 insertions, 0 deletions
diff --git a/contrib/deprecated/python/backports-abc/backports_abc.py b/contrib/deprecated/python/backports-abc/backports_abc.py
new file mode 100644
index 0000000000..da4cb32983
--- /dev/null
+++ b/contrib/deprecated/python/backports-abc/backports_abc.py
@@ -0,0 +1,216 @@
+"""
+Patch recently added ABCs into the standard lib module
+``collections.abc`` (Py3) or ``collections`` (Py2).
+
+Usage::
+
+ import backports_abc
+ backports_abc.patch()
+
+or::
+
+ try:
+ from collections.abc import Generator
+ except ImportError:
+ from backports_abc import Generator
+"""
+
+try:
+ import collections.abc as _collections_abc
+except ImportError:
+ import collections as _collections_abc
+
+
+def get_mro(cls):
+ try:
+ return cls.__mro__
+ except AttributeError:
+ return old_style_mro(cls)
+
+
+def old_style_mro(cls):
+ yield cls
+ for base in cls.__bases__:
+ for c in old_style_mro(base):
+ yield c
+
+
+def mk_gen():
+ from abc import abstractmethod
+
+ required_methods = (
+ '__iter__', '__next__' if hasattr(iter(()), '__next__') else 'next',
+ 'send', 'throw', 'close')
+
+ class Generator(_collections_abc.Iterator):
+ __slots__ = ()
+
+ if '__next__' in required_methods:
+ def __next__(self):
+ return self.send(None)
+ else:
+ def next(self):
+ return self.send(None)
+
+ @abstractmethod
+ def send(self, value):
+ raise StopIteration
+
+ @abstractmethod
+ def throw(self, typ, val=None, tb=None):
+ if val is None:
+ if tb is None:
+ raise typ
+ val = typ()
+ if tb is not None:
+ val = val.with_traceback(tb)
+ raise val
+
+ def close(self):
+ try:
+ self.throw(GeneratorExit)
+ except (GeneratorExit, StopIteration):
+ pass
+ else:
+ raise RuntimeError('generator ignored GeneratorExit')
+
+ @classmethod
+ def __subclasshook__(cls, C):
+ if cls is Generator:
+ mro = get_mro(C)
+ for method in required_methods:
+ for base in mro:
+ if method in base.__dict__:
+ break
+ else:
+ return NotImplemented
+ return True
+ return NotImplemented
+
+ generator = type((lambda: (yield))())
+ Generator.register(generator)
+ return Generator
+
+
+def mk_awaitable():
+ from abc import abstractmethod, ABCMeta
+
+ @abstractmethod
+ def __await__(self):
+ yield
+
+ @classmethod
+ def __subclasshook__(cls, C):
+ if cls is Awaitable:
+ for B in get_mro(C):
+ if '__await__' in B.__dict__:
+ if B.__dict__['__await__']:
+ return True
+ break
+ return NotImplemented
+
+ # calling metaclass directly as syntax differs in Py2/Py3
+ Awaitable = ABCMeta('Awaitable', (), {
+ '__slots__': (),
+ '__await__': __await__,
+ '__subclasshook__': __subclasshook__,
+ })
+
+ return Awaitable
+
+
+def mk_coroutine():
+ from abc import abstractmethod
+
+ class Coroutine(Awaitable):
+ __slots__ = ()
+
+ @abstractmethod
+ def send(self, value):
+ """Send a value into the coroutine.
+ Return next yielded value or raise StopIteration.
+ """
+ raise StopIteration
+
+ @abstractmethod
+ def throw(self, typ, val=None, tb=None):
+ """Raise an exception in the coroutine.
+ Return next yielded value or raise StopIteration.
+ """
+ if val is None:
+ if tb is None:
+ raise typ
+ val = typ()
+ if tb is not None:
+ val = val.with_traceback(tb)
+ raise val
+
+ def close(self):
+ """Raise GeneratorExit inside coroutine.
+ """
+ try:
+ self.throw(GeneratorExit)
+ except (GeneratorExit, StopIteration):
+ pass
+ else:
+ raise RuntimeError('coroutine ignored GeneratorExit')
+
+ @classmethod
+ def __subclasshook__(cls, C):
+ if cls is Coroutine:
+ mro = get_mro(C)
+ for method in ('__await__', 'send', 'throw', 'close'):
+ for base in mro:
+ if method in base.__dict__:
+ break
+ else:
+ return NotImplemented
+ return True
+ return NotImplemented
+
+ return Coroutine
+
+
+###
+# make all ABCs available in this module
+
+try:
+ Generator = _collections_abc.Generator
+except AttributeError:
+ Generator = mk_gen()
+
+try:
+ Awaitable = _collections_abc.Awaitable
+except AttributeError:
+ Awaitable = mk_awaitable()
+
+try:
+ Coroutine = _collections_abc.Coroutine
+except AttributeError:
+ Coroutine = mk_coroutine()
+
+try:
+ from inspect import isawaitable
+except ImportError:
+ def isawaitable(obj):
+ return isinstance(obj, Awaitable)
+
+
+###
+# allow patching the stdlib
+
+PATCHED = {}
+
+
+def patch(patch_inspect=True):
+ """
+ Main entry point for patching the ``collections.abc`` and ``inspect``
+ standard library modules.
+ """
+ PATCHED['collections.abc.Generator'] = _collections_abc.Generator = Generator
+ PATCHED['collections.abc.Coroutine'] = _collections_abc.Coroutine = Coroutine
+ PATCHED['collections.abc.Awaitable'] = _collections_abc.Awaitable = Awaitable
+
+ if patch_inspect:
+ import inspect
+ PATCHED['inspect.isawaitable'] = inspect.isawaitable = isawaitable