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 }} 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", 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 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(