Pattern matching on function parameters in Python

As a Pythonic way in Python 3.X (but not 2.X), you can attach annotation information (arbitrary user-defined data about a function’s arguments and result) to a function object. Here you can use this feature in a decorator to wrap your function to check the range of your arguments.

For example you can use the following range test function :

def rangetest(func):
    def onCall(**kargs):
        argchecks = func.__annotations__

        if all(val in range(*argchecks.get(arg)) for arg,val in kargs.items()):
            return func(**kargs)
        else :
              print ("invalid arg range")
    return onCall


@rangetest
def func(a:(1, 5), b:(4,7), c:(0, 10)):
    print(a + b + c)

Demo :

func(a=2, b=6, c=8)
16
func(a=2, b=6, c=15)
invalid arg range

There is some point here. The first is that, since the annotation information is within a dictionary (python returns it as a dictionary) and dictionaries don't have a specific order, you need to use keyword arguments in your function to be able to get its relative range in annotation information dictionary.

Also here I just used numeric range but you can use some custom ranges like list of words like what you show in your question.But inside the all you need to check its type then based on its type use a proper operation :

all(kwargs.get(arg) in range(*arg_range) if is instance (arg_range,tuple) else kwargs.get(arg) in arg_range for arg,arg_range in argchecks.items())