From 0ee8a5a44751fe45a0861c4dc671eb541b525103 Mon Sep 17 00:00:00 2001 From: Peter Hron Date: Tue, 18 Aug 2026 13:15:40 +0200 Subject: [PATCH 1/3] fix: _as_index() calls to_index() for DataArrays --- linopy/alignment.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/linopy/alignment.py b/linopy/alignment.py index 13126b852..541aa55ae 100644 --- a/linopy/alignment.py +++ b/linopy/alignment.py @@ -172,9 +172,11 @@ def _coords_to_dict( def _as_index(coord_values: Any) -> pd.Index: - return ( - coord_values if isinstance(coord_values, pd.Index) else pd.Index(coord_values) - ) + if isinstance(coord_values, DataArray): + return coord_values.to_index() + if isinstance(coord_values, pd.Index): + return coord_values + return pd.Index(coord_values) def _as_multiindex(coord_values: Any) -> pd.MultiIndex | None: From c630a7b45e2be728b29c0eafae15456a2ce5565c Mon Sep 17 00:00:00 2001 From: Peter Hron Date: Tue, 18 Aug 2026 13:35:59 +0200 Subject: [PATCH 2/3] test: add tests with tz-aware coords --- test/test_alignment.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/test_alignment.py b/test/test_alignment.py index 73d2cfdb0..a6eb2b099 100644 --- a/test/test_alignment.py +++ b/test/test_alignment.py @@ -572,6 +572,17 @@ def test_invalid_entry_raises_typeerror( class TestAddVariablesCoords: """End-to-end: each coords / dims form sets the variable's dimensions.""" + @staticmethod + def _datetime_coordinates(timezone: str | None) -> xr.Coordinates: + time = pd.date_range( + "2025-10-26 00:00", + periods=5, + freq="h", + tz=timezone, + name="time", + ) + return xr.Coordinates({"time": time}) + @pytest.mark.parametrize( "coords, dims, expected_dims", [ @@ -586,6 +597,9 @@ class TestAddVariablesCoords: ([np.array([0, 1, 2])], None, ("dim_0",)), ([pd.Index([0, 1, 2])], None, ("dim_0",)), ([("origin", ["a", "b"]), ("dest", ["x", "y"])], None, ("origin", "dest")), + (_datetime_coordinates(None), None, ("time",)), + (_datetime_coordinates("UTC"), None, ("time",)), + (_datetime_coordinates("Europe/Berlin"), None, ("time",)), ], ids=[ "tuple", @@ -599,6 +613,9 @@ class TestAddVariablesCoords: "ndarray", "unnamed-index", "multiple-tuples", + "xarray-datetime-naive", + "xarray-datetime-utc", + "xarray-datetime-dst", ], ) def test_coords_set_variable_dims( From bf4a4adaa51d523a38ac08243a85943f9234000f Mon Sep 17 00:00:00 2001 From: Peter Hron Date: Wed, 19 Aug 2026 11:49:51 +0200 Subject: [PATCH 3/3] chore: add release note entry --- doc/release_notes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/release_notes.rst b/doc/release_notes.rst index fe026debd..697c89e32 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -15,7 +15,7 @@ Upcoming Version * ``Model.remove_variables`` no longer removes constraints that never reference the removed variable. A masked variable carries ``-1`` label entries, which matched the ``-1`` that marks an empty term slot in a constraint, so any masked variable looked like it was used by any constraint with padded terms. Models built with ``mask=`` could silently lose constraints and solve to a wrong optimum. (`#883 `__) * ``Model.remove_variables`` now also works on a model with a quadratic objective, where it raised an ``IndexError`` because the term mask was built over the factor dimension as well. Quadratic terms are dropped when any of their factors references the removed variable. (`#883 `__) - +* Using timezone-aware ``DatetimeIndex`` coordinates in a model no longer raises a ``ValueError``. The index is now retrieved directly via ``DataArray.to_index()`` instead of rebuilding it with ``pd.Index()``, which dropped the timezone info and failed during alignment. (`#898 `__) Version v0.9.0 --------------