PKZzGS S go_defer.py""" Go's defer for python. The idea behind defer is very simple. Defer postpones a call to a function till the end of the enclosing function call. Defer calls are pushed to a stack and called in LIFO (last-in-first-out) order. Example:: >>> @with_defer ... def foo(): ... for i in range(4): ... defer(print, i) >>> foo() 3 2 1 0 """ from __future__ import print_function, absolute_import import functools import inspect import logging __all__ = ('defer', 'with_defer') class _defer_chain(object): def __init__(self): self._chain = [] def defer(self, fn, args, kwargs, filename, lineno): self._chain.append((fn, args, kwargs, filename, lineno)) def cleanup(self): if self._chain is None: return for fn, args, kwargs, filename, lineno in reversed(self._chain): try: fn(*args, **kwargs) except Exception as exc: logging.error( "defer call in %s:%d raised: %s", filename, lineno, exc) self._chain = None def __enter__(self): return self def __exit__(self, exc_type, exc_value, traceback): self.cleanup() def with_defer(fn): """ Decorator for functions that use defer() :param fn: Function to decorate :returns: Decorated function that can now use defer() """ @functools.wraps(fn) def wrapper(*args, **kwargs): with _defer_chain() as __defer__: __defer__ # Just to seem used return fn(*args, **kwargs) return wrapper def defer(fn, *args, **kwargs): """ Defer the call to fn(...) until the end of the function scope. :param fn: The function to call :param args: Positional arguments to pass to the function :param kwargs: Keyword arguments to pass to the function """ with_defer_f = inspect.stack(context=0)[2][0] caller_f = inspect.stack(context=0)[1][0] try: if '__defer__' not in with_defer_f.f_locals: raise TypeError("decorate {} with @defer.with_defer".format( with_defer_f.f_code.co_name)) with_defer_f.f_locals['__defer__'].defer( fn, args, kwargs, caller_f.f_code.co_filename, caller_f.f_lineno) finally: del with_defer_f del caller_f PKq]zG^- (go_defer-1.0.1.dist-info/DESCRIPTION.rstUNKNOWN PKq]zG(&go_defer-1.0.1.dist-info/metadata.json{"classifiers": ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy"], "extensions": {"python.details": {"contacts": [{"email": "", "name": "Zygmunt Krynicki", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://github.com/zyga/go-defer"}}}, "generator": "bdist_wheel (0.26.0)", "license": "BSD", "metadata_version": "2.0", "name": "go-defer", "summary": "Go's defer for Python", "version": "1.0.1"}PKq]zG5gm &go_defer-1.0.1.dist-info/top_level.txtgo_defer PKq]zGndnngo_defer-1.0.1.dist-info/WHEELWheel-Version: 1.0 Generator: bdist_wheel (0.26.0) Root-Is-Purelib: true Tag: py2-none-any Tag: py3-none-any PKq]zGݎZZ!go_defer-1.0.1.dist-info/METADATAMetadata-Version: 2.0 Name: go-defer Version: 1.0.1 Summary: Go's defer for Python Home-page: https://github.com/zyga/go-defer Author: Zygmunt Krynicki Author-email: License: BSD Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.2 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy UNKNOWN PKq]zGrC>55go_defer-1.0.1.dist-info/RECORDgo_defer.py,sha256=yUEHTvXYjp2fh9gRmSZJk16P9UWDY4spdm_CfR97EJ0,2387 go_defer-1.0.1.dist-info/DESCRIPTION.rst,sha256=OCTuuN6LcWulhHS3d5rfjdsQtW22n7HENFRh6jC6ego,10 go_defer-1.0.1.dist-info/METADATA,sha256=Pt-6oaDcz2JW7FTM8v6bTDLQlC1VxmnO5Jy_pbbI6ls,858 go_defer-1.0.1.dist-info/RECORD,, go_defer-1.0.1.dist-info/WHEEL,sha256=GrqQvamwgBV4nLoJe0vhYRSWzWsx7xjlt74FT0SWYfE,110 go_defer-1.0.1.dist-info/metadata.json,sha256=RPQTTsLANDACLfC7Yi4qg3U0YI6AienwcWSsrNtI5mE,943 go_defer-1.0.1.dist-info/top_level.txt,sha256=We5-Lgq7oEQesRQ5Fq2uHKr-LczEelRqqu1l1nBS7Hk,9 PKZzGS S go_defer.pyPKq]zG^- (| go_defer-1.0.1.dist-info/DESCRIPTION.rstPKq]zG(& go_defer-1.0.1.dist-info/metadata.jsonPKq]zG5gm & go_defer-1.0.1.dist-info/top_level.txtPKq]zGndnn go_defer-1.0.1.dist-info/WHEELPKq]zGݎZZ!go_defer-1.0.1.dist-info/METADATAPKq]zGrC>55Ogo_defer-1.0.1.dist-info/RECORDPK