summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Peuch <cortex@worlddomination.be>2020-05-22 16:51:56 +0200
committerLaurent Peuch <cortex@worlddomination.be>2020-05-22 16:51:56 +0200
commitfcc526e63d7c1333845dd7ebba97db646aba7bcd (patch)
tree9ddc531dc4bd6a4feed694b8c65a7d1000042c29
parent787bd229345479c9e193f2695366ff584157548e (diff)
downloadlogilab-common-fcc526e63d7c1333845dd7ebba97db646aba7bcd.tar.gz
[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.
-rw-r--r--logilab/common/deprecation.py53
1 files changed, 37 insertions, 16 deletions
diff --git a/logilab/common/deprecation.py b/logilab/common/deprecation.py
index 8b8f8a5..0ddedf2 100644
--- a/logilab/common/deprecation.py
+++ b/logilab/common/deprecation.py
@@ -23,7 +23,7 @@ import os
import sys
from warnings import warn
from functools import WRAPPER_ASSIGNMENTS, WRAPPER_UPDATES
-from typing import Any, Callable, Dict, Optional, Iterable
+from typing import Any, Callable, Dict, Optional
from typing_extensions import Protocol
@@ -237,25 +237,28 @@ deprecated: CallableDeprecatedCallable = callable_renamed(
)
-def class_deprecated(old_name: str, parent: Iterable[type], class_dict: Dict[str, Any]) -> type:
- class DeprecatedClass(*parent): # type: ignore
- def __init__(self, *args, **kwargs):
- msg: str = class_dict.get(
- "__deprecation_warning__", f"{old_name} is deprecated"
- ) # type: ignore
+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)
+
+ return _class_deprecated
- DeprecatedClass.__name__ = old_name
- return DeprecatedClass
+class_deprecated = _generate_class_deprecated()
def attribute_renamed(old_name: str, new_name: str, version: Optional[str] = None) -> Callable:
@@ -412,7 +415,25 @@ def class_renamed(
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
+ # mypy can't handle dynamic base classes https://github.com/python/mypy/issues/2477
+ class DeprecatedClass(new_class): # type: ignore
+ def __init__(self, *args, **kwargs):
+ msg = class_dict.get(
+ "__deprecation_warning__",
+ f"{old_name} is deprecated, use {new_class.__name__} instead",
+ )
+ 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(