From 518222d1f76d1bcd3ee9d4abc496c27c69286c73 Mon Sep 17 00:00:00 2001 From: Prithwish Mukherjee Date: Sun, 12 Oct 2025 21:12:13 +0530 Subject: [PATCH 01/15] refactor: Update deprecate arguments. --- src/ansys/fluent/core/utils/deprecate_new.py | 109 +++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 src/ansys/fluent/core/utils/deprecate_new.py diff --git a/src/ansys/fluent/core/utils/deprecate_new.py b/src/ansys/fluent/core/utils/deprecate_new.py new file mode 100644 index 00000000000..b3440815f00 --- /dev/null +++ b/src/ansys/fluent/core/utils/deprecate_new.py @@ -0,0 +1,109 @@ +"""Deprecate Arguments.""" + +import functools +from typing import Any, Callable +import warnings + +from deprecated.sphinx import deprecated + +from ansys.fluent.core.pyfluent_warnings import PyFluentDeprecationWarning + + +def deprecate_arguments( + old_arg_list: list[list[str]], + new_arg_list: list[list[str]], + version: str, + converter: Callable | None = None, + warning_cls: type = PyFluentDeprecationWarning, +) -> Callable: + """ + Deprecate multiple arguments (possibly grouped) and automatically replace them with new ones. + + Parameters + ---------- + old_arg_list : list[list[str]] + Each inner list represents a group of old argument names being deprecated. + new_arg_list : list[list[str]] + Each inner list represents a corresponding group of new argument names. + version : str + The version in which the arguments were deprecated. + converter : callable, optional + Custom converter function that takes (kwargs, old_arg_list, new_arg_list) + and returns modified kwargs. + If not provided, a default converter is used. + warning_cls : type, optional + The warning class to use for deprecation warnings. + + Raises + ------ + ValueError + For arguments mismatch. + """ + + # Validation + if len(old_arg_list) != len(new_arg_list): + raise ValueError( + f"old_arg_list and new_arg_list must have the same number of groups. " + f"Got {len(old_arg_list)} vs {len(new_arg_list)}." + ) + + # Default converter + def _default_converter( + kwargs: dict[str, Any], + old_param_list: list[list[str]], + new_param_list: list[list[str]], + ) -> dict[str, Any]: + """Default converter that maps all old args to new args one-to-one across groups.""" + for old_group, new_group in zip(old_param_list, new_param_list): + if len(old_group) > len(new_group): + raise ValueError( + f"Cannot automatically convert {old_group} → {new_group}: " + "too many old args. Provide a custom converter." + ) + + # map values from old args to new args (1-to-1 or many-to-one) + for i, old_arg in enumerate(old_group): + if old_arg in kwargs: + old_val = kwargs.pop(old_arg) + target_arg = new_group[min(i, len(new_group) - 1)] + kwargs.setdefault(target_arg, old_val) + return kwargs + + converter = converter or _default_converter + + def build_warning_messages() -> list[str]: + messages = [] + for old_group, new_group in zip(old_arg_list, new_arg_list): + old_str = ", ".join(f"'{o}'" for o in old_group) + new_str = ", ".join(f"'{n}'" for n in new_group) + messages.append( + f"Arguments {old_str} are deprecated; use {new_str} instead." + ) + return messages + + reason = " ".join(build_warning_messages()) + + def decorator(func: Callable): + # Documentation + deprecated_func = deprecated(version=version, reason=reason)(func) + + @functools.wraps(deprecated_func) + def wrapper(*args, **kwargs): + # Issue warnings for all relevant mappings + for old_group, new_group in zip(old_arg_list, new_arg_list): + if any(arg in kwargs for arg in old_group): + old_str = ", ".join(f"'{o}'" for o in old_group) + new_str = ", ".join(f"'{n}'" for n in new_group) + warnings.warn( + f"Arguments {old_str} are deprecated; use {new_str} instead.", + warning_cls, + stacklevel=2, + ) + + # Perform conversion (default or custom) + kwargs = converter(kwargs, old_arg_list, new_arg_list) + return deprecated_func(*args, **kwargs) + + return wrapper + + return decorator From e3771b95ed0bc6870f3dbc592b7e08666261b085 Mon Sep 17 00:00:00 2001 From: pyansys-ci-bot <92810346+pyansys-ci-bot@users.noreply.github.com> Date: Sun, 12 Oct 2025 15:55:25 +0000 Subject: [PATCH 02/15] chore: adding changelog file 4553.miscellaneous.md [dependabot-skip] --- doc/changelog.d/4553.miscellaneous.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 doc/changelog.d/4553.miscellaneous.md diff --git a/doc/changelog.d/4553.miscellaneous.md b/doc/changelog.d/4553.miscellaneous.md new file mode 100644 index 00000000000..647f4e65c6a --- /dev/null +++ b/doc/changelog.d/4553.miscellaneous.md @@ -0,0 +1 @@ +Update deprecate arguments. From 4ce6ca98ea5cfa86d3dfb20cc96b127fc5bcefae Mon Sep 17 00:00:00 2001 From: Prithwish Mukherjee Date: Mon, 13 Oct 2025 10:12:51 +0530 Subject: [PATCH 03/15] Sample Implementation. --- src/ansys/fluent/core/file_session.py | 38 +++++++++------- src/ansys/fluent/core/launcher/launcher.py | 36 +++++++-------- src/ansys/fluent/core/services/field_data.py | 48 +++++++++++++------- src/ansys/fluent/core/utils/deprecate_new.py | 27 +++++++---- 4 files changed, 89 insertions(+), 60 deletions(-) diff --git a/src/ansys/fluent/core/file_session.py b/src/ansys/fluent/core/file_session.py index 2b0853f1a1c..d0bc7f29e19 100644 --- a/src/ansys/fluent/core/file_session.py +++ b/src/ansys/fluent/core/file_session.py @@ -55,6 +55,7 @@ _to_vector_field_name, ) from ansys.fluent.core.utils.deprecate import all_deprecators +from ansys.fluent.core.utils.deprecate_new import deprecate_arguments class InvalidMultiPhaseFieldName(ValueError): @@ -87,6 +88,19 @@ def _data_type_convertor(args_dict): return args_dict +def _custom_converter(kwargs, old_arg_list, new_arg_list): + for old_group, new_group in zip(old_arg_list, new_arg_list): + if old_group == ["surface_names"] and new_group == ["surfaces"]: + kwargs["surfaces"] = kwargs.pop("surface_names", None) + elif old_group == ["surface_ids"] and new_group == ["surfaces"]: + kwargs["surfaces"] = kwargs.pop("surface_ids", None) + elif old_group == ["provide_vertices", "provide_faces"] and new_group == [ + "data_types" + ]: + kwargs = _data_type_convertor(kwargs) + return kwargs + + class BatchFieldData: """Provides access to Fluent field data on surfaces collected via batches.""" @@ -253,23 +267,15 @@ def get_surface_ids(self, surfaces: List[str | int]) -> List[int]: surfaces=surfaces, ) - @all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "surface_names", - "new_arg": "surfaces", - "converter": lambda old_arg_val: old_arg_val, - }, - { - "old_arg": "surface_ids", - "new_arg": "surfaces", - "converter": lambda old_arg_val: old_arg_val, - }, + @deprecate_arguments( + old_arg_list=[ + ["surface_names"], + ["surface_ids"], + ["provide_vertices", "provide_faces"], ], - data_type_converter=_data_type_convertor, - deprecated_version="v0.25.0", - deprecated_reason="Old arguments 'surface_ids' and 'surface_names' are deprecated. Use 'surfaces' instead.", - warn_message="'add_surfaces_request' is deprecated, use 'add_requests' instead.", + new_arg_list=[["surfaces"], ["surfaces"], ["data_types"]], + version="v0.25.0", + converter=_custom_converter, ) def add_surfaces_request( self, diff --git a/src/ansys/fluent/core/launcher/launcher.py b/src/ansys/fluent/core/launcher/launcher.py index 18245060745..c8ce9a5fc7d 100644 --- a/src/ansys/fluent/core/launcher/launcher.py +++ b/src/ansys/fluent/core/launcher/launcher.py @@ -58,7 +58,7 @@ from ansys.fluent.core.session_pure_meshing import PureMeshing from ansys.fluent.core.session_solver import Solver from ansys.fluent.core.session_solver_icing import SolverIcing -from ansys.fluent.core.utils.deprecate import all_deprecators +from ansys.fluent.core.utils.deprecate_new import deprecate_arguments from ansys.fluent.core.utils.fluent_version import FluentVersion _THIS_DIR = os.path.dirname(__file__) @@ -125,24 +125,22 @@ def _version_to_dimension(old_arg_val): return None -# pylint: disable=unused-argument -@all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "show_gui", - "new_arg": "ui_mode", - "converter": _show_gui_to_ui_mode, - }, - { - "old_arg": "version", - "new_arg": "dimension", - "converter": _version_to_dimension, - }, - ], - data_type_converter=None, - deprecated_version="v0.22.dev0", - deprecated_reason="'show_gui' and 'version' are deprecated. Use 'ui_mode' and 'dimension' instead.", - warn_message="", +def _custom_converter(kwargs, old_arg_list, new_arg_list): + for old_group, new_group in zip(old_arg_list, new_arg_list): + if old_group == ["show_gui"] and new_group == ["ui_mode"]: + old_val = kwargs.pop("show_gui", None) + kwargs["ui_mode"] = _show_gui_to_ui_mode(old_val, **kwargs) + elif old_group == ["version"] and new_group == ["dimension"]: + old_val = kwargs.pop("version", None) + kwargs["dimension"] = _version_to_dimension(old_val) + return kwargs + + +@deprecate_arguments( + old_arg_list=[["show_gui"], ["version"]], + new_arg_list=[["ui_mode"], ["dimension"]], + version="v0.22.0", + converter=_custom_converter, ) def launch_fluent( product_version: FluentVersion | str | float | int | None = None, diff --git a/src/ansys/fluent/core/services/field_data.py b/src/ansys/fluent/core/services/field_data.py index ba2597c8b49..14ca3c53d5d 100644 --- a/src/ansys/fluent/core/services/field_data.py +++ b/src/ansys/fluent/core/services/field_data.py @@ -69,6 +69,7 @@ ) from ansys.fluent.core.services.streaming import StreamingService from ansys.fluent.core.utils.deprecate import all_deprecators +from ansys.fluent.core.utils.deprecate_new import deprecate_arguments logger = logging.getLogger("pyfluent.field_data") @@ -413,6 +414,24 @@ def _data_type_convertor(args_dict): return args_dict +def _custom_converter(kwargs, old_arg_list, new_arg_list): + for old_group, new_group in zip(old_arg_list, new_arg_list): + if old_group == ["surface_names"] and new_group == ["surfaces"]: + if "surface_names" in kwargs: + kwargs["surfaces"] = kwargs.pop("surface_names") + elif old_group == ["surface_ids"] and new_group == ["surfaces"]: + if "surface_ids" in kwargs: + kwargs["surfaces"] = kwargs.pop("surface_ids") + elif old_group == [ + "provide_vertices", + "provide_faces", + "provide_faces_centroid", + "provide_faces_normal", + ] and new_group == ["data_types"]: + kwargs = _data_type_convertor(kwargs) + return kwargs + + class _FetchFieldData: @staticmethod @@ -783,23 +802,20 @@ def _add_pathlines_fields_request( ) ) - @all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "surface_names", - "new_arg": "surfaces", - "converter": lambda old_arg_val: old_arg_val or [], - }, - { - "old_arg": "surface_ids", - "new_arg": "surfaces", - "converter": lambda old_arg_val: old_arg_val or [], - }, + @deprecate_arguments( + old_arg_list=[ + ["surface_names"], + ["surface_ids"], + [ + "provide_vertices", + "provide_faces", + "provide_faces_centroid", + "provide_faces_normal", + ], ], - data_type_converter=_data_type_convertor, - deprecated_version="v0.23.dev0", - deprecated_reason="Old arguments 'surface_ids' and 'surface_names' are deprecated. Use 'surfaces' instead.", - warn_message="'add_surfaces_request' is deprecated, use 'add_requests' instead", + new_arg_list=[["surfaces"], ["surfaces"], ["data_types"]], + version="v0.23.0", + converter=_custom_converter, ) def add_surfaces_request( self, diff --git a/src/ansys/fluent/core/utils/deprecate_new.py b/src/ansys/fluent/core/utils/deprecate_new.py index b3440815f00..9241e4c4ed7 100644 --- a/src/ansys/fluent/core/utils/deprecate_new.py +++ b/src/ansys/fluent/core/utils/deprecate_new.py @@ -14,7 +14,7 @@ def deprecate_arguments( new_arg_list: list[list[str]], version: str, converter: Callable | None = None, - warning_cls: type = PyFluentDeprecationWarning, + warning_cls: warnings = PyFluentDeprecationWarning, ) -> Callable: """ Deprecate multiple arguments (possibly grouped) and automatically replace them with new ones. @@ -31,7 +31,7 @@ def deprecate_arguments( Custom converter function that takes (kwargs, old_arg_list, new_arg_list) and returns modified kwargs. If not provided, a default converter is used. - warning_cls : type, optional + warning_cls : warnings, optional The warning class to use for deprecation warnings. Raises @@ -61,24 +61,33 @@ def _default_converter( "too many old args. Provide a custom converter." ) - # map values from old args to new args (1-to-1 or many-to-one) for i, old_arg in enumerate(old_group): if old_arg in kwargs: old_val = kwargs.pop(old_arg) - target_arg = new_group[min(i, len(new_group) - 1)] - kwargs.setdefault(target_arg, old_val) + target_arg = new_group[i] + if target_arg in kwargs: + warnings.warn( + f"Both deprecated argument '{old_arg}' and new argument '{target_arg}' were provided. " + f"Ignoring {old_arg}." + ) + else: + kwargs[target_arg] = old_val return kwargs converter = converter or _default_converter + def _message(old: str, new: str) -> str: + if "," in old: + return f"Arguments {old} are deprecated; use {new} instead." + else: + return f"Argument {old} is deprecated; use {new} instead." + def build_warning_messages() -> list[str]: messages = [] for old_group, new_group in zip(old_arg_list, new_arg_list): old_str = ", ".join(f"'{o}'" for o in old_group) new_str = ", ".join(f"'{n}'" for n in new_group) - messages.append( - f"Arguments {old_str} are deprecated; use {new_str} instead." - ) + messages.append(_message(old_str, new_str)) return messages reason = " ".join(build_warning_messages()) @@ -95,7 +104,7 @@ def wrapper(*args, **kwargs): old_str = ", ".join(f"'{o}'" for o in old_group) new_str = ", ".join(f"'{n}'" for n in new_group) warnings.warn( - f"Arguments {old_str} are deprecated; use {new_str} instead.", + _message(old_str, new_str), warning_cls, stacklevel=2, ) From 15024cb980aada1043d5ed4dba751d8d7d22028c Mon Sep 17 00:00:00 2001 From: Prithwish Mukherjee <109645853+prmukherj@users.noreply.github.com> Date: Mon, 13 Oct 2025 10:16:10 +0530 Subject: [PATCH 04/15] Update src/ansys/fluent/core/launcher/launcher.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/ansys/fluent/core/launcher/launcher.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ansys/fluent/core/launcher/launcher.py b/src/ansys/fluent/core/launcher/launcher.py index c8ce9a5fc7d..fddf3971651 100644 --- a/src/ansys/fluent/core/launcher/launcher.py +++ b/src/ansys/fluent/core/launcher/launcher.py @@ -129,7 +129,10 @@ def _custom_converter(kwargs, old_arg_list, new_arg_list): for old_group, new_group in zip(old_arg_list, new_arg_list): if old_group == ["show_gui"] and new_group == ["ui_mode"]: old_val = kwargs.pop("show_gui", None) - kwargs["ui_mode"] = _show_gui_to_ui_mode(old_val, **kwargs) + if old_val is not None: + kwargs["ui_mode"] = _show_gui_to_ui_mode(old_val, **kwargs) + else: + kwargs["ui_mode"] = None elif old_group == ["version"] and new_group == ["dimension"]: old_val = kwargs.pop("version", None) kwargs["dimension"] = _version_to_dimension(old_val) From 1e655f5aae5c352bbcb4fb04a8b765365d2ac42f Mon Sep 17 00:00:00 2001 From: Prithwish Mukherjee <109645853+prmukherj@users.noreply.github.com> Date: Mon, 13 Oct 2025 10:16:29 +0530 Subject: [PATCH 05/15] Update src/ansys/fluent/core/utils/deprecate_new.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/ansys/fluent/core/utils/deprecate_new.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/fluent/core/utils/deprecate_new.py b/src/ansys/fluent/core/utils/deprecate_new.py index 9241e4c4ed7..9515c3e6634 100644 --- a/src/ansys/fluent/core/utils/deprecate_new.py +++ b/src/ansys/fluent/core/utils/deprecate_new.py @@ -14,7 +14,7 @@ def deprecate_arguments( new_arg_list: list[list[str]], version: str, converter: Callable | None = None, - warning_cls: warnings = PyFluentDeprecationWarning, + warning_cls: type[Warning] = PyFluentDeprecationWarning, ) -> Callable: """ Deprecate multiple arguments (possibly grouped) and automatically replace them with new ones. From a191e0617910f92b3a1fb206bea86c61dadb05aa Mon Sep 17 00:00:00 2001 From: Prithwish Mukherjee Date: Mon, 13 Oct 2025 10:19:12 +0530 Subject: [PATCH 06/15] Refactor. --- src/ansys/fluent/core/utils/deprecate_new.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ansys/fluent/core/utils/deprecate_new.py b/src/ansys/fluent/core/utils/deprecate_new.py index 9515c3e6634..0cf62314c0b 100644 --- a/src/ansys/fluent/core/utils/deprecate_new.py +++ b/src/ansys/fluent/core/utils/deprecate_new.py @@ -68,7 +68,9 @@ def _default_converter( if target_arg in kwargs: warnings.warn( f"Both deprecated argument '{old_arg}' and new argument '{target_arg}' were provided. " - f"Ignoring {old_arg}." + f"Ignoring {old_arg}.", + PyFluentDeprecationWarning, + stacklevel=2, ) else: kwargs[target_arg] = old_val From 2c5555b3938ec956c691f911b74e365a77cffb42 Mon Sep 17 00:00:00 2001 From: Prithwish Mukherjee <109645853+prmukherj@users.noreply.github.com> Date: Mon, 13 Oct 2025 10:20:21 +0530 Subject: [PATCH 07/15] Update src/ansys/fluent/core/launcher/launcher.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/ansys/fluent/core/launcher/launcher.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/ansys/fluent/core/launcher/launcher.py b/src/ansys/fluent/core/launcher/launcher.py index fddf3971651..c8ce9a5fc7d 100644 --- a/src/ansys/fluent/core/launcher/launcher.py +++ b/src/ansys/fluent/core/launcher/launcher.py @@ -129,10 +129,7 @@ def _custom_converter(kwargs, old_arg_list, new_arg_list): for old_group, new_group in zip(old_arg_list, new_arg_list): if old_group == ["show_gui"] and new_group == ["ui_mode"]: old_val = kwargs.pop("show_gui", None) - if old_val is not None: - kwargs["ui_mode"] = _show_gui_to_ui_mode(old_val, **kwargs) - else: - kwargs["ui_mode"] = None + kwargs["ui_mode"] = _show_gui_to_ui_mode(old_val, **kwargs) elif old_group == ["version"] and new_group == ["dimension"]: old_val = kwargs.pop("version", None) kwargs["dimension"] = _version_to_dimension(old_val) From 8919d889c888ac6a1caf479c34d2562c621d5df9 Mon Sep 17 00:00:00 2001 From: Prithwish Mukherjee Date: Wed, 15 Oct 2025 10:11:39 +0530 Subject: [PATCH 08/15] Update signature. --- src/ansys/fluent/core/file_session.py | 33 +++--- src/ansys/fluent/core/launcher/launcher.py | 29 +++-- src/ansys/fluent/core/services/field_data.py | 46 +++----- src/ansys/fluent/core/utils/deprecate_new.py | 110 +++++++++---------- 4 files changed, 98 insertions(+), 120 deletions(-) diff --git a/src/ansys/fluent/core/file_session.py b/src/ansys/fluent/core/file_session.py index d0bc7f29e19..19a9d82d6eb 100644 --- a/src/ansys/fluent/core/file_session.py +++ b/src/ansys/fluent/core/file_session.py @@ -88,19 +88,6 @@ def _data_type_convertor(args_dict): return args_dict -def _custom_converter(kwargs, old_arg_list, new_arg_list): - for old_group, new_group in zip(old_arg_list, new_arg_list): - if old_group == ["surface_names"] and new_group == ["surfaces"]: - kwargs["surfaces"] = kwargs.pop("surface_names", None) - elif old_group == ["surface_ids"] and new_group == ["surfaces"]: - kwargs["surfaces"] = kwargs.pop("surface_ids", None) - elif old_group == ["provide_vertices", "provide_faces"] and new_group == [ - "data_types" - ]: - kwargs = _data_type_convertor(kwargs) - return kwargs - - class BatchFieldData: """Provides access to Fluent field data on surfaces collected via batches.""" @@ -268,14 +255,20 @@ def get_surface_ids(self, surfaces: List[str | int]) -> List[int]: ) @deprecate_arguments( - old_arg_list=[ - ["surface_names"], - ["surface_ids"], - ["provide_vertices", "provide_faces"], - ], - new_arg_list=[["surfaces"], ["surfaces"], ["data_types"]], + old_args="surface_names", + new_args="surfaces", + version="v0.25.0", + ) + @deprecate_arguments( + old_args="surface_ids", + new_args="surfaces", + version="v0.25.0", + ) + @deprecate_arguments( + old_args=["provide_vertices", "provide_faces"], + new_args="data_types", version="v0.25.0", - converter=_custom_converter, + converter=_data_type_convertor, ) def add_surfaces_request( self, diff --git a/src/ansys/fluent/core/launcher/launcher.py b/src/ansys/fluent/core/launcher/launcher.py index c8ce9a5fc7d..fea4754fa95 100644 --- a/src/ansys/fluent/core/launcher/launcher.py +++ b/src/ansys/fluent/core/launcher/launcher.py @@ -125,22 +125,29 @@ def _version_to_dimension(old_arg_val): return None -def _custom_converter(kwargs, old_arg_list, new_arg_list): - for old_group, new_group in zip(old_arg_list, new_arg_list): - if old_group == ["show_gui"] and new_group == ["ui_mode"]: - old_val = kwargs.pop("show_gui", None) - kwargs["ui_mode"] = _show_gui_to_ui_mode(old_val, **kwargs) - elif old_group == ["version"] and new_group == ["dimension"]: - old_val = kwargs.pop("version", None) - kwargs["dimension"] = _version_to_dimension(old_val) +def _custom_converter_gui(kwargs): + old_val = kwargs.pop("show_gui", None) + kwargs["ui_mode"] = _show_gui_to_ui_mode(old_val, **kwargs) return kwargs +def _custom_converter_dimension(kwargs): + old_val = kwargs.pop("version", None) + kwargs["dimension"] = _version_to_dimension(old_val) + return kwargs + + +@deprecate_arguments( + old_args="show_gui", + new_args="ui_mode", + version="v0.22.0", + converter=_custom_converter_gui, +) @deprecate_arguments( - old_arg_list=[["show_gui"], ["version"]], - new_arg_list=[["ui_mode"], ["dimension"]], + old_args="version", + new_args="dimension", version="v0.22.0", - converter=_custom_converter, + converter=_custom_converter_dimension, ) def launch_fluent( product_version: FluentVersion | str | float | int | None = None, diff --git a/src/ansys/fluent/core/services/field_data.py b/src/ansys/fluent/core/services/field_data.py index 14ca3c53d5d..750f6fe2599 100644 --- a/src/ansys/fluent/core/services/field_data.py +++ b/src/ansys/fluent/core/services/field_data.py @@ -414,24 +414,6 @@ def _data_type_convertor(args_dict): return args_dict -def _custom_converter(kwargs, old_arg_list, new_arg_list): - for old_group, new_group in zip(old_arg_list, new_arg_list): - if old_group == ["surface_names"] and new_group == ["surfaces"]: - if "surface_names" in kwargs: - kwargs["surfaces"] = kwargs.pop("surface_names") - elif old_group == ["surface_ids"] and new_group == ["surfaces"]: - if "surface_ids" in kwargs: - kwargs["surfaces"] = kwargs.pop("surface_ids") - elif old_group == [ - "provide_vertices", - "provide_faces", - "provide_faces_centroid", - "provide_faces_normal", - ] and new_group == ["data_types"]: - kwargs = _data_type_convertor(kwargs) - return kwargs - - class _FetchFieldData: @staticmethod @@ -803,19 +785,25 @@ def _add_pathlines_fields_request( ) @deprecate_arguments( - old_arg_list=[ - ["surface_names"], - ["surface_ids"], - [ - "provide_vertices", - "provide_faces", - "provide_faces_centroid", - "provide_faces_normal", - ], + old_args="surface_names", + new_args="surfaces", + version="v0.23.0", + ) + @deprecate_arguments( + old_args="surface_ids", + new_args="surfaces", + version="v0.23.0", + ) + @deprecate_arguments( + old_args=[ + "provide_vertices", + "provide_faces", + "provide_faces_centroid", + "provide_faces_normal", ], - new_arg_list=[["surfaces"], ["surfaces"], ["data_types"]], + new_args="data_types", version="v0.23.0", - converter=_custom_converter, + converter=_data_type_convertor, ) def add_surfaces_request( self, diff --git a/src/ansys/fluent/core/utils/deprecate_new.py b/src/ansys/fluent/core/utils/deprecate_new.py index 0cf62314c0b..3e5dff98303 100644 --- a/src/ansys/fluent/core/utils/deprecate_new.py +++ b/src/ansys/fluent/core/utils/deprecate_new.py @@ -10,8 +10,8 @@ def deprecate_arguments( - old_arg_list: list[list[str]], - new_arg_list: list[list[str]], + old_args: str | list[str], + new_args: str | list[str], version: str, converter: Callable | None = None, warning_cls: type[Warning] = PyFluentDeprecationWarning, @@ -21,15 +21,14 @@ def deprecate_arguments( Parameters ---------- - old_arg_list : list[list[str]] - Each inner list represents a group of old argument names being deprecated. - new_arg_list : list[list[str]] - Each inner list represents a corresponding group of new argument names. + old_args : str | list[str] + Old argument name(s) to deprecate. + new_args : str | list[str] + New argument name(s) to use instead. version : str The version in which the arguments were deprecated. converter : callable, optional - Custom converter function that takes (kwargs, old_arg_list, new_arg_list) - and returns modified kwargs. + Custom converter function taking (kwargs, old_args, new_args) and returning modified kwargs. If not provided, a default converter is used. warning_cls : warnings, optional The warning class to use for deprecation warnings. @@ -39,60 +38,50 @@ def deprecate_arguments( ValueError For arguments mismatch. """ + if isinstance(old_args, str): + old_args = [old_args] + + if isinstance(new_args, str): + new_args = [new_args] # Validation - if len(old_arg_list) != len(new_arg_list): + if len(old_args) != len(new_args) and converter is None: raise ValueError( - f"old_arg_list and new_arg_list must have the same number of groups. " - f"Got {len(old_arg_list)} vs {len(new_arg_list)}." + f"Cannot automatically convert {old_args} → {new_args}: too many old args. " + f"Provide a custom converter." ) # Default converter def _default_converter( kwargs: dict[str, Any], - old_param_list: list[list[str]], - new_param_list: list[list[str]], + old_params: list[str], + new_params: list[str], ) -> dict[str, Any]: - """Default converter that maps all old args to new args one-to-one across groups.""" - for old_group, new_group in zip(old_param_list, new_param_list): - if len(old_group) > len(new_group): - raise ValueError( - f"Cannot automatically convert {old_group} → {new_group}: " - "too many old args. Provide a custom converter." - ) - - for i, old_arg in enumerate(old_group): - if old_arg in kwargs: - old_val = kwargs.pop(old_arg) - target_arg = new_group[i] - if target_arg in kwargs: - warnings.warn( - f"Both deprecated argument '{old_arg}' and new argument '{target_arg}' were provided. " - f"Ignoring {old_arg}.", - PyFluentDeprecationWarning, - stacklevel=2, - ) - else: - kwargs[target_arg] = old_val + """Default converter that maps all old args to new args one-to-one.""" + for i, old_arg in enumerate(old_params): + if old_arg in kwargs: + old_val = kwargs.pop(old_arg) + target_arg = new_params[i] + if target_arg in kwargs: + warnings.warn( + f"Both deprecated argument '{old_arg}' and new argument '{target_arg}' were provided. " + f"Ignoring {old_arg}.", + PyFluentDeprecationWarning, + stacklevel=2, + ) + else: + kwargs[target_arg] = old_val return kwargs converter = converter or _default_converter - def _message(old: str, new: str) -> str: - if "," in old: - return f"Arguments {old} are deprecated; use {new} instead." - else: - return f"Argument {old} is deprecated; use {new} instead." - - def build_warning_messages() -> list[str]: - messages = [] - for old_group, new_group in zip(old_arg_list, new_arg_list): - old_str = ", ".join(f"'{o}'" for o in old_group) - new_str = ", ".join(f"'{n}'" for n in new_group) - messages.append(_message(old_str, new_str)) - return messages - - reason = " ".join(build_warning_messages()) + # Build reason message for @deprecated + old_str = ", ".join(f"'{o}'" for o in old_args) + new_str = ", ".join(f"'{n}'" for n in new_args) + if len(old_args) > 1: + reason = f"Arguments {old_str} are deprecated; use {new_str} instead." + else: + reason = f"Argument {old_str} is deprecated; use {new_str} instead." def decorator(func: Callable): # Documentation @@ -100,19 +89,20 @@ def decorator(func: Callable): @functools.wraps(deprecated_func) def wrapper(*args, **kwargs): - # Issue warnings for all relevant mappings - for old_group, new_group in zip(old_arg_list, new_arg_list): - if any(arg in kwargs for arg in old_group): - old_str = ", ".join(f"'{o}'" for o in old_group) - new_str = ", ".join(f"'{n}'" for n in new_group) - warnings.warn( - _message(old_str, new_str), - warning_cls, - stacklevel=2, - ) + # Warn only if any old arg(s) present + if any(arg in kwargs for arg in old_args): + warnings.warn( + reason, + warning_cls, + stacklevel=2, + ) # Perform conversion (default or custom) - kwargs = converter(kwargs, old_arg_list, new_arg_list) + try: + kwargs = converter(kwargs, old_args, new_args) + except TypeError: + # If the custom converter takes only kwargs + kwargs = converter(kwargs) return deprecated_func(*args, **kwargs) return wrapper From 532a912dc87521c8bc0c43d639341711c3bc09f0 Mon Sep 17 00:00:00 2001 From: Prithwish Mukherjee Date: Wed, 15 Oct 2025 11:17:30 +0530 Subject: [PATCH 09/15] Clean up. --- src/ansys/fluent/core/file_session.py | 201 +++++++----------- .../fluent/core/launcher/fluent_container.py | 28 +-- .../core/services/deprecated_field_data.py | 120 ++++------- src/ansys/fluent/core/services/field_data.py | 111 ++++------ .../core/services/solution_variables.py | 114 +++------- src/ansys/fluent/core/utils/deprecate_new.py | 50 +++++ .../core/utils/file_transfer_service.py | 28 +-- 7 files changed, 260 insertions(+), 392 deletions(-) diff --git a/src/ansys/fluent/core/file_session.py b/src/ansys/fluent/core/file_session.py index 19a9d82d6eb..0352e70c94c 100644 --- a/src/ansys/fluent/core/file_session.py +++ b/src/ansys/fluent/core/file_session.py @@ -54,8 +54,10 @@ _to_scalar_field_name, _to_vector_field_name, ) -from ansys.fluent.core.utils.deprecate import all_deprecators -from ansys.fluent.core.utils.deprecate_new import deprecate_arguments +from ansys.fluent.core.utils.deprecate_new import ( + deprecate_arguments, + deprecate_function, +) class InvalidMultiPhaseFieldName(ValueError): @@ -270,6 +272,7 @@ def get_surface_ids(self, surfaces: List[str | int]) -> List[int]: version="v0.25.0", converter=_data_type_convertor, ) + @deprecate_function(version="v0.25.0", new_func="add_requests") def add_surfaces_request( self, data_types: List[SurfaceDataType] | List[str], @@ -310,24 +313,17 @@ def _add_surfaces_request( Batch._SurfaceTransaction(surface_id, provide_vertices, provide_faces) ) - @all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "surface_names", - "new_arg": "surfaces", - "converter": lambda old_arg_val: old_arg_val, - }, - { - "old_arg": "surface_ids", - "new_arg": "surfaces", - "converter": lambda old_arg_val: old_arg_val, - }, - ], - data_type_converter=None, - deprecated_version="v0.25.0", - deprecated_reason="Old arguments 'surface_ids' and 'surface_names' are deprecated. Use 'surfaces' instead.", - warn_message="'add_scalar_fields_request' is deprecated, use 'add_requests' instead.", + @deprecate_arguments( + old_args="surface_names", + new_args="surfaces", + version="v0.25.0", + ) + @deprecate_arguments( + old_args="surface_ids", + new_args="surfaces", + version="v0.25.0", ) + @deprecate_function(version="v0.25.0", new_func="add_requests") def add_scalar_fields_request( self, field_name: str, @@ -387,24 +383,17 @@ def _add_scalar_fields_request( Batch._ScalarFieldTransaction(field_name, surface_ids) ) - @all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "surface_names", - "new_arg": "surfaces", - "converter": lambda old_arg_val: old_arg_val, - }, - { - "old_arg": "surface_ids", - "new_arg": "surfaces", - "converter": lambda old_arg_val: old_arg_val, - }, - ], - data_type_converter=None, - deprecated_version="v0.25.0", - deprecated_reason="Old arguments 'surface_ids' and 'surface_names' are deprecated. Use 'surfaces' instead.", - warn_message="'add_vector_fields_request' is deprecated, use 'add_requests' instead.", + @deprecate_arguments( + old_args="surface_names", + new_args="surfaces", + version="v0.25.0", + ) + @deprecate_arguments( + old_args="surface_ids", + new_args="surfaces", + version="v0.25.0", ) + @deprecate_function(version="v0.25.0", new_func="add_requests") def add_vector_fields_request( self, field_name: str, @@ -449,24 +438,17 @@ def _add_vector_fields_request( Batch._VectorFieldTransaction(field_name, surface_ids) ) - @all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "surface_names", - "new_arg": "surfaces", - "converter": lambda old_arg_val: old_arg_val, - }, - { - "old_arg": "surface_ids", - "new_arg": "surfaces", - "converter": lambda old_arg_val: old_arg_val, - }, - ], - data_type_converter=None, - deprecated_version="v0.25.0", - deprecated_reason="Old arguments 'surface_ids' and 'surface_names' are deprecated. Use 'surfaces' instead.", - warn_message="Pathlines are not supported.", + @deprecate_arguments( + old_args="surface_names", + new_args="surfaces", + version="v0.25.0", + ) + @deprecate_arguments( + old_args="surface_ids", + new_args="surfaces", + version="v0.25.0", ) + @deprecate_function(version="v0.25.0", new_func="add_requests") def add_pathlines_fields_request( self, field_name: str, @@ -658,29 +640,17 @@ def get_surface_ids(self, surfaces: List[str | int]) -> List[int]: surfaces=surfaces, ) - @all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "surface_names", - "new_arg": "surfaces", - "converter": lambda old_arg_val: [old_arg_val], - }, - { - "old_arg": "surface_ids", - "new_arg": "surfaces", - "converter": lambda old_arg_val: old_arg_val, - }, - { - "old_arg": "data_type", - "new_arg": "data_types", - "converter": lambda old_arg_val: [old_arg_val] if old_arg_val else None, - }, - ], - data_type_converter=None, - deprecated_version="v0.25.0", - deprecated_reason="Old arguments 'surface_ids', 'surface_names' and 'data_type' are deprecated. Use 'surfaces' and 'data_types' instead.", - warn_message="'get_surface_data' is deprecated, use 'get_field_data' instead.", + @deprecate_arguments( + old_args="surface_names", + new_args="surfaces", + version="v0.25.0", ) + @deprecate_arguments( + old_args="surface_ids", + new_args="surfaces", + version="v0.25.0", + ) + @deprecate_function(version="v0.25.0", new_func="get_field_data") def get_surface_data( self, data_types: List[SurfaceDataType] | List[str], @@ -761,24 +731,17 @@ def _get_surface_data( for count, surface in enumerate(surfaces) } - @all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "surface_names", - "new_arg": "surfaces", - "converter": lambda old_arg_val: [old_arg_val], - }, - { - "old_arg": "surface_ids", - "new_arg": "surfaces", - "converter": lambda old_arg_val: old_arg_val, - }, - ], - data_type_converter=None, - deprecated_version="v0.25.0", - deprecated_reason="Old arguments 'surface_ids' and 'surface_names' are deprecated. Use 'surfaces' instead.", - warn_message="'get_scalar_field_data' is deprecated, use 'get_field_data' instead.", + @deprecate_arguments( + old_args="surface_names", + new_args="surfaces", + version="v0.25.0", + ) + @deprecate_arguments( + old_args="surface_ids", + new_args="surfaces", + version="v0.25.0", ) + @deprecate_function(version="v0.25.0", new_func="get_field_data") def get_scalar_field_data( self, field_name: str, @@ -847,24 +810,17 @@ def _get_scalar_field_data( for count, surface in enumerate(surfaces) } - @all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "surface_names", - "new_arg": "surfaces", - "converter": lambda old_arg_val: [old_arg_val], - }, - { - "old_arg": "surface_ids", - "new_arg": "surfaces", - "converter": lambda old_arg_val: old_arg_val, - }, - ], - data_type_converter=None, - deprecated_version="v0.25.0", - deprecated_reason="Old arguments 'surface_ids' and 'surface_names' are deprecated. Use 'surfaces' instead.", - warn_message="'get_vector_field_data' is deprecated, use 'get_field_data' instead.", + @deprecate_arguments( + old_args="surface_names", + new_args="surfaces", + version="v0.25.0", + ) + @deprecate_arguments( + old_args="surface_ids", + new_args="surfaces", + version="v0.25.0", ) + @deprecate_function(version="v0.25.0", new_func="get_field_data") def get_vector_field_data( self, field_name: str, @@ -928,24 +884,17 @@ def _get_vector_field_data( for count, surface in enumerate(surfaces) } - @all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "surface_names", - "new_arg": "surfaces", - "converter": lambda old_arg_val: [old_arg_val], - }, - { - "old_arg": "surface_ids", - "new_arg": "surfaces", - "converter": lambda old_arg_val: old_arg_val, - }, - ], - data_type_converter=None, - deprecated_version="v0.25.0", - deprecated_reason="Old arguments 'surface_ids' and 'surface_names' are deprecated. Use 'surfaces' instead.", - warn_message="Pathlines are not supported.", + @deprecate_arguments( + old_args="surface_names", + new_args="surfaces", + version="v0.25.0", + ) + @deprecate_arguments( + old_args="surface_ids", + new_args="surfaces", + version="v0.25.0", ) + @deprecate_function(version="v0.25.0", new_func="get_field_data") def get_pathlines_field_data( self, field_name: str, diff --git a/src/ansys/fluent/core/launcher/fluent_container.py b/src/ansys/fluent/core/launcher/fluent_container.py index c9593cf09a0..d0a0efa1860 100644 --- a/src/ansys/fluent/core/launcher/fluent_container.py +++ b/src/ansys/fluent/core/launcher/fluent_container.py @@ -88,7 +88,7 @@ from ansys.fluent.core.launcher.launcher_utils import ComposeConfig from ansys.fluent.core.pyfluent_warnings import PyFluentDeprecationWarning from ansys.fluent.core.session import _parse_server_info_file -from ansys.fluent.core.utils.deprecate import all_deprecators +from ansys.fluent.core.utils.deprecate_new import deprecate_arguments from ansys.fluent.core.utils.execution import timeout_loop from ansys.fluent.core.utils.networking import get_free_port @@ -139,23 +139,15 @@ def dict_to_str(dict: dict) -> str: return pformat(dict) -@all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "container_mount_path", - "new_arg": "mount_target", - "converter": lambda old_arg_val: old_arg_val, - }, - { - "old_arg": "host_mount_path", - "new_arg": "mount_source", - "converter": lambda old_arg_val: old_arg_val, - }, - ], - data_type_converter=None, - deprecated_version="v0.23.dev1", - deprecated_reason="'container_mount_path' and 'host_mount_path' are deprecated. Use 'mount_target' and 'mount_source' instead.", - warn_message="", +@deprecate_arguments( + old_args="container_mount_path", + new_args="mount_target", + version="v0.23.0", +) +@deprecate_arguments( + old_args="host_mount_path", + new_args="mount_source", + version="v0.23.0", ) def configure_container_dict( args: List[str], diff --git a/src/ansys/fluent/core/services/deprecated_field_data.py b/src/ansys/fluent/core/services/deprecated_field_data.py index 1edd785d7ef..bef3056a899 100644 --- a/src/ansys/fluent/core/services/deprecated_field_data.py +++ b/src/ansys/fluent/core/services/deprecated_field_data.py @@ -42,7 +42,7 @@ get_fields_request, override_help_text, ) -from ansys.fluent.core.utils.deprecate import all_deprecators +from ansys.fluent.core.utils.deprecate_new import deprecate_arguments DEPRECATION_MSG = "'field_data_old' is deprecated. Use 'field_data' instead." @@ -297,23 +297,15 @@ def new_transaction(self): self._allowed_vector_field_names, ) - @all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "surface_names", - "new_arg": "surfaces", - "converter": lambda old_arg_val: [old_arg_val] if old_arg_val else [], - }, - { - "old_arg": "surface_ids", - "new_arg": "surfaces", - "converter": lambda old_arg_val: old_arg_val or [], - }, - ], - data_type_converter=None, - deprecated_version="v0.27.0", - deprecated_reason="Old arguments 'surface_ids' and 'surface_names' are deprecated. Use 'surfaces' instead.", - warn_message=DEPRECATION_MSG, + @deprecate_arguments( + old_args="surface_names", + new_args="surfaces", + version="v0.27.0", + ) + @deprecate_arguments( + old_args="surface_ids", + new_args="surfaces", + version="v0.27.0", ) def get_scalar_field_data( self, @@ -344,6 +336,7 @@ def get_scalar_field_data( IDs are provided as input, a dictionary containing a map of surface IDs to scalar field data. """ + warnings.warn(DEPRECATION_MSG, PyFluentDeprecationWarning) surface_ids = _get_surface_ids( field_info=self._field_info, allowed_surface_names=self._allowed_surface_names, @@ -383,28 +376,20 @@ def get_scalar_field_data( for surface_id in surface_ids } - @all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "surface_names", - "new_arg": "surfaces", - "converter": lambda old_arg_val: [old_arg_val] if old_arg_val else [], - }, - { - "old_arg": "surface_ids", - "new_arg": "surfaces", - "converter": lambda old_arg_val: old_arg_val or [], - }, - { - "old_arg": "data_type", - "new_arg": "data_types", - "converter": lambda old_arg_val: [old_arg_val] if old_arg_val else [], - }, - ], - data_type_converter=None, - deprecated_version="v0.27.0", - deprecated_reason="Old arguments 'surface_names', 'surface_ids' and 'data_type' are deprecated. Use 'surfaces' and 'data_types' instead.", - warn_message=DEPRECATION_MSG, + @deprecate_arguments( + old_args="surface_names", + new_args="surfaces", + version="v0.27.0", + ) + @deprecate_arguments( + old_args="surface_ids", + new_args="surfaces", + version="v0.27.0", + ) + @deprecate_arguments( + old_args="data_type", + new_args="data_types", + version="v0.27.0", ) def get_surface_data( self, @@ -436,6 +421,7 @@ def get_surface_data( If surface IDs are provided as input, a dictionary containing a map of surface IDs to face vertices, connectivity data, and normal or centroid data is returned. """ + warnings.warn(DEPRECATION_MSG, PyFluentDeprecationWarning) surface_ids = _get_surface_ids( field_info=self._field_info, allowed_surface_names=self._allowed_surface_names, @@ -523,23 +509,15 @@ def _get_surfaces_data(parent_class, surf_id, _data_type): for surface_id in surface_ids } - @all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "surface_names", - "new_arg": "surfaces", - "converter": lambda old_arg_val: [old_arg_val] if old_arg_val else [], - }, - { - "old_arg": "surface_ids", - "new_arg": "surfaces", - "converter": lambda old_arg_val: old_arg_val or [], - }, - ], - data_type_converter=None, - deprecated_version="v0.27.0", - deprecated_reason="Old arguments 'surface_ids' and 'surface_names' are deprecated. Use 'surfaces' instead.", - warn_message=DEPRECATION_MSG, + @deprecate_arguments( + old_args="surface_names", + new_args="surfaces", + version="v0.27.0", + ) + @deprecate_arguments( + old_args="surface_ids", + new_args="surfaces", + version="v0.27.0", ) def get_vector_field_data( self, @@ -562,6 +540,7 @@ def get_vector_field_data( If surface IDs are provided as input, a dictionary containing a map of surface IDs to vector field data is returned. """ + warnings.warn(DEPRECATION_MSG, PyFluentDeprecationWarning) surface_ids = _get_surface_ids( field_info=self._field_info, allowed_surface_names=self._allowed_surface_names, @@ -600,23 +579,15 @@ def get_vector_field_data( for surface_id in surface_ids } - @all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "surface_names", - "new_arg": "surfaces", - "converter": lambda old_arg_val: [old_arg_val] if old_arg_val else [], - }, - { - "old_arg": "surface_ids", - "new_arg": "surfaces", - "converter": lambda old_arg_val: old_arg_val or [], - }, - ], - data_type_converter=None, - deprecated_version="v0.27.0", - deprecated_reason="Old arguments 'surface_ids' and 'surface_names' are deprecated. Use 'surfaces' instead.", - warn_message=DEPRECATION_MSG, + @deprecate_arguments( + old_args="surface_names", + new_args="surfaces", + version="v0.27.0", + ) + @deprecate_arguments( + old_args="surface_ids", + new_args="surfaces", + version="v0.27.0", ) def get_pathlines_field_data( self, @@ -675,6 +646,7 @@ def get_pathlines_field_data( Dictionary containing a map of surface IDs to the pathline data. For example, pathlines connectivity, vertices, and field. """ + warnings.warn(DEPRECATION_MSG, PyFluentDeprecationWarning) if zones is None: zones = [] surface_ids = _get_surface_ids( diff --git a/src/ansys/fluent/core/services/field_data.py b/src/ansys/fluent/core/services/field_data.py index 750f6fe2599..92428b0ee66 100644 --- a/src/ansys/fluent/core/services/field_data.py +++ b/src/ansys/fluent/core/services/field_data.py @@ -31,7 +31,6 @@ import warnings import weakref -from deprecated.sphinx import deprecated import grpc import numpy as np @@ -68,8 +67,10 @@ TracingInterceptor, ) from ansys.fluent.core.services.streaming import StreamingService -from ansys.fluent.core.utils.deprecate import all_deprecators -from ansys.fluent.core.utils.deprecate_new import deprecate_arguments +from ansys.fluent.core.utils.deprecate_new import ( + deprecate_arguments, + deprecate_function, +) logger = logging.getLogger("pyfluent.field_data") @@ -805,6 +806,7 @@ def _add_pathlines_fields_request( version="v0.23.0", converter=_data_type_convertor, ) + @deprecate_function(version="v0.23.0", new_func="add_requests") def add_surfaces_request( self, data_types: List[SurfaceDataType] | List[str], @@ -819,24 +821,17 @@ def add_surfaces_request( overset_mesh=overset_mesh, ) - @all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "surface_names", - "new_arg": "surfaces", - "converter": lambda old_arg_val: old_arg_val or [], - }, - { - "old_arg": "surface_ids", - "new_arg": "surfaces", - "converter": lambda old_arg_val: old_arg_val or [], - }, - ], - data_type_converter=None, - deprecated_version="v0.23.dev0", - deprecated_reason="Old arguments 'surface_ids' and 'surface_names' are deprecated. Use 'surfaces' instead.", - warn_message="'add_scalar_fields_request' is deprecated, use 'add_requests' instead", + @deprecate_arguments( + old_args="surface_names", + new_args="surfaces", + version="v0.23.0", + ) + @deprecate_arguments( + old_args="surface_ids", + new_args="surfaces", + version="v0.23.0", ) + @deprecate_function(version="v0.23.0", new_func="add_requests") def add_scalar_fields_request( self, field_name: str, @@ -852,24 +847,17 @@ def add_scalar_fields_request( boundary_value=boundary_value, ) - @all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "surface_names", - "new_arg": "surfaces", - "converter": lambda old_arg_val: old_arg_val or [], - }, - { - "old_arg": "surface_ids", - "new_arg": "surfaces", - "converter": lambda old_arg_val: old_arg_val or [], - }, - ], - data_type_converter=None, - deprecated_version="v0.23.dev0", - deprecated_reason="Old arguments 'surface_ids' and 'surface_names' are deprecated. Use 'surfaces' instead.", - warn_message="'add_vector_fields_request' is deprecated, use 'add_requests' instead", + @deprecate_arguments( + old_args="surface_names", + new_args="surfaces", + version="v0.23.0", ) + @deprecate_arguments( + old_args="surface_ids", + new_args="surfaces", + version="v0.23.0", + ) + @deprecate_function(version="v0.23.0", new_func="add_requests") def add_vector_fields_request( self, field_name: str, @@ -880,24 +868,17 @@ def add_vector_fields_request( field_name=field_name, surfaces=self.get_surface_ids(surfaces) ) - @all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "surface_names", - "new_arg": "surfaces", - "converter": lambda old_arg_val: old_arg_val or [], - }, - { - "old_arg": "surface_ids", - "new_arg": "surfaces", - "converter": lambda old_arg_val: old_arg_val or [], - }, - ], - data_type_converter=None, - deprecated_version="v0.23.dev0", - deprecated_reason="Old arguments 'surface_ids' and 'surface_names' are deprecated. Use 'surfaces' instead.", - warn_message="'add_pathlines_fields_request' is deprecated, use 'add_requests' instead", + @deprecate_arguments( + old_args="surface_names", + new_args="surfaces", + version="v0.23.0", ) + @deprecate_arguments( + old_args="surface_ids", + new_args="surfaces", + version="v0.23.0", + ) + @deprecate_function(version="v0.23.0", new_func="add_requests") def add_pathlines_fields_request( self, field_name: str, @@ -1493,7 +1474,7 @@ def new_batch(self): self._allowed_vector_field_names, ) - @deprecated(version="0.34", reason="Use `new_batch` instead.") + @deprecate_function(version="v0.34.0", new_func="new_batch") def new_transaction(self): """Create a new field transaction.""" return self.new_batch() @@ -1640,6 +1621,7 @@ def _get_pathlines_field_data( flatten_connectivity=kwargs.get("flatten_connectivity"), ) + @deprecate_function(version="v0.34.0", new_func="get_field_data") def get_scalar_field_data( self, field_name: str, @@ -1648,10 +1630,6 @@ def get_scalar_field_data( boundary_value: bool | None = True, ) -> Dict[int | str, np.array]: """Get scalar field data on a surface.""" - warnings.warn( - "'get_scalar_field_data' is deprecated, use 'get_field_data' instead", - PyFluentDeprecationWarning, - ) return self._get_scalar_field_data( field_name=field_name, surfaces=surfaces, @@ -1659,6 +1637,7 @@ def get_scalar_field_data( boundary_value=boundary_value, ) + @deprecate_function(version="v0.34.0", new_func="get_field_data") def get_surface_data( self, data_types: List[SurfaceDataType], @@ -1666,30 +1645,24 @@ def get_surface_data( overset_mesh: bool | None = False, ) -> Dict[int | str, Dict[SurfaceDataType, np.array | List[np.array]]]: """Get surface data (vertices, faces connectivity, centroids, and normals).""" - warnings.warn( - "'get_surface_data' is deprecated, use 'get_field_data' instead", - PyFluentDeprecationWarning, - ) self._deprecated_flag = True return self._get_surface_data( data_types=data_types, surfaces=surfaces, overset_mesh=overset_mesh ) + @deprecate_function(version="v0.34.0", new_func="get_field_data") def get_vector_field_data( self, field_name: str, surfaces: List[int | str], ) -> Dict[int | str, np.array]: """Get vector field data on a surface.""" - warnings.warn( - "'get_vector_field_data' is deprecated, use 'get_field_data' instead", - PyFluentDeprecationWarning, - ) return self._get_vector_field_data( field_name=field_name, surfaces=surfaces, ) + @deprecate_function(version="v0.34.0", new_func="get_field_data") def get_pathlines_field_data( self, field_name: str, @@ -1708,10 +1681,6 @@ def get_pathlines_field_data( zones: list | None = None, ) -> Dict: """Get the pathlines field data on a surface.""" - warnings.warn( - "'get_pathlines_field_data' is deprecated, use 'get_field_data' instead", - PyFluentDeprecationWarning, - ) self._deprecated_flag = True return self._get_pathlines_field_data( field_name=field_name, diff --git a/src/ansys/fluent/core/services/solution_variables.py b/src/ansys/fluent/core/services/solution_variables.py index 7d1febdd00a..84456f446c2 100644 --- a/src/ansys/fluent/core/services/solution_variables.py +++ b/src/ansys/fluent/core/services/solution_variables.py @@ -42,7 +42,7 @@ TracingInterceptor, ) from ansys.fluent.core.solver.error_message import allowed_name_error_message -from ansys.fluent.core.utils.deprecate import all_deprecators +from ansys.fluent.core.utils.deprecate_new import deprecate_arguments from ansys.fluent.core.variable_strategies import ( FluentSVarNamingStrategy as naming_strategy, ) @@ -344,18 +344,10 @@ def __call__( zone_names=zone_names, domain_name=domain_name ).solution_variables - # pylint: disable=unused-argument - @all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "solution_variable_name", - "new_arg": "variable_name", - }, - ], - data_type_converter=None, - deprecated_version="v0.35.1", - deprecated_reason="'solution_variable_name' is deprecated. Use 'variable_name' instead.", - warn_message="", + @deprecate_arguments( + old_args="solution_variable_name", + new_args="variable_name", + version="v0.35.1", ) def is_valid( self, @@ -366,18 +358,10 @@ def is_valid( """Check whether solution variable name is valid or not.""" return variable_name in self(zone_names=zone_names, domain_name=domain_name) - # pylint: disable=unused-argument - @all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "solution_variable_name", - "new_arg": "variable_name", - }, - ], - data_type_converter=None, - deprecated_version="v0.35.1", - deprecated_reason="'solution_variable_name' is deprecated. Use 'variable_name' instead.", - warn_message="", + @deprecate_arguments( + old_args="solution_variable_name", + new_args="variable_name", + version="v0.35.1", ) def valid_name( self, @@ -608,18 +592,10 @@ def _update_solution_variable_info(self): self._solution_variable_info ) - # pylint: disable=unused-argument - @all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "solution_variable_name", - "new_arg": "variable_name", - }, - ], - data_type_converter=None, - deprecated_version="v0.35.1", - deprecated_reason="'solution_variable_name' is deprecated. Use 'variable_name' instead.", - warn_message="", + @deprecate_arguments( + old_args="solution_variable_name", + new_args="variable_name", + version="v0.35.1", ) def create_empty_array( self, @@ -645,18 +621,10 @@ def create_empty_array( dtype=solution_variables_info[variable_name].field_type, ) - # pylint: disable=unused-argument - @all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "solution_variable_name", - "new_arg": "variable_name", - }, - ], - data_type_converter=None, - deprecated_version="v0.35.1", - deprecated_reason="'solution_variable_name' is deprecated. Use 'variable_name' instead.", - warn_message="", + @deprecate_arguments( + old_args="solution_variable_name", + new_args="variable_name", + version="v0.35.1", ) def get_data( self, @@ -703,18 +671,10 @@ def get_data( extract_svars(self._service.get_data(svars_request)), ) - # pylint: disable=unused-argument - @all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "solution_variable_name", - "new_arg": "variable_name", - }, - ], - data_type_converter=None, - deprecated_version="v0.35.1", - deprecated_reason="'solution_variable_name' is deprecated. Use 'variable_name' instead.", - warn_message="", + @deprecate_arguments( + old_args="solution_variable_name", + new_args="variable_name", + version="v0.35.1", ) def get_svar_data( self, @@ -733,18 +693,10 @@ def get_svar_data( domain_name=domain_name, ) - # pylint: disable=unused-argument - @all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "solution_variable_name", - "new_arg": "variable_name", - }, - ], - data_type_converter=None, - deprecated_version="v0.35.1", - deprecated_reason="'solution_variable_name' is deprecated. Use 'variable_name' instead.", - warn_message="", + @deprecate_arguments( + old_args="solution_variable_name", + new_args="variable_name", + version="v0.35.1", ) def set_data( self, @@ -846,18 +798,10 @@ def generate_set_data_requests(): self._service.set_data(generate_set_data_requests()) - # pylint: disable=unused-argument - @all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "solution_variable_name", - "new_arg": "variable_name", - }, - ], - data_type_converter=None, - deprecated_version="v0.35.1", - deprecated_reason="'solution_variable_name' is deprecated. Use 'variable_name' instead.", - warn_message="", + @deprecate_arguments( + old_args="solution_variable_name", + new_args="variable_name", + version="v0.35.1", ) def set_svar_data( self, diff --git a/src/ansys/fluent/core/utils/deprecate_new.py b/src/ansys/fluent/core/utils/deprecate_new.py index 3e5dff98303..96af40b618c 100644 --- a/src/ansys/fluent/core/utils/deprecate_new.py +++ b/src/ansys/fluent/core/utils/deprecate_new.py @@ -37,6 +37,11 @@ def deprecate_arguments( ------ ValueError For arguments mismatch. + + Returns + ------- + Callable + The decorated function. """ if isinstance(old_args, str): old_args = [old_args] @@ -108,3 +113,48 @@ def wrapper(*args, **kwargs): return wrapper return decorator + + +def deprecate_function( + version: str, + new_func: str | None = None, + warning_cls: type[Warning] = PyFluentDeprecationWarning, +) -> Callable: + """ + Decorator to mark a function as deprecated. + + Parameters + ---------- + version : str + Version in which this function was deprecated. + new_func : str, optional + Name of the new/replacement function to use. + warning_cls : type[Warning], optional + Warning class to use for the deprecation warning. + + Returns + ------- + Callable + The decorated function. + """ + + def decorator(func): + func_name = func.__name__ + + # Build reason message for @deprecated + if new_func: + reason = f"Function '{func_name}' is deprecated since version {version}. Use '{new_func}' instead." + else: + reason = f"Function '{func_name}' is deprecated since version {version}." + + # Documentation + decorated = deprecated(version=version, reason=reason)(func) + + @functools.wraps(decorated) + def wrapper(*args, **kwargs): + warnings.warn(reason, warning_cls, stacklevel=2) + return decorated(*args, **kwargs) + + return wrapper + + return decorator diff --git a/src/ansys/fluent/core/utils/file_transfer_service.py b/src/ansys/fluent/core/utils/file_transfer_service.py index e7873825219..22d54738a6e 100644 --- a/src/ansys/fluent/core/utils/file_transfer_service.py +++ b/src/ansys/fluent/core/utils/file_transfer_service.py @@ -31,7 +31,7 @@ from ansys.fluent.core.pyfluent_warnings import PyFluentUserWarning from ansys.fluent.core.utils import get_user_data_dir -from ansys.fluent.core.utils.deprecate import all_deprecators +from ansys.fluent.core.utils.deprecate_new import deprecate_arguments import ansys.platform.instancemanagement as pypim # Host path which is mounted to the file-transfer-service container @@ -229,23 +229,15 @@ class ContainerFileTransferStrategy(FileTransferStrategy): >>> solver_session.download(file_name="write_elbow.cas.h5", local_directory="") """ - @all_deprecators( - deprecate_arg_mappings=[ - { - "old_arg": "container_mount_path", - "new_arg": "mount_target", - "converter": lambda old_arg_val: old_arg_val, - }, - { - "old_arg": "host_mount_path", - "new_arg": "mount_source", - "converter": lambda old_arg_val: old_arg_val, - }, - ], - data_type_converter=None, - deprecated_version="v0.23.dev1", - deprecated_reason="'container_mount_path' and 'host_mount_path' are deprecated. Use 'mount_target' and 'mount_source' instead.", - warn_message="", + @deprecate_arguments( + old_args="container_mount_path", + new_args="mount_target", + version="v0.23.0", + ) + @deprecate_arguments( + old_args="host_mount_path", + new_args="mount_source", + version="v0.23.0", ) def __init__( self, From 1775fe38b194b54cada5beba75707caaa0fa98d5 Mon Sep 17 00:00:00 2001 From: Prithwish Mukherjee Date: Wed, 15 Oct 2025 11:25:24 +0530 Subject: [PATCH 10/15] Renaming --- src/ansys/fluent/core/file_session.py | 2 +- .../fluent/core/launcher/fluent_container.py | 2 +- src/ansys/fluent/core/launcher/launcher.py | 2 +- .../core/services/deprecated_field_data.py | 2 +- src/ansys/fluent/core/services/field_data.py | 2 +- .../core/services/solution_variables.py | 2 +- src/ansys/fluent/core/utils/deprecate.py | 250 +++++++++--------- src/ansys/fluent/core/utils/deprecate_new.py | 160 ----------- .../core/utils/file_transfer_service.py | 2 +- 9 files changed, 135 insertions(+), 289 deletions(-) delete mode 100644 src/ansys/fluent/core/utils/deprecate_new.py diff --git a/src/ansys/fluent/core/file_session.py b/src/ansys/fluent/core/file_session.py index 0352e70c94c..2fff44339d4 100644 --- a/src/ansys/fluent/core/file_session.py +++ b/src/ansys/fluent/core/file_session.py @@ -54,7 +54,7 @@ _to_scalar_field_name, _to_vector_field_name, ) -from ansys.fluent.core.utils.deprecate_new import ( +from ansys.fluent.core.utils.deprecate import ( deprecate_arguments, deprecate_function, ) diff --git a/src/ansys/fluent/core/launcher/fluent_container.py b/src/ansys/fluent/core/launcher/fluent_container.py index d0a0efa1860..5a8ab0b75c3 100644 --- a/src/ansys/fluent/core/launcher/fluent_container.py +++ b/src/ansys/fluent/core/launcher/fluent_container.py @@ -88,7 +88,7 @@ from ansys.fluent.core.launcher.launcher_utils import ComposeConfig from ansys.fluent.core.pyfluent_warnings import PyFluentDeprecationWarning from ansys.fluent.core.session import _parse_server_info_file -from ansys.fluent.core.utils.deprecate_new import deprecate_arguments +from ansys.fluent.core.utils.deprecate import deprecate_arguments from ansys.fluent.core.utils.execution import timeout_loop from ansys.fluent.core.utils.networking import get_free_port diff --git a/src/ansys/fluent/core/launcher/launcher.py b/src/ansys/fluent/core/launcher/launcher.py index fea4754fa95..335c7c0ea82 100644 --- a/src/ansys/fluent/core/launcher/launcher.py +++ b/src/ansys/fluent/core/launcher/launcher.py @@ -58,7 +58,7 @@ from ansys.fluent.core.session_pure_meshing import PureMeshing from ansys.fluent.core.session_solver import Solver from ansys.fluent.core.session_solver_icing import SolverIcing -from ansys.fluent.core.utils.deprecate_new import deprecate_arguments +from ansys.fluent.core.utils.deprecate import deprecate_arguments from ansys.fluent.core.utils.fluent_version import FluentVersion _THIS_DIR = os.path.dirname(__file__) diff --git a/src/ansys/fluent/core/services/deprecated_field_data.py b/src/ansys/fluent/core/services/deprecated_field_data.py index bef3056a899..c2bda66e9f5 100644 --- a/src/ansys/fluent/core/services/deprecated_field_data.py +++ b/src/ansys/fluent/core/services/deprecated_field_data.py @@ -42,7 +42,7 @@ get_fields_request, override_help_text, ) -from ansys.fluent.core.utils.deprecate_new import deprecate_arguments +from ansys.fluent.core.utils.deprecate import deprecate_arguments DEPRECATION_MSG = "'field_data_old' is deprecated. Use 'field_data' instead." diff --git a/src/ansys/fluent/core/services/field_data.py b/src/ansys/fluent/core/services/field_data.py index 92428b0ee66..ca760bddf9e 100644 --- a/src/ansys/fluent/core/services/field_data.py +++ b/src/ansys/fluent/core/services/field_data.py @@ -67,7 +67,7 @@ TracingInterceptor, ) from ansys.fluent.core.services.streaming import StreamingService -from ansys.fluent.core.utils.deprecate_new import ( +from ansys.fluent.core.utils.deprecate import ( deprecate_arguments, deprecate_function, ) diff --git a/src/ansys/fluent/core/services/solution_variables.py b/src/ansys/fluent/core/services/solution_variables.py index 84456f446c2..70a4fe3ebea 100644 --- a/src/ansys/fluent/core/services/solution_variables.py +++ b/src/ansys/fluent/core/services/solution_variables.py @@ -42,7 +42,7 @@ TracingInterceptor, ) from ansys.fluent.core.solver.error_message import allowed_name_error_message -from ansys.fluent.core.utils.deprecate_new import deprecate_arguments +from ansys.fluent.core.utils.deprecate import deprecate_arguments from ansys.fluent.core.variable_strategies import ( FluentSVarNamingStrategy as naming_strategy, ) diff --git a/src/ansys/fluent/core/utils/deprecate.py b/src/ansys/fluent/core/utils/deprecate.py index 60f21e1e272..96af40b618c 100644 --- a/src/ansys/fluent/core/utils/deprecate.py +++ b/src/ansys/fluent/core/utils/deprecate.py @@ -1,153 +1,159 @@ -# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. -# SPDX-License-Identifier: MIT -# -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -"""Module that provides a method to handle deprecated arguments.""" +"""Deprecate Arguments.""" import functools -from functools import wraps -import logging +from typing import Any, Callable import warnings from deprecated.sphinx import deprecated from ansys.fluent.core.pyfluent_warnings import PyFluentDeprecationWarning -logger = logging.getLogger("pyfluent.general") +def deprecate_arguments( + old_args: str | list[str], + new_args: str | list[str], + version: str, + converter: Callable | None = None, + warning_cls: type[Warning] = PyFluentDeprecationWarning, +) -> Callable: + """ + Deprecate multiple arguments (possibly grouped) and automatically replace them with new ones. + + Parameters + ---------- + old_args : str | list[str] + Old argument name(s) to deprecate. + new_args : str | list[str] + New argument name(s) to use instead. + version : str + The version in which the arguments were deprecated. + converter : callable, optional + Custom converter function taking (kwargs, old_args, new_args) and returning modified kwargs. + If not provided, a default converter is used. + warning_cls : warnings, optional + The warning class to use for deprecation warnings. + + Raises + ------ + ValueError + For arguments mismatch. + + Returns + ------- + Callable + The decorated function. + """ + if isinstance(old_args, str): + old_args = [old_args] + + if isinstance(new_args, str): + new_args = [new_args] + + # Validation + if len(old_args) != len(new_args) and converter is None: + raise ValueError( + f"Cannot automatically convert {old_args} → {new_args}: too many old args. " + f"Provide a custom converter." + ) + + # Default converter + def _default_converter( + kwargs: dict[str, Any], + old_params: list[str], + new_params: list[str], + ) -> dict[str, Any]: + """Default converter that maps all old args to new args one-to-one.""" + for i, old_arg in enumerate(old_params): + if old_arg in kwargs: + old_val = kwargs.pop(old_arg) + target_arg = new_params[i] + if target_arg in kwargs: + warnings.warn( + f"Both deprecated argument '{old_arg}' and new argument '{target_arg}' were provided. " + f"Ignoring {old_arg}.", + PyFluentDeprecationWarning, + stacklevel=2, + ) + else: + kwargs[target_arg] = old_val + return kwargs -# TODO: Refactor 'all_deprecators' to remove boilerplate code from implementation -def all_deprecators( - deprecate_arg_mappings, - data_type_converter, - deprecated_version, - deprecated_reason, - warn_message, -): - """Decorator that applies multiple deprecators to a function.""" - - def decorator(func): - decorated = func - for mapping in deprecate_arg_mappings: - decorated = deprecate_argument( - old_arg=mapping["old_arg"], - new_arg=mapping["new_arg"], - converter=mapping.get("converter", lambda x: x), - warning_cls=PyFluentDeprecationWarning, - )(decorated) - if data_type_converter: - decorated = deprecate_arguments( - converter=data_type_converter, - warning_cls=PyFluentDeprecationWarning, - )(decorated) - decorated = deprecated( - version=deprecated_version, - reason=deprecated_reason, - )(decorated) - - @wraps(decorated) - def wrapper(*args, **kwargs): - if warn_message: - warnings.warn( - warn_message, - PyFluentDeprecationWarning, - stacklevel=2, - ) - return decorated(*args, **kwargs) - - return wrapper - - return decorator - + converter = converter or _default_converter -def deprecate_argument( - old_arg, - new_arg, - converter=lambda x: x, - warning_cls=PyFluentDeprecationWarning, - **kwds, -): - """Warns that the argument provided is deprecated and automatically replaces the - deprecated argument with the appropriate new argument.""" + # Build reason message for @deprecated + old_str = ", ".join(f"'{o}'" for o in old_args) + new_str = ", ".join(f"'{n}'" for n in new_args) + if len(old_args) > 1: + reason = f"Arguments {old_str} are deprecated; use {new_str} instead." + else: + reason = f"Argument {old_str} is deprecated; use {new_str} instead." - def decorator(func): - """Holds the original method to perform operations on it.""" + def decorator(func: Callable): + # Documentation + deprecated_func = deprecated(version=version, reason=reason)(func) - @functools.wraps(func) + @functools.wraps(deprecated_func) def wrapper(*args, **kwargs): - """Warns about the deprecated argument and replaces it with the new - argument.""" - if old_arg in kwargs: + # Warn only if any old arg(s) present + if any(arg in kwargs for arg in old_args): warnings.warn( - f"'{old_arg}' is deprecated. Use '{new_arg}' instead.", + reason, warning_cls, stacklevel=2, ) - old_value = kwargs[old_arg] - new_value = kwargs.get(new_arg) - if new_value is None: - new_value = converter(kwargs[old_arg], **kwds) - kwargs[new_arg] = new_value - logger.warning( - f"Using '{new_arg} = {new_value}' for '{func.__name__}()'" - f" instead of '{old_arg} = {old_value}'." - ) - else: - logger.warning( - f"Ignoring '{old_arg} = {old_value}' specification for '{func.__name__}()'," - f" only '{new_arg} = {new_value}' applies." - ) - kwargs.pop(old_arg) - return func(*args, **kwargs) + + # Perform conversion (default or custom) + try: + kwargs = converter(kwargs, old_args, new_args) + except TypeError: + # If the custom converter takes only kwargs + kwargs = converter(kwargs) + return deprecated_func(*args, **kwargs) return wrapper return decorator -def deprecate_arguments( - converter, - warning_cls=PyFluentDeprecationWarning, -): - """Warns that the arguments provided are deprecated and automatically replaces the - deprecated arguments with the appropriate new arguments.""" +def deprecate_function( + version: str, + new_func: str | None = None, + warning_cls: type[Warning] = PyFluentDeprecationWarning, +) -> Callable: + """ + Decorator to mark a function as deprecated. + + Parameters + ---------- + version : str + Version in which this function was deprecated. + new_func : str, optional + Name of the new/replacement function to use. + warning_cls : type[Warning], optional + Warning class to use for the deprecation warning. + + Returns + ------- + Callable + The decorated function. + """ def decorator(func): - """Holds the original method to perform operations on it.""" + func_name = func.__name__ - @functools.wraps(func) + # Build reason message for @deprecated + if new_func: + reason = f"Function '{func_name}' is deprecated since version {version}. Use '{new_func}' instead." + else: + reason = f"Function '{func_name}' is deprecated since version {version}." + + # Documentation + decorated = deprecated(version=version, reason=reason)(func) + + @functools.wraps(decorated) def wrapper(*args, **kwargs): - """Warns about the deprecated arguments and replaces them with the new - arguments.""" - input_kwargs = kwargs.copy() - kwargs = converter(kwargs) - new_args = set(kwargs) - set(input_kwargs) - old_args = set(input_kwargs) - set(kwargs) - if old_args and new_args: - warnings.warn( - f"The arguments: {', '.join(old_args)} are deprecated. Use {', '.join(new_args)} instead.", - warning_cls, - stacklevel=2, - ) - return func(*args, **kwargs) + warnings.warn(reason, warning_cls, stacklevel=2) + return decorated(*args, **kwargs) return wrapper diff --git a/src/ansys/fluent/core/utils/deprecate_new.py b/src/ansys/fluent/core/utils/deprecate_new.py deleted file mode 100644 index 96af40b618c..00000000000 --- a/src/ansys/fluent/core/utils/deprecate_new.py +++ /dev/null @@ -1,160 +0,0 @@ -"""Deprecate Arguments.""" - -import functools -from typing import Any, Callable -import warnings - -from deprecated.sphinx import deprecated - -from ansys.fluent.core.pyfluent_warnings import PyFluentDeprecationWarning - - -def deprecate_arguments( - old_args: str | list[str], - new_args: str | list[str], - version: str, - converter: Callable | None = None, - warning_cls: type[Warning] = PyFluentDeprecationWarning, -) -> Callable: - """ - Deprecate multiple arguments (possibly grouped) and automatically replace them with new ones. - - Parameters - ---------- - old_args : str | list[str] - Old argument name(s) to deprecate. - new_args : str | list[str] - New argument name(s) to use instead. - version : str - The version in which the arguments were deprecated. - converter : callable, optional - Custom converter function taking (kwargs, old_args, new_args) and returning modified kwargs. - If not provided, a default converter is used. - warning_cls : warnings, optional - The warning class to use for deprecation warnings. - - Raises - ------ - ValueError - For arguments mismatch. - - Returns - ------- - Callable - The decorated function. - """ - if isinstance(old_args, str): - old_args = [old_args] - - if isinstance(new_args, str): - new_args = [new_args] - - # Validation - if len(old_args) != len(new_args) and converter is None: - raise ValueError( - f"Cannot automatically convert {old_args} → {new_args}: too many old args. " - f"Provide a custom converter." - ) - - # Default converter - def _default_converter( - kwargs: dict[str, Any], - old_params: list[str], - new_params: list[str], - ) -> dict[str, Any]: - """Default converter that maps all old args to new args one-to-one.""" - for i, old_arg in enumerate(old_params): - if old_arg in kwargs: - old_val = kwargs.pop(old_arg) - target_arg = new_params[i] - if target_arg in kwargs: - warnings.warn( - f"Both deprecated argument '{old_arg}' and new argument '{target_arg}' were provided. " - f"Ignoring {old_arg}.", - PyFluentDeprecationWarning, - stacklevel=2, - ) - else: - kwargs[target_arg] = old_val - return kwargs - - converter = converter or _default_converter - - # Build reason message for @deprecated - old_str = ", ".join(f"'{o}'" for o in old_args) - new_str = ", ".join(f"'{n}'" for n in new_args) - if len(old_args) > 1: - reason = f"Arguments {old_str} are deprecated; use {new_str} instead." - else: - reason = f"Argument {old_str} is deprecated; use {new_str} instead." - - def decorator(func: Callable): - # Documentation - deprecated_func = deprecated(version=version, reason=reason)(func) - - @functools.wraps(deprecated_func) - def wrapper(*args, **kwargs): - # Warn only if any old arg(s) present - if any(arg in kwargs for arg in old_args): - warnings.warn( - reason, - warning_cls, - stacklevel=2, - ) - - # Perform conversion (default or custom) - try: - kwargs = converter(kwargs, old_args, new_args) - except TypeError: - # If the custom converter takes only kwargs - kwargs = converter(kwargs) - return deprecated_func(*args, **kwargs) - - return wrapper - - return decorator - - -def deprecate_function( - version: str, - new_func: str | None = None, - warning_cls: type[Warning] = PyFluentDeprecationWarning, -) -> Callable: - """ - Decorator to mark a function as deprecated. - - Parameters - ---------- - version : str - Version in which this function was deprecated. - new_func : str, optional - Name of the new/replacement function to use. - warning_cls : type[Warning], optional - Warning class to use for the deprecation warning. - - Returns - ------- - Callable - The decorated function. - """ - - def decorator(func): - func_name = func.__name__ - - # Build reason message for @deprecated - if new_func: - reason = f"Function '{func_name}' is deprecated since version {version}. Use '{new_func}' instead." - else: - reason = f"Function '{func_name}' is deprecated since version {version}." - - # Documentation - decorated = deprecated(version=version, reason=reason)(func) - - @functools.wraps(decorated) - def wrapper(*args, **kwargs): - warnings.warn(reason, warning_cls, stacklevel=2) - return decorated(*args, **kwargs) - - return wrapper - - return decorator diff --git a/src/ansys/fluent/core/utils/file_transfer_service.py b/src/ansys/fluent/core/utils/file_transfer_service.py index 22d54738a6e..53f32057236 100644 --- a/src/ansys/fluent/core/utils/file_transfer_service.py +++ b/src/ansys/fluent/core/utils/file_transfer_service.py @@ -31,7 +31,7 @@ from ansys.fluent.core.pyfluent_warnings import PyFluentUserWarning from ansys.fluent.core.utils import get_user_data_dir -from ansys.fluent.core.utils.deprecate_new import deprecate_arguments +from ansys.fluent.core.utils.deprecate import deprecate_arguments import ansys.platform.instancemanagement as pypim # Host path which is mounted to the file-transfer-service container From 5de5ed976c7c15ac51dac607a3748e8d604f699f Mon Sep 17 00:00:00 2001 From: Prithwish Mukherjee Date: Wed, 15 Oct 2025 11:37:49 +0530 Subject: [PATCH 11/15] Graceful handling of TypeError. --- src/ansys/fluent/core/utils/deprecate.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/ansys/fluent/core/utils/deprecate.py b/src/ansys/fluent/core/utils/deprecate.py index 96af40b618c..7ee469ac419 100644 --- a/src/ansys/fluent/core/utils/deprecate.py +++ b/src/ansys/fluent/core/utils/deprecate.py @@ -1,6 +1,7 @@ """Deprecate Arguments.""" import functools +import inspect from typing import Any, Callable import warnings @@ -102,12 +103,18 @@ def wrapper(*args, **kwargs): stacklevel=2, ) - # Perform conversion (default or custom) - try: - kwargs = converter(kwargs, old_args, new_args) - except TypeError: - # If the custom converter takes only kwargs + sig = inspect.signature(converter) + params = sig.parameters + n_params = len(params) + if n_params == 1: kwargs = converter(kwargs) + elif n_params == 3: + kwargs = converter(kwargs, old_args, new_args) + else: + raise TypeError( + f"Converter must accept either (kwargs) or (kwargs, old_args, new_args), " + f"but got {n_params} parameter(s): {list(params)}" + ) return deprecated_func(*args, **kwargs) return wrapper From b89b2e91160bd44922fa303c79be8c638eb83426 Mon Sep 17 00:00:00 2001 From: Prithwish Mukherjee Date: Thu, 16 Oct 2025 12:33:23 +0530 Subject: [PATCH 12/15] Added tests and minor updates. --- src/ansys/fluent/core/file_session.py | 4 +- src/ansys/fluent/core/services/field_data.py | 4 +- src/ansys/fluent/core/utils/deprecate.py | 10 +- tests/test_deprecate.py | 157 +++++++++++++++++++ 4 files changed, 163 insertions(+), 12 deletions(-) create mode 100644 tests/test_deprecate.py diff --git a/src/ansys/fluent/core/file_session.py b/src/ansys/fluent/core/file_session.py index 2fff44339d4..107e8c07e2e 100644 --- a/src/ansys/fluent/core/file_session.py +++ b/src/ansys/fluent/core/file_session.py @@ -76,7 +76,7 @@ def __init__(self): super().__init__("The only allowed field is 'velocity'.") -def _data_type_convertor(args_dict): +def _data_type_converter(args_dict): d_type_list = [] d_type_map = { "provide_vertices": SurfaceDataType.Vertices, @@ -270,7 +270,7 @@ def get_surface_ids(self, surfaces: List[str | int]) -> List[int]: old_args=["provide_vertices", "provide_faces"], new_args="data_types", version="v0.25.0", - converter=_data_type_convertor, + converter=_data_type_converter, ) @deprecate_function(version="v0.25.0", new_func="add_requests") def add_surfaces_request( diff --git a/src/ansys/fluent/core/services/field_data.py b/src/ansys/fluent/core/services/field_data.py index ca760bddf9e..ef9d5f0a278 100644 --- a/src/ansys/fluent/core/services/field_data.py +++ b/src/ansys/fluent/core/services/field_data.py @@ -398,7 +398,7 @@ def __call__(self, *args, **kwargs): return self._field_data_accessor(*args, **kwargs) -def _data_type_convertor(args_dict): +def _data_type_converter(args_dict): d_type_list = [] d_type_map = { "provide_vertices": SurfaceDataType.Vertices, @@ -804,7 +804,7 @@ def _add_pathlines_fields_request( ], new_args="data_types", version="v0.23.0", - converter=_data_type_convertor, + converter=_data_type_converter, ) @deprecate_function(version="v0.23.0", new_func="add_requests") def add_surfaces_request( diff --git a/src/ansys/fluent/core/utils/deprecate.py b/src/ansys/fluent/core/utils/deprecate.py index 7ee469ac419..da477e48110 100644 --- a/src/ansys/fluent/core/utils/deprecate.py +++ b/src/ansys/fluent/core/utils/deprecate.py @@ -50,24 +50,22 @@ def deprecate_arguments( if isinstance(new_args, str): new_args = [new_args] - # Validation if len(old_args) != len(new_args) and converter is None: raise ValueError( f"Cannot automatically convert {old_args} → {new_args}: too many old args. " f"Provide a custom converter." ) - # Default converter def _default_converter( kwargs: dict[str, Any], old_params: list[str], new_params: list[str], ) -> dict[str, Any]: """Default converter that maps all old args to new args one-to-one.""" - for i, old_arg in enumerate(old_params): + for old_arg, new_arg in zip(old_params, new_params): if old_arg in kwargs: old_val = kwargs.pop(old_arg) - target_arg = new_params[i] + target_arg = new_arg if target_arg in kwargs: warnings.warn( f"Both deprecated argument '{old_arg}' and new argument '{target_arg}' were provided. " @@ -81,7 +79,6 @@ def _default_converter( converter = converter or _default_converter - # Build reason message for @deprecated old_str = ", ".join(f"'{o}'" for o in old_args) new_str = ", ".join(f"'{n}'" for n in new_args) if len(old_args) > 1: @@ -90,7 +87,6 @@ def _default_converter( reason = f"Argument {old_str} is deprecated; use {new_str} instead." def decorator(func: Callable): - # Documentation deprecated_func = deprecated(version=version, reason=reason)(func) @functools.wraps(deprecated_func) @@ -148,13 +144,11 @@ def deprecate_function( def decorator(func): func_name = func.__name__ - # Build reason message for @deprecated if new_func: reason = f"Function '{func_name}' is deprecated since version {version}. Use '{new_func}' instead." else: reason = f"Function '{func_name}' is deprecated since version {version}." - # Documentation decorated = deprecated(version=version, reason=reason)(func) @functools.wraps(decorated) diff --git a/tests/test_deprecate.py b/tests/test_deprecate.py new file mode 100644 index 00000000000..8137853fa5b --- /dev/null +++ b/tests/test_deprecate.py @@ -0,0 +1,157 @@ +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import warnings + +import pytest + +from ansys.fluent.core import PyFluentDeprecationWarning +from ansys.fluent.core.utils.deprecate import deprecate_arguments, deprecate_function + + +def test_deprecate_argument_warns(): + """Test that deprecated arguments triggers a warning and maps correctly.""" + + @deprecate_arguments(old_args=["a", "b"], new_args=["d", "e"], version="3.0.0") + @deprecate_arguments(old_args="c", new_args="f", version="3.0.0") + @deprecate_arguments(old_args="x1", new_args="z1", version="3.0.0") + def example_func(**kwargs): + assert "d" in kwargs + assert "f" in kwargs + assert "z1" in kwargs + assert "a" not in kwargs + assert "c" not in kwargs + assert "x1" not in kwargs + return kwargs + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") # ensure deprecation warnings are captured + result = example_func(a=1, b=2, c=3, x1=2, x2=4) + + # Check that the warnings were raised + assert len(w) == 6 + warning = w[0] + assert issubclass(warning.category, PyFluentDeprecationWarning) + assert "'a', 'b'" in str(warning.message) + assert "'d', 'e'" in str(warning.message) + + # Check that function received the new argument + assert result == {"d": 1, "e": 2, "f": 3, "x2": 4, "z1": 2} + + +def test_deprecate_argument_warns_with_custom_converter(): + """Test that deprecated arguments triggers a warning and maps correctly.""" + + def my_custom_converter(kwargs, old_args, new_args): + # Combine values of a, b into a tuple → d + values = tuple(kwargs.pop(arg) for arg in old_args if arg in kwargs) + if values: + kwargs[new_args[0]] = values + return kwargs + + @deprecate_arguments( + old_args=["a", "b"], + new_args="d", + version="3.0.0", + converter=my_custom_converter, + ) + @deprecate_arguments( + old_args="c", + new_args="e", + version="3.0.0", + ) + def example_func(**kwargs): + assert "d" in kwargs + assert "e" in kwargs + assert "c" not in kwargs + assert "a" not in kwargs + return kwargs + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") # ensure deprecation warnings are captured + result = example_func(a=1, b=2, c=3) + + # Check that the warnings were raised + assert len(w) == 4 + warning = w[0] + assert issubclass(warning.category, PyFluentDeprecationWarning) + assert "'a', 'b'" in str(warning.message) + assert "'d'" in str(warning.message) + + assert result == {"d": (1, 2), "e": 3} + + +def test_deprecate_argument_raises_value_error_without_converter(): + """Test that deprecated arguments raises ValueError for incorrect mapping.""" + + with pytest.raises(ValueError): + + @deprecate_arguments( + old_args=["a", "b"], + new_args="d", + version="3.0.0", + ) + def example_func_1(**kwargs): + assert "d" in kwargs + assert "e" in kwargs + assert "c" not in kwargs + assert "a" not in kwargs + return kwargs + + with pytest.raises(ValueError): + + @deprecate_arguments( + old_args="a", + new_args=["d", "e"], + version="3.0.0", + ) + def example_func_2(**kwargs): + assert "d" in kwargs + assert "e" in kwargs + assert "c" not in kwargs + assert "a" not in kwargs + return kwargs + + +def test_deprecate_function(): + """Test that deprecated function display warning.""" + + @deprecate_function(version="3.0.0", new_func="new_add") + def old_add(a, b): + return a + b + + def new_add(a, b): + return a + b + 10 + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") # ensure deprecation warnings are captured + result = old_add(1, 2) + + # Check that the warnings were raised + assert len(w) == 2 + warning = w[0] + assert issubclass(warning.category, PyFluentDeprecationWarning) + assert "'old_add'" in str(warning.message) + assert "'new_add'" in str(warning.message) + assert "3.0.0" in str(warning.message) + + assert result == 3 From e04909221193722a06e25ab5fe721caf4d263a2a Mon Sep 17 00:00:00 2001 From: Prithwish Mukherjee Date: Thu, 16 Oct 2025 13:27:47 +0530 Subject: [PATCH 13/15] Update logic. --- src/ansys/fluent/core/utils/deprecate.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/ansys/fluent/core/utils/deprecate.py b/src/ansys/fluent/core/utils/deprecate.py index da477e48110..f5622a37078 100644 --- a/src/ansys/fluent/core/utils/deprecate.py +++ b/src/ansys/fluent/core/utils/deprecate.py @@ -99,18 +99,18 @@ def wrapper(*args, **kwargs): stacklevel=2, ) - sig = inspect.signature(converter) - params = sig.parameters - n_params = len(params) - if n_params == 1: - kwargs = converter(kwargs) - elif n_params == 3: - kwargs = converter(kwargs, old_args, new_args) - else: - raise TypeError( - f"Converter must accept either (kwargs) or (kwargs, old_args, new_args), " - f"but got {n_params} parameter(s): {list(params)}" - ) + sig = inspect.signature(converter) + params = sig.parameters + n_params = len(params) + if n_params == 1: + kwargs = converter(kwargs) + elif n_params == 3: + kwargs = converter(kwargs, old_args, new_args) + else: + raise TypeError( + f"Converter must accept either (kwargs) or (kwargs, old_args, new_args), " + f"but got {n_params} parameter(s): {list(params)}" + ) return deprecated_func(*args, **kwargs) return wrapper From 7d508c352917496f93295e0ba81804a7d252f2f9 Mon Sep 17 00:00:00 2001 From: Prithwish Mukherjee Date: Thu, 16 Oct 2025 21:26:10 +0530 Subject: [PATCH 14/15] Fix file session test. --- tests/test_file_session.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_file_session.py b/tests/test_file_session.py index 40d5c5c84f2..5425588d89a 100644 --- a/tests/test_file_session.py +++ b/tests/test_file_session.py @@ -572,7 +572,7 @@ def test_batch_request_single_phase_deprecated(): batch_1 = field_data.new_batch() - batch_1.add_surfaces_request(surfaces=[3, 5]) + batch_1.add_surfaces_request(provide_vertices=True, surfaces=[3, 5]) batch_1.add_scalar_fields_request("SV_T", surfaces=[3, 5]) batch_1.add_scalar_fields_request("SV_T", surfaces=["wall", "symmetry"]) From 82ea05e353831d2242083f27efccb5b12f7c6505 Mon Sep 17 00:00:00 2001 From: Prithwish Mukherjee Date: Thu, 16 Oct 2025 21:50:09 +0530 Subject: [PATCH 15/15] Add licensing info. --- src/ansys/fluent/core/utils/deprecate.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/ansys/fluent/core/utils/deprecate.py b/src/ansys/fluent/core/utils/deprecate.py index f5622a37078..de64bf0da58 100644 --- a/src/ansys/fluent/core/utils/deprecate.py +++ b/src/ansys/fluent/core/utils/deprecate.py @@ -1,3 +1,25 @@ +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + """Deprecate Arguments.""" import functools