forked from ray-project/ray
-
Notifications
You must be signed in to change notification settings - Fork 0
/
deprecation.py
142 lines (116 loc) · 4.81 KB
/
deprecation.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
import inspect
import logging
from typing import Optional, Union
from ray.util import log_once
from ray.util.annotations import _mark_annotated
logger = logging.getLogger(__name__)
# A constant to use for any configuration that should be deprecated
# (to check, whether this config has actually been assigned a proper value or
# not).
DEPRECATED_VALUE = -1
def deprecation_warning(
old: str,
new: Optional[str] = None,
*,
help: Optional[str] = None,
error: Optional[Union[bool, Exception]] = None,
) -> None:
"""Warns (via the `logger` object) or throws a deprecation warning/error.
Args:
old: A description of the "thing" that is to be deprecated.
new: A description of the new "thing" that replaces it.
help: An optional help text to tell the user, what to
do instead of using `old`.
error: Whether or which exception to raise. If True, raise ValueError.
If False, just warn. If `error` is-a subclass of Exception,
raise that Exception.
Raises:
ValueError: If `error=True`.
Exception: Of type `error`, iff `error` is a sub-class of `Exception`.
"""
msg = "`{}` has been deprecated.{}".format(
old, (" Use `{}` instead.".format(new) if new else f" {help}" if help else "")
)
if error:
if not type(error) is bool and issubclass(error, Exception):
# error is an Exception
raise error(msg)
else:
# error is a boolean, construct ValueError ourselves
raise ValueError(msg)
else:
logger.warning(
"DeprecationWarning: " + msg + " This will raise an error in the future!"
)
def Deprecated(old=None, *, new=None, help=None, error):
"""Decorator for documenting a deprecated class, method, or function.
Automatically adds a `deprecation.deprecation_warning(old=...,
error=False)` to not break existing code at this point to the decorated
class' constructor, method, or function.
In a next major release, this warning should then be made an error
(by setting error=True), which means at this point that the
class/method/function is no longer supported, but will still inform
the user about the deprecation event.
In a further major release, the class, method, function should be erased
entirely from the codebase.
.. testcode::
:skipif: True
from ray.rllib.utils.deprecation import Deprecated
# Deprecated class: Patches the constructor to warn if the class is
# used.
@Deprecated(new="NewAndMuchCoolerClass", error=False)
class OldAndUncoolClass:
...
# Deprecated class method: Patches the method to warn if called.
class StillCoolClass:
...
@Deprecated(new="StillCoolClass.new_and_much_cooler_method()",
error=False)
def old_and_uncool_method(self, uncool_arg):
...
# Deprecated function: Patches the function to warn if called.
@Deprecated(new="new_and_much_cooler_function", error=False)
def old_and_uncool_function(*uncool_args):
...
"""
def _inner(obj):
# A deprecated class.
if inspect.isclass(obj):
# Patch the class' init method to raise the warning/error.
obj_init = obj.__init__
def patched_init(*args, **kwargs):
if log_once(old or obj.__name__):
deprecation_warning(
old=old or obj.__name__,
new=new,
help=help,
error=error,
)
return obj_init(*args, **kwargs)
obj.__init__ = patched_init
_mark_annotated(obj)
# Return the patched class (with the warning/error when
# instantiated).
return obj
# A deprecated class method or function.
# Patch with the warning/error at the beginning.
def _ctor(*args, **kwargs):
if log_once(old or obj.__name__):
deprecation_warning(
old=old or obj.__name__,
new=new,
help=help,
error=error,
)
# Call the deprecated method/function.
return obj(*args, **kwargs)
# Return the patched class method/function.
return _ctor
# Return the prepared decorator.
return _inner
ALGO_DEPRECATION_WARNING = (
"This algorithm will be removed by ray 2.9 It is being "
"moved to the ray/rllib_contrib dir. See "
"https://github.com/ray-project/enhancements/blob/main/reps/2023-04-28-remove-algorithms-from-rllib.md " # noqa: E501
"for more details. Any associated components (e.g. policies) will also be moved."
)