diff --git a/rocketpy/mathutils/function.py b/rocketpy/mathutils/function.py index 221974ca8..a034ba6f8 100644 --- a/rocketpy/mathutils/function.py +++ b/rocketpy/mathutils/function.py @@ -24,7 +24,7 @@ RBFInterpolator, ) -from rocketpy.tools import from_hex_decode, to_hex_encode +from rocketpy.tools import deprecated, from_hex_decode, to_hex_encode from ..plots.plot_helpers import show_or_save_plot @@ -1459,14 +1459,13 @@ def plot(self, *args, **kwargs): else: print("Error: Only functions with 1D or 2D domains can be plotted.") + @deprecated( + reason="The `Function.plot1D` method is set to be deprecated and fully " + "removed in rocketpy v2.0.0", + alternative="Function.plot_1d", + ) def plot1D(self, *args, **kwargs): # pragma: no cover """Deprecated method, use Function.plot_1d instead.""" - warnings.warn( - "The `Function.plot1D` method is set to be deprecated and fully " - + "removed in rocketpy v2.0.0, use `Function.plot_1d` instead. " - + "This method is calling `Function.plot_1d`.", - DeprecationWarning, - ) return self.plot_1d(*args, **kwargs) def plot_1d( # pylint: disable=too-many-statements @@ -1559,14 +1558,13 @@ def plot_1d( # pylint: disable=too-many-statements if return_object: return fig, ax + @deprecated( + reason="The `Function.plot2D` method is set to be deprecated and fully " + "removed in rocketpy v2.0.0", + alternative="Function.plot_2d", + ) def plot2D(self, *args, **kwargs): # pragma: no cover """Deprecated method, use Function.plot_2d instead.""" - warnings.warn( - "The `Function.plot2D` method is set to be deprecated and fully " - + "removed in rocketpy v2.0.0, use `Function.plot_2d` instead. " - + "This method is calling `Function.plot_2d`.", - DeprecationWarning, - ) return self.plot_2d(*args, **kwargs) def plot_2d( # pylint: disable=too-many-statements diff --git a/rocketpy/rocket/rocket.py b/rocketpy/rocket/rocket.py index bf938d4be..31ef9dd3f 100644 --- a/rocketpy/rocket/rocket.py +++ b/rocketpy/rocket/rocket.py @@ -1,5 +1,4 @@ import math -import warnings import numpy as np @@ -22,7 +21,7 @@ from rocketpy.rocket.aero_surface.generic_surface import GenericSurface from rocketpy.rocket.components import Components from rocketpy.rocket.parachute import Parachute -from rocketpy.tools import parallel_axis_theorem_from_com +from rocketpy.tools import deprecated, parallel_axis_theorem_from_com # pylint: disable=too-many-instance-attributes, too-many-public-methods, too-many-instance-attributes @@ -1173,16 +1172,16 @@ def add_nose( self.add_surfaces(nose, position) return nose + @deprecated( + reason="This method is set to be deprecated in version 1.0.0 and fully " + "removed by version 2.0.0", + alternative="Rocket.add_trapezoidal_fins", + ) def add_fins(self, *args, **kwargs): # pragma: no cover """See Rocket.add_trapezoidal_fins for documentation. This method is set to be deprecated in version 1.0.0 and fully removed by version 2.0.0. Use Rocket.add_trapezoidal_fins instead. It keeps the same arguments and signature.""" - warnings.warn( - "This method is set to be deprecated in version 1.0.0 and fully " - "removed by version 2.0.0. Use Rocket.add_trapezoidal_fins instead", - DeprecationWarning, - ) return self.add_trapezoidal_fins(*args, **kwargs) def add_trapezoidal_fins( diff --git a/rocketpy/tools.py b/rocketpy/tools.py index 692d5e224..a5ffb1b50 100644 --- a/rocketpy/tools.py +++ b/rocketpy/tools.py @@ -14,6 +14,7 @@ import math import re import time +import warnings from bisect import bisect_left import dill @@ -28,6 +29,66 @@ INSTALL_MAPPING = {"IPython": "ipython"} +def deprecated(reason=None, version=None, alternative=None): + """ + Decorator to mark functions or methods as deprecated. + + This decorator issues a DeprecationWarning when the decorated function + is called, indicating that it will be removed in future versions. + + Parameters + ---------- + reason : str, optional + Custom deprecation message. If not provided, a default message will be used. + version : str, optional + Version when the function will be removed. If provided, it will be + included in the warning message. + alternative : str, optional + Name of the alternative function/method that should be used instead. + If provided, it will be included in the warning message. + + Returns + ------- + callable + The decorated function with deprecation warning functionality. + + Examples + -------- + >>> @deprecated(reason="This function is obsolete", version="v2.0.0", + ... alternative="new_function") + ... def old_function(): + ... return "old result" + + >>> @deprecated() + ... def another_old_function(): + ... return "result" + """ + + def decorator(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + # Build the deprecation message + if reason: + message = reason + else: + message = f"The function `{func.__name__}` is deprecated" + + if version: + message += f" and will be removed in {version}" + + if alternative: + message += f". Use `{alternative}` instead" + + message += "." + + warnings.warn(message, DeprecationWarning, stacklevel=2) + return func(*args, **kwargs) + + return wrapper + + return decorator + + def tuple_handler(value): """Transforms the input value into a tuple that represents a range. If the input is an int or float, the output is a tuple from zero to the input