Skip to content

Commit 26f9224

Browse files
committed
add _deprecation.py module
1 parent e88458d commit 26f9224

File tree

2 files changed

+371
-9
lines changed

2 files changed

+371
-9
lines changed

pvlib/_deprecation.py

Lines changed: 313 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,313 @@
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 PVLibDeprecationWarning(UserWarning):
109+
"""A class for issuing deprecation warnings for pvlib 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.
115+
116+
https://docs.python.org/dev/whatsnew/2.7.html#the-future-for-python-2-x
117+
"""
118+
119+
pass
120+
121+
122+
pvlibDeprecation = PVLibDeprecationWarning
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 "pvlib.name_of_module"
193+
warn_deprecated('0.6.0', name='pvlib.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, pvlibDeprecation, 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, pvlibDeprecation, 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

0 commit comments

Comments
 (0)