Advertisement
Guest User

Untitled

a guest
Jan 23rd, 2017
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.21 KB | None | 0 0
  1. class Implementation(object):
  2. """
  3. Implementation object collection all methods for a given implementation
  4. """
  5.  
  6. def __init__(self):
  7. self.funcMap = {}
  8. self._currentInstance = None
  9.  
  10. def __get__(self, instance, instanceCls):
  11. # set the current instance
  12. self._currentInstance = instance
  13. # return self, this mains the object will __getattr__ calls for methods
  14. return self
  15.  
  16. def __getattr__(self, attr):
  17. # get a method
  18. # if the curren instance does not have the attr
  19. # raise an not implemented error
  20. if not hasattr(self._currentInstance, attr):
  21. raise NotImplementedError("'%s' not implemented" % attr)
  22. def attrWrapper(*args, **kwargs):
  23. # loop over all parent classes
  24. for cls in self._currentInstance.__class__.__mro__:
  25. # check if the cls has that attr
  26. if hasattr(cls, attr):
  27. # get the function
  28. func = getattr(cls, attr)
  29. # check if the function is wrapped
  30. if hasattr(func, "wrappedFunc"):
  31. # check the wrapped function is in the function map
  32. # it can happen multiple implementation have wrapped functions
  33. # with the same attr name
  34. if func.wrappedFunc == self.funcMap[attr]:
  35. # call the function with the current instance
  36. result = func.wrappedFunc(self._currentInstance, *args, **kwargs)
  37. # reset the currentInstance
  38. self._currentInstance = None
  39. # return the result
  40. return result
  41. # decorate by returning an attrWrapper
  42. return attrWrapper
  43.  
  44. def implement(self, func):
  45. # `implement` decorates the function
  46. # accisible through an implementation
  47.  
  48. # if this is called without an implementation
  49. # it will search in the parent classes for the same
  50. # function by name, if not available it will raise
  51. # a NotImplementedError
  52.  
  53. # get the name of the decorated func
  54. name = func.__name__
  55. # map the func
  56. self.funcMap[name] = func
  57. # the decorator wrapper
  58. def wrapper(instance, *args, **kwargs):
  59. found = False
  60. # loop over all parent classes
  61. for cls in instance.__class__.__mro__:
  62. # check if func name is available
  63. if hasattr(cls, name):
  64. # get the func
  65. func = getattr(cls, name)
  66. # check if the function is not a wrapped func
  67. if not hasattr(func, "wrappedFunc"):
  68. # set found flag to true
  69. found = True
  70. break
  71. # if not found raise NotImplementedError
  72. if found is False:
  73. raise NotImplementedError("'%s' not implemented" % name)
  74. # call that found function
  75. return func(instance, *args, **kwargs)
  76. # tag the wrapped decorator with the wrapped func
  77. wrapper.wrappedFunc = func
  78. # decorate by returning an wrapper
  79. return wrapper
  80.  
  81.  
  82. ####
  83.  
  84. class BaseContour(object):
  85.  
  86. def aMethod(self, point):
  87. return "BaseContour aMethod", point
  88.  
  89.  
  90. class BetaContour(BaseContour):
  91.  
  92. beta = Implementation()
  93.  
  94. @beta.implement
  95. def aMethod(self, point):
  96. return "BetaContour aMethod", point
  97.  
  98. @beta.implement
  99. def moreMethods(self, foo):
  100. return "BetaContour moreMethods", foo
  101.  
  102.  
  103. class Contour(BetaContour):
  104.  
  105. roboFont = Implementation()
  106.  
  107. @roboFont.implement
  108. def aMethod(self, point, test):
  109. return "Contour aMethod", point, test
  110.  
  111. @BetaContour.beta.implement
  112. def testing(self, someThing):
  113. return "Contour testing", someThing
  114.  
  115.  
  116. c = Contour()
  117.  
  118. print c.aMethod((10, 10))
  119. print c.beta.aMethod((20, 20)), "-"
  120. print c.roboFont.aMethod((30, 30), False)
  121. print c.roboFont.aMethod("ll", "kk")
  122. print c.beta.moreMethods("bar")
  123. # print c.roboFont.aMethoddfsdf("ll", "kk") # raise error
  124. print c.beta.testing("hello")
  125. # print c.testing("hello") # raise error
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement