From c3b91d476d4f77fa21b6e79cad55490c46821673 Mon Sep 17 00:00:00 2001 From: Gilberto RUIZ JIMENEZ Date: Mon, 15 Sep 2025 14:01:36 +0200 Subject: [PATCH 01/16] refactor(DesignSpace): allow custom characters in to_csv/from_csv Signed-off-by: Gilberto RUIZ JIMENEZ --- src/gemseo/__init__.py | 5 ++- src/gemseo/algos/design_space.py | 77 ++++++++++++++++++++++++++------ tests/algos/test_design_space.py | 7 +-- 3 files changed, 72 insertions(+), 17 deletions(-) diff --git a/src/gemseo/__init__.py b/src/gemseo/__init__.py index bf617d58cb..25c7cdb4e1 100644 --- a/src/gemseo/__init__.py +++ b/src/gemseo/__init__.py @@ -1290,6 +1290,7 @@ def print_configuration() -> None: def read_design_space( file_path: str | Path, header: Iterable[str] = (), + delimiter: str | None = None, ) -> DesignSpace: """Read a design space from a CSV or HDF file. @@ -1305,6 +1306,8 @@ def read_design_space( file_path: The path to the file. header: The names of the fields saved in the CSV file. If empty, read them in the first row of the CSV file. + delimiter: The string used to separate values for CSV files. If ``None``, any + consecutive whitespaces act as delimiter. Returns: The design space. @@ -1328,7 +1331,7 @@ def read_design_space( """ from gemseo.algos.design_space import DesignSpace - return DesignSpace.from_file(file_path, header=header) + return DesignSpace.from_file(file_path, header=header, delimiter=delimiter) def write_design_space( diff --git a/src/gemseo/algos/design_space.py b/src/gemseo/algos/design_space.py index 155a7d7cb2..0121c99b2c 100644 --- a/src/gemseo/algos/design_space.py +++ b/src/gemseo/algos/design_space.py @@ -78,6 +78,7 @@ from numpy import round as np_round from numpy import vectorize from numpy import where from numpy import zeros_like +from pandas import DataFrame from prettytable import PrettyTable from gemseo.algos._variable import TYPE_MAP @@ -2067,6 +2068,7 @@ class DesignSpace: cls, file_path: str | Path, hdf_node_path: str = "", + delimiter: str | None = None, **options: Any, ) -> DesignSpace: """Create a design space from a file. @@ -2078,6 +2080,8 @@ class DesignSpace: hdf_node_path: The path of the HDF node from which the database should be imported. If empty, the root node is considered. + delimiter: The string used to separate values for CSV files. If ``None``, + any consecutive whitespaces act as delimiter. **options: The keyword reading options. Returns: @@ -2085,28 +2089,30 @@ class DesignSpace: """ if h5py.is_hdf5(file_path): return cls.from_hdf(file_path, hdf_node_path) - return cls.from_csv(file_path, **options) + return cls.from_csv(file_path, delimiter=delimiter, **options) - def to_file(self, file_path: str | Path, **options) -> None: + def to_file(self, file_path: str | Path, delimiter: str = " ", **options) -> None: """Save the design space. Args: file_path: The file path to save the design space. If the extension starts with `"hdf"`, the design space will be saved in an HDF file. + delimiter: The string used to separate values for CSV files. **options: The keyword reading options. """ file_path = Path(file_path) if file_path.suffix.startswith((".hdf", ".h5")): self.to_hdf(file_path, append=options.get("append", False)) else: - self.to_csv(file_path, **options) + self.to_csv(file_path, delimiter=delimiter, **options) def to_csv( self, output_file: str | Path, fields: Sequence[str] = (), header_char: str = "", + delimiter: str = " ", **table_options: Any, ) -> None: """Export the design space to a CSV file. @@ -2116,27 +2122,72 @@ class DesignSpace: fields: The fields to be exported. If empty, export all fields. header_char: The header character. + delimiter: The string used to separate values. **table_options: The names and values of additional attributes for the :class:`.PrettyTable` view generated by :meth:`.DesignSpace.get_pretty_table`. """ output_file = Path(output_file) - table = self.get_pretty_table(fields=fields) - table.border = False - for option, val in table_options.items(): - table.__setattr__(option, val) - with output_file.open("w") as outf: - table_str = header_char + table.get_string() - outf.write(table_str) + dataframe = self.__to_dataframe() + dataframe.to_csv( + output_file, + sep=delimiter or " ", + index=False, + columns=fields or self.TABLE_NAMES, + na_rep="None", + ) + + def __to_dataframe(self) -> DataFrame: + """Export the design space to a dataframe.""" + variable_names = [] + variable_values = [] + lower_bounds = [] + upper_bounds = [] + variable_types = [] + for name, variable in self._variables.items(): + curr = self.__current_value.get(name) + + for i in range(variable.size): + variable_names.append(name) + variable_types.append(variable.type) + lower_bounds.append(variable.lower_bound[i]) + upper_bounds.append(variable.upper_bound[i]) + + if curr is not None: + value = curr[i] + # The current value of a float variable can be a complex array + # when approximating gradients with complex step. + if variable.type == "float": + value = value.real + + variable_values.append(value) + else: + variable_values.append(None) + + data = { + "name": variable_names, + "value": variable_values, + "lower_bound": lower_bounds, + "upper_bound": upper_bounds, + "type": variable_types, + } + return DataFrame(data) @classmethod - def from_csv(cls, file_path: str | Path, header: Iterable[str] = ()) -> DesignSpace: + def from_csv( + cls, + file_path: str | Path, + header: Iterable[str] = (), + delimiter: str | None = None, + ) -> DesignSpace: """Create a design space from a CSV file. Args: file_path: The path to the CSV file. header: The names of the fields saved in the file. If empty, read them in the file. + delimiter: The string used to separate values. If ``None``, any consecutive + whitespaces act as delimiter. Returns: The design space defined in the file. @@ -2146,8 +2197,8 @@ class DesignSpace: in its header. """ design_space = cls() - float_data = genfromtxt(file_path, dtype="float") - str_data = genfromtxt(file_path, dtype="str") + float_data = genfromtxt(file_path, delimiter=delimiter, dtype="float") + str_data = genfromtxt(file_path, delimiter=delimiter, dtype="str") if header: start_read = 0 else: diff --git a/tests/algos/test_design_space.py b/tests/algos/test_design_space.py index 887eb08c8a..36c12ea32d 100644 --- a/tests/algos/test_design_space.py +++ b/tests/algos/test_design_space.py @@ -1002,14 +1002,15 @@ def test_hdf5_with_node(tmp_wd): @pytest.mark.parametrize("suffix", [".csv", ".h5", ".hdf", ".hdf5", ".txt"]) -def test_to_from_file(tmp_wd, suffix) -> None: +@pytest.mark.parametrize("delimiter", [None, ","]) +def test_to_from_file(tmp_wd, suffix, delimiter) -> None: """Check that the methods to_file() and from_file() work correctly.""" file_path = Path("foo").with_suffix(suffix) design_space = get_sobieski_design_space() - design_space.to_file(file_path) + design_space.to_file(file_path, delimiter) assert h5py.is_hdf5(file_path) == file_path.suffix.startswith((".h5", ".hdf")) - read_design_space = DesignSpace.from_file(file_path) + read_design_space = DesignSpace.from_file(file_path, delimiter=delimiter) check_ds(design_space, read_design_space, file_path) -- GitLab From 4182cfe516d8edaf928d77a0de294bd76b884836 Mon Sep 17 00:00:00 2001 From: Gilberto RUIZ JIMENEZ Date: Mon, 15 Sep 2025 15:19:18 +0200 Subject: [PATCH 02/16] test: add missing coverage for API functions Signed-off-by: Gilberto RUIZ JIMENEZ --- tests/test_gemseo.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/tests/test_gemseo.py b/tests/test_gemseo.py index ac28bc542a..7e2fc33ece 100644 --- a/tests/test_gemseo.py +++ b/tests/test_gemseo.py @@ -82,6 +82,7 @@ from gemseo import import_database from gemseo import import_discipline from gemseo import monitor_scenario from gemseo import print_configuration +from gemseo import read_design_space from gemseo import sample_disciplines from gemseo import wrap_discipline_in_job_scheduler from gemseo import write_design_space @@ -686,8 +687,9 @@ def test_create_design_space() -> None: design_space.check() -def test_write_design_space(tmp_wd) -> None: - """Test that a design space can be exported to a text or h5 file. +@pytest.mark.parametrize("file_name", ["design_space.csv", "design_space.h5"]) +def test_read_write_design_space(tmp_wd, file_name) -> None: + """Test that a design space can be exported/imported to/from a text or h5 file. Args: tmp_wd: Fixture to move into a temporary directory. @@ -696,8 +698,18 @@ def test_write_design_space(tmp_wd) -> None: design_space.add_variable( "name", type_="float", lower_bound=-1, upper_bound=1, value=0 ) - write_design_space(design_space, "design_space.csv") - write_design_space(design_space, "design_space.h5") + design_space.add_variable( + "another_name", + type_="integer", + lower_bound=-1, + upper_bound=1, + value=[0, 0], + size=2, + ) + write_design_space(design_space, file_name) + assert Path(file_name).exists() + design_space_from_file = read_design_space(file_path=file_name) + assert design_space == design_space_from_file def test_create_cache() -> None: -- GitLab From 199c6e945f545232f6c46164ed69f65f38e15076 Mon Sep 17 00:00:00 2001 From: Gilberto RUIZ JIMENEZ Date: Mon, 15 Sep 2025 15:39:04 +0200 Subject: [PATCH 03/16] refactor(DesignSpace): add deprecation warnings Signed-off-by: Gilberto RUIZ JIMENEZ --- src/gemseo/__init__.py | 4 ++-- src/gemseo/algos/design_space.py | 22 ++++++++++++++++++---- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/gemseo/__init__.py b/src/gemseo/__init__.py index 25c7cdb4e1..10af0e1904 100644 --- a/src/gemseo/__init__.py +++ b/src/gemseo/__init__.py @@ -1338,8 +1338,8 @@ def write_design_space( design_space: DesignSpace, output_file: str | Path, fields: Sequence[str] = (), - header_char: str = "", - **table_options: Any, + header_char: str = "", # TODO API: remove. + **table_options: Any, # TODO API: remove. ) -> None: """Save a design space to a CSV or HDF file. diff --git a/src/gemseo/algos/design_space.py b/src/gemseo/algos/design_space.py index 0121c99b2c..8c1c5abd3e 100644 --- a/src/gemseo/algos/design_space.py +++ b/src/gemseo/algos/design_space.py @@ -2069,7 +2069,7 @@ class DesignSpace: file_path: str | Path, hdf_node_path: str = "", delimiter: str | None = None, - **options: Any, + **options: Any, # TODO: API remove. ) -> DesignSpace: """Create a design space from a file. @@ -2089,6 +2089,10 @@ class DesignSpace: """ if h5py.is_hdf5(file_path): return cls.from_hdf(file_path, hdf_node_path) + if options: + LOGGER.warning( + "The **options argument is deprecated and will be removed in GEMSEO 7." + ) return cls.from_csv(file_path, delimiter=delimiter, **options) def to_file(self, file_path: str | Path, delimiter: str = " ", **options) -> None: @@ -2105,15 +2109,15 @@ class DesignSpace: if file_path.suffix.startswith((".hdf", ".h5")): self.to_hdf(file_path, append=options.get("append", False)) else: - self.to_csv(file_path, delimiter=delimiter, **options) + self.to_csv(file_path, delimiter=delimiter) def to_csv( self, output_file: str | Path, fields: Sequence[str] = (), - header_char: str = "", + header_char: str = "", # TODO API: remove. delimiter: str = " ", - **table_options: Any, + **table_options: Any, # TODO API: remove. ) -> None: """Export the design space to a CSV file. @@ -2127,6 +2131,16 @@ class DesignSpace: for the :class:`.PrettyTable` view generated by :meth:`.DesignSpace.get_pretty_table`. """ + if table_options: + LOGGER.warning( + "The **table_options argument is deprecated and will be" + " removed in GEMSEO 7." + ) + if header_char: + LOGGER.warning( + "The header_char argument is deprecated and will be removed" + " in GEMSEO 7." + ) output_file = Path(output_file) dataframe = self.__to_dataframe() dataframe.to_csv( -- GitLab From 76ae2cc464bf8f90c730d2e9c643909107a5aff3 Mon Sep 17 00:00:00 2001 From: Gilberto RUIZ JIMENEZ Date: Mon, 15 Sep 2025 16:11:00 +0200 Subject: [PATCH 04/16] docs(DesignSpace): add missing return in the docstring Signed-off-by: Gilberto RUIZ JIMENEZ --- src/gemseo/algos/design_space.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gemseo/algos/design_space.py b/src/gemseo/algos/design_space.py index 8c1c5abd3e..a7af2f7369 100644 --- a/src/gemseo/algos/design_space.py +++ b/src/gemseo/algos/design_space.py @@ -2152,7 +2152,11 @@ class DesignSpace: ) def __to_dataframe(self) -> DataFrame: - """Export the design space to a dataframe.""" + """Export the design space to a ``DataFrame``. + + Returns: + The ``DesignSpace`` as a ``DataFrame``. + """ variable_names = [] variable_values = [] lower_bounds = [] -- GitLab From 6f1909d9dfecb981fbd09b8e5d4c2d98f62c31d5 Mon Sep 17 00:00:00 2001 From: Gilberto RUIZ JIMENEZ Date: Tue, 16 Sep 2025 13:44:39 +0200 Subject: [PATCH 05/16] test(DesignSpace): add missing coverage for deprecation warnings Signed-off-by: Gilberto RUIZ JIMENEZ --- src/gemseo/algos/design_space.py | 2 +- tests/algos/test_design_space.py | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/gemseo/algos/design_space.py b/src/gemseo/algos/design_space.py index a7af2f7369..0a840c04b2 100644 --- a/src/gemseo/algos/design_space.py +++ b/src/gemseo/algos/design_space.py @@ -2093,7 +2093,7 @@ class DesignSpace: LOGGER.warning( "The **options argument is deprecated and will be removed in GEMSEO 7." ) - return cls.from_csv(file_path, delimiter=delimiter, **options) + return cls.from_csv(file_path, delimiter=delimiter) def to_file(self, file_path: str | Path, delimiter: str = " ", **options) -> None: """Save the design space. diff --git a/tests/algos/test_design_space.py b/tests/algos/test_design_space.py index 36c12ea32d..c6703d503b 100644 --- a/tests/algos/test_design_space.py +++ b/tests/algos/test_design_space.py @@ -2061,3 +2061,28 @@ def test_normalize_vect_with_inout_argument() -> None: inout = array([0]) space.normalize_vect(array([0]), out=inout) assert_array_equal(inout, array([0])) + + +# TODO API: remove this test along with the deprecated arguments. +def test_deprecation_warnings_from_file(caplog): + """Test the warnings for deprecated arguments.""" + DesignSpace.from_file(TEST_INFILE, some_argument="some_value") + assert ( + r"The **options argument is deprecated and will be removed in GEMSEO 7." + in caplog.text + ) + + +# TODO API: remove this test along with the deprecated arguments. +def test_deprecation_warnings_to_csv(tmp_wd, caplog): + """Test the warnings for deprecated arguments.""" + design_space = DesignSpace.from_file(TEST_INFILE) + design_space.to_csv("design_space.csv", header_char=",", some_option="some_option") + assert ( + r"The header_char argument is deprecated and will be removed in GEMSEO 7." + in caplog.text + ) + assert ( + r"The **table_options argument is deprecated and will be removed in GEMSEO 7." + in caplog.text + ) -- GitLab From 8fb9f566a09148ac6ccb0c0ea4c8b0f97caab385 Mon Sep 17 00:00:00 2001 From: Gilberto RUIZ JIMENEZ Date: Tue, 16 Sep 2025 14:01:09 +0200 Subject: [PATCH 06/16] refactor(DesignSpace): cascade arguments properly Signed-off-by: Gilberto RUIZ JIMENEZ --- src/gemseo/__init__.py | 8 +++++++- src/gemseo/algos/design_space.py | 5 ++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/gemseo/__init__.py b/src/gemseo/__init__.py index 10af0e1904..f8e26960e2 100644 --- a/src/gemseo/__init__.py +++ b/src/gemseo/__init__.py @@ -1338,6 +1338,7 @@ def write_design_space( design_space: DesignSpace, output_file: str | Path, fields: Sequence[str] = (), + delimiter: str = " ", header_char: str = "", # TODO API: remove. **table_options: Any, # TODO API: remove. ) -> None: @@ -1348,6 +1349,7 @@ def write_design_space( output_file: The path to the file. fields: The fields to be exported. If empty, export all fields. + delimiter: The string used to separate values for CSV files. header_char: The header character. **table_options: The names and values of additional attributes for the :class:`.PrettyTable` view @@ -1360,7 +1362,11 @@ def write_design_space( >>> write_design_space(design_space, "file.csv") """ design_space.to_file( - output_file, fields=fields, header_char=header_char, **table_options + output_file, + fields=fields, + delimiter=delimiter, + header_char=header_char, + **table_options, ) diff --git a/src/gemseo/algos/design_space.py b/src/gemseo/algos/design_space.py index 0a840c04b2..c8cc730bd2 100644 --- a/src/gemseo/algos/design_space.py +++ b/src/gemseo/algos/design_space.py @@ -2068,6 +2068,7 @@ class DesignSpace: cls, file_path: str | Path, hdf_node_path: str = "", + header: Iterable[str] = (), delimiter: str | None = None, **options: Any, # TODO: API remove. ) -> DesignSpace: @@ -2080,6 +2081,8 @@ class DesignSpace: hdf_node_path: The path of the HDF node from which the database should be imported. If empty, the root node is considered. + header: The names of the fields saved in the CSV file. + If empty, read them in the first row of the CSV file. delimiter: The string used to separate values for CSV files. If ``None``, any consecutive whitespaces act as delimiter. **options: The keyword reading options. @@ -2093,7 +2096,7 @@ class DesignSpace: LOGGER.warning( "The **options argument is deprecated and will be removed in GEMSEO 7." ) - return cls.from_csv(file_path, delimiter=delimiter) + return cls.from_csv(file_path, header=header, delimiter=delimiter) def to_file(self, file_path: str | Path, delimiter: str = " ", **options) -> None: """Save the design space. -- GitLab From d7da49bc463efb59f50976860d2450aaa4942acf Mon Sep 17 00:00:00 2001 From: Gilberto RUIZ JIMENEZ Date: Tue, 16 Sep 2025 14:01:25 +0200 Subject: [PATCH 07/16] docs(Changelog): update the changelog Signed-off-by: Gilberto RUIZ JIMENEZ --- changelog/fragments/1627.changed.rst | 12 ++++++++++++ changelog/fragments/1627.removed.rst | 3 +++ 2 files changed, 15 insertions(+) create mode 100644 changelog/fragments/1627.changed.rst create mode 100644 changelog/fragments/1627.removed.rst diff --git a/changelog/fragments/1627.changed.rst b/changelog/fragments/1627.changed.rst new file mode 100644 index 0000000000..2e2ef6ffea --- /dev/null +++ b/changelog/fragments/1627.changed.rst @@ -0,0 +1,12 @@ +The ``write_design_space`` function now includes the argument ``delimiter`` which allows users to choose the +delimiter character for CSV files. +The ``DesignSpace.to_file`` method now includes the argument ``delimiter`` which allows users to choose the +delimiter character for CSV files. +The ``DesignSpace.to_csv`` method now includes the argument ``delimiter`` which allows users to choose the +delimiter character for the output file. +The ``read_design_space`` function now includes the argument ``delimiter`` which allows users to choose the +delimiter character for CSV files. +The ``DesignSpace.from_file`` method now includes the argument ``delimiter`` which allows users to choose the +delimiter character for CSV files. +The ``DesignSpace.from_csv`` method now includes the argument ``delimiter`` which allows users to choose the +delimiter character for the output file. diff --git a/changelog/fragments/1627.removed.rst b/changelog/fragments/1627.removed.rst new file mode 100644 index 0000000000..4a40f9e138 --- /dev/null +++ b/changelog/fragments/1627.removed.rst @@ -0,0 +1,3 @@ +The ``**options`` argument in ``DesignSpace.from_file`` has been deprecated. +The ``**table_options`` argument in ``DesignSpace.to_csv`` has been deprecated. +The ``header_char`` argument in ``DesignSpace.to_csv`` has been deprecated. -- GitLab From a622797d79c01278e2063ccdbf44452e828e48f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gilberto=20Ruiz=20Jim=C3=A9nez?= <8931332-gilberto.ruiz@users.noreply.gitlab.com> Date: Thu, 18 Sep 2025 10:59:54 +0200 Subject: [PATCH 08/16] Apply 10 suggestion(s) to 4 file(s) Co-authored-by: Matthias De Lozzo --- changelog/fragments/1627.changed.rst | 14 ++------------ changelog/fragments/1627.removed.rst | 6 +++--- src/gemseo/__init__.py | 8 ++++++-- src/gemseo/algos/design_space.py | 20 ++++++++++++++++---- 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/changelog/fragments/1627.changed.rst b/changelog/fragments/1627.changed.rst index 2e2ef6ffea..e08160e19b 100644 --- a/changelog/fragments/1627.changed.rst +++ b/changelog/fragments/1627.changed.rst @@ -1,12 +1,2 @@ -The ``write_design_space`` function now includes the argument ``delimiter`` which allows users to choose the -delimiter character for CSV files. -The ``DesignSpace.to_file`` method now includes the argument ``delimiter`` which allows users to choose the -delimiter character for CSV files. -The ``DesignSpace.to_csv`` method now includes the argument ``delimiter`` which allows users to choose the -delimiter character for the output file. -The ``read_design_space`` function now includes the argument ``delimiter`` which allows users to choose the -delimiter character for CSV files. -The ``DesignSpace.from_file`` method now includes the argument ``delimiter`` which allows users to choose the -delimiter character for CSV files. -The ``DesignSpace.from_csv`` method now includes the argument ``delimiter`` which allows users to choose the -delimiter character for the output file. +The following functions now include the argument ``delimiter`` which allows users to choose the +delimiter character for CSV files: ``write_design_space``, ``read_design_space``, ``DesignSpace.from_file``, ``DesignSpace.to_file``, ``DesignSpace.from_csv`` and ``DesignSpace.to_csv``. diff --git a/changelog/fragments/1627.removed.rst b/changelog/fragments/1627.removed.rst index 4a40f9e138..3df9162efe 100644 --- a/changelog/fragments/1627.removed.rst +++ b/changelog/fragments/1627.removed.rst @@ -1,3 +1,3 @@ -The ``**options`` argument in ``DesignSpace.from_file`` has been deprecated. -The ``**table_options`` argument in ``DesignSpace.to_csv`` has been deprecated. -The ``header_char`` argument in ``DesignSpace.to_csv`` has been deprecated. +- The ``**options`` argument in ``DesignSpace.from_file`` has been deprecated. +- The ``**table_options`` argument in ``DesignSpace.to_csv`` has been deprecated. +- The ``header_char`` argument in ``DesignSpace.to_csv`` has been deprecated. diff --git a/src/gemseo/__init__.py b/src/gemseo/__init__.py index f8e26960e2..ccdaef6e9e 100644 --- a/src/gemseo/__init__.py +++ b/src/gemseo/__init__.py @@ -1339,8 +1339,10 @@ def write_design_space( output_file: str | Path, fields: Sequence[str] = (), delimiter: str = " ", - header_char: str = "", # TODO API: remove. - **table_options: Any, # TODO API: remove. + # TODO: API: remove. + header_char: str = "", + # TODO: API: remove. + **table_options: Any, ) -> None: """Save a design space to a CSV or HDF file. @@ -1350,10 +1352,12 @@ def write_design_space( fields: The fields to be exported. If empty, export all fields. delimiter: The string used to separate values for CSV files. + These options are ignored and will be removed in GEMSEO 7. header_char: The header character. **table_options: The names and values of additional attributes for the :class:`.PrettyTable` view generated by :meth:`.DesignSpace.get_pretty_table`. + These options are ignored and will be removed in GEMSEO 7. Examples: >>> from gemseo import create_design_space, write_design_space diff --git a/src/gemseo/algos/design_space.py b/src/gemseo/algos/design_space.py index c8cc730bd2..134eeb9839 100644 --- a/src/gemseo/algos/design_space.py +++ b/src/gemseo/algos/design_space.py @@ -2070,7 +2070,8 @@ class DesignSpace: hdf_node_path: str = "", header: Iterable[str] = (), delimiter: str | None = None, - **options: Any, # TODO: API remove. + # TODO: API: remove. + **options: Any, ) -> DesignSpace: """Create a design space from a file. @@ -2098,7 +2099,13 @@ class DesignSpace: ) return cls.from_csv(file_path, header=header, delimiter=delimiter) - def to_file(self, file_path: str | Path, delimiter: str = " ", **options) -> None: + def to_file( + self, + file_path: str | Path, + delimiter: str = " ", + # TODO: API: remove. + **options: Any + ) -> None: """Save the design space. Args: @@ -2107,6 +2114,7 @@ class DesignSpace: the design space will be saved in an HDF file. delimiter: The string used to separate values for CSV files. **options: The keyword reading options. + These options are ignored and will be removed in GEMSEO 7. """ file_path = Path(file_path) if file_path.suffix.startswith((".hdf", ".h5")): @@ -2118,9 +2126,11 @@ class DesignSpace: self, output_file: str | Path, fields: Sequence[str] = (), - header_char: str = "", # TODO API: remove. + # TODO: API: remove. + header_char: str = "", delimiter: str = " ", - **table_options: Any, # TODO API: remove. + # TODO: API: remove. + **table_options: Any, ) -> None: """Export the design space to a CSV file. @@ -2129,10 +2139,12 @@ class DesignSpace: fields: The fields to be exported. If empty, export all fields. header_char: The header character. + This argument is ignored and will be removed in GEMSEO 7. delimiter: The string used to separate values. **table_options: The names and values of additional attributes for the :class:`.PrettyTable` view generated by :meth:`.DesignSpace.get_pretty_table`. + These options are ignored and will be removed in GEMSEO 7. """ if table_options: LOGGER.warning( -- GitLab From f064f9a05310a8202837282c55a59080aa547067 Mon Sep 17 00:00:00 2001 From: Gilberto RUIZ JIMENEZ Date: Thu, 18 Sep 2025 11:10:54 +0200 Subject: [PATCH 09/16] style: ruff corrections Signed-off-by: Gilberto RUIZ JIMENEZ --- src/gemseo/algos/design_space.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gemseo/algos/design_space.py b/src/gemseo/algos/design_space.py index 134eeb9839..80ec1df0ad 100644 --- a/src/gemseo/algos/design_space.py +++ b/src/gemseo/algos/design_space.py @@ -2104,7 +2104,7 @@ class DesignSpace: file_path: str | Path, delimiter: str = " ", # TODO: API: remove. - **options: Any + **options: Any, ) -> None: """Save the design space. -- GitLab From 60569aa1574fbfea4c6ee8047486108387ba11cb Mon Sep 17 00:00:00 2001 From: Gilberto RUIZ JIMENEZ Date: Thu, 18 Sep 2025 11:17:51 +0200 Subject: [PATCH 10/16] refactor(DesignSpace): remove deprecation warnings and the associated test Signed-off-by: Gilberto RUIZ JIMENEZ --- src/gemseo/algos/design_space.py | 10 ---------- tests/algos/test_design_space.py | 15 --------------- 2 files changed, 25 deletions(-) diff --git a/src/gemseo/algos/design_space.py b/src/gemseo/algos/design_space.py index 80ec1df0ad..c8c0b6e81b 100644 --- a/src/gemseo/algos/design_space.py +++ b/src/gemseo/algos/design_space.py @@ -2146,16 +2146,6 @@ class DesignSpace: generated by :meth:`.DesignSpace.get_pretty_table`. These options are ignored and will be removed in GEMSEO 7. """ - if table_options: - LOGGER.warning( - "The **table_options argument is deprecated and will be" - " removed in GEMSEO 7." - ) - if header_char: - LOGGER.warning( - "The header_char argument is deprecated and will be removed" - " in GEMSEO 7." - ) output_file = Path(output_file) dataframe = self.__to_dataframe() dataframe.to_csv( diff --git a/tests/algos/test_design_space.py b/tests/algos/test_design_space.py index c6703d503b..1ea0316d05 100644 --- a/tests/algos/test_design_space.py +++ b/tests/algos/test_design_space.py @@ -2071,18 +2071,3 @@ def test_deprecation_warnings_from_file(caplog): r"The **options argument is deprecated and will be removed in GEMSEO 7." in caplog.text ) - - -# TODO API: remove this test along with the deprecated arguments. -def test_deprecation_warnings_to_csv(tmp_wd, caplog): - """Test the warnings for deprecated arguments.""" - design_space = DesignSpace.from_file(TEST_INFILE) - design_space.to_csv("design_space.csv", header_char=",", some_option="some_option") - assert ( - r"The header_char argument is deprecated and will be removed in GEMSEO 7." - in caplog.text - ) - assert ( - r"The **table_options argument is deprecated and will be removed in GEMSEO 7." - in caplog.text - ) -- GitLab From 151efdc6642b7e25f6575e1c1a22181f7cc325e4 Mon Sep 17 00:00:00 2001 From: Gilberto RUIZ JIMENEZ Date: Thu, 18 Sep 2025 11:33:02 +0200 Subject: [PATCH 11/16] docs(Changelog): move changes from removed to changed Signed-off-by: Gilberto RUIZ JIMENEZ --- changelog/fragments/1627.changed.rst | 3 +++ changelog/fragments/1627.removed.rst | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 changelog/fragments/1627.removed.rst diff --git a/changelog/fragments/1627.changed.rst b/changelog/fragments/1627.changed.rst index e08160e19b..df506f5621 100644 --- a/changelog/fragments/1627.changed.rst +++ b/changelog/fragments/1627.changed.rst @@ -1,2 +1,5 @@ The following functions now include the argument ``delimiter`` which allows users to choose the delimiter character for CSV files: ``write_design_space``, ``read_design_space``, ``DesignSpace.from_file``, ``DesignSpace.to_file``, ``DesignSpace.from_csv`` and ``DesignSpace.to_csv``. +- The ``**options`` argument in ``DesignSpace.from_file`` has been deprecated. +- The ``**table_options`` argument in ``DesignSpace.to_csv`` has been deprecated. +- The ``header_char`` argument in ``DesignSpace.to_csv`` has been deprecated. diff --git a/changelog/fragments/1627.removed.rst b/changelog/fragments/1627.removed.rst deleted file mode 100644 index 3df9162efe..0000000000 --- a/changelog/fragments/1627.removed.rst +++ /dev/null @@ -1,3 +0,0 @@ -- The ``**options`` argument in ``DesignSpace.from_file`` has been deprecated. -- The ``**table_options`` argument in ``DesignSpace.to_csv`` has been deprecated. -- The ``header_char`` argument in ``DesignSpace.to_csv`` has been deprecated. -- GitLab From 77f5d3f9674bae780d30221503cf8ebc4f5e0638 Mon Sep 17 00:00:00 2001 From: Gilberto RUIZ JIMENEZ Date: Thu, 18 Sep 2025 11:37:51 +0200 Subject: [PATCH 12/16] refactor(DesignSpace): remove deprecation warning Signed-off-by: Gilberto RUIZ JIMENEZ --- src/gemseo/algos/design_space.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/gemseo/algos/design_space.py b/src/gemseo/algos/design_space.py index c8c0b6e81b..8f039fab01 100644 --- a/src/gemseo/algos/design_space.py +++ b/src/gemseo/algos/design_space.py @@ -2087,16 +2087,13 @@ class DesignSpace: delimiter: The string used to separate values for CSV files. If ``None``, any consecutive whitespaces act as delimiter. **options: The keyword reading options. + These options are ignored and will be removed in GEMSEO 7. Returns: The design space defined in the file. """ if h5py.is_hdf5(file_path): return cls.from_hdf(file_path, hdf_node_path) - if options: - LOGGER.warning( - "The **options argument is deprecated and will be removed in GEMSEO 7." - ) return cls.from_csv(file_path, header=header, delimiter=delimiter) def to_file( -- GitLab From 1e20234ecd7af6cdd31bc738b47abe2c9a95a017 Mon Sep 17 00:00:00 2001 From: Gilberto RUIZ JIMENEZ Date: Thu, 18 Sep 2025 11:41:54 +0200 Subject: [PATCH 13/16] refactor: update dependencies Signed-off-by: Gilberto RUIZ JIMENEZ --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index eca1088fd3..e897bcdbb6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -74,7 +74,7 @@ repos: - id: ruff-format - repo: https://github.com/commitizen-tools/commitizen - rev: v4.9.0 + rev: v4.9.1 hooks: - id: commitizen stages: [commit-msg] -- GitLab From e4adaf21f7fc2d129ae8a8d8c3395a8c9e58c8f4 Mon Sep 17 00:00:00 2001 From: Gilberto RUIZ JIMENEZ Date: Thu, 18 Sep 2025 12:25:39 +0200 Subject: [PATCH 14/16] refactor(DesignSpace): allow the use of table_options to keep the API unchanged Signed-off-by: Gilberto RUIZ JIMENEZ --- src/gemseo/__init__.py | 17 ++++++++---- src/gemseo/algos/design_space.py | 47 ++++++++++++++++++++++---------- tests/algos/test_design_space.py | 16 +++++------ 3 files changed, 53 insertions(+), 27 deletions(-) diff --git a/src/gemseo/__init__.py b/src/gemseo/__init__.py index ccdaef6e9e..97a2552f09 100644 --- a/src/gemseo/__init__.py +++ b/src/gemseo/__init__.py @@ -1352,12 +1352,19 @@ def write_design_space( fields: The fields to be exported. If empty, export all fields. delimiter: The string used to separate values for CSV files. - These options are ignored and will be removed in GEMSEO 7. + This argument is not compatible with ``header_char`` nor + ``**table_options``. header_char: The header character. - **table_options: The names and values of additional attributes - for the :class:`.PrettyTable` view - generated by :meth:`.DesignSpace.get_pretty_table`. - These options are ignored and will be removed in GEMSEO 7. + **table_options: + For HDF files: + The ``append`` option may be passed here. + See :meth:`.DesignSpace.to_hdf`. + For CSV files: + The names and values of additional attributes + for the :class:`.PrettyTable` view + generated by :meth:`.DesignSpace.get_pretty_table`. + These options will be removed in GEMSEO 7. + Examples: >>> from gemseo import create_design_space, write_design_space diff --git a/src/gemseo/algos/design_space.py b/src/gemseo/algos/design_space.py index 8f039fab01..da4d0d17c5 100644 --- a/src/gemseo/algos/design_space.py +++ b/src/gemseo/algos/design_space.py @@ -2109,15 +2109,23 @@ class DesignSpace: file_path: The file path to save the design space. If the extension starts with `"hdf"`, the design space will be saved in an HDF file. - delimiter: The string used to separate values for CSV files. + delimiter: The string used to separate values for CSV files. This argument + is not compatible with the argument ``**options``. **options: The keyword reading options. - These options are ignored and will be removed in GEMSEO 7. + For HDF files: + The ``append`` option may be passed here. + See :meth:`.DesignSpace.to_hdf`. + For CSV files: + The names and values of additional attributes + for the :class:`.PrettyTable` view + generated by :meth:`.DesignSpace.get_pretty_table`. + These options will be removed in GEMSEO 7. """ file_path = Path(file_path) if file_path.suffix.startswith((".hdf", ".h5")): self.to_hdf(file_path, append=options.get("append", False)) else: - self.to_csv(file_path, delimiter=delimiter) + self.to_csv(file_path, delimiter=delimiter, **options) def to_csv( self, @@ -2136,22 +2144,33 @@ class DesignSpace: fields: The fields to be exported. If empty, export all fields. header_char: The header character. - This argument is ignored and will be removed in GEMSEO 7. - delimiter: The string used to separate values. + This argument will be removed in GEMSEO 7. + delimiter: The string used to separate values. This argument is not + compatible with ``header_char`` nor ``**table_options``. **table_options: The names and values of additional attributes for the :class:`.PrettyTable` view generated by :meth:`.DesignSpace.get_pretty_table`. - These options are ignored and will be removed in GEMSEO 7. + These options will be removed in GEMSEO 7. """ output_file = Path(output_file) - dataframe = self.__to_dataframe() - dataframe.to_csv( - output_file, - sep=delimiter or " ", - index=False, - columns=fields or self.TABLE_NAMES, - na_rep="None", - ) + + if table_options or header_char: + table = self.get_pretty_table(fields=fields) + table.border = False + for option, val in table_options.items(): + table.__setattr__(option, val) + with output_file.open("w") as outf: + table_str = header_char + table.get_string() + outf.write(table_str) + else: + dataframe = self.__to_dataframe() + dataframe.to_csv( + output_file, + sep=delimiter or " ", + index=False, + columns=fields or self.TABLE_NAMES, + na_rep="None", + ) def __to_dataframe(self) -> DataFrame: """Export the design space to a ``DataFrame``. diff --git a/tests/algos/test_design_space.py b/tests/algos/test_design_space.py index 1ea0316d05..6f62bc79c1 100644 --- a/tests/algos/test_design_space.py +++ b/tests/algos/test_design_space.py @@ -2063,11 +2063,11 @@ def test_normalize_vect_with_inout_argument() -> None: assert_array_equal(inout, array([0])) -# TODO API: remove this test along with the deprecated arguments. -def test_deprecation_warnings_from_file(caplog): - """Test the warnings for deprecated arguments.""" - DesignSpace.from_file(TEST_INFILE, some_argument="some_value") - assert ( - r"The **options argument is deprecated and will be removed in GEMSEO 7." - in caplog.text - ) +# TODO: API: remove this test along with **table_options +def test_to_csv_pretty_table(tmp_wd): + """Test that the pretty table options are taken into account.""" + ref_ds = get_sobieski_design_space() + f_path = Path("sobieski_design_space.csv") + ref_ds.to_csv(f_path, border=True) + table_text = f_path.read_text() + assert "-" in table_text -- GitLab From 7e17416687e41eefffb1fdf20a2f945f04215c07 Mon Sep 17 00:00:00 2001 From: Gilberto RUIZ JIMENEZ Date: Thu, 18 Sep 2025 14:14:20 +0200 Subject: [PATCH 15/16] refactor(DesignSpace): delimiter can only be a string Signed-off-by: Gilberto RUIZ JIMENEZ --- src/gemseo/__init__.py | 4 ++-- src/gemseo/algos/design_space.py | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/gemseo/__init__.py b/src/gemseo/__init__.py index 97a2552f09..4b4553f37e 100644 --- a/src/gemseo/__init__.py +++ b/src/gemseo/__init__.py @@ -1290,7 +1290,7 @@ def print_configuration() -> None: def read_design_space( file_path: str | Path, header: Iterable[str] = (), - delimiter: str | None = None, + delimiter: str = "", ) -> DesignSpace: """Read a design space from a CSV or HDF file. @@ -1306,7 +1306,7 @@ def read_design_space( file_path: The path to the file. header: The names of the fields saved in the CSV file. If empty, read them in the first row of the CSV file. - delimiter: The string used to separate values for CSV files. If ``None``, any + delimiter: The string used to separate values for CSV files. If empty, any consecutive whitespaces act as delimiter. Returns: diff --git a/src/gemseo/algos/design_space.py b/src/gemseo/algos/design_space.py index da4d0d17c5..9342f490fe 100644 --- a/src/gemseo/algos/design_space.py +++ b/src/gemseo/algos/design_space.py @@ -2069,7 +2069,7 @@ class DesignSpace: file_path: str | Path, hdf_node_path: str = "", header: Iterable[str] = (), - delimiter: str | None = None, + delimiter: str = "", # TODO: API: remove. **options: Any, ) -> DesignSpace: @@ -2084,7 +2084,7 @@ class DesignSpace: If empty, the root node is considered. header: The names of the fields saved in the CSV file. If empty, read them in the first row of the CSV file. - delimiter: The string used to separate values for CSV files. If ``None``, + delimiter: The string used to separate values for CSV files. If empty, any consecutive whitespaces act as delimiter. **options: The keyword reading options. These options are ignored and will be removed in GEMSEO 7. @@ -2217,7 +2217,7 @@ class DesignSpace: cls, file_path: str | Path, header: Iterable[str] = (), - delimiter: str | None = None, + delimiter: str = "", ) -> DesignSpace: """Create a design space from a CSV file. @@ -2225,7 +2225,7 @@ class DesignSpace: file_path: The path to the CSV file. header: The names of the fields saved in the file. If empty, read them in the file. - delimiter: The string used to separate values. If ``None``, any consecutive + delimiter: The string used to separate values. If empty, any consecutive whitespaces act as delimiter. Returns: @@ -2236,8 +2236,8 @@ class DesignSpace: in its header. """ design_space = cls() - float_data = genfromtxt(file_path, delimiter=delimiter, dtype="float") - str_data = genfromtxt(file_path, delimiter=delimiter, dtype="str") + float_data = genfromtxt(file_path, delimiter=delimiter or None, dtype="float") + str_data = genfromtxt(file_path, delimiter=delimiter or None, dtype="str") if header: start_read = 0 else: -- GitLab From eddbdbe6b9b37d51d8a389b5d22ec9a44f84a8f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gilberto=20Ruiz=20Jim=C3=A9nez?= <8931332-gilberto.ruiz@users.noreply.gitlab.com> Date: Thu, 18 Sep 2025 14:35:30 +0200 Subject: [PATCH 16/16] Apply 1 suggestion(s) to 1 file(s) Co-authored-by: Matthias De Lozzo --- src/gemseo/algos/design_space.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gemseo/algos/design_space.py b/src/gemseo/algos/design_space.py index 9342f490fe..1bbf6b9646 100644 --- a/src/gemseo/algos/design_space.py +++ b/src/gemseo/algos/design_space.py @@ -2192,16 +2192,16 @@ class DesignSpace: lower_bounds.append(variable.lower_bound[i]) upper_bounds.append(variable.upper_bound[i]) - if curr is not None: + if curr is None: + value = None + else: value = curr[i] # The current value of a float variable can be a complex array # when approximating gradients with complex step. if variable.type == "float": value = value.real - variable_values.append(value) - else: - variable_values.append(None) + variable_values.append(value) data = { "name": variable_names, -- GitLab