summaryrefslogtreecommitdiff
path: root/logilab/common/deprecation.py
diff options
context:
space:
mode:
Diffstat (limited to 'logilab/common/deprecation.py')
-rw-r--r--logilab/common/deprecation.py95
1 files changed, 62 insertions, 33 deletions
diff --git a/logilab/common/deprecation.py b/logilab/common/deprecation.py
index 15f8087..a57ae33 100644
--- a/logilab/common/deprecation.py
+++ b/logilab/common/deprecation.py
@@ -45,7 +45,7 @@ class DeprecationWrapper(object):
setattr(self._proxied, attr, value)
-def _get_package_name(number=2):
+def _get_module_name(number=1):
"""
automagically try to determine the package name from which the warning has
been triggered by loop other calling frames.
@@ -55,29 +55,27 @@ def _get_package_name(number=2):
frame = sys._getframe()
- for i in range(number):
+ for i in range(number + 1):
if frame.f_back is None:
break
frame = frame.f_back
- if frame.f_globals["__package__"] is not None:
+ if frame.f_globals["__package__"]:
return frame.f_globals["__package__"]
file_name = os.path.split(frame.f_globals["__file__"])[1]
if file_name.endswith(".py"):
- file_name = file_name[:-len(".py")]
+ file_name = file_name[: -len(".py")]
return file_name
-def send_warning(reason, version=None, stacklevel=2):
+def send_warning(reason, version=None, stacklevel=2, module_name=None):
"""Display a deprecation message only if the version is older than the
compatible version.
"""
- module_name = _get_package_name(stacklevel + 1)
-
if module_name and version:
reason = '[%s %s] %s' % (module_name, version, reason)
elif module_name:
@@ -102,10 +100,15 @@ def callable_renamed(old_name, new_function, version=None):
"""
@wraps(new_function)
def wrapped(*args, **kwargs):
- send_warning((
- f"{old_name} has been renamed and is deprecated, uses {new_function.__name__} "
- f"instead"
- ), stacklevel=3, version=version)
+ send_warning(
+ (
+ f"{old_name} has been renamed and is deprecated, uses {new_function.__name__} "
+ f"instead"
+ ),
+ stacklevel=3,
+ version=version,
+ module_name=new_function.__module__,
+ )
return new_function(*args, **kwargs)
return wrapped
@@ -129,8 +132,13 @@ def argument_removed(old_argument_name, version=None):
@wraps(func)
def check_kwargs(*args, **kwargs):
if old_argument_name in kwargs:
- send_warning(f"argument {old_argument_name} of callable {func.__name__} has been "
- f"removed and is deprecated", stacklevel=3, version=version)
+ send_warning(
+ f"argument {old_argument_name} of callable {func.__name__} has been "
+ f"removed and is deprecated",
+ stacklevel=3,
+ version=version,
+ module_name=func.__module__,
+ )
del kwargs[old_argument_name]
return func(*args, **kwargs)
@@ -153,7 +161,7 @@ def callable_deprecated(reason=None, version=None, stacklevel=2):
@wraps(func)
def wrapped(*args, **kwargs):
- send_warning(message, version, stacklevel + 1)
+ send_warning(message, version, stacklevel + 1, module_name=func.__module__)
return func(*args, **kwargs)
return wrapped
@@ -167,10 +175,15 @@ class class_deprecated(type):
"""metaclass to print a warning on instantiation of a deprecated class"""
def __call__(cls, *args, **kwargs):
- msg = getattr(cls, "__deprecation_warning__",
- "%(cls)s is deprecated") % {'cls': cls.__name__}
- send_warning(msg, stacklevel=getattr(cls, "__deprecation_warning_stacklevel__", 4),
- version=getattr(cls, "__deprecation_warning_version__", None))
+ msg = getattr(cls, "__deprecation_warning__", "%(cls)s is deprecated") % {
+ "cls": cls.__name__
+ }
+ send_warning(
+ msg,
+ stacklevel=getattr(cls, "__deprecation_warning_stacklevel__", 3),
+ version=getattr(cls, "__deprecation_warning_version__", None),
+ module_name=getattr(cls, "__deprecation_warning_module_name__", cls.__module__),
+ )
return type.__call__(cls, *args, **kwargs)
@@ -201,15 +214,15 @@ def attribute_renamed(old_name, new_name, version=None):
)
def _get_old(self):
- send_warning(reason, stacklevel=3, version=version)
+ send_warning(reason, stacklevel=3, version=version, module_name=klass.__module__)
return getattr(self, new_name)
def _set_old(self, value):
- send_warning(reason, stacklevel=3, version=version)
+ send_warning(reason, stacklevel=3, version=version, module_name=klass.__module__)
setattr(self, new_name, value)
def _del_old(self):
- send_warning(reason, stacklevel=3, version=version)
+ send_warning(reason, stacklevel=3, version=version, module_name=klass.__module__)
delattr(self, new_name)
setattr(klass, old_name, property(_get_old, _set_old, _del_old))
@@ -240,9 +253,13 @@ def argument_renamed(old_name, new_name, version=None):
f"{new_name} has keyword arguments, only uses {new_name}")
if old_name in kwargs:
- send_warning(f"argument {old_name} of callable {func.__name__} has been renamed "
- f"and is deprecated, use keyword argument {new_name} instead",
- stacklevel=3, version=version)
+ send_warning(
+ f"argument {old_name} of callable {func.__name__} has been renamed "
+ f"and is deprecated, use keyword argument {new_name} instead",
+ stacklevel=3,
+ version=version,
+ module_name=func.__module__,
+ )
kwargs[new_name] = kwargs[old_name]
del kwargs[old_name]
@@ -271,7 +288,9 @@ def callable_moved(module_name, object_name, version=None, stacklevel=2):
def callnew(*args, **kwargs):
from logilab.common.modutils import load_module_from_name
- send_warning(message, version=version, stacklevel=stacklevel + 1)
+ send_warning(
+ message, version=version, stacklevel=stacklevel + 1, module_name=_get_module_name(1)
+ )
m = load_module_from_name(module_name)
return getattr(m, object_name)(*args, **kwargs)
@@ -282,7 +301,7 @@ def callable_moved(module_name, object_name, version=None, stacklevel=2):
moved = callable_renamed(old_name="moved", new_function=callable_moved)
-def class_renamed(old_name, new_class, message=None, version=None):
+def class_renamed(old_name, new_class, message=None, version=None, module_name=None):
"""automatically creates a class which fires a DeprecationWarning
when instantiated.
@@ -294,11 +313,16 @@ def class_renamed(old_name, new_class, message=None, version=None):
"""
class_dict = {}
if message is None:
- message = '%s is deprecated, use %s instead' % (old_name, new_class.__name__)
+ message = "%s is deprecated, use %s instead" % (old_name, new_class.__name__)
- class_dict['__deprecation_warning__'] = message
- class_dict['__deprecation_warning_version__'] = version
- class_dict['__deprecation_warning_stacklevel__'] = 5
+ class_dict["__deprecation_warning__"] = message
+ class_dict["__deprecation_warning_version__"] = version
+ class_dict["__deprecation_warning_stacklevel__"] = 3
+
+ if module_name:
+ class_dict["__deprecation_warning_module_name__"] = module_name
+ else:
+ class_dict["__deprecation_warning_module_name__"] = _get_module_name(1)
return class_deprecated(old_name, (new_class,), class_dict)
@@ -311,7 +335,12 @@ def class_moved(new_class, old_name=None, message=None, version=None):
old_name = new_class.__name__
if message is None:
- message = 'class %s is now available as %s.%s' % (
- old_name, new_class.__module__, new_class.__name__)
+ message = "class %s is now available as %s.%s" % (
+ old_name,
+ new_class.__module__,
+ new_class.__name__,
+ )
+
+ module_name = _get_module_name(1)
- return class_renamed(old_name, new_class, message=message)
+ return class_renamed(old_name, new_class, message=message, module_name=module_name)