def func( :( )bc:( ))print( cthat isthe range constraints would be moved into the function itselfinstead of being coded externally the following script illustrates the structure of the resulting decorators under both schemesin incomplete skeleton code for brevity the decorator arguments code pattern is that of our complete solution shown earlierthe annotation alternative requires one less level of nestingbecause it doesn' need to retain decorator arguments as stateusing decorator arguments ( xdef rangetest(**argchecks)def ondecorator(func)def oncall(*pargs**kargs)print(argchecksfor check in argcheckspass return func(*pargs**kargsreturn oncall return ondecorator add validation code here @rangetest( =( ) =( )def func(abc)print( cfunc rangetest)(funcfunc( = runs oncallargchecks in scope using function annotations ( onlydef rangetest(func)def oncall(*pargs**kargs)argchecks func __annotations__ print(argchecksfor check in argcheckspass return func(*pargs**kargsreturn oncall add validation code here @rangetest def func( :( )bc:( ))print( cfunc rangetest(funcfunc( = runs oncallannotations on func when runboth schemes have access to the same validation test informationbut in different forms--the decorator argument version' information is retained in an argument in an enclosing scopeand the annotation version' information is retained in an attribute of the function itself in onlydue to the use of function annotationsc:\codepy - decoargs-vs-annotation py {' '( )' '( ) examplevalidating function arguments