deadpixi / contracts

An implementation of contracts for Python.
GNU Lesser General Public License v3.0
342 stars 18 forks source link

Async decorators #7

Closed asmodehn closed 6 years ago

asmodehn commented 6 years ago

How about adding decorators for async procedures ?

Something like :


def require_async(description, predicate):
    def asyncdec(func):
        @wraps(func)
        @dpcontracts.require(description, predicate)
        async def wrapper(*args, **kwargs):
            return await func(*args, **kwargs)
        return wrapper
    return asyncdec

or maybe better :


import dpcontracts
from functools import wraps

def require_async(description, predicate):
    requirement = dpcontracts.require(description, predicate)
    def asyncdec(func):
        funcreq = requirement(func)
        @wraps(func)
        async def wrapper(*args, **kwargs):
            funcreq(args)
            return await func(*args, **kwargs)
        return wrapper
    return asyncdec

Could then be used like that :

    import trio

    @require_async("n is an int", lambda args: isinstance(args.n, int))
    async def return_delay(n: int) -> int:
        await trio.sleep(2)
        return n

    res = trio.run(return_delay, "bob")

    print(res)
asmodehn commented 6 years ago

As it turns out it s quite non trivial to implement on top of the existing synchronous contracts (especially for ensure, checking the result after the run), so I went ahead and made #8