Skip to content

Commit 2e8d887

Browse files
committed
deprecator decorator
1 parent 30407bf commit 2e8d887

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed

src/diffpy/utils/_deprecator.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import functools
2+
import warnings
3+
4+
# Deprecated decorator is available for Python 3.13+, once
5+
# Support for earlier versions is dropped, this custom implementation can be removed.
6+
try:
7+
from warnings import deprecated as _builtin_deprecated
8+
except ImportError:
9+
_builtin_deprecated = None
10+
11+
def deprecated(*, alt_name=None, message=None):
12+
"""
13+
Marks a function or class as deprecated.
14+
15+
Emits a DeprecationWarning whenever the decorated function is called
16+
or the decorated class is instantiated.
17+
18+
Parameters
19+
----------
20+
alt_name : str, optional
21+
Name of the recommended alternative.
22+
message : str, optional
23+
Custom deprecation message. If None, a default message is generated.
24+
25+
Returns
26+
-------
27+
decorator : function
28+
Decorator that wraps the deprecated object.
29+
30+
Examples
31+
--------
32+
.. code-block:: python
33+
34+
from diffpy._deprecations import deprecated
35+
36+
# ------------------------------
37+
# Deprecated function
38+
# ------------------------------
39+
@deprecated(alt_name="new_function")
40+
def old_function(x, y):
41+
return x + y
42+
43+
def new_function(x, y):
44+
return x + y
45+
46+
# Usage
47+
old_function(1, 2) # Emits DeprecationWarning
48+
new_function(1, 2) # No warning
49+
50+
# ------------------------------
51+
# Deprecated class
52+
# ------------------------------
53+
@deprecated(alt_name="NewAtom")
54+
class OldAtom:
55+
def __init__(self, symbol):
56+
self.symbol = symbol
57+
58+
# Usage
59+
a = OldAtom("C") # Emits DeprecationWarning
60+
atom = NewAtom("C") # No warning
61+
"""
62+
if _builtin_deprecated:
63+
return _builtin_deprecated
64+
65+
def decorator(obj):
66+
name = getattr(obj, "__name__", repr(obj))
67+
msg = message or (f"'{name}' is deprecated. Use '{alt_name}' instead."
68+
if alt_name else f"'{name}' is deprecated.")
69+
70+
if callable(obj):
71+
@functools.wraps(obj)
72+
def wrapper(*args, **kwargs):
73+
warnings.warn(msg, DeprecationWarning, stacklevel=2)
74+
return obj(*args, **kwargs)
75+
return wrapper
76+
else:
77+
raise TypeError("deprecated decorator can only be applied to functions or classes")
78+
return decorator

0 commit comments

Comments
 (0)