add_called_class_as_argument

Full name: ase2sprkkr.common.decorators.add_called_class_as_argument

ase2sprkkr.common.decorators.add_called_class_as_argument(decorator)[source]

If a decorator is used on a method, the information about the defining class is lost. As a consequence, the execution of super().... failed.

This decorator can be applied to another decorator: it will add the defining class as a first argument of the resulting function.

The implementation is very tricky - function-style decorator is not able to handle this situation, the __set_name__ special method (in class-style decorator) has to be utilized. Moreover, class style decorator lose ‘self’ from decorated method, thus, the self has to be recovered using descriptor protocol. To speed up the whole thing, the first access replaces the class-style decorator class with generated method (that can already know - and knows - everything needed)

Example

>>> @add_called_class_as_argument
... def decorator(func):
...
...       def wrapped(cls, self):
...            super(cls, self).call()
...            func(self)
...       return wrapped
...
>>> class A:
...    def call(self):
...         print('A', end='')
...
>>> class B(A):
...      @decorator
...      def call(self):
...           print('B', end='')
...
>>> B().call()
AB