Skip to content

Commit a65899e

Browse files
authored
Release version 1.4.2, Merge pull request #672 from sentinel-hub/develop
Release version 1.4.2
2 parents 9e6cd92 + 7706787 commit a65899e

File tree

142 files changed

+2504
-2640
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

142 files changed

+2504
-2640
lines changed

.flake8

-10
This file was deleted.

.github/workflows/ci_action.yml

+24-24
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@ on:
66
branches:
77
- "master"
88
- "develop"
9-
schedule:
10-
# Schedule events are triggered by whoever last changed the cron schedule
11-
- cron: "5 0 * * *"
9+
workflow_call:
10+
11+
concurrency:
12+
# This will cancel outdated runs on the same pull-request, but not runs for other triggers
13+
group: ${{ github.head_ref || github.run_id }}
14+
cancel-in-progress: true
1215

1316
env:
1417
# The only way to simulate if-else statement
@@ -19,46 +22,45 @@ jobs:
1922
runs-on: ubuntu-latest
2023
steps:
2124
- name: Checkout branch
22-
uses: actions/checkout@v2
25+
uses: actions/checkout@v3
2326
with:
2427
ref: ${{ env.CHECKOUT_BRANCH }}
2528

2629
- name: Setup Python
27-
uses: actions/setup-python@v2
30+
uses: actions/setup-python@v4
2831
with:
2932
python-version: "3.8"
30-
architecture: x64
31-
32-
- name: Prepare pre-commit validators
33-
run: |
34-
pip install pre-commit
3533

36-
- name: Check code compliance with pre-commit validators
37-
run: pre-commit run --all-files
34+
- uses: pre-commit/[email protected]
35+
with:
36+
extra_args: --all-files --verbose
3837

3938
check-code-pylint-and-mypy:
4039
runs-on: ubuntu-latest
4140
steps:
4241
- name: Checkout branch
43-
uses: actions/checkout@v2
42+
uses: actions/checkout@v3
4443
with:
4544
ref: ${{ env.CHECKOUT_BRANCH }}
4645

4746
- name: Setup Python
48-
uses: actions/setup-python@v2
47+
uses: actions/setup-python@v4
4948
with:
5049
python-version: "3.8"
51-
architecture: x64
50+
# cache: pip # uncomment when all requirements are in `pyproject.toml`
51+
# caching the entire environment is faster when cache exists but slower for cache creation
5252

5353
- name: Install packages
5454
run: |
55-
pip install -r requirements-dev.txt --upgrade
55+
pip install -r requirements-dev.txt --upgrade --upgrade-strategy eager
5656
python install_all.py
57+
pip install -r ml_tools/requirements-tdigest.txt
5758
5859
- name: Run pylint
5960
run: make pylint
6061

6162
- name: Run mypy
63+
if: success() || failure()
6264
run: |
6365
mypy \
6466
core/eolearn/core \
@@ -77,28 +79,27 @@ jobs:
7779
python-version:
7880
- "3.9"
7981
- "3.10"
82+
- "3.11"
8083
include:
8184
# A flag marks whether full or partial tests should be run
8285
# We don't run integration tests on pull requests from outside repos, because they don't have secrets
8386
- python-version: "3.8"
8487
full_test_suite: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
8588
steps:
8689
- name: Checkout branch
87-
uses: actions/checkout@v2
90+
uses: actions/checkout@v3
8891
with:
8992
ref: ${{ env.CHECKOUT_BRANCH }}
9093

9194
- name: Setup Python
92-
uses: actions/setup-python@v2
95+
uses: actions/setup-python@v4
9396
with:
9497
python-version: ${{ matrix.python-version }}
95-
architecture: x64
98+
# cache: pip # uncomment when all requirements are in `pyproject.toml`
9699

97100
- name: Install packages
98101
run: |
99-
sudo apt-get update
100-
sudo apt-get install -y build-essential libgdal-dev graphviz proj-bin gcc libproj-dev libspatialindex-dev
101-
pip install -r requirements-dev.txt --upgrade
102+
pip install -r requirements-dev.txt --upgrade --upgrade-strategy eager
102103
python install_all.py -e
103104
104105
- name: Run full tests and code coverage
@@ -111,8 +112,7 @@ jobs:
111112
112113
- name: Run reduced tests
113114
if: ${{ !matrix.full_test_suite }}
114-
run: |
115-
pytest -m "not sh_integration"
115+
run: pytest -m "not sh_integration"
116116

