Search code examples
pythondecorator

Decorator for cheking any function annotation type


i want to design a decorator to check any function annotation type and if it has similar type then run function. can python do such this thing?? if python can, please help me!!

def foo (a:int):
    if foo.__annotations__.get('a') == type(a):
        pass

def boo (b:str):
    if boo.__annotations__.get('b') == type(b):
        pass

and another thing is annotations is a dict type, i want such this :

from type import FunctionType
def check (f:FunctionType):
    result = True
    k = [k for k in f.__annotations__.keys()]
    v = [v for v in f.__annotations__.values()]
    for i in range(len(v)):
        if v[i] != type(k[i]): #but we don't access to the type of k[i] out of th f function
            result = False
    return result       

Solution

  • If I understand the idea correctly, perhaps this code will help you:

    from types import FunctionType
    
    def check(f: FunctionType):
        def wrapper(*args, **kwargs):
            result = True
    
            # check args
            keys = tuple(f.__annotations__.keys())
            for ar in enumerate(args):
                if not isinstance(ar[1], f.__annotations__.get(keys[ar[0]])):
                    result = False
                    break
    
            if result:
                # check kwargs
                for k, v in kwargs.items():
                    if not isinstance(v, f.__annotations__.get(k)):
                        result = False
                        break
    
            if result:
                f(*args, **kwargs)
    
        return wrapper
    

    Example usage:

    @check
    def foo(a: str, b: int = None):
        print(f"a  = {a}")
        print(f"b  = {b}")
    
    
    # Example 1: a=324, b=32:
    foo(234, b=32)
    # result: function not executed
    
    # Example 2: a="abc", b="zzz":
    foo("abc", b="zzz")
    # result: function not executed
    
    # Example 3: a="qwe", b= not set:
    foo("qwe")
    # result: function executed, output:
    # a  = qwe
    # b  = None
    
    # Example 4: a="abc", b=99:
    foo("abc", 99)
    # result: function executed, output:
    # a  = abc
    # b  = 99
    

    The decorator checks the argument types, and if everything is in order, it executes the function, otherwise it does nothing.