This file is indexed.

/usr/lib/python3/dist-packages/debtcollector/removals.py is in python3-debtcollector 1.5.0-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
# Copyright 2014 Hewlett-Packard Development Company, L.P.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

import functools
import inspect

import six
import wrapt

from debtcollector import _utils


def _get_qualified_name(obj):
    return _utils.get_qualified_name(obj)[1]


def _fetch_first_result(fget, fset, fdel, apply_func, value_not_found=None):
    """Fetch first non-none/empty result of applying ``apply_func``."""
    for f in filter(None, (fget, fset, fdel)):
        result = apply_func(f)
        if result:
            return result
    return value_not_found


class removed_property(object):
    """Property descriptor that deprecates a property.

    This works like the ``@property`` descriptor but can be used instead to
    provide the same functionality and also interact with the :mod:`warnings`
    module to warn when a property is accessed, set and/or deleted.

    :param message: string used as ending contents of the deprecate message
    :param version: version string (represents the version this deprecation
                    was created in)
    :param removal_version: version string (represents the version this
                            deprecation will be removed in); a string
                            of '?' will denote this will be removed in
                            some future unknown version
    :param stacklevel: stacklevel used in the :func:`warnings.warn` function
                       to locate where the users code is when reporting the
                       deprecation call (the default being 3)
    :param category: the :mod:`warnings` category to use, defaults to
                     :py:class:`DeprecationWarning` if not provided
    """

    # Message templates that will be turned into real messages as needed.
    _PROPERTY_GONE_TPLS = {
        'set': "Setting the '%s' property is deprecated",
        'get': "Reading the '%s' property is deprecated",
        'delete': "Deleting the '%s' property is deprecated",
    }

    def __init__(self, fget=None, fset=None, fdel=None, doc=None,
                 stacklevel=3, category=DeprecationWarning,
                 version=None, removal_version=None, message=None):
        self.fset = fset
        self.fget = fget
        self.fdel = fdel
        self.stacklevel = stacklevel
        self.category = category
        self.version = version
        self.removal_version = removal_version
        self.message = message
        if doc is None and inspect.isfunction(fget):
            doc = getattr(fget, '__doc__', None)
        self._message_cache = {}
        self.__doc__ = doc

    def _fetch_message_from_cache(self, kind):
        try:
            out_message = self._message_cache[kind]
        except KeyError:
            prefix_tpl = self._PROPERTY_GONE_TPLS[kind]
            prefix = prefix_tpl % _fetch_first_result(
                self.fget, self.fset, self.fdel, _get_qualified_name,
                value_not_found="???")
            out_message = _utils.generate_message(
                prefix, message=self.message, version=self.version,
                removal_version=self.removal_version)
            self._message_cache[kind] = out_message
        return out_message

    def __call__(self, fget, **kwargs):
        self.fget = fget
        self.message = kwargs.get('message', self.message)
        self.version = kwargs.get('version', self.version)
        self.removal_version = kwargs.get('removal_version',
                                          self.removal_version)
        self.stacklevel = kwargs.get('stacklevel', self.stacklevel)
        self.category = kwargs.get('category', self.category)
        self.__doc__ = kwargs.get('doc',
                                  getattr(fget, '__doc__', self.__doc__))
        # Regenerate all the messages...
        self._message_cache.clear()
        return self

    def __delete__(self, obj):
        if self.fdel is None:
            raise AttributeError("can't delete attribute")
        out_message = self._fetch_message_from_cache('delete')
        _utils.deprecation(out_message, stacklevel=self.stacklevel,
                           category=self.category)
        self.fdel(obj)

    def __set__(self, obj, value):
        if self.fset is None:
            raise AttributeError("can't set attribute")
        out_message = self._fetch_message_from_cache('set')
        _utils.deprecation(out_message, stacklevel=self.stacklevel,
                           category=self.category)
        self.fset(obj, value)

    def __get__(self, obj, value):
        if obj is None:
            return self
        if self.fget is None:
            raise AttributeError("unreadable attribute")
        out_message = self._fetch_message_from_cache('get')
        _utils.deprecation(out_message, stacklevel=self.stacklevel,
                           category=self.category)
        return self.fget(obj)

    def getter(self, fget):
        o = type(self)(fget, self.fset, self.fdel, self.__doc__)
        o.message = self.message
        o.version = self.version
        o.stacklevel = self.stacklevel
        o.removal_version = self.removal_version
        o.category = self.category
        return o

    def setter(self, fset):
        o = type(self)(self.fget, fset, self.fdel, self.__doc__)
        o.message = self.message
        o.version = self.version
        o.stacklevel = self.stacklevel
        o.removal_version = self.removal_version
        o.category = self.category
        return o

    def deleter(self, fdel):
        o = type(self)(self.fget, self.fset, fdel, self.__doc__)
        o.message = self.message
        o.version = self.version
        o.stacklevel = self.stacklevel
        o.removal_version = self.removal_version
        o.category = self.category
        return o


