From 57cf85c4302122e30e1d2eef5ac920f75fc8fe3e Mon Sep 17 00:00:00 2001 From: Laurent Peuch Date: Fri, 22 May 2020 16:51:56 +0200 Subject: [deprecation/fix] rollback to old class_deprecation being a class behavior It breaks CW because CW was using class_deprecated in a isinstance to select the good views to uses. --- logilab/common/deprecation.py | 45 ++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/logilab/common/deprecation.py b/logilab/common/deprecation.py index 47f2895..af23f07 100644 --- a/logilab/common/deprecation.py +++ b/logilab/common/deprecation.py @@ -215,23 +215,28 @@ def callable_deprecated(reason=None, version=None, stacklevel=2): deprecated = callable_renamed(old_name="deprecated", new_function=callable_deprecated) -def class_deprecated(old_name, parent, class_dict): - class DeprecatedClass(*parent): - def __init__(self, *args, **kwargs): - msg = class_dict.get("__deprecation_warning__", f"{old_name} is deprecated") +def _generate_class_deprecated(): + class _class_deprecated(type): + """metaclass to print a warning on instantiation of a deprecated class""" + + def __call__(cls, *args, **kwargs): + message = getattr(cls, "__deprecation_warning__", "%(cls)s is deprecated") % { + "cls": cls.__name__ + } send_warning( - msg, - stacklevel=class_dict.get("__deprecation_warning_stacklevel__", 3), - version=class_dict.get("__deprecation_warning_version__", None), - module_name=class_dict.get( - "__deprecation_warning_module_name__", _get_module_name(1) + message, + module_name=getattr( + cls, "__deprecation_warning_module_name__", _get_module_name(1) ), + stacklevel=getattr(cls, "__deprecation_warning_stacklevel__", 4), + version=getattr(cls, "__deprecation_warning_version__", None), ) - super(DeprecatedClass, self).__init__(*args, **kwargs) + return type.__call__(cls, *args, **kwargs) - DeprecatedClass.__name__ = old_name + return _class_deprecated - return DeprecatedClass + +class_deprecated = _generate_class_deprecated() def attribute_renamed(old_name, new_name, version=None): @@ -378,7 +383,21 @@ def class_renamed(old_name, new_class, message=None, version=None, module_name=N else: class_dict["__deprecation_warning_module_name__"] = _get_module_name(1) - return class_deprecated(old_name, (new_class,), class_dict) + try: + return class_deprecated(old_name, (new_class,), class_dict) + except (NameError, TypeError): + # in case of conflicting metaclass situation + class DeprecatedClass(new_class): + def __init__(self, *args, **kwargs): + msg = class_dict.get("__deprecation_warning__", f"{old_name} is deprecated") + send_warning( + msg, + stacklevel=class_dict.get("__deprecation_warning_stacklevel__", 3), + version=class_dict.get("__deprecation_warning_version__", None), + ) + super(DeprecatedClass, self).__init__(*args, **kwargs) + + return DeprecatedClass def class_moved(new_class, old_name=None, message=None, version=None): -- cgit v1.2.1