From 4b2ad1661d481b5224a33bbb140a306dad7adccb Mon Sep 17 00:00:00 2001 From: Jonas Kittner Date: Tue, 22 Oct 2024 19:38:39 +0200 Subject: [PATCH] make terracotta python 3.12 compatible fix deprecation/removal of pkg_resources and rasterio is_tiled --- .github/workflows/test.yml | 4 ++-- setup.py | 2 ++ terracotta/cmaps/get_cmaps.py | 15 +++++++++------ terracotta/cog.py | 10 ++++++++-- tests/cmaps/test_get_cmap.py | 15 ++++++++++----- 5 files changed, 31 insertions(+), 15 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 04d2ab55..458492e8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -24,7 +24,7 @@ jobs: matrix: os: [ubuntu-latest] - python-version: ["3.8", "3.11"] + python-version: ["3.8", "3.12"] defaults: run: @@ -107,7 +107,7 @@ jobs: matrix: os: [macos-latest, windows-latest] - python-version: ["3.8", "3.11"] + python-version: ["3.8", "3.12"] defaults: run: diff --git a/setup.py b/setup.py index f415947c..e3742465 100644 --- a/setup.py +++ b/setup.py @@ -42,6 +42,7 @@ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Framework :: Flask", "Operating System :: Microsoft :: Windows :: Windows 10", "Operating System :: MacOS :: MacOS X", @@ -69,6 +70,7 @@ "click-spinner", "flask", "flask_cors", + "importlib_resources; python_version<'3.9'", "marshmallow>=3.0.0", "mercantile", "numpy%s" % numpy_version, diff --git a/terracotta/cmaps/get_cmaps.py b/terracotta/cmaps/get_cmaps.py index 9c119d96..355e9044 100644 --- a/terracotta/cmaps/get_cmaps.py +++ b/terracotta/cmaps/get_cmaps.py @@ -5,18 +5,21 @@ from typing import Dict import os -from pkg_resources import resource_filename, Requirement, DistributionNotFound - import numpy as np +import sys + +if sys.version_info >= (3, 9): + import importlib.resources as importlib_resources +else: + import importlib_resources + SUFFIX = "_rgba.npy" EXTRA_CMAP_FOLDER = os.environ.get("TC_EXTRA_CMAP_FOLDER", "") try: - PACKAGE_DIR = resource_filename( - Requirement.parse("terracotta"), "terracotta/cmaps/data" - ) -except DistributionNotFound: + PACKAGE_DIR = str(importlib_resources.files("terracotta") / "cmaps/data") +except ModuleNotFoundError: # terracotta was not installed, fall back to file system PACKAGE_DIR = os.path.join(os.path.dirname(__file__), "data") diff --git a/terracotta/cog.py b/terracotta/cog.py index b0fe8ce5..0e9b5cb1 100644 --- a/terracotta/cog.py +++ b/terracotta/cog.py @@ -51,7 +51,10 @@ def check_raster_file(src_path: str) -> ValidationInfo: # pragma: no cover overviews = src.overviews(1) if src.width > 512 and src.height > 512: - if not src.is_tiled: + if not ( + src.block_shapes + and all(src.width != w for _, w in src.block_shapes) + ): errors.append( "The file is greater than 512xH or 512xW, but is not tiled" ) @@ -166,7 +169,10 @@ def check_raster_file(src_path: str) -> ValidationInfo: # pragma: no cover 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 not ovr_dst.is_tiled: + if not ( + ovr_dst.block_shapes + and all(ovr_dst.width != w for _, w in ovr_dst.block_shapes) + ): errors.append("Overview of index {} is not tiled".format(ix)) return errors, warnings, details diff --git a/tests/cmaps/test_get_cmap.py b/tests/cmaps/test_get_cmap.py index c81f15ca..b9095e37 100755 --- a/tests/cmaps/test_get_cmap.py +++ b/tests/cmaps/test_get_cmap.py @@ -1,6 +1,12 @@ import pytest import numpy as np +import sys + +if sys.version_info >= (3, 9): + import importlib.resources as importlib_resources +else: + import importlib_resources @pytest.fixture(autouse=True) @@ -24,19 +30,18 @@ def test_get_cmap(): def test_get_cmap_filesystem(monkeypatch): - import pkg_resources import importlib import terracotta.cmaps.get_cmaps def throw_error(*args, **kwargs): - raise pkg_resources.DistributionNotFound("monkeypatched") + raise ModuleNotFoundError with monkeypatch.context() as m: - m.setattr(pkg_resources.Requirement, "parse", throw_error) + m.setattr(importlib_resources, "files", throw_error) - with pytest.raises(pkg_resources.DistributionNotFound): - pkg_resources.Requirement.parse("terracotta") + with pytest.raises(ModuleNotFoundError): + importlib_resources.files("terracotta") importlib.reload(terracotta.cmaps.get_cmaps)