import sys from functools import wraps from textwrap import dedent from inspect import getfullargspec from typing import Callable, Sequence, Any from . import singleton DEFAULT = singleton('DEFAULT') defaults = [DEFAULT] try: from .mock import DEFAULT except ImportError: # pragma: no cover pass else: defaults.append(DEFAULT) def generator(*args): """ A utility function for creating a generator that will yield the supplied arguments. """ for i in args: yield i class Wrapping: attribute_name = None new = DEFAULT def __init__(self, before: Callable[[], None], after: Callable[[], None]): self.before, self.after = before, after def __enter__(self): return self.before() def __exit__(self, exc_type=None, exc_val=None, exc_tb=None): if self.after is not None: self.after() def wrap(before: Callable[[], Any], after: Callable[[], Any] = None): """ A decorator that causes the supplied callables to be called before or after the wrapped callable, as appropriate. """ wrapping = Wrapping(before, after) def wrapper(func): if hasattr(func, 'patchings'): func.patchings.append(wrapping) return func @wraps(func) def patched(*args, **keywargs): extra_args = [] entered_patchers = [] to_add = len(getfullargspec(func).args[len(args):]) added = 0 exc_info = (None, None, None) try: for patching in patched.patchings: arg = patching.__enter__() entered_patchers.append(patching) if patching.attribute_name is not None: keywargs.update(arg) elif patching.new in defaults and added < to_add: extra_args.append(arg) added += 1 args += tuple(extra_args) return func(*args, **keywargs) except: # Pass the exception to __exit__ exc_info = sys.exc_info() # re-raise the exception raise finally: for patching in reversed(entered_patchers): patching.__exit__(*exc_info) patched.patchings = [wrapping] return patched return wrapper def extend_docstring(docstring: str, objs: Sequence): for obj in objs: obj.__doc__ = dedent(obj.__doc__) + docstring def indent(text: str, indent_size: int = 2): indented = [] for do_indent, line in enumerate(text.splitlines(True)): if do_indent: line = ' '*indent_size + line indented.append(line) return ''.join(indented)
Name | Type | Size | Permission | Actions |
---|---|---|---|---|
__pycache__ | Folder | 0755 |
|
|
tests | Folder | 0755 |
|
|
__init__.py | File | 1.19 KB | 0644 |
|
comparison.py | File | 39.14 KB | 0644 |
|
compat.py | File | 224 B | 0644 |
|
components.py | File | 1.31 KB | 0644 |
|
datetime.py | File | 24.42 KB | 0644 |
|
django.py | File | 2.88 KB | 0644 |
|
logcapture.py | File | 10.75 KB | 0644 |
|
mock.py | File | 1.21 KB | 0644 |
|
outputcapture.py | File | 4.69 KB | 0644 |
|
popen.py | File | 9.89 KB | 0644 |
|
replace.py | File | 12.15 KB | 0644 |
|
resolve.py | File | 2.05 KB | 0644 |
|
rmtree.py | File | 2.52 KB | 0644 |
|
shouldraise.py | File | 3.58 KB | 0644 |
|
shouldwarn.py | File | 2.21 KB | 0644 |
|
sybil.py | File | 2.28 KB | 0644 |
|
tempdirectory.py | File | 12.89 KB | 0644 |
|
twisted.py | File | 4.8 KB | 0644 |
|
utils.py | File | 2.74 KB | 0644 |
|
version.txt | File | 6 B | 0644 |
|