Async Deferred Function Tools

Provides a Golang-like defer() API using decorators, which allows grouping resource initialization and cleanup in one place without extra indentations.

Example:

async def init(x):
    ...

async def cleanup(x):
    ...

@aiotools.adefer
async def do(defer):  # <-- be aware of defer argument!
    x = SomeResource()
    await init(x)
    defer(cleanup(x))
    ...
    ...

This is equivalent to:

async def do():
    x = SomeResource()
    await init(x)
    try:
        ...
        ...
    finally:
        await cleanup(x)

Note that aiotools.context.AsyncContextGroup or contextlib.AsyncExitStack serves well for the same purpose, but for simple cleanups, this defer API makes your codes simple because it steps aside the main execution context without extra indentations.

Warning

Any exception in the deferred functions is raised transparently, and may block execution of the remaining deferred functions. This behavior may be changed in the future versions, though.

defer(func)[source]

A synchronous version of the defer API. It can only defer normal functions.

adefer(func)[source]

An asynchronous version of the defer API. It can defer coroutine functions, coroutines, and normal functions.