Skip to content

Commit 9c04eb9

Browse files
authored
Merge pull request #373 from sbillinge/deprecator
deprecator
2 parents aab1765 + a3ca6c3 commit 9c04eb9

File tree

2 files changed

+82
-19
lines changed

2 files changed

+82
-19
lines changed

news/deprecator.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
**Added:**
22

3+
* added a function in _deprecator to generate a deprecation message for copy pasting
34
* Add ``@deprecated`` decorator.
45

56
**Changed:**

src/diffpy/utils/_deprecator.py

Lines changed: 81 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,40 +20,54 @@ def deprecated(message, *, category=DeprecationWarning, stacklevel=1):
2020
2121
.. code-block:: python
2222
23-
from diffpy._deprecations import deprecated
24-
import warnings
23+
from diffpy.utils._deprecator import deprecated, deprecation_message
2524
26-
@deprecated("old_function is deprecated; use new_function instead")
25+
deprecation_warning = build_deprecation_message("diffpy.utils",
26+
"old_function",
27+
"new_function",
28+
"4.0.0")
29+
30+
@deprecated(deprecation_warning)
2731
def old_function(x, y):
28-
return x + y
32+
'''This function is deprecated and will be removed in version
33+
4.0.0. Please use new_function instead'''
34+
return new_function(x, y)
2935
3036
def new_function(x, y):
3137
return x + y
3238
33-
old_function(1, 2) # Emits DeprecationWarning
34-
new_function(1, 2) # No warning
39+
old_function(1, 2) # Works but emits DeprecationWarning
40+
new_function(1, 2) # Works, no warning
3541
3642
3743
Deprecating a class:
3844
3945
.. code-block:: python
4046
41-
from diffpy._deprecations import deprecated
42-
import warnings
47+
from diffpy.utils._deprecator import deprecated, deprecation_message
4348
44-
warnings.simplefilter("always", DeprecationWarning)
49+
deprecation_warning = build_deprecation_message("diffpy.utils",
50+
"OldAtom",
51+
"NewAtom",
52+
"4.0.0")
4553
46-
@deprecated("OldAtom is deprecated; use NewAtom instead")
54+
@deprecated(deprecation_warning)
4755
class OldAtom:
48-
def __init__(self, symbol):
49-
self.symbol = symbol
56+
def __new__(cls, *args, **kwargs):
57+
warnings.warn(
58+
"OldAtom is deprecated and will be removed in
59+
version 4.0.0. Use NewClass instead.",
60+
DeprecationWarning,
61+
stacklevel=2,
62+
)
63+
return NewAtom(*args, **kwargs)
5064
5165
class NewAtom:
5266
def __init__(self, symbol):
5367
self.symbol = symbol
5468
55-
a = OldAtom("C") # Emits DeprecationWarning
56-
b = NewAtom("C") # No warning
69+
a = OldAtom("C") # Works but emits DeprecationWarning
70+
b = NewAtom("C") # Works with no warning
5771
"""
5872
if _builtin_deprecated is not None:
5973
return _builtin_deprecated(
@@ -75,34 +89,82 @@ def wrapper(*args, **kwargs):
7589
return obj(*args, **kwargs)
7690

7791
return wrapper
78-
7992
raise TypeError(
8093
"deprecated decorator can only be applied to functions or classes"
8194
)
8295

8396
return decorator
8497

8598

86-
def deprecation_message(base, old_name, new_name, removal_version):
99+
def build_deprecation_message(
100+
old_base, old_name, new_name, removal_version, new_base=None
101+
):
87102
"""Generate a deprecation message.
88103
89104
Parameters
90105
----------
91-
base : str
106+
old_base : str
92107
The base module or class where the deprecated item resides.
108+
This will look like the import statement used in the code
109+
currently
93110
old_name : str
94111
The name of the deprecated item.
95112
new_name : str
96113
The name of the new item to use.
97114
removal_version : str
98115
The version when the deprecated item will be removed.
116+
new_base : str Optional. Defaults to old_base.
117+
The base module or class where the new item resides.
118+
This will look like the import statement that
119+
will be used in the code moving forward. If not specified,
120+
the new base defaults to the old one.
99121
100122
Returns
101123
-------
102124
str
103125
A formatted deprecation message.
104126
"""
127+
if new_base is None:
128+
new_base = old_base
105129
return (
106-
f"'{base}.{old_name}' is deprecated and will be removed in "
107-
f"version {removal_version}. Please use '{base}.{new_name}' instead."
130+
f"'{old_base}.{old_name}' is deprecated and will be removed in "
131+
f"version {removal_version}. Please use '{new_base}.{new_name}' "
132+
f"instead."
133+
)
134+
135+
136+
def generate_deprecation_docstring(new_name, removal_version, new_base=None):
137+
"""Generate a docstring for copy-pasting into a deprecated function.
138+
139+
this function will print the text to the terminal for copy-pasting
140+
141+
usage:
142+
python
143+
>>> import diffpy.utils._deprecator.generate_deprecation_docstring as gdd
144+
>>> gdd("new_name", "4.0.0")
145+
146+
The message looks like:
147+
This function has been deprecated and will be removed in version
148+
{removal_version}. Please use {new_base}.{new_name} instead.
149+
150+
Parameters
151+
----------
152+
new_name: str
153+
The name of the new function or class to replace the existing one
154+
removal_version: str
155+
The version when the deprecated item is targeted for removal,
156+
e.g., 4.0.0
157+
new_base: str Optional. Defaults to old_base.
158+
The new base for importing. The new import statement would look like
159+
"from new_base import new_name"
160+
161+
Returns
162+
-------
163+
None
164+
"""
165+
print(
166+
f"This function has been deprecated and will be "
167+
f"removed in version {removal_version}. Please use"
168+
f"{new_base}.{new_name} instead."
108169
)
170+
return

0 commit comments

Comments
 (0)