From 05348f30a2df3280ae469b9cd7b32664d6488bae Mon Sep 17 00:00:00 2001 From: Ivan Ruiz Manuel <72193617+irm-codebase@users.noreply.github.com> Date: Sat, 17 Aug 2024 13:56:07 +0200 Subject: [PATCH] PR improvements: math components in CalliopeMath, small fixes --- src/calliope/backend/backend_model.py | 11 ++-------- src/calliope/backend/parsing.py | 5 +++-- src/calliope/preprocess/model_math.py | 31 +++++++++++++++------------ tests/test_preprocess_model_math.py | 13 +++++------ 4 files changed, 29 insertions(+), 31 deletions(-) diff --git a/src/calliope/backend/backend_model.py b/src/calliope/backend/backend_model.py index 098ea07e..8c53a22d 100644 --- a/src/calliope/backend/backend_model.py +++ b/src/calliope/backend/backend_model.py @@ -31,7 +31,7 @@ from calliope.backend import helper_functions, parsing from calliope.exceptions import warn as model_warn from calliope.io import load_config -from calliope.preprocess import CalliopeMath +from calliope.preprocess.model_math import ORDERED_COMPONENTS_T, CalliopeMath from calliope.util.schema import ( MODEL_SCHEMA, extract_from_schema, @@ -44,13 +44,6 @@ from calliope.exceptions import BackendError T = TypeVar("T") -ORDERED_COMPONENTS_T = Literal[ - "variables", - "global_expressions", - "constraints", - "piecewise_constraints", - "objectives", -] ALL_COMPONENTS_T = Literal["parameters", ORDERED_COMPONENTS_T] @@ -539,7 +532,7 @@ def _raise_error_on_preexistence(self, key: str, obj_type: ALL_COMPONENTS_T): Args: key (str): Backend object name - obj_type (Literal["variables", "constraints", "objectives", "parameters", "expressions"]): Object type. + obj_type (ALL_COMPONENTS_T): Object type. Raises: BackendError: if `key` already exists in the backend model diff --git a/src/calliope/backend/parsing.py b/src/calliope/backend/parsing.py index 00eb2c94..33c9ea47 100644 --- a/src/calliope/backend/parsing.py +++ b/src/calliope/backend/parsing.py @@ -850,12 +850,13 @@ def generate_top_level_where_array( return where def raise_caught_errors(self): - """If there are any parsing errors, pipe them to the ModelError bullet point list generator.""" + """Pipe parsing errors to the ModelError bullet point list generator.""" if not self._is_valid: exceptions.print_warnings_and_raise_errors( errors={f"{self.name}": self._errors}, during=( - "math string parsing (marker indicates where parsing stopped, but may not point to the root cause of the issue)" + "math string parsing (marker indicates where parsing stopped, " + "but may not point to the root cause of the issue)" ), bullet=self._ERR_BULLET, ) diff --git a/src/calliope/preprocess/model_math.py b/src/calliope/preprocess/model_math.py index 0498ad56..54ab6960 100644 --- a/src/calliope/preprocess/model_math.py +++ b/src/calliope/preprocess/model_math.py @@ -2,6 +2,7 @@ import importlib.resources import logging +import typing from copy import deepcopy from pathlib import Path @@ -11,6 +12,13 @@ from calliope.util.tools import relative_path LOGGER = logging.getLogger(__name__) +ORDERED_COMPONENTS_T = typing.Literal[ + "variables", + "global_expressions", + "constraints", + "piecewise_constraints", + "objectives", +] class CalliopeMath: @@ -33,13 +41,7 @@ def __init__( """ self.history: list[str] = [] self.data: AttrDict = AttrDict( - { - "variables": {}, - "global_expressions": {}, - "constraints": {}, - "piecewise_constraints": {}, - "objectives": {}, - } + {name: {} for name in typing.get_args(ORDERED_COMPONENTS_T)} ) for math in math_to_add: @@ -61,12 +63,13 @@ def __iter__(self): def __repr__(self) -> str: """Custom string representation of class.""" - return f"""Calliope math definition dictionary with: - {len(self.data["variables"])} decision variable(s) - {len(self.data["global_expressions"])} global expression(s) - {len(self.data["constraints"])} constraint(s) - {len(self.data["piecewise_constraints"])} piecewise constraint(s) - {len(self.data["objectives"])} objective(s) + return f""" + Calliope math definition dictionary with: + {len(self.data["variables"])} decision variable(s) + {len(self.data["global_expressions"])} global expression(s) + {len(self.data["constraints"])} constraint(s) + {len(self.data["piecewise_constraints"])} piecewise constraint(s) + {len(self.data["objectives"])} objective(s) """ def add(self, math: AttrDict): @@ -127,7 +130,7 @@ def _add_pre_defined_file(self, filename: str) -> None: self._add_file(f / f"{filename}.yaml", filename) def _add_user_defined_file( - self, relative_filepath: str | Path, model_def_path: str | Path + self, relative_filepath: str | Path, model_def_path: str | Path | None ) -> None: """Add user-defined Calliope math, relative to the model definition path. diff --git a/tests/test_preprocess_model_math.py b/tests/test_preprocess_model_math.py index 8fc95931..9270a2d3 100644 --- a/tests/test_preprocess_model_math.py +++ b/tests/test_preprocess_model_math.py @@ -143,12 +143,13 @@ def test_user_math_add_history(self, model_math_w_mode_user, user_math_path): assert model_math_w_mode_user.in_history(user_math_path) def test_repr(self, model_math_w_mode): - expected_repr_content = """Calliope math definition dictionary with: - 4 decision variable(s) - 0 global expression(s) - 9 constraint(s) - 0 piecewise constraint(s) - 0 objective(s) + expected_repr_content = """ + Calliope math definition dictionary with: + 4 decision variable(s) + 0 global expression(s) + 9 constraint(s) + 0 piecewise constraint(s) + 0 objective(s) """ assert expected_repr_content == str(model_math_w_mode)