From cf1263c74c3d04e2cb1dba68f3457688d630d471 Mon Sep 17 00:00:00 2001 From: wakonig_k Date: Wed, 6 May 2026 14:06:32 +0200 Subject: [PATCH] chore(device): add deprecation decorator and mark methods for removal in version 4.0 --- bec_lib/bec_lib/device.py | 21 ++++++++++++++ bec_lib/bec_lib/utils/deprecation.py | 42 ++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 bec_lib/bec_lib/utils/deprecation.py diff --git a/bec_lib/bec_lib/device.py b/bec_lib/bec_lib/device.py index 7da672b2d..26f6a0f17 100644 --- a/bec_lib/bec_lib/device.py +++ b/bec_lib/bec_lib/device.py @@ -26,6 +26,7 @@ from bec_lib.endpoints import MessageEndpoints from bec_lib.logger import bec_logger from bec_lib.queue_items import QueueItem +from bec_lib.utils.deprecation import deprecated from bec_lib.utils.import_utils import lazy_import if TYPE_CHECKING: # pragma: no cover @@ -1315,10 +1316,18 @@ def stop(self): msg = messages.VariableMessage(value=[self.root.name]) self.root.parent.parent.connector.send(MessageEndpoints.stop_devices(), msg) + @deprecated( + remove_in_version="4.0", + recommendation="If necessary, implement a custom ophyd signal with the desired functionality. For assistance, please contact the BEC team.", + ) @rpc def settle_time(self): pass + @deprecated( + remove_in_version="4.0", + recommendation="If necessary, implement a custom ophyd signal with the desired functionality. For assistance, please contact the BEC team.", + ) @rpc def timeout(self): pass @@ -1326,14 +1335,26 @@ def timeout(self): def egu(self): return self.describe_configuration().get("egu") + @deprecated( + remove_in_version="4.0", + recommendation="Use umv, umvr, mv, or mvr methods instead, depending on your use case. For assistance, please contact the BEC team.", + ) def move(self, val: float, relative=False): return self.root.parent.parent.scans.mv(self, val, relative=relative) @property + @deprecated( + remove_in_version="4.0", + recommendation="Use the read method or .wm property instead to get the current position of the device. For assistance, please contact the BEC team.", + ) @rpc def position(self): pass + @deprecated( + remove_in_version="4.0", + recommendation="Use the status object returned by the set method to check if the device is still moving. For assistance, please contact the BEC team.", + ) @rpc def moving(self): pass diff --git a/bec_lib/bec_lib/utils/deprecation.py b/bec_lib/bec_lib/utils/deprecation.py new file mode 100644 index 000000000..38ef39fa5 --- /dev/null +++ b/bec_lib/bec_lib/utils/deprecation.py @@ -0,0 +1,42 @@ +from __future__ import annotations + +import warnings +from functools import wraps + +warnings.formatwarning = lambda msg, *args, **kwargs: f">>> DEPRECATION: {msg}\n" + + +def deprecated(remove_in_version: str | None = None, recommendation: str | None = None): + """ + Decorator to mark functions as deprecated. + + Args: + remove_in_version (str | None): Optional version string indicating when the function will be removed. + recommendation (str | None): Optional string suggesting an alternative function or approach to use. + + Returns: + A decorator that can be applied to functions to mark them as deprecated. + + Example usage: + @deprecated(remove_in_version="2.0", recommendation="Use new_function instead.") + def old_function(): + pass + + # This will print: + # "old_function is deprecated and will be removed in version 2.0. Use new_function instead" + """ + + def decorator(func): + @wraps(func) + def wrapper(*args, **kwargs): + message = f"{func.__name__} is deprecated" + if remove_in_version: + message += f" and will be removed in version {remove_in_version}" + if recommendation: + message += f". {recommendation}" + warnings.warn(message, category=DeprecationWarning) + return func(*args, **kwargs) + + return wrapper + + return decorator