Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- def check(self,param,annot,value,check_history=''):
- # Define local functions for checking, list/tuple, dict, set/frozenset,
- # lambda/functions, and str (str for extra credit)
- # Many of these local functions called by check, call check on their
- # elements (thus are indirectly recursive)
- def list_tuple_check(p):
- assert isinstance(value,p), '{} failed annotation check(wrong type): value = {}\n was type {} ...should be type {}\n{}'.format(repr(param), repr(value), type_as_str(value), str(p), check_history)
- if len(annot) != 1:
- assert len(annot) == len(value) ,'{} failed annotation check(wrong number of elements): value = {}\n annotation had {} elements{}\n{}'.format(repr(param), repr(value), str(len(annot)),str(annot),check_history)
- a_list = list(zip(annot,value))
- for key,val in a_list:
- self.check(param, key,val,'{}{}[{}] check: {}\n'.format(check_history,type_as_str(value),str(value.index(val)),str(annot.index(key))))
- else:
- for ann in annot:
- for val in value:
- self.check(param, ann,val,'{}{}[{}] check: {}\n'.format(check_history,type_as_str(value),str(value.index(val)),str(ann)))
- # Return result of calling decorated function call, checking present
- # parameter/return annotations if required
- def __call__(self, *args, **kargs):
- # Return a dictionary of the parameter/argument bindings (actually an
- # ordereddict, in the order parameters occur in the function's header)
- def param_arg_bindings():
- f_signature = inspect.signature(self._f)
- bound_f_signature = f_signature.bind(*args,**kargs)
- for param in f_signature.parameters.values():
- if param.name not in bound_f_signature.arguments:
- bound_f_signature.arguments[param.name] = param.default
- return bound_f_signature.arguments
- # If annotation checking is turned off at the class or function level
- # just return the result of calling the decorated function
- # Otherwise do all the annotation checking
- if not (Check_Annotation.checking_on and self.checking_on):
- return self._f(*args, **kargs)
- self._b = param_arg_bindings()
- try:
- # Check the annotation for every parameter (if there is one)
- for x,y in self._b.items():
- if x in self._f.__annotations__:
- self.check(x, self._f.__annotations__[x], y)
- # Compute/remember the value of the decorated function
- v = self._f(*args, **kargs)
- # If 'return' is in the annotation, check it
- if 'return' in self._f.__annotations__:
- self._b['_return'] = v
- self.check('_return', self._f.__annotations__['return'], v)
- # Return the decorated answer
- return v
- # On first AssertionError, print the source lines of the function and reraise
- except AssertionError:
- print(80*'-')
- for l in inspect.getsourcelines(self._f)[0]: # ignore starting line #
- print(l.rstrip())
- print(80*'-')
- raise
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement