~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/symbol_versioning.py

(jameinel) Allow 'bzr serve' to interpret SIGHUP as a graceful shutdown.
 (bug #795025) (John A Meinel)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006, 2007, 2008 Canonical Ltd
2
 
#   Authors: Robert Collins <robert.collins@canonical.com> and others
 
1
# Copyright (C) 2006-2010 Canonical Ltd
3
2
#
4
3
# This program is free software; you can redistribute it and/or modify
5
4
# it under the terms of the GNU General Public License as published by
13
12
#
14
13
# You should have received a copy of the GNU General Public License
15
14
# along with this program; if not, write to the Free Software
16
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
16
 
18
17
"""Symbol versioning
19
18
 
28
27
           'deprecated_passed',
29
28
           'set_warning_method',
30
29
           'warn',
31
 
           'zero_seven',
32
 
           'zero_eight',
33
 
           'zero_nine',
34
 
           'zero_ten',
35
 
           'zero_eleven',
36
 
           'zero_twelve',
37
 
           'zero_thirteen',
38
 
           'zero_fourteen',
39
 
           'zero_fifteen',
40
 
           'zero_sixteen',
41
 
           'zero_seventeen',
42
 
           'zero_eighteen',
43
 
           'zero_ninety',
44
 
           'zero_ninetyone',
45
 
           'zero_ninetytwo',
46
 
           'zero_ninetythree',
47
 
           'one_zero',
48
 
           'one_one',
49
 
           'one_two',
50
 
           'one_three',
51
 
           'one_four',
52
 
           'one_five',
53
 
           'one_six',
54
30
           ]
55
31
 
 
32
 
 
33
import warnings
 
34
# Import the 'warn' symbol so bzrlib can call it even if we redefine it
56
35
from warnings import warn
57
36
 
58
37
import bzrlib
59
38
 
60
39
 
61
40
DEPRECATED_PARAMETER = "A deprecated parameter marker."
62
 
zero_seven = "%s was deprecated in version 0.7."
63
 
zero_eight = "%s was deprecated in version 0.8."
64
 
zero_nine = "%s was deprecated in version 0.9."
65
 
zero_ten = "%s was deprecated in version 0.10."
66
 
zero_eleven = "%s was deprecated in version 0.11."
67
 
zero_twelve = "%s was deprecated in version 0.12."
68
 
zero_thirteen = "%s was deprecated in version 0.13."
69
 
zero_fourteen = "%s was deprecated in version 0.14."
70
 
zero_fifteen = "%s was deprecated in version 0.15."
71
 
zero_sixteen = "%s was deprecated in version 0.16."
72
 
zero_seventeen = "%s was deprecated in version 0.17."
73
 
zero_eighteen = "%s was deprecated in version 0.18."
74
 
zero_ninety = "%s was deprecated in version 0.90."
75
 
zero_ninetyone = "%s was deprecated in version 0.91."
76
 
zero_ninetytwo = "%s was deprecated in version 0.92."
77
 
one_zero = "%s was deprecated in version 1.0."
78
 
zero_ninetythree = one_zero # Maintained for backwards compatibility
79
 
one_one = "%s was deprecated in version 1.1."
80
 
one_two = "%s was deprecated in version 1.2."
81
 
one_three = "%s was deprecated in version 1.3."
82
 
one_four = "%s was deprecated in version 1.4."
83
 
one_five = "%s was deprecated in version 1.5."
84
 
one_six = "%s was deprecated in version 1.6."
85
41
 
86
42
 
87
43
def deprecated_in(version_tuple):
88
44
    """Generate a message that something was deprecated in a release.
89
45
 
90
46
    >>> deprecated_in((1, 4, 0))
91
 
    '%s was deprecated in version 1.4.'
 
47
    '%s was deprecated in version 1.4.0.'
92
48
    """
93
49
    return ("%%s was deprecated in version %s."
94
50
            % bzrlib._format_version_tuple(version_tuple))
135
91
 
136
92
    def function_decorator(callable):
137
93
        """This is the function python calls to perform the decoration."""
138
 
        
 
94
 
139
95
        def decorated_function(*args, **kwargs):
140
96
            """This is the decorated function."""
141
97
            from bzrlib import trace
152
108
def deprecated_method(deprecation_version):
153
109
    """Decorate a method so that use of it will trigger a warning.
154
110
 
155
 
    To deprecate a static or class method, use 
 
111
    To deprecate a static or class method, use
156
112
 
157
113
        @staticmethod
158
114
        @deprecated_function
159
115
        def ...
160
 
    
 
116
 
161
117
    To deprecate an entire class, decorate __init__.
162
118
    """
163
119
 
164
120
    def method_decorator(callable):
165
121
        """This is the function python calls to perform the decoration."""
166
 
        
 
122
 
167
123
        def decorated_method(self, *args, **kwargs):
168
124
            """This is the decorated method."""
169
125
            from bzrlib import trace
187
143
 
188
144
def deprecated_passed(parameter_value):
189
145
    """Return True if parameter_value was used."""
190
 
    # FIXME: it might be nice to have a parameter deprecation decorator. 
 
146
    # FIXME: it might be nice to have a parameter deprecation decorator.
191
147
    # it would need to handle positional and *args and **kwargs parameters,
192
148
    # which means some mechanism to describe how the parameter was being
193
149
    # passed before deprecation, and some way to deprecate parameters that
213
169
    if len(docstring_lines) == 0:
214
170
        decorated_callable.__doc__ = deprecation_version % ("This " + label)
215
171
    elif len(docstring_lines) == 1:
216
 
        decorated_callable.__doc__ = (callable.__doc__ 
 
172
        decorated_callable.__doc__ = (callable.__doc__
217
173
                                    + "\n"
218
174
                                    + "\n"
219
175
                                    + deprecation_version % ("This " + label)
267
223
            typically from deprecated_in()
268
224
        :param initial_value: The contents of the dict
269
225
        :param variable_name: This allows better warnings to be printed
270
 
        :param advice: String of advice on what callers should do instead 
 
226
        :param advice: String of advice on what callers should do instead
271
227
            of using this variable.
272
228
        """
273
229
        self._deprecation_version = deprecation_version
309
265
        def _warn_deprecated(self, func, *args, **kwargs):
310
266
            warn(msg, DeprecationWarning, stacklevel=3)
311
267
            return func(self, *args, **kwargs)
312
 
            
 
268
 
313
269
        def append(self, obj):
314
270
            """appending to %s is deprecated""" % (variable_name,)
315
271
            return self._warn_deprecated(list.append, obj)
327
283
            return self._warn_deprecated(list.remove, value)
328
284
 
329
285
        def pop(self, index=None):
330
 
            """pop'ing from from %s is deprecated""" % (variable_name,)
 
286
            """pop'ing from %s is deprecated""" % (variable_name,)
331
287
            if index:
332
288
                return self._warn_deprecated(list.pop, index)
333
289
            else:
339
295
 
340
296
def _check_for_filter(error_only):
341
297
    """Check if there is already a filter for deprecation warnings.
342
 
    
 
298
 
343
299
    :param error_only: Only match an 'error' filter
344
300
    :return: True if a filter is found, False otherwise
345
301
    """
346
 
    import warnings
347
302
    for filter in warnings.filters:
348
303
        if issubclass(DeprecationWarning, filter[2]):
349
304
            # This filter will effect DeprecationWarning
352
307
    return False
353
308
 
354
309
 
 
310
def _remove_filter_callable(filter):
 
311
    """Build and returns a callable removing filter from the warnings.
 
312
 
 
313
    :param filter: The filter to remove (can be None).
 
314
 
 
315
    :return: A callable that will remove filter from warnings.filters.
 
316
    """
 
317
    def cleanup():
 
318
        if filter:
 
319
            warnings.filters.remove(filter)
 
320
    return cleanup
 
321
 
 
322
 
355
323
def suppress_deprecation_warnings(override=True):
356
324
    """Call this function to suppress all deprecation warnings.
357
325
 
361
329
 
362
330
    :param override: If True, always set the ignore, if False, only set the
363
331
        ignore if there isn't already a filter.
 
332
 
 
333
    :return: A callable to remove the new warnings this added.
364
334
    """
365
 
    import warnings
366
335
    if not override and _check_for_filter(error_only=False):
367
336
        # If there is already a filter effecting suppress_deprecation_warnings,
368
337
        # then skip it.
369
 
        return
370
 
    warnings.filterwarnings('ignore', category=DeprecationWarning)
 
338
        filter = None
 
339
    else:
 
340
        warnings.filterwarnings('ignore', category=DeprecationWarning)
 
341
        filter = warnings.filters[0]
 
342
    return _remove_filter_callable(filter)
371
343
 
372
344
 
373
345
def activate_deprecation_warnings(override=True):
384
356
    :param override: If False, only add a filter if there isn't an error filter
385
357
        already. (This slightly differs from suppress_deprecation_warnings, in
386
358
        because it always overrides everything but -Werror).
 
359
 
 
360
    :return: A callable to remove the new warnings this added.
387
361
    """
388
 
    import warnings
389
362
    if not override and _check_for_filter(error_only=True):
390
363
        # DeprecationWarnings are already turned into errors, don't downgrade
391
364
        # them to 'default'.
392
 
        return
393
 
    warnings.filterwarnings('default', category=DeprecationWarning)
 
365
        filter = None
 
366
    else:
 
367
        warnings.filterwarnings('default', category=DeprecationWarning)
 
368
        filter = warnings.filters[0]
 
369
    return _remove_filter_callable(filter)