From 024a37c65accdd450a4ae70dde6ba06bba9e2c7b Mon Sep 17 00:00:00 2001 From: Ziga Luksic Date: Fri, 27 Sep 2024 09:44:28 +0200 Subject: [PATCH 1/3] update files for release --- .pre-commit-config.yaml | 6 +++--- CHANGELOG.md | 4 ++++ eolearn/__init__.py | 2 +- eolearn/core/constants.py | 12 ++++++------ eolearn/core/utils/raster.py | 2 +- eolearn/features/utils.py | 15 +++++++-------- eolearn/visualization/eopatch.py | 2 +- examples/land-cover-map/SI_LULC_pipeline.ipynb | 2 +- pyproject.toml | 14 +++++++------- tests/features/test_features_utils.py | 2 +- tests/io/test_sentinelhub_process.py | 4 ++-- tests/visualization/test_eopatch.py | 2 +- 12 files changed, 35 insertions(+), 32 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fd66ebdcc..1410e559c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,18 +13,18 @@ repos: - id: debug-statements - repo: https://github.com/psf/black - rev: 24.4.2 + rev: 24.8.0 hooks: - id: black language_version: python3 - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: "v0.4.9" + rev: "v0.6.8" hooks: - id: ruff - repo: https://github.com/nbQA-dev/nbQA - rev: 1.8.5 + rev: 1.8.7 hooks: - id: nbqa-black - id: nbqa-ruff diff --git a/CHANGELOG.md b/CHANGELOG.md index 717e53d20..1c627b829 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [Version 1.5.7] - 2024-09-27 + +- Remove `numpy<2` restriction. + ## [Version 1.5.6] - 2024-06-26 - Limit `geopandas` version to < 1.0.0 diff --git a/eolearn/__init__.py b/eolearn/__init__.py index 8e917b72d..81a347728 100644 --- a/eolearn/__init__.py +++ b/eolearn/__init__.py @@ -1,6 +1,6 @@ """Main module of the `eolearn` package.""" -__version__ = "1.5.6" +__version__ = "1.5.7" import importlib.util import warnings diff --git a/eolearn/core/constants.py b/eolearn/core/constants.py index 3205577e0..d3a22e3da 100644 --- a/eolearn/core/constants.py +++ b/eolearn/core/constants.py @@ -46,13 +46,13 @@ def _warn_and_adjust(name: T) -> T: class EnumWithDeprecations(EnumMeta): """A custom EnumMeta class for catching the deprecated Enum members of the FeatureType Enum class.""" - def __getattribute__(cls, name: str) -> Any: # noqa: N805 + def __getattribute__(cls, name: str) -> Any: return super().__getattribute__(_warn_and_adjust(name)) - def __getitem__(cls, name: str) -> Any: # noqa: N805 + def __getitem__(cls, name: str) -> Any: return super().__getitem__(_warn_and_adjust(name)) - def __call__(cls, value: str, *args: Any, **kwargs: Any) -> Any: # noqa: N805 + def __call__(cls, value: str, *args: Any, **kwargs: Any) -> Any: return super().__call__(_warn_and_adjust(value), *args, **kwargs) @@ -238,13 +238,13 @@ def _warn_and_adjust_permissions(name: T) -> T: class PermissionsWithDeprecations(EnumMeta): """A custom EnumMeta class for catching the deprecated Enum members of the OverwritePermission Enum class.""" - def __getattribute__(cls, name: str) -> Any: # noqa: N805 + def __getattribute__(cls, name: str) -> Any: return super().__getattribute__(_warn_and_adjust_permissions(name)) - def __getitem__(cls, name: str) -> Any: # noqa: N805 + def __getitem__(cls, name: str) -> Any: return super().__getitem__(_warn_and_adjust_permissions(name)) - def __call__(cls, value: str, *args: Any, **kwargs: Any) -> Any: # noqa: N805 + def __call__(cls, value: str, *args: Any, **kwargs: Any) -> Any: return super().__call__(_warn_and_adjust_permissions(value), *args, **kwargs) diff --git a/eolearn/core/utils/raster.py b/eolearn/core/utils/raster.py index c7abfe1fc..0e55b07b8 100644 --- a/eolearn/core/utils/raster.py +++ b/eolearn/core/utils/raster.py @@ -112,7 +112,7 @@ def constant_pad( # noqa: C901 else: raise ValueError("Padding rule for columns not supported. Choose between even, left or right!") - return np.lib.pad( + return np.pad( array, ((row_padding_up, row_padding_down), (col_padding_left, col_padding_right)), "constant", diff --git a/eolearn/features/utils.py b/eolearn/features/utils.py index 0c67d1675..e9c6b881a 100644 --- a/eolearn/features/utils.py +++ b/eolearn/features/utils.py @@ -12,7 +12,7 @@ import warnings from enum import Enum from functools import partial -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Callable import cv2 import numpy as np @@ -86,6 +86,8 @@ class ResizeLib(Enum): def get_compatible_dtype(self, dtype: np.dtype | type) -> np.dtype: """Returns a suitable dtype with which the library can work. Warns if information loss could occur.""" + lossless: dict[type, type] + infoloss: dict[type, type] if self is ResizeLib.CV2: lossless = {bool: np.uint8, np.float16: np.float32} infoloss = {x: np.int32 for x in (np.uint32, np.int64, np.uint64, int)} @@ -93,8 +95,8 @@ def get_compatible_dtype(self, dtype: np.dtype | type) -> np.dtype: lossless = {np.float16: np.float32} infoloss = {x: np.int32 for x in (np.uint16, np.uint32, np.int64, np.uint64, int)} - lossless_casts = {np.dtype(k): np.dtype(v) for k, v in lossless.items()} - infoloss_casts = {np.dtype(k): np.dtype(v) for k, v in infoloss.items()} + lossless_casts: dict[np.dtype, np.dtype] = {np.dtype(k): np.dtype(v) for k, v in lossless.items()} + infoloss_casts: dict[np.dtype, np.dtype] = {np.dtype(k): np.dtype(v) for k, v in infoloss.items()} return self._extract_compatible_dtype(dtype, lossless_casts, infoloss_casts) @staticmethod @@ -159,14 +161,11 @@ def spatially_resize_image( old_dtype, new_dtype = data.dtype, resize_library.get_compatible_dtype(data.dtype) data = data.astype(new_dtype) + resize_function: Callable[[np.ndarray], np.ndarray] if resize_library is ResizeLib.CV2: resize_function = partial(cv2.resize, dsize=size, interpolation=resize_method.get_cv2_method(data.dtype)) else: - resize_function = partial( - _pil_resize_ndarray, # type: ignore[arg-type] - size=size, - method=resize_method.get_pil_method(), - ) + resize_function = partial(_pil_resize_ndarray, size=size, method=resize_method.get_pil_method()) resized_data = _apply_to_spatial_axes(resize_function, data, spatial_axes) diff --git a/eolearn/visualization/eopatch.py b/eolearn/visualization/eopatch.py index 47142154f..a280b70f5 100644 --- a/eolearn/visualization/eopatch.py +++ b/eolearn/visualization/eopatch.py @@ -330,7 +330,7 @@ def _provide_axes(self, *, nrows: int, ncols: int, title: str | None = None, **s **subplot_kwargs, ) if title and self.config.show_title: - title_kwargs = {"t": title, "fontsize": 16, "y": 1.0, **self.config.title_kwargs} + title_kwargs: dict[str, Any] = {"t": title, "fontsize": 16, "y": 1.0, **self.config.title_kwargs} fig.suptitle(**title_kwargs) fig.subplots_adjust(wspace=0.06, hspace=0.06) diff --git a/examples/land-cover-map/SI_LULC_pipeline.ipynb b/examples/land-cover-map/SI_LULC_pipeline.ipynb index 775a25010..d701e6b05 100644 --- a/examples/land-cover-map/SI_LULC_pipeline.ipynb +++ b/examples/land-cover-map/SI_LULC_pipeline.ipynb @@ -1559,7 +1559,7 @@ "source": [ "class_labels = np.unique(labels_test)\n", "class_names = [lulc_type.name for lulc_type in LULC]\n", - "mask = np.in1d(predicted_labels_test, labels_test)\n", + "mask = np.in1d(predicted_labels_test, labels_test) # noqa: NPY201\n", "predictions = predicted_labels_test[mask]\n", "true_labels = labels_test[mask]\n", "\n", diff --git a/pyproject.toml b/pyproject.toml index f159dace8..c592899df 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,7 +48,7 @@ dependencies = [ "fs", "fs-s3fs", "geopandas>=0.11.0,<1", - "numpy>=1.20.0,<2", + "numpy>=1.20.0", "python-dateutil", "sentinelhub>=3.9.0", "tqdm>=4.27", @@ -104,7 +104,7 @@ preview = true [tool.ruff] line-length = 120 target-version = "py38" -select = [ +lint.select = [ "F", # pyflakes "E", # pycodestyle "W", # pycodestyle @@ -137,7 +137,7 @@ select = [ "RUF", # ruff rules ] fix = true -fixable = [ +lint.fixable = [ "I", # sort imports "F401", # remove redundant imports "UP007", # use new-style union type annotations @@ -145,7 +145,7 @@ fixable = [ "UP037", # remove quotes around types when not necessary "FA100", # import future annotations where necessary (not autofixable ATM) ] -ignore = [ +lint.ignore = [ "C408", # complains about `dict()` calls, we use them to avoid too many " in the code "SIM108", # tries to aggresively inline `if`, not always readable "A003", # complains when ATTRIBUTES shadow builtins, we have objects that implement `filter` and such @@ -156,17 +156,17 @@ ignore = [ "B028", # always demands a stacklevel argument when warning "PT011", # complains for `pytest.raises(ValueError)` but we use it a lot ] -per-file-ignores = { "__init__.py" = [ +lint.per-file-ignores = { "__init__.py" = [ "F401", "I002", ], "conf.py" = [ "I002", "FA100", ] } -exclude = [".git", "__pycache__", "build", "dist"] +exclude = [".git", "__pycache__", "build", "dist", "*.ipynb"] -[tool.ruff.isort] +[tool.ruff.lint.isort] required-imports = ["from __future__ import annotations"] section-order = [ "future", diff --git a/tests/features/test_features_utils.py b/tests/features/test_features_utils.py index 34b2545d1..a4ef040b6 100644 --- a/tests/features/test_features_utils.py +++ b/tests/features/test_features_utils.py @@ -15,7 +15,7 @@ def test_spatially_resize_image_new_size( ): """Test that all methods and backends are able to downscale and upscale images of various dtypes.""" if library is ResizeLib.CV2: # noqa: SIM102 - if np.issubdtype(dtype, np.integer) and method is ResizeMethod.CUBIC or dtype == bool: + if np.issubdtype(dtype, np.integer) and method is ResizeMethod.CUBIC or dtype is bool: return old_shape = (111, 111) diff --git a/tests/io/test_sentinelhub_process.py b/tests/io/test_sentinelhub_process.py index d0d00cd75..9a74b3fbb 100644 --- a/tests/io/test_sentinelhub_process.py +++ b/tests/io/test_sentinelhub_process.py @@ -62,7 +62,7 @@ def calculate_stats(array): return np.round(np.array(values), 4) -@pytest.mark.sh_integration() +@pytest.mark.sh_integration class TestProcessingIO: """Test cases for SentinelHubInputTask""" @@ -554,7 +554,7 @@ def test_no_data_evalscript_task_request(self): assert masks.shape == (0, 101, 99, 1) -@pytest.mark.sh_integration() +@pytest.mark.sh_integration class TestSentinelHubInputTaskDataCollections: """Integration tests for all supported data collections""" diff --git a/tests/visualization/test_eopatch.py b/tests/visualization/test_eopatch.py index ee0dbad76..f17895ef7 100644 --- a/tests/visualization/test_eopatch.py +++ b/tests/visualization/test_eopatch.py @@ -47,7 +47,7 @@ def eopatch_fixture(): ((FeatureType.VECTOR_TIMELESS, "LULC"), {}), ], ) -@pytest.mark.sh_integration() +@pytest.mark.sh_integration def test_eopatch_plot(eopatch: EOPatch, feature, params): """A simple test of EOPatch plotting for different features.""" # We reduce width and height otherwise running matplotlib.pyplot.subplots in combination with pytest would From d577218709ca147ae824dc6e47cfc43a7571ffc2 Mon Sep 17 00:00:00 2001 From: Ziga Luksic Date: Fri, 27 Sep 2024 09:56:45 +0200 Subject: [PATCH 2/3] update geopandas bounds --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c592899df..a6da4e103 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,7 +47,7 @@ dependencies = [ "boto3", "fs", "fs-s3fs", - "geopandas>=0.11.0,<1", + "geopandas>=0.14.4,<1", "numpy>=1.20.0", "python-dateutil", "sentinelhub>=3.9.0", From 3da4914377f1a3735b43459fe1ba7011568782f0 Mon Sep 17 00:00:00 2001 From: Ziga Luksic Date: Fri, 27 Sep 2024 10:12:15 +0200 Subject: [PATCH 3/3] add version-specific requirements for geopandas and fiona --- pyproject.toml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a6da4e103..753f19b41 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,7 +47,8 @@ dependencies = [ "boto3", "fs", "fs-s3fs", - "geopandas>=0.14.4,<1", + "geopandas>=0.14.4,<1; python_version>='3.9'", + "geopandas>=0.11.0,<1; python_version<'3.9'", "numpy>=1.20.0", "python-dateutil", "sentinelhub>=3.9.0", @@ -57,7 +58,8 @@ dependencies = [ "affine", "rasterio>=1.3.8", "shapely", - "fiona>=1.8.18", + "fiona>=1.8.18; python_version>='3.9'", + "fiona>=1.8.18,<1.10; python_version<'3.9'", ] [project.optional-dependencies]