decorator - Deprecate Warning Decorator#

deprecate_warning_decorator.py
 1# -*- coding: utf-8 -*-
 2
 3"""
 4在维护一个开源项目时, 随着版本的推进, 很多旧的 API 会不推荐使用了, 但是为了兼容性, 一般维护着
 5不会粗暴的将这个 API 删除. 正确的做法是实现一个新的 API 来取代这个 API, 然后在旧的 API 上
 6加上 PendingDeprecationWarning, 让开发者自己看到这个 API 以后要准备被 deprecate 了.
 7然后在 1 - 2 个版本时间后, 再在旧的 API 上加上 DeprecationWarning, 让旧的 API 依然能够工作,
 8但是明确说明什么时候这个 API 会被彻底删除, 并且提示用户使用新的 API. 再经过再经过 1 - 2 个
 9版本时间后, 再将旧的 API 删除.
10
11这种做法在 Python 中一般由装饰器实现.
12"""
13
14import warnings
15from decorator import decorator
16
17
18@decorator
19def mark_pending_deprecation(func, *args, **kwargs):
20    """
21    这个不是给最终用户看的, 这个是给开发者自己看的.
22    """
23    warnings.warn(
24        f"{func.__name__} will be deprecated soon, it will be marked as deprecated from A.B.C",
25        PendingDeprecationWarning,
26    )
27    result = func(*args, **kwargs)
28    return result
29
30
31@decorator
32def mark_deprecation(func, *args, **kwargs):
33    """
34    这是给最终用户看的, 提示用户使用新的 API.
35    """
36    warnings.warn(
37        f"{func.__name__} is deprecated, it will be deleted from X.Y.Z, "
38        f"you should use 'this' API instead",
39        DeprecationWarning,
40    )
41    result = func(*args, **kwargs)
42    return result
43
44
45@mark_pending_deprecation
46def my_func(name: str):
47    print(f"Hello {name} from my_func")
48
49
50class Model:
51    @mark_pending_deprecation
52    def __init__(self, name: str):
53        print("Construct an instance of class Model")
54        self.name = name
55
56    @mark_pending_deprecation
57    def my_method(self):
58        print(f"Hello {self.name} from Model.my_method")
59
60    @property
61    @mark_pending_deprecation
62    def my_property(self):
63        print(f"Hello {self.name} from Model.my_property")
64        return None
65
66    @classmethod
67    @mark_deprecation
68    def my_classmethod(cls, name: str):
69        print(f"Hello {name} from Model.my_classmethod")
70
71    @staticmethod
72    @mark_deprecation
73    def my_staticmethod(name: str):
74        print(f"Hello {name} from Model.my_staticmethod")
75
76
77if __name__ == "__main__":
78    """
79    打印的结果如下:
80    
81    Hello Alice from my_func
82    Construct an instance of class Model
83    Hello Alice from Model.my_method
84    Hello Alice from Model.my_property
85    Hello Alice from Model.my_classmethod
86    Hello Alice from Model.my_staticmethod
87    /path/to/learn_pylib-project/docs/source/decorator/Deprecate-Warning-Decorator/deprecate_warning_decorator.py:36: DeprecationWarning: my_classmethod is deprecated, it will be deleted from X.Y.Z, you should use 'this' API instead
88      warnings.warn(
89    /path/to/learn_pylib-project/docs/source/decorator/Deprecate-Warning-Decorator/deprecate_warning_decorator.py:36: DeprecationWarning: my_staticmethod is deprecated, it will be deleted from X.Y.Z, you should use 'this' API instead
90      warnings.warn(
91    """
92    my_func(name="Alice")
93
94    model = Model(name="Alice")
95    model.my_method()
96    _ = model.my_property
97    Model.my_classmethod(name="Alice")
98    Model.my_staticmethod(name="Alice")