PK±ZzGñÞS 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 PK0]zG^-Ò &go_defer-1.0.dist-info/DESCRIPTION.rstUNKNOWN PK0]zG]ûªª$go_defer-1.0.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/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"}PK0]zG…5gm $go_defer-1.0.dist-info/top_level.txtgo_defer PK0]zGìndªnngo_defer-1.0.dist-info/WHEELWheel-Version: 1.0 Generator: bdist_wheel (0.26.0) Root-Is-Purelib: true Tag: py2-none-any Tag: py3-none-any PK0]zG¾´kUUgo_defer-1.0.dist-info/METADATAMetadata-Version: 2.0 Name: go-defer Version: 1.0 Summary: Go's defer for Python Home-page: https://github.com/zyga/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 PK0]zG”—D²))go_defer-1.0.dist-info/RECORDgo_defer.py,sha256=yUEHTvXYjp2fh9gRmSZJk16P9UWDY4spdm_CfR97EJ0,2387 go_defer-1.0.dist-info/DESCRIPTION.rst,sha256=OCTuuN6LcWulhHS3d5rfjdsQtW22n7HENFRh6jC6ego,10 go_defer-1.0.dist-info/METADATA,sha256=Udr82ClfTn_Arxgqwxg_qrnTstx452mjMR-wPcy_S_k,853 go_defer-1.0.dist-info/RECORD,, go_defer-1.0.dist-info/WHEEL,sha256=GrqQvamwgBV4nLoJe0vhYRSWzWsx7xjlt74FT0SWYfE,110 go_defer-1.0.dist-info/metadata.json,sha256=mbi1T-R1zHEI-HOs9FzUvH7ehoixu7MMIvPI4ub6PVE,938 go_defer-1.0.dist-info/top_level.txt,sha256=We5-Lgq7oEQesRQ5Fq2uHKr-LczEelRqqu1l1nBS7Hk,9 PK±ZzGñÞS S go_defer.pyPK0]zG^-Ò &| go_defer-1.0.dist-info/DESCRIPTION.rstPK0]zG]ûªª$Ê go_defer-1.0.dist-info/metadata.jsonPK0]zG…5gm $¶ go_defer-1.0.dist-info/top_level.txtPK0]zGìndªnngo_defer-1.0.dist-info/WHEELPK0]zG¾´kUU©go_defer-1.0.dist-info/METADATAPK0]zG”—D²));go_defer-1.0.dist-info/RECORDPKŸ