|
28 | 28 | import types |
29 | 29 | import warnings |
30 | 30 | from weakref import ref, WeakKeyDictionary |
| 31 | +from .deprecation import deprecated, warn_deprecated |
| 32 | +from .deprecation import mplDeprecation, MatplotlibDeprecationWarning |
31 | 33 |
|
32 | 34 | import numpy as np |
33 | 35 |
|
34 | 36 |
|
35 | | -class MatplotlibDeprecationWarning(UserWarning): |
36 | | - """ |
37 | | - A class for issuing deprecation warnings for Matplotlib users. |
38 | | -
|
39 | | - In light of the fact that Python builtin DeprecationWarnings are ignored |
40 | | - by default as of Python 2.7 (see link below), this class was put in to |
41 | | - allow for the signaling of deprecation, but via UserWarnings which are not |
42 | | - ignored by default. |
43 | | -
|
44 | | - https://docs.python.org/dev/whatsnew/2.7.html#the-future-for-python-2-x |
45 | | - """ |
46 | | - pass |
47 | | - |
48 | | -mplDeprecation = MatplotlibDeprecationWarning |
49 | | - |
50 | | - |
51 | | -def _generate_deprecation_message(since, message='', name='', |
52 | | - alternative='', pending=False, |
53 | | - obj_type='attribute', |
54 | | - addendum=''): |
55 | | - |
56 | | - if not message: |
57 | | - |
58 | | - if pending: |
59 | | - message = ( |
60 | | - 'The %(name)s %(obj_type)s will be deprecated in a ' |
61 | | - 'future version.') |
62 | | - else: |
63 | | - message = ( |
64 | | - 'The %(name)s %(obj_type)s was deprecated in version ' |
65 | | - '%(since)s.') |
66 | | - |
67 | | - altmessage = '' |
68 | | - if alternative: |
69 | | - altmessage = ' Use %s instead.' % alternative |
70 | | - |
71 | | - message = ((message % { |
72 | | - 'func': name, |
73 | | - 'name': name, |
74 | | - 'alternative': alternative, |
75 | | - 'obj_type': obj_type, |
76 | | - 'since': since}) + |
77 | | - altmessage) |
78 | | - |
79 | | - if addendum: |
80 | | - message += addendum |
81 | | - |
82 | | - return message |
83 | | - |
84 | | - |
85 | | -def warn_deprecated( |
86 | | - since, message='', name='', alternative='', pending=False, |
87 | | - obj_type='attribute', addendum=''): |
88 | | - """ |
89 | | - Used to display deprecation warning in a standard way. |
90 | | -
|
91 | | - Parameters |
92 | | - ---------- |
93 | | - since : str |
94 | | - The release at which this API became deprecated. |
95 | | -
|
96 | | - message : str, optional |
97 | | - Override the default deprecation message. The format |
98 | | - specifier `%(name)s` may be used for the name of the function, |
99 | | - and `%(alternative)s` may be used in the deprecation message |
100 | | - to insert the name of an alternative to the deprecated |
101 | | - function. `%(obj_type)s` may be used to insert a friendly name |
102 | | - for the type of object being deprecated. |
103 | | -
|
104 | | - name : str, optional |
105 | | - The name of the deprecated object. |
106 | | -
|
107 | | - alternative : str, optional |
108 | | - An alternative function that the user may use in place of the |
109 | | - deprecated function. The deprecation warning will tell the user |
110 | | - about this alternative if provided. |
111 | | -
|
112 | | - pending : bool, optional |
113 | | - If True, uses a PendingDeprecationWarning instead of a |
114 | | - DeprecationWarning. |
115 | | -
|
116 | | - obj_type : str, optional |
117 | | - The object type being deprecated. |
118 | | -
|
119 | | - addendum : str, optional |
120 | | - Additional text appended directly to the final message. |
121 | | -
|
122 | | - Examples |
123 | | - -------- |
124 | | -
|
125 | | - Basic example:: |
126 | | -
|
127 | | - # To warn of the deprecation of "matplotlib.name_of_module" |
128 | | - warn_deprecated('1.4.0', name='matplotlib.name_of_module', |
129 | | - obj_type='module') |
130 | | -
|
131 | | - """ |
132 | | - message = _generate_deprecation_message( |
133 | | - since, message, name, alternative, pending, obj_type) |
134 | | - |
135 | | - warnings.warn(message, mplDeprecation, stacklevel=1) |
136 | | - |
137 | | - |
138 | | -def deprecated(since, message='', name='', alternative='', pending=False, |
139 | | - obj_type=None, addendum=''): |
140 | | - """ |
141 | | - Decorator to mark a function or a class as deprecated. |
142 | | -
|
143 | | - Parameters |
144 | | - ---------- |
145 | | - since : str |
146 | | - The release at which this API became deprecated. This is |
147 | | - required. |
148 | | -
|
149 | | - message : str, optional |
150 | | - Override the default deprecation message. The format |
151 | | - specifier `%(name)s` may be used for the name of the object, |
152 | | - and `%(alternative)s` may be used in the deprecation message |
153 | | - to insert the name of an alternative to the deprecated |
154 | | - object. `%(obj_type)s` may be used to insert a friendly name |
155 | | - for the type of object being deprecated. |
156 | | -
|
157 | | - name : str, optional |
158 | | - The name of the deprecated object; if not provided the name |
159 | | - is automatically determined from the passed in object, |
160 | | - though this is useful in the case of renamed functions, where |
161 | | - the new function is just assigned to the name of the |
162 | | - deprecated function. For example:: |
163 | | -
|
164 | | - def new_function(): |
165 | | - ... |
166 | | - oldFunction = new_function |
167 | | -
|
168 | | - alternative : str, optional |
169 | | - An alternative object that the user may use in place of the |
170 | | - deprecated object. The deprecation warning will tell the user |
171 | | - about this alternative if provided. |
172 | | -
|
173 | | - pending : bool, optional |
174 | | - If True, uses a PendingDeprecationWarning instead of a |
175 | | - DeprecationWarning. |
176 | | -
|
177 | | - addendum : str, optional |
178 | | - Additional text appended directly to the final message. |
179 | | -
|
180 | | - Examples |
181 | | - -------- |
182 | | -
|
183 | | - Basic example:: |
184 | | -
|
185 | | - @deprecated('1.4.0') |
186 | | - def the_function_to_deprecate(): |
187 | | - pass |
188 | | -
|
189 | | - """ |
190 | | - def deprecate(obj, message=message, name=name, alternative=alternative, |
191 | | - pending=pending, addendum=addendum): |
192 | | - import textwrap |
193 | | - |
194 | | - if not name: |
195 | | - name = obj.__name__ |
196 | | - |
197 | | - if isinstance(obj, type): |
198 | | - obj_type = "class" |
199 | | - old_doc = obj.__doc__ |
200 | | - func = obj.__init__ |
201 | | - def finalize(wrapper, new_doc): |
202 | | - try: |
203 | | - obj.__doc__ = new_doc |
204 | | - except AttributeError: |
205 | | - pass # cls.__doc__ is not writeable on Py2. |
206 | | - obj.__init__ = wrapper |
207 | | - return obj |
208 | | - else: |
209 | | - obj_type = "function" |
210 | | - if isinstance(obj, classmethod): |
211 | | - func = obj.__func__ |
212 | | - old_doc = func.__doc__ |
213 | | - def finalize(wrapper, new_doc): |
214 | | - wrapper = functools.wraps(func)(wrapper) |
215 | | - wrapper.__doc__ = new_doc |
216 | | - return classmethod(wrapper) |
217 | | - else: |
218 | | - func = obj |
219 | | - old_doc = func.__doc__ |
220 | | - def finalize(wrapper, new_doc): |
221 | | - wrapper = functools.wraps(func)(wrapper) |
222 | | - wrapper.__doc__ = new_doc |
223 | | - return wrapper |
224 | | - |
225 | | - message = _generate_deprecation_message( |
226 | | - since, message, name, alternative, pending, |
227 | | - obj_type, addendum) |
228 | | - |
229 | | - def wrapper(*args, **kwargs): |
230 | | - warnings.warn(message, mplDeprecation, stacklevel=2) |
231 | | - return func(*args, **kwargs) |
232 | | - |
233 | | - old_doc = textwrap.dedent(old_doc or '').strip('\n') |
234 | | - message = message.strip() |
235 | | - new_doc = (('\n.. deprecated:: %(since)s' |
236 | | - '\n %(message)s\n\n' % |
237 | | - {'since': since, 'message': message}) + old_doc) |
238 | | - if not old_doc: |
239 | | - # This is to prevent a spurious 'unexected unindent' warning from |
240 | | - # docutils when the original docstring was blank. |
241 | | - new_doc += r'\ ' |
242 | | - |
243 | | - return finalize(wrapper, new_doc) |
244 | | - |
245 | | - return deprecate |
246 | | - |
247 | | - |
248 | 37 | # On some systems, locale.getpreferredencoding returns None, |
249 | 38 | # which can break unicode; and the sage project reports that |
250 | 39 | # some systems have incorrect locale specifications, e.g., |
|
0 commit comments