Skip to content

Commit 803f15b

Browse files
authored
Tests run in random order (#2)
* bump version to 0.4.0 * fix bug in open_dataset(). Make test_no_grass_session more robust * CI: run tests in random order. Add python 3.14 to the matrix
1 parent 6ea443a commit 803f15b

File tree

4 files changed

+37
-15
lines changed

4 files changed

+37
-15
lines changed

.github/workflows/tests.yml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,17 @@ jobs:
1010
test:
1111
strategy:
1212
matrix:
13-
python-version: ["3.11", "3.12", "3.13"]
13+
python-version: ["3.11", "3.12", "3.13", "3.14"]
1414

1515
runs-on: ubuntu-latest
1616
container: osgeo/grass-gis:releasebranch_8_4-ubuntu
1717
steps:
18-
- uses: actions/checkout@v4
18+
- name: Install dependencies
19+
run: |
20+
apt update
21+
apt install -y ca-certificates
22+
23+
- uses: actions/checkout@v5
1924

2025
- name: Install uv
2126
run: |
@@ -28,4 +33,4 @@ jobs:
2833
2934
- name: Run tests
3035
run: |
31-
uv run pytest
36+
uv run pytest --random-order

src/xarray_grass/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
from xarray_grass.to_grass import to_grass as to_grass
66
from xarray_grass.coord_utils import RegionData as RegionData
77

8-
__version__ = "0.2.0"
8+
__version__ = "0.4.0"

src/xarray_grass/xarray_grass.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
import os
1717
from pathlib import Path
18-
from typing import Iterable
18+
from typing import Iterable, Optional
1919

2020
import numpy as np
2121
from xarray.backends import BackendEntrypoint
@@ -44,10 +44,10 @@ def open_dataset(
4444
self,
4545
filename_or_obj,
4646
*,
47-
raster: str | Iterable[str] = [],
48-
raster_3d: str | Iterable[str] = [],
49-
strds: str | Iterable[str] = [],
50-
str3ds: str | Iterable[str] = [],
47+
raster: Optional[str | Iterable[str]] = None,
48+
raster_3d: Optional[str | Iterable[str]] = None,
49+
strds: Optional[str | Iterable[str]] = None,
50+
str3ds: Optional[str | Iterable[str]] = None,
5151
drop_variables: Iterable[str],
5252
) -> xr.Dataset:
5353
"""Open GRASS project or mapset as an xarray.Dataset.
@@ -69,13 +69,19 @@ def open_dataset(
6969
for strds_name in grass_objects["strds"]:
7070
maps_in_strds = gi.list_maps_in_strds(strds_name)
7171
rasters_in_strds.extend([map_data.id for map_data in maps_in_strds])
72-
open_func_params["strds_list"].append(strds_name)
72+
if open_func_params["strds_list"] is None:
73+
open_func_params["strds_list"] = [strds_name]
74+
else:
75+
open_func_params["strds_list"].append(strds_name)
7376
raster3ds_in_str3ds = []
7477
# str3ds
7578
for str3ds_name in grass_objects["str3ds"]:
7679
maps_in_str3ds = gi.list_maps_in_str3ds(str3ds_name)
7780
raster3ds_in_str3ds.extend([map_data.id for map_data in maps_in_str3ds])
78-
open_func_params["str3ds_list"].append(str3ds_name)
81+
if open_func_params["str3ds_list"] is None:
82+
open_func_params["str3ds_list"] = [str3ds_name]
83+
else:
84+
open_func_params["str3ds_list"].append(str3ds_name)
7985
# rasters not in strds
8086
open_func_params["raster_list"] = [
8187
name for name in grass_objects["raster"] if name not in rasters_in_strds
@@ -287,7 +293,6 @@ def open_grass_raster(raster_name: str, grass_i: GrassInterface) -> xr.DataArray
287293
)
288294
# Add CF attributes
289295
r_infos = grass_i.get_raster_info(raster_name)
290-
print(f"{r_infos=}")
291296
da_with_attrs = set_cf_coordinates(data_array, gi=grass_i, is_3d=False)
292297
da_with_attrs.attrs["long_name"] = r_infos.get("title", "")
293298
da_with_attrs.attrs["source"] = ",".join([r_infos["source1"], r_infos["source2"]])
@@ -330,7 +335,6 @@ def open_grass_raster_3d(raster_3d_name: str, grass_i: GrassInterface) -> xr.Dat
330335

331336
def open_grass_strds(strds_name: str, grass_i: GrassInterface) -> xr.DataArray:
332337
"""must be called from within a grass session
333-
TODO: add unit, description etc. as attributes
334338
TODO: lazy loading
335339
"""
336340
x_coords, y_coords, _ = get_coordinates(grass_i, raster_3d=False).values()

tests/test_grass_interface.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,21 @@
3636

3737

3838
def test_no_grass_session():
39-
with pytest.raises(RuntimeError):
40-
GrassInterface()
39+
"""Test that GrassInterface raises RuntimeError when no GRASS session exists.
40+
This test must clear GISRC to ensure isolation from other tests that may have
41+
set up a GRASS session.
42+
"""
43+
import os
44+
45+
# Save and clear GISRC to ensure no session exists
46+
original_gisrc = os.environ.pop("GISRC", None)
47+
try:
48+
with pytest.raises(RuntimeError):
49+
GrassInterface()
50+
finally:
51+
# Restore GISRC if it was set
52+
if original_gisrc is not None:
53+
os.environ["GISRC"] = original_gisrc
4154

4255

4356
@pytest.mark.usefixtures("grass_session_fixture")

0 commit comments

Comments
 (0)