Advertisement
Guest User

WithFinals

a guest
Dec 5th, 2016
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.09 KB | None | 0 0
  1. #!/usr/bin/evn python3
  2.  
  3. import functools
  4.  
  5. buffer = set()
  6.  
  7.  
  8. class WithFinals(type):
  9.     def __init__(cls, name, bases, dct):
  10.         finals = set()
  11.  
  12.         # updating finals
  13.         for base in bases:
  14.             if hasattr(base, 'finals'):
  15.                 finals.update(base.finals)
  16.  
  17.         # creating methods
  18.         def get_methods(cls_dct):
  19.             meths = set()
  20.             for key in cls_dct:
  21.                 if callable(cls_dct[key]):
  22.                     meths.add(key)
  23.             return meths
  24.  
  25.         methods = get_methods(dct)
  26.  
  27.         if len(methods & finals) >= 1:
  28.             raise AttributeError
  29.  
  30.         for item in buffer:
  31.             if item in finals:
  32.                 raise AttributeError
  33.             else:
  34.                 finals.add(item.__name__)
  35.  
  36.         # check parents in mro
  37.  
  38.         mro = cls.mro()[1:-1]
  39.         if len(mro) >= 2:
  40.             ln = len(mro) - 1
  41.             if type(mro[ln]) is WithFinals:
  42.                 united_finals = mro[ln].finals
  43.             else:
  44.                 united_finals = set()
  45.  
  46.             for i in range(ln, 0, -1):
  47.                 if type(mro[i - 1]) is WithFinals:
  48.                     cls_finals = mro[i - 1].finals
  49.                     cls_methods = mro[i - 1].methods
  50.                 else:
  51.                     cls_finals = set()
  52.                     cls_methods = get_methods(mro[i - 1].__dict__)
  53.  
  54.                 if len(united_finals & cls_finals) >= 1 or \
  55.                         len(united_finals & cls_methods) >= 1:
  56.                     raise AttributeError
  57.  
  58.                 united_finals |= cls_finals
  59.  
  60.         super(WithFinals, cls).__init__(name, bases, dct)
  61.         setattr(cls, 'finals', finals)
  62.         setattr(cls, 'methods', methods)
  63.         buffer.clear()
  64.  
  65.  
  66. def final(method):
  67.     buffer.add(method)
  68.  
  69.     @functools.wraps(method)
  70.     def inner(self, *args, **kwargs):
  71.         return method(self, *args, **kwargs)
  72.     return inner
  73.  
  74.  
  75. class A(metaclass=WithFinals):
  76.     @final
  77.     def foo(self):
  78.         pass
  79.  
  80.  
  81. class X(metaclass=WithFinals):
  82.     @final
  83.     def foo(self):
  84.         pass
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement