From edb6e8d6cfe611352d97371982b32d00d4d6e525 Mon Sep 17 00:00:00 2001 From: Matthew Perry Date: Sat, 23 May 2026 14:58:26 -0600 Subject: [PATCH 1/4] more pythons --- .github/workflows/test-rasterstats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-rasterstats.yml b/.github/workflows/test-rasterstats.yml index bc979fe..bc2b292 100644 --- a/.github/workflows/test-rasterstats.yml +++ b/.github/workflows/test-rasterstats.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} From ea9179dc587a77d61283105c3cc1974e2e3ae648 Mon Sep 17 00:00:00 2001 From: Matthew Perry Date: Sat, 23 May 2026 15:02:17 -0600 Subject: [PATCH 2/4] don't install fiona on py314 or higher --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index dbd35eb..b9d858a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,7 +48,7 @@ dependencies = [ [project.optional-dependencies] progress = ["tqdm"] -fiona = ["fiona"] +fiona = ["fiona; python_version < '3.14'"] docs = ["numpydoc", "sphinx", "sphinx-rtd-theme"] test = [ "coverage", From 8590297c91b7c866811f029c913faeb56f3a5191 Mon Sep 17 00:00:00 2001 From: Matthew Perry Date: Sat, 23 May 2026 15:12:24 -0600 Subject: [PATCH 3/4] don't swallow import error --- src/rasterstats/io.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/rasterstats/io.py b/src/rasterstats/io.py index 93e9015..a07d698 100644 --- a/src/rasterstats/io.py +++ b/src/rasterstats/io.py @@ -34,17 +34,9 @@ def _fiona_generator(obj, layer=0): - """Yield GeoJSON-like Feature dicts using fiona (optional engine). + """Yield GeoJSON-like Feature dicts using fiona (optional engine).""" + import fiona - Raises ImportError with a helpful message if fiona is not installed. - """ - try: - import fiona - except ImportError: - raise ImportError( - "fiona is required for engine='fiona'. " - "Install it with: pip install rasterstats[fiona]" - ) try: import fiona.model From 8519b237f145430bda11b259ded415bf4f0e3788 Mon Sep 17 00:00:00 2001 From: Matthew Perry Date: Sat, 23 May 2026 15:12:55 -0600 Subject: [PATCH 4/4] separate tests, import or skip fiona ones --- tests/test_io.py | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/tests/test_io.py b/tests/test_io.py index 8242452..e2327aa 100644 --- a/tests/test_io.py +++ b/tests/test_io.py @@ -8,7 +8,6 @@ from shapely.geometry import shape from rasterstats.io import ( # todo parse_feature - DEFAULT_CHUNK_SIZE, Raster, _is_vector_file, boundless_array, @@ -537,7 +536,7 @@ def test_geodataframe(): def test_feature_generator_chunk_size(tmp_path): - """Reading with default engine, fiona engine, and alternative chunk sizes + """Reading with default engine vs alternative chunk sizes, all result in equivalent feature dicts.""" geojson = { "type": "FeatureCollection", @@ -555,9 +554,31 @@ def test_feature_generator_chunk_size(tmp_path): default_results = list(feature_generator(polygons)) small_chunk_results = list(feature_generator(polygons, chunk_size=2)) - fiona_results = list(feature_generator(polygons, engine="fiona", chunk_size=2)) assert default_results == small_chunk_results + + +def test_feature_generator_engines(tmp_path): + """Reading with default engine vs fiona engine, + all result in equivalent feature dicts.""" + _ = pytest.importorskip("fiona") + geojson = { + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "geometry": {"type": "Point", "coordinates": [float(i), 0.0]}, + "properties": {"n": i}, + } + for i in range(6) + ], + } + p = tmp_path / "chunked.geojson" + p.write_text(json.dumps(geojson)) + + default_results = list(feature_generator(polygons)) + fiona_results = list(feature_generator(polygons, engine="fiona", chunk_size=2)) + # cannot compare them directly since they differ in tuples vs list representation for some reason # let json roundtrip normalize it assert json.loads(json.dumps(default_results)) == json.loads(