Advertisement
Guest User

Untitled

a guest
May 24th, 2016
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.17 KB | None | 0 0
  1. from goody import type_as_str
  2. import inspect
  3.  
  4. class Check_All_OK:
  5. """
  6. Check_All_OK class implements __check_annotation__ by checking whether each
  7. annotation passed to its constructor is OK; the first one that
  8. fails (by raising AssertionError) prints its problem, with a list of all
  9. annotations being tried at the end of the check_history.
  10. """
  11.  
  12. def __init__(self,*args):
  13. self._annotations = args
  14.  
  15. def __repr__(self):
  16. return 'Check_All_OK('+','.join([str(i) for i in self._annotations])+')'
  17.  
  18. def __check_annotation__(self, check, param, value,check_history):
  19. for annot in self._annotations:
  20. check(param, annot, value, check_history+'Check_All_OK check: '+str(annot)+' while trying: '+str(self)+'\n')
  21.  
  22.  
  23. class Check_Any_OK:
  24. """
  25. Check_Any_OK implements __check_annotation__ by checking whether at least
  26. one of the annotations passed to its constructor is OK; if all fail
  27. (by raising AssertionError) this classes raises AssertionError and prints
  28. its failure, along with a list of all annotations tried followed by the
  29. check_history.
  30. """
  31.  
  32. def __init__(self,*args):
  33. self._annotations = args
  34.  
  35. def __repr__(self):
  36. return 'Check_Any_OK('+','.join([str(i) for i in self._annotations])+')'
  37.  
  38. def __check_annotation__(self, check, param, value, check_history):
  39. failed = 0
  40. for annot in self._annotations:
  41. try:
  42. check(param, annot, value, check_history)
  43. except AssertionError:
  44. failed += 1
  45. if failed == len(self._annotations):
  46. assert False, repr(param)+' failed annotation check(Check_Any_OK): value = '+repr(value)+\
  47. '\n tried '+str(self)+'\n'+check_history
  48.  
  49.  
  50.  
  51. class Check_Annotation():
  52. # set this name to True for checking to occur
  53. checking_on = True
  54.  
  55. # self._checking_on must also be true for checking to occur
  56. def __init__(self,f):
  57. self._f = f
  58. self.checking_on = True
  59.  
  60. # Check whether param's annot is correct for value, adding to check_history
  61. # if recurs; defines many local function which use it parameters.
  62. def check(self,param,annot,value,check_history=''):
  63.  
  64. # Define local functions for checking, list/tuple, dict, set/frozenset,
  65. # lambda/functions, and str (str for extra credit)
  66. # Many of these local functions called by check, call check on their
  67. # elements (thus are indirectly recursive)
  68. def list_tuple_check(p):
  69. 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)
  70. if len(annot) != 1:
  71. 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)
  72. a_list = list(zip(annot,value))
  73. for key,val in a_list:
  74. self.check(param, key,val,'{}{}[{}] check: {}\n'.format(check_history,type_as_str(value),str(value.index(val)),str(annot.index(key))))
  75. else:
  76. for ann in annot:
  77. for val in value:
  78. self.check(param, ann,val,'{}{}[{}] check: {}\n'.format(check_history,type_as_str(value),str(value.index(val)),str(ann)))
  79.  
  80. # Return result of calling decorated function call, checking present
  81. # parameter/return annotations if required
  82. def __call__(self, *args, **kargs):
  83.  
  84. # Return a dictionary of the parameter/argument bindings (actually an
  85. # ordereddict, in the order parameters occur in the function's header)
  86. def param_arg_bindings():
  87. f_signature = inspect.signature(self._f)
  88. bound_f_signature = f_signature.bind(*args,**kargs)
  89. for param in f_signature.parameters.values():
  90. if param.name not in bound_f_signature.arguments:
  91. bound_f_signature.arguments[param.name] = param.default
  92. return bound_f_signature.arguments
  93.  
  94. # If annotation checking is turned off at the class or function level
  95. # just return the result of calling the decorated function
  96. # Otherwise do all the annotation checking
  97. if not (Check_Annotation.checking_on and self.checking_on):
  98. return self._f(*args, **kargs)
  99.  
  100. self._b = param_arg_bindings()
  101.  
  102. try:
  103. # Check the annotation for every parameter (if there is one)
  104. for x,y in self._b.items():
  105. if x in self._f.__annotations__:
  106. self.check(x, self._f.__annotations__[x], y)
  107. # Compute/remember the value of the decorated function
  108. v = self._f(*args, **kargs)
  109. # If 'return' is in the annotation, check it
  110. if 'return' in self._f.__annotations__:
  111. self._b['_return'] = v
  112. self.check('_return', self._f.__annotations__['return'], v)
  113. # Return the decorated answer
  114. return v
  115.  
  116. # On first AssertionError, print the source lines of the function and reraise
  117. except AssertionError:
  118. #===================================================================
  119. # print(80*'-')
  120. # for l in inspect.getsourcelines(self._f)[0]: # ignore starting line #
  121. # print(l.rstrip())
  122. # print(80*'-')
  123. #===================================================================
  124. raise
  125.  
  126.  
  127.  
  128.  
  129.  
  130. if __name__ == '__main__':
  131. # an example of testing a simple annotation
  132. #===========================================================================
  133. # def f(x:int): pass
  134. # f = Check_Annotation(f)
  135. # f(3)
  136. # f('a')
  137. #===========================================================================
  138.  
  139. import driver
  140. driver.driver()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement