[Git][debian-gis-team/rio-cogeo][upstream] New upstream version 7.0.3

Antonio Valentino (@antonio.valentino) gitlab at salsa.debian.org
Sat Sep 26 09:56:20 BST 2026



Antonio Valentino pushed to branch upstream at Debian GIS Project / rio-cogeo


Commits:
97266718 by Antonio Valentino at 2026-09-26T08:48:41+00:00
New upstream version 7.0.3
- - - - -


21 changed files:

- + .github/dependabot.yml
- .github/workflows/ci.yml
- .github/workflows/deploy_mkdocs.yml
- .github/workflows/release.yml
- .pre-commit-config.yaml
- CHANGES.md
- docs/docs/API.md
- docs/docs/Advanced.md
- pyproject.toml
- rio_cogeo/__init__.py
- rio_cogeo/cogeo.py
- rio_cogeo/profiles.py
- rio_cogeo/scripts/cli.py
- rio_cogeo/utils.py
- + tests/fixtures/validate/image_2000x128.tif
- + tests/fixtures/validate/image_ovr_non_tiled.tif
- tests/test_cli.py
- tests/test_cogeo.py
- tests/test_validate.py
- tests/test_web.py
- uv.lock


Changes:

=====================================
.github/dependabot.yml
=====================================
@@ -0,0 +1,24 @@
+version: 2
+updates:
+  - package-ecosystem: "github-actions"
+    cooldown:
+      default-days: 3
+    directory: "/"
+    schedule:
+      interval: "weekly"
+      day: "monday"
+    groups:
+      all:
+        patterns:
+        - "*"
+  
+  - package-ecosystem: uv
+    cooldown:
+      default-days: 7
+    directory: "/"
+    schedule:
+      interval: weekly
+    groups:
+      all:
+        patterns:
+        - "*"
\ No newline at end of file


=====================================
.github/workflows/ci.yml
=====================================
@@ -19,10 +19,10 @@ jobs:
         python-version: ['3.11', '3.12', '3.13', '3.14']
 
     steps:
-      - uses: actions/checkout at v5
+      - uses: actions/checkout at 3d3c42e5aac5ba805825da76410c181273ba90b1 # v5
 
       - name: Install uv
-        uses: astral-sh/setup-uv at v7
+        uses: astral-sh/setup-uv at c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
         with:
           version: "0.9.*" 
           enable-cache: true
@@ -42,7 +42,7 @@ jobs:
 
       - name: Upload Results
         if: ${{ matrix.python-version == env.LATEST_PY_VERSION }}
-        uses: codecov/codecov-action at v5
+        uses: codecov/codecov-action at 303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v5
         with:
           files: ./coverage.xml
           flags: unittests


=====================================
.github/workflows/deploy_mkdocs.yml
=====================================
@@ -17,10 +17,10 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout main
-        uses: actions/checkout at v5
+        uses: actions/checkout at 3d3c42e5aac5ba805825da76410c181273ba90b1 # v5
 
       - name: Install uv
-        uses: astral-sh/setup-uv at v7
+        uses: astral-sh/setup-uv at c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
         with:
           version: "0.9.*" 
           enable-cache: true


=====================================
.github/workflows/release.yml
=====================================
@@ -13,10 +13,10 @@ jobs:
     runs-on: ubuntu-latest
     if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
     steps:
-      - uses: actions/checkout at v6
+      - uses: actions/checkout at 3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
 
       - name: Install uv
-        uses: astral-sh/setup-uv at v7
+        uses: astral-sh/setup-uv at c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
         with:
           version: "0.9.*" 
           enable-cache: true
@@ -48,7 +48,7 @@ jobs:
         run: |
           uv run hatch build
 
-      - uses: actions/upload-artifact at v7
+      - uses: actions/upload-artifact at 043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
         with:
           path: ./dist/
 
@@ -62,11 +62,11 @@ jobs:
     permissions:
       id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
     steps:
-      - uses: actions/download-artifact at v8
+      - uses: actions/download-artifact at 3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
         with:
           name: artifact
           path: dist
           merge-multiple: true
 
       - name: Publish package distributions to PyPI
-        uses: pypa/gh-action-pypi-publish at release/v1
+        uses: pypa/gh-action-pypi-publish at dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1


=====================================
.pre-commit-config.yaml
=====================================
@@ -1,29 +1,24 @@
 repos:
   - repo: https://github.com/abravalheri/validate-pyproject
-    rev: v0.24
+    rev: '0.26'
     hooks:
       - id: validate-pyproject
 
-  - repo: https://github.com/psf/black
-    rev: 22.12.0
-    hooks:
-      - id: black
-        language_version: python
-
   - repo: https://github.com/PyCQA/isort
-    rev: 5.12.0
+    rev: 9.0.1
     hooks:
       - id: isort
         language_version: python
 
   - repo: https://github.com/charliermarsh/ruff-pre-commit
-    rev: v0.0.238
+    rev: v0.16.8
     hooks:
       - id: ruff
         args: ["--fix"]
+      - id: ruff-format
 
   - repo: https://github.com/pre-commit/mirrors-mypy
-    rev: v1.19.1
+    rev: v2.3.1
     hooks:
       - id: mypy
         language_version: python


=====================================
CHANGES.md
=====================================
@@ -1,5 +1,9 @@
 # Release Notes
 
+## 7.0.3 (2026-09-24)
+
+* fix: tiling check for datasets exceeding 512px in a single dimension (author @m3zn, https://github.com/cogeotiff/rio-cogeo/pull/332)
+
 ## 7.0.2 (2026-03-27)
 
 * fix: add data_offsets initialization in cog_validate function (author @benboothby, https://github.com/cogeotiff/rio-cogeo/pull/318)
@@ -75,22 +79,11 @@
     output_profile = cog_profiles.get(profile)
 
     tms = morecantile.tms.get("WGS1984Quad")
-    cog_translate(
-        "in.tif",
-        "out.tif",
-        output_profile,
-        web_optimzed=True,
-        tms=tms
-    )
+    cog_translate("in.tif", "out.tif", output_profile, web_optimzed=True, tms=tms)
 
     # now
     tms = morecantile.tms.get("WGS1984Quad")
-    cog_translate(
-        "in.tif",
-        "out.tif",
-        output_profile,
-        tms=tms
-    )
+    cog_translate("in.tif", "out.tif", output_profile, tms=tms)
     ```
 
 * fix COG validation for SPARSE dataset (author @mpadillaruiz, https://github.com/cogeotiff/rio-cogeo/issues/281)


=====================================
docs/docs/API.md
=====================================
@@ -7,6 +7,7 @@ e.g:
 ```python
 from rio_cogeo.cogeo import cog_translate
 
+
 def _translate(src_path, dst_path, profile="webp", profile_options={}, **options):
     """Convert image to COG."""
     # Format creation option (see gdalwarp `-co` option)
@@ -50,7 +51,7 @@ from rio_cogeo.cogeo import cog_translate
 from rio_cogeo.profiles import cog_profiles
 
 # Create GeoTIFF profile
-bounds = mercantile.bounds(mercantile.Tile(0,0,0))
+bounds = mercantile.bounds(mercantile.Tile(0, 0, 0))
 
 # Rasterio uses numpy array of shape of `(bands, height, width)`
 width = 1024
@@ -126,7 +127,6 @@ config = {
 
 
 with open("logfile.txt", "w+") as buffer:
-
     # Progress output buffer must be interactive
     buffer.isatty = lambda: True
 
@@ -148,7 +148,8 @@ translation is using the text buffer.
 ```python
 import re
 
-def getPercentage(buffer:str) -> float:
+
+def getPercentage(buffer: str) -> float:
     return int(re.findall("\d*%", buffer)[-1].replace("%", "")) / 100
 ```
 


=====================================
docs/docs/Advanced.md
=====================================
@@ -36,7 +36,7 @@ power of two:
 
 ```python
 overview_level = 3
-overviews = [2 ** j for j in range(1, overview_level + 1)]
+overviews = [2**j for j in range(1, overview_level + 1)]
 print(overviews)
 [2, 4, 8]
 ```
@@ -48,7 +48,7 @@ As described above, a decimation base of 2 is used by default. However you can p
 ```python
 overview_level = 3
 decimation_base = 3
-overviews = [decimation_base ** j for j in range(1, overview_level + 1)]
+overviews = [decimation_base**j for j in range(1, overview_level + 1)]
 print(overviews)
 [3, 9, 27]
 ```


=====================================
pyproject.toml
=====================================
@@ -32,7 +32,6 @@ dev = [
     "pytest",
     "pytest-cov",    
     "pre-commit",
-    "bump-my-version",
 ]
 docs = [
     "mkdocs",
@@ -83,7 +82,7 @@ default_section = "THIRDPARTY"
 no_strict_optional = "True"
 ignore_missing_imports = "True"
 
-[tool.ruff]
+[tool.ruff.lint]
 select = [
     "D1",  # pydocstyle errors
     "E",  # pycodestyle errors
@@ -99,7 +98,7 @@ ignore = [
 ]
 
 [tool.bumpversion]
-current_version = "7.0.2"
+current_version = "7.0.3"
 search = "{current_version}"
 replace = "{new_version}"
 tag = true


=====================================
rio_cogeo/__init__.py
=====================================
@@ -1,6 +1,6 @@
 """rio_cogeo: Cloud Optimized GeoTIFF creation and validation plugin for rasterio."""
 
-__version__ = "7.0.2"
+__version__ = "7.0.3"
 
 from .cogeo import cog_info, cog_translate, cog_validate  # noqa
 from .profiles import cog_profiles  # noqa


=====================================
rio_cogeo/cogeo.py
=====================================
@@ -190,6 +190,7 @@ def cog_translate(  # noqa: C901
         warnings.warn(
             "'web_optomized' option is deprecated and will be removed in 6.0. Please use the `tms` option",
             DeprecationWarning,
+            stacklevel=2,
         )
         tms = tms or morecantile.tms.get("WebMercatorQuad")
 
@@ -226,6 +227,7 @@ def cog_translate(  # noqa: C901
                 warnings.warn(
                     "Input dataset has both a nodata value and internal alpha/mask band. Nodata value will be prioritized.",
                     NodataAlphaMaskWarning,
+                    stacklevel=2,
                 )
 
             if colormap and len(indexes) > 1:
@@ -246,6 +248,7 @@ def cog_translate(  # noqa: C901
             ):
                 warnings.warn(
                     "Nodata/Alpha band will be translated to an internal mask band.",
+                    stacklevel=2,
                 )
                 add_mask = True
                 indexes = (
@@ -311,7 +314,8 @@ def cog_translate(  # noqa: C901
                 ):
                     warnings.warn(
                         "PHOTOMETRIC=YCBCR not supported on a 1-band raster"
-                        " and has been set to 'MINISBLACK'"
+                        " and has been set to 'MINISBLACK'",
+                        stacklevel=2,
                     )
                     dst_kwargs["photometric"] = "MINISBLACK"
 
@@ -346,7 +350,8 @@ def cog_translate(  # noqa: C901
                     if tmp_dst.colorinterp[0] is not ColorInterp.palette:
                         tmp_dst.colorinterp = [ColorInterp.palette]
                         warnings.warn(
-                            "Dataset color interpretation was set to `Palette`"
+                            "Dataset color interpretation was set to `Palette`",
+                            stacklevel=2,
                         )
                     tmp_dst.write_colormap(1, colormap)
 
@@ -356,7 +361,8 @@ def cog_translate(  # noqa: C901
                     except ValueError:
                         warnings.warn(
                             "Dataset has `Palette` color interpretation"
-                            " but is missing colormap information"
+                            " but is missing colormap information",
+                            stacklevel=2,
                         )
 
                 wind = list(tmp_dst.block_windows(1))
@@ -449,7 +455,8 @@ def cog_translate(  # noqa: C901
 
                     if add_mask and dst_kwargs.get("compress", "") != "JPEG":
                         warnings.warn(
-                            "With GDAL COG driver, mask band will be translated to an alpha band."
+                            "With GDAL COG driver, mask band will be translated to an alpha band.",
+                            stacklevel=2,
                         )
                     if overview_level == 0:
                         dst_kwargs["overviews"] = "NONE"
@@ -524,7 +531,7 @@ def cog_validate(  # noqa: C901
                 )
 
             overviews = src.overviews(1)
-            if src.width > 512 and src.height > 512:
+            if src.width > 512 or src.height > 512:
                 if src.block_shapes and src.block_shapes[0][1] == src.width:
                     errors.append(
                         "The file is greater than 512xH or 512xW, but is not tiled"
@@ -574,7 +581,6 @@ def cog_validate(  # noqa: C901
                 errors.append("Overviews should be sorted")
 
             for ix, dec in enumerate(overviews):
-
                 # NOTE: Size check is handled in rasterio `src.overviews` methods
                 # https://github.com/mapbox/rasterio/blob/4ebdaa08cdcc65b141ed3fe95cf8bbdd9117bc0b/rasterio/_base.pyx
                 # We just need to make sure the decimation level is > 1
@@ -631,7 +637,6 @@ def cog_validate(  # noqa: C901
                 break
 
             for ix, _dec in enumerate(overviews):
-
                 # Get the width and height of the overview
                 overview_width = src.width // (_dec)
                 overview_height = src.height // (_dec)
@@ -646,9 +651,9 @@ def cog_validate(  # noqa: C901
                         if data_offset > 0:
                             data_offset = int(data_offset) if data_offset else 0
                             data_offsets.append(data_offset)
-                            details["data_offsets"][
-                                "overview_{}".format(ix)
-                            ] = data_offset
+                            details["data_offsets"]["overview_{}".format(ix)] = (
+                                data_offset
+                            )
                             break
                     else:
                         continue
@@ -683,7 +688,7 @@ def cog_validate(  # noqa: C901
 
         for ix, _dec in enumerate(overviews):
             with rasterio.open(src_path, OVERVIEW_LEVEL=ix) as ovr_dst:
-                if ovr_dst.width > 512 and ovr_dst.height > 512:
+                if ovr_dst.width > 512 or ovr_dst.height > 512:
                     if (
                         ovr_dst.block_shapes
                         and ovr_dst.block_shapes[0][1] == ovr_dst.width


=====================================
rio_cogeo/profiles.py
=====================================
@@ -181,7 +181,8 @@ class COGProfiles(dict):
         if key in ["zstd", "webp", "lerc", "lerc_deflate", "lerc_zstd"]:
             warnings.warn(
                 "Non-standard compression schema: {}. The output COG might not be fully"
-                " supported by software not build against latest libtiff.".format(key)
+                " supported by software not build against latest libtiff.".format(key),
+                stacklevel=2,
             )
 
         return self[key].copy()


=====================================
rio_cogeo/scripts/cli.py
=====================================
@@ -382,16 +382,14 @@ def info(input, to_json, config):  # noqa: C901
     if to_json:
         click.echo(metadata.model_dump_json(exclude_none=True, by_alias=True))
     else:
-
         sep = 25
-        click.echo(
-            f"""{click.style('Driver:', bold=True)} {metadata.Driver}
-{click.style('File:', bold=True)} {metadata.Path}
-{click.style('COG:', bold=True)} {metadata.COG}
-{click.style('Compression:', bold=True)} {metadata.Compression}
-{click.style('ColorSpace:', bold=True)} {metadata.ColorSpace}
+        click.echo(f"""{click.style("Driver:", bold=True)} {metadata.Driver}
+{click.style("File:", bold=True)} {metadata.Path}
+{click.style("COG:", bold=True)} {metadata.COG}
+{click.style("Compression:", bold=True)} {metadata.Compression}
+{click.style("ColorSpace:", bold=True)} {metadata.ColorSpace}
 
-{click.style('Profile', bold=True)}
+{click.style("Profile", bold=True)}
     {click.style("Width:", bold=True):<{sep}} {metadata.Profile.Width}
     {click.style("Height:", bold=True):<{sep}} {metadata.Profile.Height}
     {click.style("Bands:", bold=True):<{sep}} {metadata.Profile.Bands}
@@ -404,35 +402,28 @@ def info(input, to_json, config):  # noqa: C901
     {click.style("ColorMap:", bold=True):<{sep}} {metadata.Profile.ColorMap}
     {click.style("ColorInterp:", bold=True):<{sep}} {metadata.Profile.ColorInterp}
     {click.style("Scales:", bold=True):<{sep}} {metadata.Profile.Scales}
-    {click.style("Offsets:", bold=True):<{sep}} {metadata.Profile.Offsets}"""
-        )
+    {click.style("Offsets:", bold=True):<{sep}} {metadata.Profile.Offsets}""")
 
-        click.echo(
-            f"""
-{click.style('Geo', bold=True)}
+        click.echo(f"""
+{click.style("Geo", bold=True)}
     {click.style("Crs:", bold=True):<{sep}} {metadata.GEO.CRS}
     {click.style("Origin:", bold=True):<{sep}} {metadata.GEO.Origin}
     {click.style("Resolution:", bold=True):<{sep}} {metadata.GEO.Resolution}
     {click.style("BoundingBox:", bold=True):<{sep}} {metadata.GEO.BoundingBox}
     {click.style("MinZoom:", bold=True):<{sep}} {metadata.GEO.MinZoom}
-    {click.style("MaxZoom:", bold=True):<{sep}} {metadata.GEO.MaxZoom}"""
-        )
+    {click.style("MaxZoom:", bold=True):<{sep}} {metadata.GEO.MaxZoom}""")
 
         for ns, values in metadata.Tags.items():
-            click.echo(
-                f"""
-{click.style(ns, bold=True)}"""
-            )
+            click.echo(f"""
+{click.style(ns, bold=True)}""")
             for key, val in values.items():
                 click.echo(
                     f"""    {click.style(key, underline=True, bold=True)}: {val}"""
                 )
 
         for ns, meta in metadata.Band_Metadata.items():
-            click.echo(
-                f"""
-{click.style(ns, bold=True)}"""
-            )
+            click.echo(f"""
+{click.style(ns, bold=True)}""")
 
             if meta.Description:
                 click.echo(
@@ -460,8 +451,8 @@ def info(input, to_json, config):  # noqa: C901
 
         click.echo(
             f"""
-{click.style('IFD', bold=True)}
-    {click.style('Id', underline=True, bold=True):<20}{click.style('Size', underline=True, bold=True):<27}{click.style('BlockSize', underline=True, bold=True):<26}{click.style('Decimation', underline=True, bold=True)}"""
+{click.style("IFD", bold=True)}
+    {click.style("Id", underline=True, bold=True):<20}{click.style("Size", underline=True, bold=True):<27}{click.style("BlockSize", underline=True, bold=True):<26}{click.style("Decimation", underline=True, bold=True)}"""
         )
 
         for ifd in metadata.IFD:
@@ -470,10 +461,8 @@ def info(input, to_json, config):  # noqa: C901
             click.echo(f"""    {ifd.Level:<8}{wh:<15}{bl:<14}{ifd.Decimation}""")
 
         if metadata.COG_errors or metadata.COG_warnings:
-            click.echo(
-                f"""
-{click.style('COG Validation info', bold=True)}"""
-            )
+            click.echo(f"""
+{click.style("COG Validation info", bold=True)}""")
             for error in metadata.COG_errors or []:
                 click.secho(f"""    - {error} (error)""", fg="red")
             for warning in metadata.COG_warnings or []:


=====================================
rio_cogeo/utils.py
=====================================
@@ -14,7 +14,7 @@ from rasterio.warp import calculate_default_transform
 def has_alpha_band(src_dst: Union[DatasetReader, DatasetWriter, WarpedVRT]):
     """Check for alpha band or mask in source."""
     if (
-        any([MaskFlags.alpha in flags for flags in src_dst.mask_flag_enums])
+        any(MaskFlags.alpha in flags for flags in src_dst.mask_flag_enums)
         or ColorInterp.alpha in src_dst.colorinterp
     ):
         return True
@@ -24,10 +24,8 @@ def has_alpha_band(src_dst: Union[DatasetReader, DatasetWriter, WarpedVRT]):
 def has_mask_band(src_dst):
     """Check for mask band in source."""
     if any(
-        [
-            (MaskFlags.per_dataset in flags and MaskFlags.alpha not in flags)
-            for flags in src_dst.mask_flag_enums
-        ]
+        (MaskFlags.per_dataset in flags and MaskFlags.alpha not in flags)
+        for flags in src_dst.mask_flag_enums
     ):
         return True
     return False


=====================================
tests/fixtures/validate/image_2000x128.tif
=====================================
Binary files /dev/null and b/tests/fixtures/validate/image_2000x128.tif differ


=====================================
tests/fixtures/validate/image_ovr_non_tiled.tif
=====================================
Binary files /dev/null and b/tests/fixtures/validate/image_ovr_non_tiled.tif differ


=====================================
tests/test_cli.py
=====================================
@@ -47,7 +47,7 @@ def test_cogeo_valid(runner):
             assert src.height == 512
             assert src.width == 512
             assert src.meta["dtype"] == "uint8"
-            assert all([(512, 512) == (h, w) for (h, w) in src.block_shapes])
+            assert all((512, 512) == (h, w) for (h, w) in src.block_shapes)
             assert src.compression.value == "DEFLATE"
             assert not src.photometric
             assert src.interleaving.value == "PIXEL"
@@ -206,7 +206,7 @@ def test_cogeo_validOvrOption(runner):
         assert not result.exception
         assert result.exit_code == 0
         with rasterio.open("output.tif") as src:
-            assert all([(512, 512) == (h, w) for (h, w) in src.block_shapes])
+            assert all((512, 512) == (h, w) for (h, w) in src.block_shapes)
             assert src.overviews(1) == [2, 4]
 
 
@@ -251,7 +251,7 @@ def test_cogeo_overviewTilesize(monkeypatch, runner):
         assert not result.exception
         assert result.exit_code == 0
         with rasterio.open("output.tif") as src:
-            assert all([(128, 128) == (h, w) for (h, w) in src.block_shapes])
+            assert all((128, 128) == (h, w) for (h, w) in src.block_shapes)
             assert src.overviews(1)
 
         with rasterio.open("output.tif", OVERVIEW_LEVEL=1) as src:
@@ -265,7 +265,7 @@ def test_cogeo_overviewTilesize(monkeypatch, runner):
         assert not result.exception
         assert result.exit_code == 0
         with rasterio.open("output.tif") as src:
-            assert all([(128, 128) == (h, w) for (h, w) in src.block_shapes])
+            assert all((128, 128) == (h, w) for (h, w) in src.block_shapes)
             assert src.overviews(1)
 
         with rasterio.open("output.tif", OVERVIEW_LEVEL=1) as src:
@@ -355,7 +355,7 @@ def test_cogeo_validgdalBlockOption(runner):
         assert not result.exception
         assert result.exit_code == 0
         with rasterio.open("output.tif") as src:
-            assert all([(128, 128) == (h, w) for (h, w) in src.block_shapes])
+            assert all((128, 128) == (h, w) for (h, w) in src.block_shapes)
             assert src.overviews(1) == [2, 4]
 
 


=====================================
tests/test_cogeo.py
=====================================
@@ -63,7 +63,7 @@ def _validate_translated_rgb_jpeg(src):
     assert src.height == 512
     assert src.width == 512
     assert src.meta["dtype"] == "uint8"
-    assert all([(64, 64) == (h, w) for (h, w) in src.block_shapes])
+    assert all((64, 64) == (h, w) for (h, w) in src.block_shapes)
     assert src.profile["blockxsize"] == 64
     assert src.profile["blockysize"] == 64
     assert src.compression == "YCbCr JPEG" or src.compression.value == "JPEG"
@@ -132,7 +132,7 @@ def test_cog_translate_validRaw(runner):
         with rasterio.open("cogeo.tif") as src:
             assert src.height == 512
             assert src.width == 512
-            assert all([(64, 64) == (h, w) for (h, w) in src.block_shapes])
+            assert all((64, 64) == (h, w) for (h, w) in src.block_shapes)
             assert not src.compression
             assert src.interleaving.value == "PIXEL"
 
@@ -166,7 +166,7 @@ def test_cog_translate_validAlpha(runner):
             assert src.height == 512
             assert src.width == 512
             assert src.meta["dtype"] == "uint8"
-            assert all([(64, 64) == (h, w) for (h, w) in src.block_shapes])
+            assert all((64, 64) == (h, w) for (h, w) in src.block_shapes)
             assert src.compression.value == "WEBP"
             assert has_alpha_band(src)
 
@@ -209,9 +209,10 @@ def test_cog_translate_validAlpha(runner):
             cog_profiles.get("deflate"),
             quiet=True,
         )
-        with rasterio.open("cogeo.tif") as cog, rasterio.open(
-            raster_path_rgba
-        ) as source:
+        with (
+            rasterio.open("cogeo.tif") as cog,
+            rasterio.open(raster_path_rgba) as source,
+        ):
             assert cog.read(1, masked=True).max() == source.read(1, masked=True).max()
             assert cog.count == source.count
             assert cog.colorinterp == source.colorinterp
@@ -223,9 +224,10 @@ def test_cog_translate_validAlpha(runner):
             quiet=True,
             add_mask=True,
         )
-        with rasterio.open("cogeo.tif") as cog, rasterio.open(
-            raster_path_rgba
-        ) as source:
+        with (
+            rasterio.open("cogeo.tif") as cog,
+            rasterio.open(raster_path_rgba) as source,
+        ):
             assert cog.read(1, masked=True).max() == source.read(1, masked=True).max()
             assert cog.count <= source.count
             assert cog.colorinterp != source.colorinterp
@@ -297,7 +299,7 @@ def test_cog_translate_validCustom(runner):
             assert src.height == 512
             assert src.width == 512
             assert src.meta["dtype"] == "uint8"
-            assert all([(256, 256) == (h, w) for (h, w) in src.block_shapes])
+            assert all((256, 256) == (h, w) for (h, w) in src.block_shapes)
             assert src.compression == "YCbCr JPEG" or src.compression.value == "JPEG"
             assert src.profile["blockxsize"] == 256
             assert src.profile["blockysize"] == 256
@@ -310,9 +312,10 @@ def test_cog_translate_mask(runner):
     """Should work as expected (copy mask from input)."""
     with runner.isolated_filesystem():
         cog_translate(raster_path_mask, "cogeo.tif", jpeg_profile, quiet=True)
-        with rasterio.open("cogeo.tif") as cog, rasterio.open(
-            raster_path_mask
-        ) as source:
+        with (
+            rasterio.open("cogeo.tif") as cog,
+            rasterio.open(raster_path_mask) as source,
+        ):
             assert cog.read(1, masked=True).max() == source.read(1, masked=True).max()
             assert cog.count == source.count
             assert cog.colorinterp == source.colorinterp
@@ -366,7 +369,7 @@ def test_cog_translate_valid_blocksize(runner):
         with rasterio.open("cogeo.tif") as src:
             assert src.height == 171
             assert src.width == 171
-            all([(128, 128) == (h, w) for (h, w) in src.block_shapes])
+            assert all((128, 128) == (h, w) for (h, w) in src.block_shapes)
             assert src.profile["blockxsize"] == 128
             assert src.profile["blockysize"] == 128
             assert src.overviews(1) == [2]
@@ -376,7 +379,7 @@ def test_cog_translate_valid_blocksize(runner):
         with rasterio.open("cogeo.tif") as src:
             assert src.height == 51
             assert src.width == 51
-            assert all([(512, 512) == (h, w) for (h, w) in src.block_shapes])
+            assert all((512, 512) == (h, w) for (h, w) in src.block_shapes)
             assert src.profile.get("blockxsize") == 512
             assert src.profile.get("blockysize") == 512
             assert not src.overviews(1)
@@ -674,9 +677,11 @@ def test_gdal_cog_compare(runner):
             quiet=True,
         )
 
-        with rasterio.open("riocogeo.tif") as riocogeo, rasterio.open(
-            "gdalcogeo.tif"
-        ) as gdalcogeo, rasterio.open("cog.tif") as cog:
+        with (
+            rasterio.open("riocogeo.tif") as riocogeo,
+            rasterio.open("gdalcogeo.tif") as gdalcogeo,
+            rasterio.open("cog.tif") as cog,
+        ):
             assert cog.profile == gdalcogeo.profile == riocogeo.profile
             assert cog.overviews(1) == gdalcogeo.overviews(1) == riocogeo.overviews(1)
 
@@ -712,9 +717,10 @@ def test_gdal_cog_compareWeb(runner):
             TILING_SCHEME_ALIGNED_LEVELS="2",
         )
 
-        with rasterio.open("gdalcogeo.tif") as gdalcogeo, rasterio.open(
-            "cog.tif"
-        ) as cog:
+        with (
+            rasterio.open("gdalcogeo.tif") as gdalcogeo,
+            rasterio.open("cog.tif") as cog,
+        ):
             cog_meta = cog.meta
             _ = cog_meta.pop("transform")
 
@@ -820,7 +826,6 @@ def test_cog_translate_forward_ns_metadata(runner):
 def test_cog_translate_decimation_base(runner):
     """Should create proper overviews when using custom decimation base."""
     with runner.isolated_filesystem():
-
         base_level_pairs = [(3, 6), (4, 5), (5, 4)]
 
         for decimation_base, overview_level in base_level_pairs:
@@ -847,9 +852,10 @@ def test_cog_translate_gcps(runner):
             quiet=True,
         )
 
-        with rasterio.open("cogeo.tif") as cog, rasterio.open(
-            raster_path_gcps
-        ) as source:
+        with (
+            rasterio.open("cogeo.tif") as cog,
+            rasterio.open(raster_path_gcps) as source,
+        ):
             assert cog.read(1).max() == source.read(1).max()
             assert not cog.count == source.count
 
@@ -870,9 +876,10 @@ def test_cog_translate_gcps(runner):
             quiet=True,
         )
 
-        with rasterio.open("cogeo.tif") as cog, rasterio.open(
-            raster_path_gcps
-        ) as source:
+        with (
+            rasterio.open("cogeo.tif") as cog,
+            rasterio.open(raster_path_gcps) as source,
+        ):
             assert cog.read(1).max() == source.read(1).max()
             assert cog.count == source.count
             assert cog.count == 1


=====================================
tests/test_validate.py
=====================================
@@ -32,6 +32,10 @@ raster_known_incompatible = os.path.join(
     fixture_dir, "validate", "image_known_incompatible_ghost_headers.tif"
 )
 
+raster_big_width = os.path.join(fixture_dir, "validate", "image_2000x128.tif")
+# Tiled 2000x128 with non tiled 1000x64 overview
+raster_ovr_non_tiled = os.path.join(fixture_dir, "validate", "image_ovr_non_tiled.tif")
+
 jpeg_profile = cog_profiles.get("jpeg")
 jpeg_profile.update({"blockxsize": 256, "blockysize": 256})
 
@@ -46,6 +50,16 @@ def test_cog_validate_valid(monkeypatch):
     # not tiled, no overview
     assert not cog_validate(raster_big, quiet=True, config=config)[0]
 
+    assert (
+        "The file is greater than 512xH or 512xW, but is not tiled"
+        in cog_validate(raster_big_width, quiet=True, config=config)[1]
+    )
+
+    # tiled, non tiled overview
+    assert (
+        "Overview of index 0 is not tiled"
+        in cog_validate(raster_ovr_non_tiled, quiet=True, config=config)[1]
+    )
     # external overview
     assert not cog_validate(raster_external, config=config)[0]
 


=====================================
tests/test_web.py
=====================================
@@ -82,7 +82,6 @@ def test_cog_translate_web():
 
     runner = CliRunner()
     with runner.isolated_filesystem():
-
         web_profile = cog_profiles.get("raw")
         web_profile.update({"blockxsize": 256, "blockysize": 256})
         config = {"GDAL_TIFF_OVR_BLOCKSIZE": "256"}
@@ -171,7 +170,6 @@ def test_cog_translate_Internal():
 
     runner = CliRunner()
     with runner.isolated_filesystem():
-
         web_profile = cog_profiles.get("raw")
         web_profile.update({"blockxsize": 256, "blockysize": 256})
         config = {"GDAL_TIFF_OVR_BLOCKSIZE": "256"}
@@ -249,7 +247,6 @@ def test_cog_translate_web_align():
 
     runner = CliRunner()
     with runner.isolated_filesystem():
-
         web_profile = cog_profiles.get("raw")
         web_profile.update({"blockxsize": 256, "blockysize": 256})
         config = {"GDAL_TIFF_OVR_BLOCKSIZE": "256"}
@@ -332,9 +329,10 @@ def test_cog_translate_web_geos():
             use_cog_driver=True,
             config=config,
         )
-        with rasterio.open("cogeo.tif") as cog_dst, rasterio.open(
-            "cogeo_gdal.tif"
-        ) as cog_gdal:
+        with (
+            rasterio.open("cogeo.tif") as cog_dst,
+            rasterio.open("cogeo_gdal.tif") as cog_gdal,
+        ):
             assert cog_dst.shape == cog_gdal.shape
             for i in range(0, 4):
                 assert round(cog_dst.bounds[i], 5) == round(cog_gdal.bounds[i], 5)
@@ -345,7 +343,6 @@ def test_web_align_cogeo_gdal():
     """Test Web-Optimized COG conformance with GDAL."""
     runner = CliRunner()
     with runner.isolated_filesystem():
-
         web_tms = morecantile.tms.get("WebMercatorQuad")
 
         web_profile = cog_profiles.get("raw")
@@ -369,9 +366,10 @@ def test_web_align_cogeo_gdal():
             config=config,
             use_cog_driver=True,
         )
-        with rasterio.open("cogeo.tif") as cog_dst, rasterio.open(
-            "cogeo_gdal.tif"
-        ) as cog_gdal:
+        with (
+            rasterio.open("cogeo.tif") as cog_dst,
+            rasterio.open("cogeo_gdal.tif") as cog_gdal,
+        ):
             assert cog_dst.shape == cog_gdal.shape
             for i in range(0, 4):
                 assert round(cog_dst.bounds[i], 5) == round(cog_gdal.bounds[i], 5)
@@ -397,9 +395,10 @@ def test_web_align_cogeo_gdal():
             use_cog_driver=True,
         )
 
-        with rasterio.open("cogeo.tif") as cog_dst, rasterio.open(
-            "cogeo_gdal.tif"
-        ) as cog_gdal:
+        with (
+            rasterio.open("cogeo.tif") as cog_dst,
+            rasterio.open("cogeo_gdal.tif") as cog_gdal,
+        ):
             assert cog_dst.shape == cog_gdal.shape
             for i in range(0, 4):
                 assert round(cog_dst.bounds[i], 5) == round(cog_gdal.bounds[i], 5)


=====================================
uv.lock
=====================================
The diff for this file was not included because it is too large.


View it on GitLab: https://salsa.debian.org/debian-gis-team/rio-cogeo/-/commit/9726671893345836b66d22d0ab672cf7f88a53e2

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/rio-cogeo/-/commit/9726671893345836b66d22d0ab672cf7f88a53e2
You're receiving this email because of your account on salsa.debian.org. Manage all notifications: https://salsa.debian.org/-/profile/notifications | Help: https://salsa.debian.org/help


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20260926/e3ec5bf5/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list