of the expected arguments list)but we'll pass on such an extension here decorator nesting finallyand perhaps most subtlythis code' approach does not fully support use of decorator nesting to combine steps because it analyzes arguments using names in function definitionsand the names of the call proxy function returned by nested decoration won' correspond to argument names in either the original function or decorator argumentsit does not fully support use in nested mode technicallywhen nestedonly the most deeply nested appearance' validations are run in fullall other nesting levels run tests on arguments passed by keyword only trace the code to see whybecause the oncall proxy' call signature expects no named positional argumentsany to-be-validated arguments passed to it by position are treated as if they were omitted and hence defaultedand are thus skipped this may be inherent in this tool' approach--proxies change the argument name signatures at their levelsmaking it impossible to directly map names in decorator arguments to positions in passed argument sequences when proxies are presentargument names ultimately apply to keywords onlyby contrastthe first-cut solution' argument positions may support proxies betterbut do not fully support keywords in lieu of this nesting capabilitywe'll generalize this decorator to support multiple types of validations in single decoration in an end-of-quiz solutionwhich also gives examples of the nesting limitation in action since we've already neared the space allocation for this examplethoughif you care about these or any other further improvementsyou've officially crossed over into the realm of suggested exercises decorator arguments versus function annotations interestinglythe function annotation feature introduced in python ( and latercould provide an alternative to the decorator arguments used by our example to specify range tests as we learned in annotations allow us to associate expressions with arguments and return valuesby coding them in the def header line itselfpython collects annotations in dictionary and attaches it to the annotated function we could use this in our example to code range limits in the header lineinstead of in decorator arguments we would still need function decorator to wrap the function in order to intercept later callsbut we would essentially trade decorator argument syntax@rangetest( =( ) =( )def func(abc)print( cfor annotation syntax like this decorators func rangetest)(func