Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class Implementation(object):
- """
- Implementation object collection all methods for a given implementation
- """
- def __init__(self):
- self.funcMap = {}
- self._currentInstance = None
- def __get__(self, instance, instanceCls):
- # set the current instance
- self._currentInstance = instance
- # return self, this mains the object will __getattr__ calls for methods
- return self
- def __getattr__(self, attr):
- # get a method
- # if the curren instance does not have the attr
- # raise an not implemented error
- if not hasattr(self._currentInstance, attr):
- raise NotImplementedError("'%s' not implemented" % attr)
- def attrWrapper(*args, **kwargs):
- # loop over all parent classes
- for cls in self._currentInstance.__class__.__mro__:
- # check if the cls has that attr
- if hasattr(cls, attr):
- # get the function
- func = getattr(cls, attr)
- # check if the function is wrapped
- if hasattr(func, "wrappedFunc"):
- # check the wrapped function is in the function map
- # it can happen multiple implementation have wrapped functions
- # with the same attr name
- if func.wrappedFunc == self.funcMap[attr]:
- # call the function with the current instance
- result = func.wrappedFunc(self._currentInstance, *args, **kwargs)
- # reset the currentInstance
- self._currentInstance = None
- # return the result
- return result
- # decorate by returning an attrWrapper
- return attrWrapper
- def implement(self, func):
- # `implement` decorates the function
- # accisible through an implementation
- # if this is called without an implementation
- # it will search in the parent classes for the same
- # function by name, if not available it will raise
- # a NotImplementedError
- # get the name of the decorated func
- name = func.__name__
- # map the func
- self.funcMap[name] = func
- # the decorator wrapper
- def wrapper(instance, *args, **kwargs):
- found = False
- # loop over all parent classes
- for cls in instance.__class__.__mro__:
- # check if func name is available
- if hasattr(cls, name):
- # get the func
- func = getattr(cls, name)
- # check if the function is not a wrapped func
- if not hasattr(func, "wrappedFunc"):
- # set found flag to true
- found = True
- break
- # if not found raise NotImplementedError
- if found is False:
- raise NotImplementedError("'%s' not implemented" % name)
- # call that found function
- return func(instance, *args, **kwargs)
- # tag the wrapped decorator with the wrapped func
- wrapper.wrappedFunc = func
- # decorate by returning an wrapper
- return wrapper
- ####
- class BaseContour(object):
- def aMethod(self, point):
- return "BaseContour aMethod", point
- class BetaContour(BaseContour):
- beta = Implementation()
- @beta.implement
- def aMethod(self, point):
- return "BetaContour aMethod", point
- @beta.implement
- def moreMethods(self, foo):
- return "BetaContour moreMethods", foo
- class Contour(BetaContour):
- roboFont = Implementation()
- @roboFont.implement
- def aMethod(self, point, test):
- return "Contour aMethod", point, test
- @BetaContour.beta.implement
- def testing(self, someThing):
- return "Contour testing", someThing
- c = Contour()
- print c.aMethod((10, 10))
- print c.beta.aMethod((20, 20)), "-"
- print c.roboFont.aMethod((30, 30), False)
- print c.roboFont.aMethod("ll", "kk")
- print c.beta.moreMethods("bar")
- # print c.roboFont.aMethoddfsdf("ll", "kk") # raise error
- print c.beta.testing("hello")
- # print c.testing("hello") # raise error
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement