deprecate()   D
last analyzed

Complexity

Conditions 10

Size

Total Lines 59

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 10
c 1
b 0
f 0
dl 0
loc 59
rs 4.8648

1 Method

Rating   Name   Duplication   Size   Complexity  
A finalize() 0 10 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like deprecate() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
"""Matplotlib license for the deprecation module.
2
3
License agreement for matplotlib versions 1.3.0 and later
4
=========================================================
5
6
1. This LICENSE AGREEMENT is between the Matplotlib Development Team
7
("MDT"), and the Individual or Organization ("Licensee") accessing and
8
otherwise using matplotlib software in source or binary form and its
9
associated documentation.
10
11
2. Subject to the terms and conditions of this License Agreement, MDT
12
hereby grants Licensee a nonexclusive, royalty-free, world-wide license
13
to reproduce, analyze, test, perform and/or display publicly, prepare
14
derivative works, distribute, and otherwise use matplotlib
15
alone or in any derivative version, provided, however, that MDT's
16
License Agreement and MDT's notice of copyright, i.e., "Copyright (c)
17
2012- Matplotlib Development Team; All Rights Reserved" are retained in
18
matplotlib  alone or in any derivative version prepared by
19
Licensee.
20
21
3. In the event Licensee prepares a derivative work that is based on or
22
incorporates matplotlib or any part thereof, and wants to
23
make the derivative work available to others as provided herein, then
24
Licensee hereby agrees to include in any such work a brief summary of
25
the changes made to matplotlib .
26
27
4. MDT is making matplotlib available to Licensee on an "AS
28
IS" basis.  MDT MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
29
IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, MDT MAKES NO AND
30
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
31
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF MATPLOTLIB
32
WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
33
34
5. MDT SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF MATPLOTLIB
35
 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR
36
LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING
37
MATPLOTLIB , OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF
38
THE POSSIBILITY THEREOF.
39
40
6. This License Agreement will automatically terminate upon a material
41
breach of its terms and conditions.
42
43
7. Nothing in this License Agreement shall be deemed to create any
44
relationship of agency, partnership, or joint venture between MDT and
45
Licensee.  This License Agreement does not grant permission to use MDT
46
trademarks or trade name in a trademark sense to endorse or promote
47
products or services of Licensee, or any third party.
48
49
8. By copying, installing or otherwise using matplotlib ,
50
Licensee agrees to be bound by the terms and conditions of this License
51
Agreement.
52
53
License agreement for matplotlib versions prior to 1.3.0
54
========================================================
55
56
1. This LICENSE AGREEMENT is between John D. Hunter ("JDH"), and the
57
Individual or Organization ("Licensee") accessing and otherwise using
58
matplotlib software in source or binary form and its associated
59
documentation.
60
61
2. Subject to the terms and conditions of this License Agreement, JDH
62
hereby grants Licensee a nonexclusive, royalty-free, world-wide license
63
to reproduce, analyze, test, perform and/or display publicly, prepare
64
derivative works, distribute, and otherwise use matplotlib
65
alone or in any derivative version, provided, however, that JDH's
66
License Agreement and JDH's notice of copyright, i.e., "Copyright (c)
67
2002-2011 John D. Hunter; All Rights Reserved" are retained in
68
matplotlib  alone or in any derivative version prepared by
69
Licensee.
70
71
3. In the event Licensee prepares a derivative work that is based on or
72
incorporates matplotlib  or any part thereof, and wants to
73
make the derivative work available to others as provided herein, then
74
Licensee hereby agrees to include in any such work a brief summary of
75
the changes made to matplotlib.
76
77
4. JDH is making matplotlib  available to Licensee on an "AS
78
IS" basis.  JDH MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
79
IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, JDH MAKES NO AND
80
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
81
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF MATPLOTLIB
82
WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
83
84
5. JDH SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF MATPLOTLIB
85
 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR
86
LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING
87
MATPLOTLIB , OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF
88
THE POSSIBILITY THEREOF.
89
90
6. This License Agreement will automatically terminate upon a material
91
breach of its terms and conditions.
92
93
7. Nothing in this License Agreement shall be deemed to create any
94
relationship of agency, partnership, or joint venture between JDH and
95
Licensee.  This License Agreement does not grant permission to use JDH
96
trademarks or trade name in a trademark sense to endorse or promote
97
products or services of Licensee, or any third party.
98
99
8. By copying, installing or otherwise using matplotlib,
100
Licensee agrees to be bound by the terms and conditions of this License
101
Agreement.
102
"""
103
104
import functools
105
import warnings
106
107
108
class MetpyDeprecationWarning(UserWarning):
109
    """A class for issuing deprecation warnings for MetPy users.
110
111
    In light of the fact that Python builtin DeprecationWarnings are ignored
112
    by default as of Python 2.7 (see link below), this class was put in to
113
    allow for the signaling of deprecation, but via UserWarnings which are not
114
    ignored by default. Borrowed with love from matplotlib.
115
116
    https://docs.python.org/dev/whatsnew/2.7.html#the-future-for-python-2-x
117
    """
118
119
    pass
120
121
122
metpyDeprecation = MetpyDeprecationWarning
123
124
125
def _generate_deprecation_message(since, message='', name='',
126
                                  alternative='', pending=False,
127
                                  obj_type='attribute',
128
                                  addendum=''):
129
130
    if not message:
131
132
        if pending:
133
            message = (
134
                'The {} {} will be deprecated in a '
135
                'future version.'.format(name, obj_type))
136
        else:
137
            message = (
138
                'The {} {} was deprecated in version '
139
                '{}.'.format(name, obj_type, since))
140
141
    altmessage = ''
142
    if alternative:
143
        altmessage = ' Use {} instead.'.format(alternative)
144
145
    message = message + altmessage
146
147
    if addendum:
148
        message += addendum
149
150
    return message
151
152
153
def warn_deprecated(since, message='', name='', alternative='', pending=False,
154
                    obj_type='attribute', addendum=''):
155
    """Display deprecation warning in a standard way.
156
157
    Parameters
158
    ----------
159
    since : str
160
        The release at which this API became deprecated.
161
162
    message : str, optional
163
        Override the default deprecation message.  The format
164
        specifier `%(name)s` may be used for the name of the function,
165
        and `%(alternative)s` may be used in the deprecation message
166
        to insert the name of an alternative to the deprecated
167
        function.  `%(obj_type)s` may be used to insert a friendly name
168
        for the type of object being deprecated.
169
170
    name : str, optional
171
        The name of the deprecated object.
172
173
    alternative : str, optional
174
        An alternative function that the user may use in place of the
175
        deprecated function.  The deprecation warning will tell the user
176
        about this alternative if provided.
177
178
    pending : bool, optional
179
        If True, uses a PendingDeprecationWarning instead of a
180
        DeprecationWarning.
181
182
    obj_type : str, optional
183
        The object type being deprecated.
184
185
    addendum : str, optional
186
        Additional text appended directly to the final message.
187
188
    Examples
189
    --------
190
        Basic example::
191
192
            # To warn of the deprecation of "metpy.name_of_module"
193
            warn_deprecated('0.6.0', name='metpy.name_of_module',
194
                            obj_type='module')
195
196
    """
197
    message = _generate_deprecation_message(since, message, name, alternative,
198
                                            pending, obj_type)
199
200
    warnings.warn(message, metpyDeprecation, stacklevel=1)
201
202
203
def deprecated(since, message='', name='', alternative='', pending=False,
204
               obj_type=None, addendum=''):
205
    """Mark a function or a class as deprecated.
206
207
    Parameters
208
    ----------
209
    since : str
210
        The release at which this API became deprecated.  This is
211
        required.
212
213
    message : str, optional
214
        Override the default deprecation message.  The format
215
        specifier `%(name)s` may be used for the name of the object,
216
        and `%(alternative)s` may be used in the deprecation message
217
        to insert the name of an alternative to the deprecated
218
        object.  `%(obj_type)s` may be used to insert a friendly name
219
        for the type of object being deprecated.
220
221
    name : str, optional
222
        The name of the deprecated object; if not provided the name
223
        is automatically determined from the passed in object,
224
        though this is useful in the case of renamed functions, where
225
        the new function is just assigned to the name of the
226
        deprecated function.  For example::
227
228
            def new_function():
229
                ...
230
            oldFunction = new_function
231
232
    alternative : str, optional
233
        An alternative object that the user may use in place of the
234
        deprecated object.  The deprecation warning will tell the user
235
        about this alternative if provided.
236
237
    pending : bool, optional
238
        If True, uses a PendingDeprecationWarning instead of a
239
        DeprecationWarning.
240
241
    addendum : str, optional
242
        Additional text appended directly to the final message.
243
244
    Examples
245
    --------
246
        Basic example::
247
248
            @deprecated('1.4.0')
249
            def the_function_to_deprecate():
250
                pass
251
252
    """
253
    def deprecate(obj, message=message, name=name, alternative=alternative,
254
                  pending=pending, addendum=addendum):
255
        import textwrap
256
257
        if not name:
258
            name = obj.__name__
259
260
        if isinstance(obj, type):
261
            obj_type = 'class'
262
            old_doc = obj.__doc__
263
            func = obj.__init__
264
265
            def finalize(wrapper, new_doc):
266
                try:
267
                    pass
268
                    # obj.__doc = new_doc
269
                except (AttributeError, TypeError):
270
                    # cls.__doc__ is not writeable on Py2.
271
                    # TypeError occurs on PyPy
272
                    pass
273
                obj.__init__ = wrapper
274
                return obj
275
        else:
276
            obj_type = 'function'
277
            if isinstance(obj, classmethod):
278
                func = obj.__func__
279
                old_doc = func.__doc__
280
281
                def finalize(wrapper, new_doc):
282
                    wrapper = functools.wraps(func)(wrapper)
283
                    # wrapper.__doc__ = new_doc
284
                    return classmethod(wrapper)
285
            else:
286
                func = obj
287
                old_doc = func.__doc__
288
289
                def finalize(wrapper, new_doc):
290
                    wrapper = functools.wraps(func)(wrapper)
291
                    # wrapper.__doc__ = new_doc
292
                    return wrapper
293
294
        message = _generate_deprecation_message(since, message, name,
295
                                                alternative, pending,
296
                                                obj_type, addendum)
297
298
        def wrapper(*args, **kwargs):
299
            warnings.warn(message, metpyDeprecation, stacklevel=2)
300
            return func(*args, **kwargs)
301
302
        old_doc = textwrap.dedent(old_doc or '').strip('\n')
303
        message = message.strip()
304
        new_doc = ('\n.. deprecated:: {}'
305
                   '\n    {}\n\n'.format(since, message) + old_doc)
306
        if not old_doc:
307
            # This is to prevent a spurious 'unexected unindent' warning from
308
            # docutils when the original docstring was blank.
309
            new_doc += r'\ '
310
311
        return finalize(wrapper, new_doc)
312
313
    return deprecate
314