Advertisement
Guest User

Untitled

a guest
May 24th, 2016
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.35 KB | None | 0 0
  1. def check(self,param,annot,value,check_history=''):
  2.  
  3. # Define local functions for checking, list/tuple, dict, set/frozenset,
  4. # lambda/functions, and str (str for extra credit)
  5. # Many of these local functions called by check, call check on their
  6. # elements (thus are indirectly recursive)
  7. def list_tuple_check(p):
  8. 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)
  9. if len(annot) != 1:
  10. 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)
  11. a_list = list(zip(annot,value))
  12. for key,val in a_list:
  13. self.check(param, key,val,'{}{}[{}] check: {}\n'.format(check_history,type_as_str(value),str(value.index(val)),str(annot.index(key))))
  14. else:
  15. for ann in annot:
  16. for val in value:
  17. self.check(param, ann,val,'{}{}[{}] check: {}\n'.format(check_history,type_as_str(value),str(value.index(val)),str(ann)))
  18.  
  19. # Return result of calling decorated function call, checking present
  20. # parameter/return annotations if required
  21. def __call__(self, *args, **kargs):
  22.  
  23. # Return a dictionary of the parameter/argument bindings (actually an
  24. # ordereddict, in the order parameters occur in the function's header)
  25. def param_arg_bindings():
  26. f_signature = inspect.signature(self._f)
  27. bound_f_signature = f_signature.bind(*args,**kargs)
  28. for param in f_signature.parameters.values():
  29. if param.name not in bound_f_signature.arguments:
  30. bound_f_signature.arguments[param.name] = param.default
  31. return bound_f_signature.arguments
  32.  
  33. # If annotation checking is turned off at the class or function level
  34. # just return the result of calling the decorated function
  35. # Otherwise do all the annotation checking
  36. if not (Check_Annotation.checking_on and self.checking_on):
  37. return self._f(*args, **kargs)
  38.  
  39. self._b = param_arg_bindings()
  40.  
  41. try:
  42. # Check the annotation for every parameter (if there is one)
  43. for x,y in self._b.items():
  44. if x in self._f.__annotations__:
  45. self.check(x, self._f.__annotations__[x], y)
  46. # Compute/remember the value of the decorated function
  47. v = self._f(*args, **kargs)
  48. # If 'return' is in the annotation, check it
  49. if 'return' in self._f.__annotations__:
  50. self._b['_return'] = v
  51. self.check('_return', self._f.__annotations__['return'], v)
  52. # Return the decorated answer
  53. return v
  54.  
  55. # On first AssertionError, print the source lines of the function and reraise
  56. except AssertionError:
  57. print(80*'-')
  58. for l in inspect.getsourcelines(self._f)[0]: # ignore starting line #
  59. print(l.rstrip())
  60. print(80*'-')
  61. raise
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement