ContextMethodDecorator   A
last analyzed

Complexity

Total Complexity 6

Size/Duplication

Total Lines 47
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 47
rs 10
wmc 6

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __exit__() 0 4 2
A __init__() 0 23 1
A decorated() 0 5 1
A __enter__() 0 15 3
1
import functools
2
3
4
class ContextMethodDecorator():
5
    """A helper ContextManager decorating a method with a custom function."""
6
7
    def __init__(self, classx, method_name, decorator_func):
8
        """
9
        Create a new context manager decorating a function within its scope.
10
11
        This is a helper Context Manager that decorates a method of a class
12
        with a custom function.
13
        The decoration is only valid within the scope.
14
        :param classx: A class (object)
15
        :param method_name A string name of the method to be decorated
16
        :param decorator_func: The decorator function is responsible
17
         for calling the original method.
18
         The signature should be: func(instance, original_method,
19
         original_args, original_kwargs)
20
         when called, instance refers to an instance of classx and the
21
         original_method refers to the original method object which can be
22
         called.
23
         args and kwargs are arguments passed to the method
24
25
        """
26
        self.method_name = method_name
27
        self.decorator_func = decorator_func
28
        self.classx = classx
29
        self.patched_by_me = False
30
31
    def __enter__(self):
32
33
        self.original_method = getattr(self.classx, self.method_name)
34
        if not getattr(self.original_method,
35
                       "sacred_patched%s" % self.__class__.__name__, False):
36
            @functools.wraps(self.original_method)
37
            def decorated(instance, *args, **kwargs):
38
                return self.decorator_func(instance,
39
                                           self.original_method, args,
40
                                           kwargs)
41
42
            setattr(self.classx, self.method_name, decorated)
43
            setattr(decorated,
44
                    "sacred_patched%s" % self.__class__.__name__, True)
45
            self.patched_by_me = True
46
47
    def __exit__(self, type, value, traceback):
48
        if self.patched_by_me:
49
            # Restore original function
50
            setattr(self.classx, self.method_name, self.original_method)
51