117117
- name: Upload code coverage
118118
if: ${{ matrix.full_test_suite && github.event_name == 'push' }}
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name: scheduled build caller
2+
3+
on:
4+
schedule:
5+
# Schedule events are triggered by whoever last changed the cron schedule
6+
- cron: "0 0 * * *"
7+
8+
jobs:
9+
call-workflow:
10+
uses: sentinel-hub/eo-learn/.github/workflows/ci_action.yml@develop
11+
secrets: inherit

.pre-commit-config.yaml

+6-29
Original file line numberDiff line numberDiff line change
@@ -13,41 +13,18 @@ repos:
1313
- id: debug-statements
1414

1515
- repo: https://github.com/psf/black
16-
rev: 23.1.0
16+
rev: 23.3.0
1717
hooks:
1818
- id: black
1919
language_version: python3
2020

21-
- repo: https://github.com/pycqa/isort
22-
rev: 5.12.0
21+
- repo: https://github.com/charliermarsh/ruff-pre-commit
22+
rev: "v0.0.269"
2323
hooks:
24-
- id: isort
25-
name: isort (python)
26-
27-
- repo: https://github.com/PyCQA/autoflake
28-
rev: v2.0.1
29-
hooks:
30-
- id: autoflake
31-
args:
32-
[
33-
--remove-all-unused-imports,
34-
--in-place,
35-
--ignore-init-module-imports,
36-
]
37-
38-
- repo: https://github.com/pycqa/flake8
39-
rev: 6.0.0
40-
hooks:
41-
- id: flake8
42-
additional_dependencies:
43-
- flake8-bugbear==23.2.13
44-
- flake8-comprehensions==3.10.1
45-
- flake8-simplify==0.19.3
46-
- flake8-typing-imports==1.14.0
24+
- id: ruff
4725

4826
- repo: https://github.com/nbQA-dev/nbQA
49-
rev: 1.6.3
27+
rev: 1.7.0
5028
hooks:
5129
- id: nbqa-black
52-
- id: nbqa-isort
53-
- id: nbqa-flake8
30+
- id: nbqa-ruff

.zenodo.json

