|
24 | 24 | import xarray as xr |
25 | 25 |
|
26 | 26 | from . import io as fx_io |
| 27 | +from .config import DEPRECATION_REMOVAL_VERSION |
27 | 28 | from .core import FlowSystemDimensions, TimeSeriesData, get_dataarray_stats |
28 | 29 |
|
29 | 30 | if TYPE_CHECKING: # for type checking and preventing circular imports |
@@ -513,6 +514,79 @@ def _extract_dataarrays_recursive(self, obj, context_name: str = '') -> tuple[An |
513 | 514 | else: |
514 | 515 | return self._serialize_to_basic_types(obj), extracted_arrays |
515 | 516 |
|
| 517 | + def _handle_deprecated_kwarg( |
| 518 | + self, |
| 519 | + kwargs: dict, |
| 520 | + old_name: str, |
| 521 | + new_name: str, |
| 522 | + current_value: Any = None, |
| 523 | + transform: callable = None, |
| 524 | + check_conflict: bool = True, |
| 525 | + additional_warning_message: str = '', |
| 526 | + ) -> Any: |
| 527 | + """ |
| 528 | + Handle a deprecated keyword argument by issuing a warning and returning the appropriate value. |
| 529 | +
|
| 530 | + This centralizes the deprecation pattern used across multiple classes (Source, Sink, InvestParameters, etc.). |
| 531 | +
|
| 532 | + Args: |
| 533 | + kwargs: Dictionary of keyword arguments to check and modify |
| 534 | + old_name: Name of the deprecated parameter |
| 535 | + new_name: Name of the replacement parameter |
| 536 | + current_value: Current value of the new parameter (if already set) |
| 537 | + transform: Optional callable to transform the old value before returning (e.g., lambda x: [x] to wrap in list) |
| 538 | + check_conflict: Whether to check if both old and new parameters are specified (default: True). |
| 539 | + Note: For parameters with non-None default values (e.g., bool parameters with default=False), |
| 540 | + set check_conflict=False since we cannot distinguish between an explicit value and the default. |
| 541 | + additional_warning_message: Add a custom message which gets appended with a line break to the default warning. |
| 542 | +
|
| 543 | + Returns: |
| 544 | + The value to use (either from old parameter or current_value) |
| 545 | +
|
| 546 | + Raises: |
| 547 | + ValueError: If both old and new parameters are specified and check_conflict is True |
| 548 | +
|
| 549 | + Example: |
| 550 | + # For parameters where None is the default (conflict checking works): |
| 551 | + value = self._handle_deprecated_kwarg(kwargs, 'old_param', 'new_param', current_value) |
| 552 | +
|
| 553 | + # For parameters with non-None defaults (disable conflict checking): |
| 554 | + mandatory = self._handle_deprecated_kwarg( |
| 555 | + kwargs, 'optional', 'mandatory', mandatory, |
| 556 | + transform=lambda x: not x, |
| 557 | + check_conflict=False # Cannot detect if mandatory was explicitly passed |
| 558 | + ) |
| 559 | + """ |
| 560 | + import warnings |
| 561 | + |
| 562 | + old_value = kwargs.pop(old_name, None) |
| 563 | + if old_value is not None: |
| 564 | + # Build base warning message |
| 565 | + base_warning = f'The use of the "{old_name}" argument is deprecated. Use the "{new_name}" argument instead. Will be removed in v{DEPRECATION_REMOVAL_VERSION}.' |
| 566 | + |
| 567 | + # Append additional message on a new line if provided |
| 568 | + if additional_warning_message: |
| 569 | + # Normalize whitespace: strip leading/trailing whitespace |
| 570 | + extra_msg = additional_warning_message.strip() |
| 571 | + if extra_msg: |
| 572 | + base_warning += '\n' + extra_msg |
| 573 | + |
| 574 | + warnings.warn( |
| 575 | + base_warning, |
| 576 | + DeprecationWarning, |
| 577 | + stacklevel=3, # Stack: this method -> __init__ -> caller |
| 578 | + ) |
| 579 | + # Check for conflicts: only raise error if both were explicitly provided |
| 580 | + if check_conflict and current_value is not None: |
| 581 | + raise ValueError(f'Either {old_name} or {new_name} can be specified, but not both.') |
| 582 | + |
| 583 | + # Apply transformation if provided |
| 584 | + if transform is not None: |
| 585 | + return transform(old_value) |
| 586 | + return old_value |
| 587 | + |
| 588 | + return current_value |
| 589 | + |
516 | 590 | def _validate_kwargs(self, kwargs: dict, class_name: str = None) -> None: |
517 | 591 | """ |
518 | 592 | Validate that no unexpected keyword arguments are present in kwargs. |
|
0 commit comments