/
_deprecated.py
159 lines (139 loc) · 5.49 KB
/
_deprecated.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# Copyright 2019-2022 The kikuchipy developers
#
# This file is part of kikuchipy.
#
# kikuchipy is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# kikuchipy is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with kikuchipy. If not, see <http://www.gnu.org/licenses/>.
"""Helper functions and classes for managing kikuchipy.
This module and documentation is only relevant for kikuchipy developers,
not for users.
.. warning:
This module and its submodules are for internal use only. Do not
use them in your own code. We may change the API at any time with no
warning.
"""
import functools
import inspect
from typing import Callable, Optional, Union
import warnings
import numpy as np
class deprecated:
"""Decorator to mark deprecated functions with an informative
warning.
Adapted from
`scikit-image
<https://github.com/scikit-image/scikit-image/blob/main/skimage/_shared/utils.py#L297>`_
and `matplotlib
<https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/_api/deprecation.py#L122>`_.
"""
def __init__(
self,
since: Union[str, int, float],
alternative: Optional[str] = None,
alternative_is_function: bool = True,
removal: Union[str, int, float, None] = None,
):
"""Visible deprecation warning.
Parameters
----------
since
The release at which this API became deprecated.
alternative
An alternative API that the user may use in place of the
deprecated API.
alternative_is_function
Whether the alternative is a function. Default is ``True``.
removal
The expected removal version.
"""
self.since = since
self.alternative = alternative
self.alternative_is_function = alternative_is_function
self.removal = removal
def __call__(self, func: Callable):
# Wrap function to raise warning when called, and add warning to
# docstring
if self.alternative is not None:
if self.alternative_is_function:
alt_msg = f" Use `{self.alternative}()` instead."
else:
alt_msg = f" Use `{self.alternative}` instead."
else:
alt_msg = ""
if self.removal is not None:
rm_msg = f" and will be removed in version {self.removal}"
else:
rm_msg = ""
if self.alternative_is_function:
msg = f"Function `{func.__name__}()` is deprecated{rm_msg}.{alt_msg}"
else:
msg = f"Attribute `{func.__name__}` is deprecated{rm_msg}.{alt_msg}"
@functools.wraps(func)
def wrapped(*args, **kwargs):
warnings.simplefilter(
action="always", category=np.VisibleDeprecationWarning, append=True
)
func_code = func.__code__
warnings.warn_explicit(
message=msg,
category=np.VisibleDeprecationWarning,
filename=func_code.co_filename,
lineno=func_code.co_firstlineno + 1,
)
return func(*args, **kwargs)
# Modify docstring to display deprecation warning
old_doc = inspect.cleandoc(func.__doc__ or "").strip("\n")
notes_header = "\nNotes\n-----"
new_doc = (
f"[*Deprecated*] {old_doc}\n"
f"{notes_header if notes_header not in old_doc else ''}\n"
f".. deprecated:: {self.since}\n"
f" {msg.strip()}" # Matplotlib uses three spaces
)
wrapped.__doc__ = new_doc
return wrapped
class deprecated_argument:
"""Decorator to remove an argument from a function or method's
signature.
Adapted from `scikit-image
<https://github.com/scikit-image/scikit-image/blob/main/skimage/_shared/utils.py#L115>`_.
"""
def __init__(self, name, since, removal, alternative=None):
self.name = name
self.since = since
self.removal = removal
self.alternative = alternative
def __call__(self, func):
@functools.wraps(func)
def wrapped(*args, **kwargs):
if self.name in kwargs.keys():
msg = (
f"Parameter `{self.name}` is deprecated and will be removed in "
f"version {self.removal}. To avoid this warning, please do not use "
f"`{self.name}`. "
)
if self.alternative is not None:
msg += f"Use `{self.alternative}` instead. "
msg += f"See the documentation of `{func.__name__}()` for more details."
warnings.simplefilter(
action="always", category=np.VisibleDeprecationWarning
)
func_code = func.__code__
warnings.warn_explicit(
message=msg,
category=np.VisibleDeprecationWarning,
filename=func_code.co_filename,
lineno=func_code.co_firstlineno + 1,
)
return func(*args, **kwargs)
return wrapped