laywerrobot/lib/python3.6/site-packages/sklearn/utils/deprecation.py

135 lines
4 KiB
Python
Raw Normal View History

2020-08-27 21:55:39 +02:00
import sys
import warnings
import functools
__all__ = ["deprecated", "DeprecationDict"]
class deprecated(object):
"""Decorator to mark a function or class as deprecated.
Issue a warning when the function is called/the class is instantiated and
adds a warning to the docstring.
The optional extra argument will be appended to the deprecation message
and the docstring. Note: to use this with the default value for extra, put
in an empty of parentheses:
>>> from sklearn.utils import deprecated
>>> deprecated() # doctest: +ELLIPSIS
<sklearn.utils.deprecation.deprecated object at ...>
>>> @deprecated()
... def some_function(): pass
Parameters
----------
extra : string
to be added to the deprecation messages
"""
# Adapted from http://wiki.python.org/moin/PythonDecoratorLibrary,
# but with many changes.
def __init__(self, extra=''):
self.extra = extra
def __call__(self, obj):
"""Call method
Parameters
----------
obj : object
"""
if isinstance(obj, type):
return self._decorate_class(obj)
else:
return self._decorate_fun(obj)
def _decorate_class(self, cls):
msg = "Class %s is deprecated" % cls.__name__
if self.extra:
msg += "; %s" % self.extra
# FIXME: we should probably reset __new__ for full generality
init = cls.__init__
def wrapped(*args, **kwargs):
warnings.warn(msg, category=DeprecationWarning)
return init(*args, **kwargs)
cls.__init__ = wrapped
wrapped.__name__ = '__init__'
wrapped.__doc__ = self._update_doc(init.__doc__)
wrapped.deprecated_original = init
return cls
def _decorate_fun(self, fun):
"""Decorate function fun"""
msg = "Function %s is deprecated" % fun.__name__
if self.extra:
msg += "; %s" % self.extra
@functools.wraps(fun)
def wrapped(*args, **kwargs):
warnings.warn(msg, category=DeprecationWarning)
return fun(*args, **kwargs)
wrapped.__doc__ = self._update_doc(wrapped.__doc__)
return wrapped
def _update_doc(self, olddoc):
newdoc = "DEPRECATED"
if self.extra:
newdoc = "%s: %s" % (newdoc, self.extra)
if olddoc:
newdoc = "%s\n\n%s" % (newdoc, olddoc)
return newdoc
def _is_deprecated(func):
"""Helper to check if func is wraped by our deprecated decorator"""
if sys.version_info < (3, 5):
raise NotImplementedError("This is only available for python3.5 "
"or above")
closures = getattr(func, '__closure__', [])
if closures is None:
closures = []
is_deprecated = ('deprecated' in ''.join([c.cell_contents
for c in closures
if isinstance(c.cell_contents, str)]))
return is_deprecated
class DeprecationDict(dict):
"""A dict which raises a warning when some keys are looked up
Note, this does not raise a warning for __contains__ and iteration.
It also will raise a warning even after the key has been manually set by
the user.
"""
def __init__(self, *args, **kwargs):
self._deprecations = {}
super(DeprecationDict, self).__init__(*args, **kwargs)
def __getitem__(self, key):
if key in self._deprecations:
warn_args, warn_kwargs = self._deprecations[key]
warnings.warn(*warn_args, **warn_kwargs)
return super(DeprecationDict, self).__getitem__(key)
def get(self, key, default=None):
# dict does not implement it like this, hence it needs to be overridden
try:
return self[key]
except KeyError:
return default
def add_warning(self, key, *args, **kwargs):
"""Add a warning to be triggered when the specified key is read"""
self._deprecations[key] = (args, kwargs)