From 264aa33b507dc149fe0344f6d0b17f0c575ac25e Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Wed, 14 Jun 2023 16:02:57 -0700 Subject: [PATCH 1/6] Fix deprecation logging to prevent logging on import --- ovos_utils/log.py | 17 ++++++++++++----- ovos_utils/skills/audioservice.py | 2 +- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/ovos_utils/log.py b/ovos_utils/log.py index 9d53512c..b6384fb2 100644 --- a/ovos_utils/log.py +++ b/ovos_utils/log.py @@ -10,6 +10,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import functools import inspect import logging import os @@ -175,6 +176,7 @@ def init_service_logger(service_name): def log_deprecation(log_message: str = "DEPRECATED", deprecation_version: str = "Unknown", func_name: str = None, + func_module: str = None, excluded_package_refs: List[str] = None): """ Log a deprecation warning with information for the call outside the module @@ -182,6 +184,7 @@ def log_deprecation(log_message: str = "DEPRECATED", @param log_message: Log contents describing the deprecation @param deprecation_version: package version in which method will be deprecated @param func_name: decorated function name (else read from stack) + @param func_module: decorated function module (else read from stack) @param excluded_package_refs: list of packages to exclude from call origin determination. i.e. an internal exception handling method should log the first call external to that package @@ -189,7 +192,7 @@ def log_deprecation(log_message: str = "DEPRECATED", import inspect stack = inspect.stack()[1:] # [0] is this method call_info = "Unknown Origin" - origin_module = None + origin_module = func_module log_name = LOG.name for call in stack: module = inspect.getmodule(call.frame) @@ -221,9 +224,13 @@ def deprecated(log_message: str, deprecation_version: str): @param deprecation_version: package version in which deprecation will occur """ def wrapped(func): - log_deprecation(log_message=log_message, - func_name=func.__name__, - deprecation_version=deprecation_version) - return func + @functools.wraps(func) + def log_wrapper(*args, **kwargs): + log_deprecation(log_message=log_message, + func_name=func.__name__, + func_module=func.__module__, + deprecation_version=deprecation_version) + return func(*args, **kwargs) + return log_wrapper return wrapped diff --git a/ovos_utils/skills/audioservice.py b/ovos_utils/skills/audioservice.py index 6f470c34..26ed3559 100644 --- a/ovos_utils/skills/audioservice.py +++ b/ovos_utils/skills/audioservice.py @@ -224,7 +224,7 @@ class AudioServiceInterface(ClassicAudioServiceInterface): """ @deprecated("AudioServiceInterface has been deprecated, compatibility " - "layer in use\nplease move to OCPInterface", "0.1.0") + "layer in use. please move to OCPInterface", "0.1.0") def __init__(self, bus=None): super().__init__(bus) From a3b8d00d95417a57c99a541c282040b81716f591 Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Wed, 14 Jun 2023 16:20:28 -0700 Subject: [PATCH 2/6] Update deprecation logging --- ovos_utils/log.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ovos_utils/log.py b/ovos_utils/log.py index b6384fb2..17e0751f 100644 --- a/ovos_utils/log.py +++ b/ovos_utils/log.py @@ -202,9 +202,13 @@ def log_deprecation(log_message: str = "DEPRECATED", # Skip calls from this module and unittests to get at real origin continue if not origin_module: + # Assume first outside call is the origin if not specified origin_module = name log_name = f"{LOG.name} - {name}:{func_name or call[3]}:{call[2]}" continue + elif log_name == LOG.name and name == origin_module: + # Decorator provided origin module name, update the log name + log_name = f"{LOG.name} - {name}:{func_name or call[3]}:{call[2]}" if excluded_package_refs and any((name.startswith(x) for x in excluded_package_refs)): continue From 283d07331c808e61257dbdf9a27322e842fdd0e9 Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Wed, 14 Jun 2023 16:32:26 -0700 Subject: [PATCH 3/6] Troubleshoot deprecated log naming --- ovos_utils/log.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ovos_utils/log.py b/ovos_utils/log.py index 17e0751f..5ebdde9d 100644 --- a/ovos_utils/log.py +++ b/ovos_utils/log.py @@ -206,7 +206,7 @@ def log_deprecation(log_message: str = "DEPRECATED", origin_module = name log_name = f"{LOG.name} - {name}:{func_name or call[3]}:{call[2]}" continue - elif log_name == LOG.name and name == origin_module: + elif log_name == LOG.name: # Decorator provided origin module name, update the log name log_name = f"{LOG.name} - {name}:{func_name or call[3]}:{call[2]}" if excluded_package_refs and any((name.startswith(x) for x in From 32292bbf3a85068b329ef10bfe6749d9fc633b79 Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Wed, 14 Jun 2023 16:44:38 -0700 Subject: [PATCH 4/6] Update default log name handling --- ovos_utils/log.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ovos_utils/log.py b/ovos_utils/log.py index 5ebdde9d..fe3c9eaf 100644 --- a/ovos_utils/log.py +++ b/ovos_utils/log.py @@ -193,7 +193,8 @@ def log_deprecation(log_message: str = "DEPRECATED", stack = inspect.stack()[1:] # [0] is this method call_info = "Unknown Origin" origin_module = func_module - log_name = LOG.name + log_name = f"{LOG.name} - {func_module}:{func_name}" if \ + func_module and func_name else LOG.name for call in stack: module = inspect.getmodule(call.frame) name = module.__name__ if module else call.filename @@ -206,9 +207,6 @@ def log_deprecation(log_message: str = "DEPRECATED", origin_module = name log_name = f"{LOG.name} - {name}:{func_name or call[3]}:{call[2]}" continue - elif log_name == LOG.name: - # Decorator provided origin module name, update the log name - log_name = f"{LOG.name} - {name}:{func_name or call[3]}:{call[2]}" if excluded_package_refs and any((name.startswith(x) for x in excluded_package_refs)): continue From de83ea053071ba51f08fb9f4d489ca2dc02bb7e5 Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Wed, 14 Jun 2023 17:03:13 -0700 Subject: [PATCH 5/6] Add class name in deprecation logging --- ovos_utils/log.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ovos_utils/log.py b/ovos_utils/log.py index fe3c9eaf..e10e1964 100644 --- a/ovos_utils/log.py +++ b/ovos_utils/log.py @@ -228,8 +228,12 @@ def deprecated(log_message: str, deprecation_version: str): def wrapped(func): @functools.wraps(func) def log_wrapper(*args, **kwargs): + if hasattr(func, "__self__"): + name = f"{func.__self__.__name__}.{func.__name__}" + else: + name = func.__name__ log_deprecation(log_message=log_message, - func_name=func.__name__, + func_name=name, func_module=func.__module__, deprecation_version=deprecation_version) return func(*args, **kwargs) From 9d0b592ab10acf9475a46407d34f3097e806c92a Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Wed, 14 Jun 2023 17:18:20 -0700 Subject: [PATCH 6/6] Update deprecation logging with updated tests --- ovos_utils/log.py | 6 +----- test/unittests/deprecation_helper.py | 6 ++++++ test/unittests/test_log.py | 9 +++++++-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/ovos_utils/log.py b/ovos_utils/log.py index e10e1964..ee8d57ee 100644 --- a/ovos_utils/log.py +++ b/ovos_utils/log.py @@ -228,12 +228,8 @@ def deprecated(log_message: str, deprecation_version: str): def wrapped(func): @functools.wraps(func) def log_wrapper(*args, **kwargs): - if hasattr(func, "__self__"): - name = f"{func.__self__.__name__}.{func.__name__}" - else: - name = func.__name__ log_deprecation(log_message=log_message, - func_name=name, + func_name=func.__qualname__, func_module=func.__module__, deprecation_version=deprecation_version) return func(*args, **kwargs) diff --git a/test/unittests/deprecation_helper.py b/test/unittests/deprecation_helper.py index c5ef3ba4..ffe31a7d 100644 --- a/test/unittests/deprecation_helper.py +++ b/test/unittests/deprecation_helper.py @@ -4,3 +4,9 @@ @deprecated("imported deprecation", "0.1.0") def deprecated_function(): pass + + +class Deprecated: + @deprecated("Class Deprecated", "0.2.0") + def __init__(self): + pass diff --git a/test/unittests/test_log.py b/test/unittests/test_log.py index 1ffb8e6f..751f96ae 100644 --- a/test/unittests/test_log.py +++ b/test/unittests/test_log.py @@ -90,14 +90,19 @@ def test_deprecated_decorator(self, create_logger): from ovos_utils.log import deprecated import sys sys.path.insert(0, dirname(__file__)) - from deprecation_helper import deprecated_function + from deprecation_helper import deprecated_function, Deprecated deprecated_function() log_warning.assert_called_once() log_msg = log_warning.call_args[0][0] self.assertIn('version=0.1.0', log_msg, log_msg) - self.assertIn('test_log:', log_msg, log_msg) + self.assertIn('test_log', log_msg, log_msg) self.assertIn('imported deprecation', log_msg, log_msg) + test_class = Deprecated() + log_msg = log_warning.call_args[0][0] + self.assertIn('version=0.2.0', log_msg, log_msg) + self.assertIn('Class Deprecated', log_msg, log_msg) + call_arg = None @deprecated("test deprecation", "1.0.0")