xref: /aosp_15_r20/external/pigweed/pw_cli/py/pw_cli/decorators.py (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1# Copyright 2024 The Pigweed Authors
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4# use this file except in compliance with the License. You may obtain a copy of
5# the License at
6#
7#     https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations under
13# the License.
14"""Common helpful decorators for Python code."""
15
16import inspect
17from pathlib import Path
18from typing import Callable
19import warnings
20
21
22def deprecated(deprecation_note: str):
23    """Deprecation decorator.
24
25    Emits a depreciation warning when the annotated function is used.
26
27    An additional deprecation note is required to redirect users to the
28    appropriate alternative.
29    """
30
31    def _decorator_impl(func: Callable):
32        def _wrapper(*args, **kwargs):
33            caller = inspect.getframeinfo(inspect.currentframe().f_back)
34            deprecated_func_module = inspect.getmodule(func)
35            module_or_file = (
36                '.'.join(
37                    (
38                        deprecated_func_module.__package__,
39                        Path(deprecated_func_module.__file__).stem,
40                    )
41                )
42                if deprecated_func_module.__package__ is not None
43                else deprecated_func_module.__file__
44            )
45            warnings.warn(
46                ' '.join(
47                    (
48                        f'{caller.filename}:{caller.lineno}:',
49                        f'{module_or_file}.{func.__qualname__}()',
50                        'is deprecated.',
51                        deprecation_note,
52                    )
53                ),
54                DeprecationWarning,
55            )
56            return func(*args, **kwargs)
57
58        return _wrapper
59
60    return _decorator_impl
61