+1
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@
141141
},
142142
{
143143
"name": "Colin Moldenhauer",
144+
"affiliation": "Technical University of Munich",
144145
"type": "Other"
145146
},
146147
{

CHANGELOG.md

+15
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
## [Version 1.4.2] - 2023-3-14
2+
3+
- Introduced support for Python 3.11.
4+
- Removed support for Python 3.7.
5+
- Added T-Digest `EOTask` in the scope of the Global Earth Monitor Project, contributed by @meengel.
6+
- Used evalscript generation utility from `sentinelhub-py` in SH related `EOTasks`.
7+
- Deprecated the `EOPatch.merge` method and extracted it as a function.
8+
- Deprecated the `OVERWRITE_PATCH` permission and enforcing the usage of explicit string permissions.
9+
- Encapsulated `FeatureDict` class as `Mapping`, removed inheritance from `dict`.
10+
- Switched to new-style typed annotations.
11+
- Introduced the `ruff` python linter, removed `flake8` and `isort` (covered by `ruff`).
12+
- Fixed issue with occasionally failing scheduled builds on the `master` branch.
13+
- Various refactoring efforts and dependency improvements.
14+
- Various improvements to tests and code.
15+
116
## [Version 1.4.1] - 2023-3-14
217

318
- The codebase is now fully annotated and type annotations are mandatory for all new code.

CONTRIBUTING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ This section assumes you have installed all packages in `requirements-dev.txt`.
131131

132132
Most of the automated code-checking is packaged into [pre-commit hooks](https://pre-commit.com/). You can activate them by running `pre-commit install`. If you wish to check all code you can do so by running `pre-commit run --all-files`. This takes care of:
133133
- auto-formatting the code using `black`, `isort`, and `autoflake`
134-
- checking the code with `flake8`
134+
- checking the code with `ruff`
135135
- checking and formatting any Jupyter notebooks with `nbqa`
136136
- various other helpful things (correcting line-endings etc.)
137137

CREDITS.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,12 @@ page or mine the [commit history](https://github.com/sentinel-hub/eo-learn/commi
3737
## Other contributors
3838

3939
* Drew Bollinger (DevelopmentSeed)
40+
* Michael Engel (Technical University of Munich)
4041
* Peter Fogh
4142
* Hugo Fournier (Magellium)
4243
* Ben Huff
4344
* Filip Koprivec (Jožef Stefan Institute)
44-
* Colin Moldenhauer
45+
* Colin Moldenhauer (Technical University of Munich)
4546
* William Ouellette (TomTom)
4647
* Radoslav Pitoňák
4748
* Johannes Schmid (GeoVille)

MANIFEST.in

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
include requirements*.txt
22

33
include README.md
4+
include CREDITS.md
45
include LICENSE

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ At the moment there are the following subpackages:
5252

5353
### PyPi distribution
5454

55-
The package requires Python version **>=3.7** . It can be installed with:
55+
The package requires Python version **>=3.8** . It can be installed with:
5656

5757
```bash
5858
pip install eo-learn
@@ -92,7 +92,7 @@ Some subpackages contain extension modules under `extra` subfolder. Those module
9292

9393
### Conda Forge distribution
9494

95-
The package requires a Python environment **>=3.7**.
95+
The package requires a Python environment **>=3.8**.
9696

9797
Thanks to the maintainers of the conda forge feedstock (@benhuff, @dcunn, @mwilson8, @oblute, @rluria14), `eo-learn` can
9898
be installed using `conda-forge` as follows:
@@ -149,7 +149,7 @@ Examples and introductions to the package can be found [here](https://github.com
149149

150150
## Contributions
151151

152-
If you would like to contribute to `eo-learn`, check out our [contribution guidelines](./CONTRIBUTING.md).
152+
The list of all `eo-learn` contributors can be found [here](./CONTRIBUTING.md). If you would like to contribute to `eo-learn`, please check our [contribution guidelines](./CONTRIBUTING.md).
153153

154154
## Blog posts and papers
155155

core/eolearn/core/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
ZipFeatureTask,
2323
)
2424
from .eodata import EOPatch
25+
from .eodata_merge import merge_eopatches
2526
from .eoexecution import EOExecutor
2627
from .eonode import EONode, linearly_connect_tasks
2728
from .eotask import EOTask
@@ -32,4 +33,4 @@
3233
from .utils.parallelize import execute_with_mp_lock, join_futures, join_futures_iter, parallelize
3334
from .utils.parsing import FeatureParser
3435

35-
__version__ = "1.4.1"
36+
__version__ = "1.4.2"

core/eolearn/core/constants.py

+52-14
Original file line numberDiff line numberDiff line change
@@ -8,37 +8,38 @@
88
"""
99
import warnings
1010
from enum import Enum, EnumMeta
11-
from typing import Any, Optional
11+
from typing import Any, Optional, TypeVar
1212

1313
from sentinelhub import BBox, MimeType
1414
from sentinelhub.exceptions import deprecated_function
1515

1616
from .exceptions import EODeprecationWarning
1717

1818
TIMESTAMP_COLUMN = "TIMESTAMP"
19+
T = TypeVar("T")
1920

2021

21-
def _warn_and_adjust(name: str) -> str:
22+
def _warn_and_adjust(name: T) -> T:
2223
# since we stick with `UPPER` for attributes and `lower` for values, we include both to reuse function
23-
deprecation_msg = None
24+
deprecation_msg = None # placeholder
2425
if name in ("TIMESTAMP", "timestamp"):
25-
name = "TIMESTAMPS" if name == "TIMESTAMP" else "timestamps"
26+
name = "TIMESTAMPS" if name == "TIMESTAMP" else "timestamps" # type: ignore[assignment]
2627

2728
if deprecation_msg:
28-
warnings.warn(deprecation_msg, category=EODeprecationWarning, stacklevel=3) # type: ignore
29+
warnings.warn(deprecation_msg, category=EODeprecationWarning, stacklevel=3) # type: ignore[unreachable]
2930
return name
3031

3132

3233
class EnumWithDeprecations(EnumMeta):
3334
"""A custom EnumMeta class for catching the deprecated Enum members of the FeatureType Enum class."""
3435

35-
def __getattribute__(cls, name: str) -> Any:
36+
def __getattribute__(cls, name: str) -> Any: # noqa[N805]
3637
return super().__getattribute__(_warn_and_adjust(name))
3738

38-
def __getitem__(cls, name: str) -> Any:
39+
def __getitem__(cls, name: str) -> Any: # noqa[N805]
3940
return super().__getitem__(_warn_and_adjust(name))
4041

41-
def __call__(cls, value: str, *args: Any, **kwargs: Any) -> Any:
42+
def __call__(cls, value: str, *args: Any, **kwargs: Any) -> Any: # noqa[N805]
4243
return super().__call__(_warn_and_adjust(value), *args, **kwargs)
4344

4445

@@ -292,17 +293,54 @@ class FeatureTypeSet(metaclass=DeprecatedCollectionClass):
292293
RASTER_TYPES_1D = frozenset([FeatureType.SCALAR_TIMELESS, FeatureType.LABEL_TIMELESS])
293294

294295

295-
class OverwritePermission(Enum):
296-
"""Enum class which specifies which content of saved EOPatch can be overwritten when saving new content.
296+
def _warn_and_adjust_permissions(name: T) -> T:
297+
if isinstance(name, str) and name.upper() == "OVERWRITE_PATCH":
298+
warnings.warn(
299+
'"OVERWRITE_PATCH" permission is deprecated and will be removed in a future version',
300+
category=EODeprecationWarning,
301+
stacklevel=3,
302+
)
303+
return name
304+
305+
306+
class PermissionsWithDeprecations(EnumMeta):
307+
"""A custom EnumMeta class for catching the deprecated Enum members of the OverwritePermission Enum class."""
308+
309+
def __getattribute__(cls, name: str) -> Any: # noqa[N805]
310+
return super().__getattribute__(_warn_and_adjust_permissions(name))
311+
312+
def __getitem__(cls, name: str) -> Any: # noqa[N805]
313+
return super().__getitem__(_warn_and_adjust_permissions(name))
314+
315+
def __call__(cls, value: str, *args: Any, **kwargs: Any) -> Any: # noqa[N805]
316+
return super().__call__(_warn_and_adjust_permissions(value), *args, **kwargs)
317+
318+
319+
class OverwritePermission(Enum, metaclass=PermissionsWithDeprecations):
320+
"""Enum class which specifies which content of the saved EOPatch can be overwritten when saving new content.
297321
298322
Permissions are in the following hierarchy:
299323
300324
- `ADD_ONLY` - Only new features can be added, anything that is already saved cannot be changed.
301325
- `OVERWRITE_FEATURES` - Overwrite only data for features which have to be saved. The remaining content of saved
302326
EOPatch will stay unchanged.
303-
- `OVERWRITE_PATCH` - Overwrite entire content of saved EOPatch and replace it with the new content.
304327
"""
305328

306-
ADD_ONLY = 0
307-
OVERWRITE_FEATURES = 1
308-
OVERWRITE_PATCH = 2
329+
ADD_ONLY = "ADD_ONLY"
330+
OVERWRITE_FEATURES = "OVERWRITE_FEATURES"
331+
OVERWRITE_PATCH = "OVERWRITE_PATCH"
332+
333+
@classmethod
334+
def _missing_(cls, value: object) -> "OverwritePermission":
335+
permissions_mapping = {0: "ADD_ONLY", 1: "OVERWRITE_FEATURES", 2: "OVERWRITE_PATCH"}
336+
if isinstance(value, int) and value in permissions_mapping:
337+
deprecation_msg = (
338+
f"Please use strings to instantiate overwrite permissions, e.g., instead of {value} use"
339+
f" {permissions_mapping[value]!r}"
340+
)
341+
warnings.warn(deprecation_msg, category=EODeprecationWarning, stacklevel=3)
342+
343+
return cls(permissions_mapping[value])
344+
if isinstance(value, str) and value.upper() in cls._value2member_map_:
345+
return cls(value.upper())
346+
return super()._missing_(value)

0 commit comments

Comments
 (0)