Completed
Pull Request — master (#2603)
by
unknown
01:54
created

_deprecate_decorator()   F

Complexity

Conditions 9

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 9
c 2
b 0
f 0
dl 0
loc 25
rs 3
1
"""
2
The bearlib is an optional library designed to ease the task of any Bear. Just
3
as the rest of coala the bearlib is designed to be as easy to use as possible
4
while offering the best possible flexibility.
5
"""
6
7
from coalib.settings.FunctionMetadata import FunctionMetadata
8
9
10
def deprecate_settings(**depr_args):
11
    """
12
     The purpose of this decorator is to allow passing old settings names to
13
     bears due to the heavy changes in their names.
14
15
     >>> @deprecate_settings(new='old')
16
     ... def run(new):
17
     ...     print(new)
18
19
     >>> @deprecate_settings(new=('old', lambda a: a + 'coala!'))
20
     ... def func(new):
21
     ...     print(new)
22
23
     Now we can simply call the bear with the deprecated setting, we'll get a
24
     warning - but it still works!
25
26
     >>> run(old="Hello world!")
27
     The setting `old` is deprecated. Please use `new` instead.
28
     Hello world!
29
     >>> run(new="Hello world!")
30
     Hello world!
31
32
     This example represents the case where the old setting name needs to be
33
     modified to match the new one.
34
35
     >>> func(old="Welcome to ")
36
     The setting `old` is deprecated. Please use `new` instead.
37
     Welcome to coala!
38
     >>> func(new='coala!')
39
     coala!
40
41
     The metadata for coala has been adjusted as well:
42
43
     >>> list(run.__metadata__.non_optional_params.keys())
44
     ['new']
45
     >>> list(run.__metadata__.optional_params.keys())
46
     ['old']
47
48
     You cannot deprecate an already deprecated setting. Don't try. It will
49
     introduce nondeterministic errors to your program.
50
51
     :param depr_args: A dictionary of settings as keys and their deprecated
52
                       names as values.
53
    """
54
    def _deprecate_decorator(func):
55
56
        def wrapping_function(*args, **kwargs):
57
            for arg, _deprecated_arg in depr_args.items():
58
                deprecated_arg, _func = (_deprecated_arg
59
                                         if isinstance(_deprecated_arg, tuple)
60
                                         else (_deprecated_arg, None))
61
                if deprecated_arg in kwargs and arg not in kwargs:
62
                    print("The setting `{}` is deprecated. Please use `{}` "
63
                          "instead.".format(deprecated_arg, arg))
64
                    kwargs[arg] = (_func.__call__(kwargs[deprecated_arg])
65
                                   if _func is not None
66
                                   else kwargs[deprecated_arg])
67
                    del kwargs[deprecated_arg]
68
            return func(*args, **kwargs)
69
70
        new_metadata = FunctionMetadata.from_function(func)
71
        for arg, _deprecated_arg in depr_args.items():
72
            deprecated_arg = (_deprecated_arg[0]
73
                              if isinstance(_deprecated_arg, tuple)
74
                              else _deprecated_arg)
75
            new_metadata.add_alias(arg, deprecated_arg)
76
        wrapping_function.__metadata__ = new_metadata
77
78
        return wrapping_function
79
80
    return _deprecate_decorator
81