From b2b019376ed8d24a9867edc25ae5a58c65590f77 Mon Sep 17 00:00:00 2001 From: furqan463 Date: Sun, 25 Jan 2026 18:39:25 +0500 Subject: [PATCH 1/5] Fix pandas 3.0 Signed-off-by: furqan463 --- src/power_grid_model_io/converters/pandapower_converter.py | 2 +- tests/unit/converters/test_tabular_converter.py | 2 +- tests/unit/data_types/test_tabular_data.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/power_grid_model_io/converters/pandapower_converter.py b/src/power_grid_model_io/converters/pandapower_converter.py index 0f7aca75..e80758a4 100644 --- a/src/power_grid_model_io/converters/pandapower_converter.py +++ b/src/power_grid_model_io/converters/pandapower_converter.py @@ -2436,7 +2436,7 @@ def get_individual_switch_states(component: pd.DataFrame, switches: pd.DataFrame ) # no need to fill na because bool(NaN) == True - return pd.Series(switch_states.astype(bool, copy=False)) + return pd.Series(switch_states.astype(bool)) def get_switch_states(self, pp_table: str) -> pd.DataFrame: """ diff --git a/tests/unit/converters/test_tabular_converter.py b/tests/unit/converters/test_tabular_converter.py index 80af60e5..66458d30 100644 --- a/tests/unit/converters/test_tabular_converter.py +++ b/tests/unit/converters/test_tabular_converter.py @@ -278,7 +278,7 @@ def test_convert_col_def_to_attribute( with pytest.raises( ValueError, match=r"DataFrame for ComponentType.node.u_rated should contain a single column " - r"\(Index\(\['id_number', 'u_nom'\], dtype='object'\)\)", + r"\(Index\(\['id_number', 'u_nom'\], dtype='str'\)\)", ): converter._convert_col_def_to_attribute( data=tabular_data_no_units_no_substitutions, diff --git a/tests/unit/data_types/test_tabular_data.py b/tests/unit/data_types/test_tabular_data.py index 9e91f378..32d40bcf 100644 --- a/tests/unit/data_types/test_tabular_data.py +++ b/tests/unit/data_types/test_tabular_data.py @@ -224,7 +224,7 @@ def test_get_column__sanity_check(mock_unit_conversion: MagicMock, nodes_iso: pd mock_unit_conversion.return_value = nodes_iso["u_rated"] # Act / Assert - with pytest.raises(TypeError, match=r"u_rated.+unitless.+V"): + with pytest.raises(TypeError, match=r"u_rated[\s\S]*unitless[\s\S]*V"): data.get_column(table_name="nodes", column_name="u_rated") From e20d7df7b35814d1036dad9fcff1303aa28f9ff2 Mon Sep 17 00:00:00 2001 From: furqan463 Date: Sun, 25 Jan 2026 18:52:34 +0500 Subject: [PATCH 2/5] Enforce pandas 3.0 Signed-off-by: furqan463 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1247035d..a9b71cd5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ dependencies = [ "numpy>=2.0", "openpyxl", "packaging>=25.0", - "pandas", + "pandas>=3.0", "power_grid_model>=1.8", "pyyaml", "structlog", From 861e443298e4288adbbf34be906ddd7715a4777e Mon Sep 17 00:00:00 2001 From: furqan463 Date: Mon, 26 Jan 2026 13:23:37 +0500 Subject: [PATCH 3/5] Apply suggestions from mgovers Signed-off-by: furqan463 --- pyproject.toml | 2 +- .../converters/pandapower_converter.py | 10 ++++++---- tests/unit/converters/test_tabular_converter.py | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a9b71cd5..1247035d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ dependencies = [ "numpy>=2.0", "openpyxl", "packaging>=25.0", - "pandas>=3.0", + "pandas", "power_grid_model>=1.8", "pyyaml", "structlog", diff --git a/src/power_grid_model_io/converters/pandapower_converter.py b/src/power_grid_model_io/converters/pandapower_converter.py index e80758a4..eb4a2228 100644 --- a/src/power_grid_model_io/converters/pandapower_converter.py +++ b/src/power_grid_model_io/converters/pandapower_converter.py @@ -5,7 +5,6 @@ """ Panda Power Converter """ - import logging from functools import lru_cache from importlib.metadata import PackageNotFoundError, version @@ -1160,7 +1159,7 @@ def _create_pgm_input_motors(self): cos_phi = self._get_pp_attr("motor", "cos_phi", expected_type="f8") valid = np.logical_and(np.not_equal(cos_phi, 0.0), np.isfinite(cos_phi)) q_spec = np.sqrt( - np.power(np.divide(p_spec, cos_phi, where=valid), 2, where=valid, out=None) - p_spec**2, + np.power(np.divide(p_spec, cos_phi, where=valid, out=None), 2, where=valid, out=None) - p_spec**2, where=valid, out=None, ) @@ -1755,7 +1754,7 @@ def join_currents(table: str, bus_name: str, i_name: str) -> pd.DataFrame: pp_switches_output.loc[link_ids, "i_ka"] = links["i_from"] * 1e-3 in_ka = self.pp_input_data["switch"]["in_ka"].values pp_switches_output["loading_percent"] = np.nan - pp_switches_output["loading_percent"] = np.divide(pp_switches_output["i_ka"], in_ka, where=in_ka != 0, out=None) + pp_switches_output["loading_percent"] = np.divide(pp_switches_output["i_ka"].values, in_ka, where=in_ka != 0, out=None) assert "res_switch" not in self.pp_output_data self.pp_output_data["res_switch"] = pp_switches_output @@ -2436,7 +2435,10 @@ def get_individual_switch_states(component: pd.DataFrame, switches: pd.DataFrame ) # no need to fill na because bool(NaN) == True - return pd.Series(switch_states.astype(bool)) + if Version(version("pandas")) >= Version("3.0.0"): + return pd.Series(switch_states.astype(bool)) + else: + return pd.Series(switch_states.astype(bool, copy=False)) def get_switch_states(self, pp_table: str) -> pd.DataFrame: """ diff --git a/tests/unit/converters/test_tabular_converter.py b/tests/unit/converters/test_tabular_converter.py index 66458d30..efe624b4 100644 --- a/tests/unit/converters/test_tabular_converter.py +++ b/tests/unit/converters/test_tabular_converter.py @@ -278,7 +278,7 @@ def test_convert_col_def_to_attribute( with pytest.raises( ValueError, match=r"DataFrame for ComponentType.node.u_rated should contain a single column " - r"\(Index\(\['id_number', 'u_nom'\], dtype='str'\)\)", + r"\(Index\(\['id_number', 'u_nom'\], dtype='(str|object)'\)\)", ): converter._convert_col_def_to_attribute( data=tabular_data_no_units_no_substitutions, From 770cbfe9efd576ef90b9fa6539167abbe4106494 Mon Sep 17 00:00:00 2001 From: furqan463 Date: Mon, 26 Jan 2026 13:34:41 +0500 Subject: [PATCH 4/5] fix format Signed-off-by: furqan463 --- src/power_grid_model_io/converters/pandapower_converter.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/power_grid_model_io/converters/pandapower_converter.py b/src/power_grid_model_io/converters/pandapower_converter.py index eb4a2228..a7892706 100644 --- a/src/power_grid_model_io/converters/pandapower_converter.py +++ b/src/power_grid_model_io/converters/pandapower_converter.py @@ -5,6 +5,7 @@ """ Panda Power Converter """ + import logging from functools import lru_cache from importlib.metadata import PackageNotFoundError, version @@ -1754,7 +1755,9 @@ def join_currents(table: str, bus_name: str, i_name: str) -> pd.DataFrame: pp_switches_output.loc[link_ids, "i_ka"] = links["i_from"] * 1e-3 in_ka = self.pp_input_data["switch"]["in_ka"].values pp_switches_output["loading_percent"] = np.nan - pp_switches_output["loading_percent"] = np.divide(pp_switches_output["i_ka"].values, in_ka, where=in_ka != 0, out=None) + pp_switches_output["loading_percent"] = np.divide( + pp_switches_output["i_ka"].values, in_ka, where=in_ka != 0, out=None + ) assert "res_switch" not in self.pp_output_data self.pp_output_data["res_switch"] = pp_switches_output From 7c6511f241a49f97733fd2119f8b244c13e427cc Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Mon, 26 Jan 2026 10:26:18 +0100 Subject: [PATCH 5/5] warnings Signed-off-by: Martijn Govers --- tests/conftest.py | 8 ++++++-- tests/unit/conftest.py | 9 ++++++--- tests/validation/conftest.py | 13 ++++++++----- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 5db6a751..ca74b95f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,8 +3,12 @@ # SPDX-License-Identifier: MPL-2.0 from contextlib import suppress +from importlib.metadata import version import pandas as pd +from packaging.version import Version -with suppress(pd.errors.OptionError): - pd.set_option("future.no_silent_downcasting", True) +if Version(version("pandas")) < Version("3.0.0"): + # Opt-in to Pandas 3 behavior for Pandas 2.x + with suppress(pd.errors.OptionError): + pd.set_option("future.no_silent_downcasting", True) diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py index 52e59ce7..9531aa08 100644 --- a/tests/unit/conftest.py +++ b/tests/unit/conftest.py @@ -3,9 +3,12 @@ # SPDX-License-Identifier: MPL-2.0 from contextlib import suppress +from importlib.metadata import version import pandas as pd +from packaging.version import Version -with suppress(pd.errors.OptionError): - # TODO(mgovers) We're ready for Pandas 3.x, but pandapower is not. Move to parent conftest when it is. - pd.set_option("mode.copy_on_write", True) +if Version(version("pandas")) < Version("3.0.0"): + # Opt-in to Pandas 3 behavior for Pandas 2.x + with suppress(pd.errors.OptionError): + pd.set_option("mode.copy_on_write", True) diff --git a/tests/validation/conftest.py b/tests/validation/conftest.py index 791d3b94..0844e6a6 100644 --- a/tests/validation/conftest.py +++ b/tests/validation/conftest.py @@ -3,12 +3,15 @@ # SPDX-License-Identifier: MPL-2.0 from contextlib import suppress +from importlib.metadata import version import pandas as pd +from packaging.version import Version -with suppress(pd.errors.OptionError): - pd.set_option("future.no_silent_downcasting", True) +if Version(version("pandas")) < Version("3.0.0"): + # Opt-in to Pandas 3 behavior for Pandas 2.x + with suppress(pd.errors.OptionError): + pd.set_option("future.no_silent_downcasting", True) -with suppress(pd.errors.OptionError): - # TODO(mgovers) We're ready for Pandas 3.x, but pandapower is not. Move to parent conftest when it is. - pd.set_option("mode.copy_on_write", False) + with suppress(pd.errors.OptionError): + pd.set_option("mode.copy_on_write", False)