Skip to content

Commit 5017a59

Browse files
committed
Re add handle deprectaed kwarg method
1 parent 80b3a88 commit 5017a59

2 files changed

Lines changed: 77 additions & 0 deletions

File tree

flixopt/config.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
SUCCESS_LEVEL = 25
3030
logging.addLevelName(SUCCESS_LEVEL, 'SUCCESS')
3131

32+
# Deprecation removal version - update this when planning the next major version
33+
DEPRECATION_REMOVAL_VERSION = '6.0.0'
34+
3235

3336
class MultilineFormatter(logging.Formatter):
3437
"""Custom formatter that handles multi-line messages with box-style borders.

flixopt/structure.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import xarray as xr
2525

2626
from . import io as fx_io
27+
from .config import DEPRECATION_REMOVAL_VERSION
2728
from .core import FlowSystemDimensions, TimeSeriesData, get_dataarray_stats
2829

2930
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
513514
else:
514515
return self._serialize_to_basic_types(obj), extracted_arrays
515516

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+
516590
def _validate_kwargs(self, kwargs: dict, class_name: str = None) -> None:
517591
"""
518592
Validate that no unexpected keyword arguments are present in kwargs.

0 commit comments

Comments
 (0)