Go defer style cleanups--in reality, just a convenience wrapper over try-finally

def deferred_cleanup(fn):
    """Go defer style cleanups--in reality, just a convenience wrapper over try-finally"""
    @functools.wraps(fn)
    def ret(*args, **kwargs):
        defers = []
        try:
            ret = fn(lambda *args: defers.extend(args), *args, **kwargs)
        finally:
            for defer in reversed(defers):
                defer()
        return ret
    return ret