From e049c82dafddb0a3b2ae4aaebb12974424feb6de Mon Sep 17 00:00:00 2001 From: Laurent Peuch Date: Wed, 22 Apr 2020 22:43:05 +0200 Subject: [deprecation/refactoring] simplify deprecated --- logilab/common/deprecation.py | 74 ++++++++++++++++++++++++++----------------- test/unittest_deprecation.py | 4 +-- test/unittest_modutils.py | 2 +- test/unittest_registry.py | 2 +- 4 files changed, 49 insertions(+), 33 deletions(-) diff --git a/logilab/common/deprecation.py b/logilab/common/deprecation.py index 4a14aac..cdf538c 100644 --- a/logilab/common/deprecation.py +++ b/logilab/common/deprecation.py @@ -226,8 +226,51 @@ def send_warning(reason, version=None, stacklevel=2): warn(reason, DeprecationWarning, stacklevel=stacklevel) -def deprecated(reason=None, stacklevel=2, name=None, doc=None): - return _defaultdeprecator.deprecated(None, reason, stacklevel, name, doc) +def argument_removed(old_argument_name): + """ + callable decorator to allow getting backward compatibility for renamed keyword arguments. + + >>> @argument_removed("old") + ... def some_function(new): + ... return new + >>> some_function(old=42) + sample.py:15: DeprecationWarning: argument old of callable some_function has been renamed and is deprecated, use keyword argument new instead + some_function(old=42) + 42 + """ + def _wrap(func): + @wraps(func) + def check_kwargs(*args, **kwargs): + if old_argument_name in kwargs: + warn(f"argument {old_argument_name} of callable {func.__name__} has been removed and is " + f"deprecated", stacklevel=2) + del kwargs[old_argument_name] + + return func(*args, **kwargs) + + return check_kwargs + + return _wrap + + +@argument_removed("name") +@argument_removed("doc") +def deprecated(reason=None, version=None, stacklevel=2): + """Display a deprecation message only if the version is older than the + compatible version. + """ + def decorator(func): + message = reason or 'The function "%s" is deprecated' + if '%s' in message: + message %= func.__name__ + + @wraps(func) + def wrapped(*args, **kwargs): + send_warning(message, version, stacklevel + 1) + return func(*args, **kwargs) + return wrapped + + return decorator class class_deprecated(type): @@ -325,33 +368,6 @@ def argument_renamed(old_name, new_name): return _wrap -def argument_removed(old_argument_name): - """ - callable decorator to allow getting backward compatibility for renamed keyword arguments. - - >>> @argument_removed("old") - ... def some_function(new): - ... return new - >>> some_function(old=42) - sample.py:15: DeprecationWarning: argument old of callable some_function has been renamed and is deprecated, use keyword argument new instead - some_function(old=42) - 42 - """ - def _wrap(func): - @wraps(func) - def check_kwargs(*args, **kwargs): - if old_argument_name in kwargs: - warn(f"argument {old_argument_name} of callable {func.__name__} has been removed and is " - f"deprecated", stacklevel=2) - del kwargs[old_argument_name] - - return func(*args, **kwargs) - - return check_kwargs - - return _wrap - - def renamed(old_name, new_function): """use to tell that a callable has been renamed. diff --git a/test/unittest_deprecation.py b/test/unittest_deprecation.py index a348d67..09902a2 100644 --- a/test/unittest_deprecation.py +++ b/test/unittest_deprecation.py @@ -57,7 +57,7 @@ class RawInputTC(TestCase): any_func = deprecation.deprecated('message')(self.mk_func()) any_func() self.assertEqual(self.messages, - ['The function "any_func" is deprecated', 'message']) + ['[logilab.common] The function "any_func" is deprecated', '[logilab.common] message']) def test_deprecated_decorator(self): @deprecation.deprecated() @@ -69,7 +69,7 @@ class RawInputTC(TestCase): pass any_func() self.assertEqual(self.messages, - ['The function "any_func" is deprecated', 'message']) + ['[logilab.common] The function "any_func" is deprecated', '[logilab.common] message']) def test_attribute_renamed(self): @deprecation.attribute_renamed(old_name="old", new_name="new") diff --git a/test/unittest_modutils.py b/test/unittest_modutils.py index 7af241e..cd639e1 100644 --- a/test/unittest_modutils.py +++ b/test/unittest_modutils.py @@ -122,7 +122,7 @@ class modpath_from_file_tc(ModutilsTestCase): with warnings.catch_warnings(record=True) as warns: self.assertEqual(modutils.modpath_from_file(modutils.__file__), ['logilab', 'common', 'modutils']) - self.assertIn('you should avoid using modpath_from_file()', + self.assertIn('[logilab.common] you should avoid using modpath_from_file()', [str(w.message) for w in warns]) def test_knownValues_modpath_from_file_2(self): diff --git a/test/unittest_registry.py b/test/unittest_registry.py index 1c07e4c..2fdb21e 100644 --- a/test/unittest_registry.py +++ b/test/unittest_registry.py @@ -181,7 +181,7 @@ class RegistryStoreTC(TestCase): with warnings.catch_warnings(record=True) as warns: store.register_objects([self.datapath('regobjects.py'), self.datapath('regobjects2.py')]) - self.assertIn('use register_modnames() instead', + self.assertIn('[logilab.common] use register_modnames() instead', [str(w.message) for w in warns]) self.assertEqual(['zereg'], list(store.keys())) self.assertEqual(set(('appobject1', 'appobject2', 'appobject3')), -- cgit v1.2.1