def remove(f=None, message=None, version=None, removal_version=None,
           stacklevel=3, category=None):
    """Decorates a function, method, or class to emit a deprecation warning

    Due to limitations of the wrapt library (and python) itself, if this
    is applied to subclasses of metaclasses then it likely will not work
    as expected. More information can be found at bug #1520397 to see if
    this situation affects your usage of this *universal* decorator, for
    this specific scenario please use :py:func:`.removed_class` instead.

    :param str message: A message to include in the deprecation warning
    :param str version: Specify what version the removed function is present in
    :param str removal_version: What version the function will be removed. If
                                '?' is used this implies an undefined future
                                version
    :param int stacklevel: How many entries deep in the call stack before
                           ignoring
    :param type category: warnings message category (this defaults to
                          ``DeprecationWarning`` when none is provided)
    """
    if f is None:
        return functools.partial(remove, message=message,
                                 version=version,
                                 removal_version=removal_version,
                                 stacklevel=stacklevel,
                                 category=category)

    @wrapt.decorator
    def wrapper(f, instance, args, kwargs):
        qualified, f_name = _utils.get_qualified_name(f)
        if qualified:
            if inspect.isclass(f):
                prefix_pre = "Using class"
                thing_post = ''
            else:
                prefix_pre = "Using function/method"
                thing_post = '()'
        if not qualified:
            prefix_pre = "Using function/method"
            base_name = None
            if instance is None:
                # Decorator was used on a class
                if inspect.isclass(f):
                    prefix_pre = "Using class"
                    thing_post = ''
                    module_name = _get_qualified_name(inspect.getmodule(f))
                    if module_name == '__main__':
                        f_name = _utils.get_class_name(
                            f, fully_qualified=False)
                    else:
                        f_name = _utils.get_class_name(
                            f, fully_qualified=True)
                # Decorator was a used on a function
                else:
                    thing_post = '()'
                    module_name = _get_qualified_name(inspect.getmodule(f))
                    if module_name != '__main__':
                        f_name = _utils.get_callable_name(f)
            # Decorator was used on a classmethod or instancemethod
            else:
                thing_post = '()'
                base_name = _utils.get_class_name(instance,
                                                  fully_qualified=False)
            if base_name:
                thing_name = ".".join([base_name, f_name])
            else:
                thing_name = f_name
        else:
            thing_name = f_name
        if thing_post:
            thing_name += thing_post
        prefix = prefix_pre + " '%s' is deprecated" % (thing_name)
        out_message = _utils.generate_message(
            prefix,
            version=version,
            removal_version=removal_version,
            message=message)
        _utils.deprecation(out_message,
                           stacklevel=stacklevel, category=category)
        return f(*args, **kwargs)
    return wrapper(f)


def removed_kwarg(old_name, message=None,
                  version=None, removal_version=None, stacklevel=3,
                  category=None):
    """Decorates a kwarg accepting function to deprecate a removed kwarg."""

    prefix = "Using the '%s' argument is deprecated" % old_name
    out_message = _utils.generate_message(
        prefix, postfix=None, message=message, version=version,
        removal_version=removal_version)

    @wrapt.decorator
    def wrapper(f, instance, args, kwargs):
        if old_name in kwargs:
            _utils.deprecation(out_message,
                               stacklevel=stacklevel, category=category)
        return f(*args, **kwargs)

    return wrapper


def removed_class(cls_name, replacement=None, message=None,
                  version=None, removal_version=None, stacklevel=3,
                  category=None):
    """Decorates a class to denote that it will be removed at some point."""

    def _wrap_it(old_init, out_message):

        @six.wraps(old_init, assigned=_utils.get_assigned(old_init))
        def new_init(self, *args, **kwargs):
            _utils.deprecation(out_message, stacklevel=stacklevel,
                               category=category)
            return old_init(self, *args, **kwargs)

        return new_init

    def _check_it(cls):
        if not inspect.isclass(cls):
            _qual, type_name = _utils.get_qualified_name(type(cls))
            raise TypeError("Unexpected class type '%s' (expected"
                            " class type only)" % type_name)

    def _cls_decorator(cls):
        _check_it(cls)
        out_message = _utils.generate_message(
            "Using class '%s' (either directly or via inheritance)"
            " is deprecated" % cls_name, postfix=None, message=message,
            version=version, removal_version=removal_version)
        cls.__init__ = _wrap_it(cls.__init__, out_message)
        return cls

    return _cls_decorator


def removed_module(module, replacement=None, message=None,
                   version=None, removal_version=None, stacklevel=3,
                   category=None):
    """Helper to be called inside a module to emit a deprecation warning

    :param str replacment: A location (or information about) of any potential
                           replacement for the removed module (if applicable)
    :param str message: A message to include in the deprecation warning
    :param str version: Specify what version the removed module is present in
    :param str removal_version: What version the module will be removed. If
                                '?' is used this implies an undefined future
                                version
    :param int stacklevel: How many entries deep in the call stack before
                           ignoring
    :param type category: warnings message category (this defaults to
                          ``DeprecationWarning`` when none is provided)
    """
    if inspect.ismodule(module):
        module_name = _get_qualified_name(module)
    elif isinstance(module, six.string_types):
        module_name = module
    else:
        _qual, type_name = _utils.get_qualified_name(type(module))
        raise TypeError("Unexpected module type '%s' (expected string or"
                        " module type only)" % type_name)
    prefix = "The '%s' module usage is deprecated" % module_name
    if replacement:
        postfix = ", please use %s instead" % replacement
    else:
        postfix = None
    out_message = _utils.generate_message(prefix,
                                          postfix=postfix, message=message,
                                          version=version,
                                          removal_version=removal_version)
    _utils.deprecation(out_message,
                       stacklevel=stacklevel, category=category)