Skip to content

Commit d4409b1

Browse files
authored
Merge pull request #141 from d-v-b/chore/min-python-3.12
Set the minimum supported python version to 3.12
2 parents efb6f6e + eb95f6b commit d4409b1

15 files changed

Lines changed: 63 additions & 379 deletions

File tree

.github/workflows/ci.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ jobs:
1313
- uses: actions/checkout@v5
1414
- uses: actions/setup-python@v6
1515
with:
16-
python-version: '3.11'
16+
python-version: '3.12'
1717
- uses: pre-commit/action@v3.0.1
1818

1919
test:
2020
runs-on: ${{ matrix.os }}
2121
strategy:
2222
matrix:
2323
os: [ubuntu-latest]
24-
python-version: ['3.11', '3.12']
24+
python-version: ['3.12', '3.13']
2525

2626
steps:
2727
- uses: actions/checkout@v5
@@ -53,7 +53,7 @@ jobs:
5353
uv run pytest tests/ -v --tb=short -m "not network" --cov=eopf_geozarr --cov-report=xml --cov-report=term-missing
5454
5555
- name: Upload coverage to Codecov
56-
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11'
56+
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'
5757
uses: codecov/codecov-action@v5
5858
with:
5959
file: ./coverage.xml
@@ -78,7 +78,7 @@ jobs:
7878
- name: Set up Python
7979
uses: actions/setup-python@v6
8080
with:
81-
python-version: '3.11'
81+
python-version: '3.12'
8282

8383
- name: Install dependencies
8484
run: |

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ repos:
1212
- id: ruff-format
1313

1414
- repo: https://github.com/pre-commit/mirrors-mypy
15-
rev: v1.11.2
15+
rev: v1.17.0
1616
hooks:
1717
- id: mypy
1818
language_version: python

pyproject.toml

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ classifiers = [
1919
"License :: OSI Approved :: Apache Software License",
2020
"Operating System :: OS Independent",
2121
"Programming Language :: Python :: 3",
22-
"Programming Language :: Python :: 3.10",
23-
"Programming Language :: Python :: 3.11",
2422
"Programming Language :: Python :: 3.12",
23+
"Programming Language :: Python :: 3.13",
24+
"Programming Language :: Python :: 3.14",
2525
"Topic :: Scientific/Engineering :: GIS",
2626
"Topic :: Scientific/Engineering :: Atmospheric Science",
2727
]
28-
requires-python = ">=3.11"
28+
requires-python = ">=3.12"
2929
dependencies = [
3030
"pydantic-zarr>=0.8.0",
3131
"pydantic>=2.12",
@@ -147,7 +147,7 @@ ignore = [
147147
]
148148

149149
[tool.mypy]
150-
python_version = "3.11"
150+
python_version = "3.12"
151151
warn_return_any = true
152152
warn_unused_configs = true
153153
disallow_untyped_defs = true
@@ -172,6 +172,14 @@ warn_untyped_fields = true
172172
module = ["zarr.*", "xarray.*", "rioxarray.*", "cf_xarray.*", "dask.*"]
173173
ignore_missing_imports = true
174174

175+
[[tool.mypy.overrides]]
176+
module = [
177+
"eopf_geozarr.data_api.s1",
178+
"eopf_geozarr.data_api.s2",
179+
"eopf_geozarr.data_api.geozarr.v2",
180+
]
181+
disable_error_code = ["valid-type"]
182+
175183
[tool.pytest.ini_options]
176184
minversion = "7.0"
177185
addopts = "-ra -q --strict-markers --strict-config"

src/eopf_geozarr/conversion/geozarr.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,8 +1522,8 @@ def _create_geozarr_encoding(
15221522
if len(data_shape) == 3:
15231523
# For 3D data (time, y, x), ensure shard dimensions are divisible by chunks
15241524
shard_time = data_shape[0] # Keep full time dimension
1525-
shard_y = _calculate_shard_dimension(data_shape[1], chunks[1])
1526-
shard_x = _calculate_shard_dimension(data_shape[2], chunks[2])
1525+
shard_y = _calculate_shard_dimension(data_shape[1], chunks[1]) # type: ignore[misc]
1526+
shard_x = _calculate_shard_dimension(data_shape[2], chunks[2]) # type: ignore[misc]
15271527
shards = (shard_time, shard_y, shard_x)
15281528
log.info(
15291529
"Sharding config for variable %s: ",
@@ -1535,7 +1535,7 @@ def _create_geozarr_encoding(
15351535
elif len(data_shape) == 2:
15361536
# For 2D data (y, x), ensure shard dimensions are divisible by chunks
15371537
shard_y = _calculate_shard_dimension(data_shape[0], chunks[0])
1538-
shard_x = _calculate_shard_dimension(data_shape[1], chunks[1])
1538+
shard_x = _calculate_shard_dimension(data_shape[1], chunks[1]) # type: ignore[misc]
15391539
shards = (shard_y, shard_x)
15401540
log.info(
15411541
" 🔧 Sharding config",

src/eopf_geozarr/data_api/geozarr/common.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
Any,
1313
Final,
1414
Literal,
15+
Protocol,
1516
Self,
1617
TypeGuard,
1718
TypeVar,
@@ -21,7 +22,7 @@
2122
from cf_xarray.utils import parse_cf_standard_name_table
2223
from pydantic import AfterValidator, BaseModel, Field, model_validator
2324
from pydantic.experimental.missing_sentinel import MISSING
24-
from typing_extensions import Protocol, runtime_checkable
25+
from typing_extensions import runtime_checkable
2526

2627
from eopf_geozarr.data_api.geozarr.projjson import ProjJSON # noqa: TC001
2728

@@ -79,7 +80,7 @@ class BaseDataArrayAttrs(BaseModel, extra="allow"):
7980
----------
8081
"""
8182

82-
grid_mapping: str | MISSING = MISSING
83+
grid_mapping: str | MISSING = MISSING # type: ignore[valid-type]
8384

8485

8586
class GridMappingAttrs(BaseModel, extra="allow"):
@@ -175,7 +176,7 @@ class GroupLike(Protocol):
175176
TGroupLike = TypeVar("TGroupLike", bound=GroupLike)
176177

177178

178-
def check_valid_coordinates(model: TGroupLike) -> TGroupLike:
179+
def check_valid_coordinates[TGroupLike: GroupLike](model: TGroupLike) -> TGroupLike:
179180
"""
180181
Check if the coordinates of the DataArrayLike objects listed in GroupLike objects are valid.
181182
@@ -247,7 +248,7 @@ class DatasetLike(Protocol):
247248
TDataSetLike = TypeVar("TDataSetLike", bound=DatasetLike)
248249

249250

250-
def check_grid_mapping(model: TDataSetLike) -> TDataSetLike:
251+
def check_grid_mapping[TDataSetLike: DatasetLike](model: TDataSetLike) -> TDataSetLike:
251252
"""
252253
Ensure that a grid mapping variable is present, and that it refers to a member of the model.
253254
"""

src/eopf_geozarr/data_api/geozarr/multiscales/geozarr.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,17 @@ class MultiscaleMeta(BaseModel):
1616
or ZCM multiscale metadata
1717
"""
1818

19-
layout: tuple[zcm.ScaleLevel, ...] | MISSING = MISSING
20-
resampling_method: str | MISSING = MISSING
21-
tile_matrix_set: tms.TileMatrixSet | MISSING = MISSING
22-
tile_matrix_limits: dict[str, tms.TileMatrixLimit] | MISSING = MISSING
19+
layout: tuple[zcm.ScaleLevel, ...] | MISSING = MISSING # type: ignore[valid-type]
20+
resampling_method: str | MISSING = MISSING # type: ignore[valid-type]
21+
tile_matrix_set: tms.TileMatrixSet | MISSING = MISSING # type: ignore[valid-type]
22+
tile_matrix_limits: dict[str, tms.TileMatrixLimit] | MISSING = MISSING # type: ignore[valid-type]
2323

2424
@model_validator(mode="after")
2525
def valid_zcm(self) -> Self:
2626
"""
2727
Ensure that the ZCM metadata, if present, is valid
2828
"""
29-
if self.layout is not MISSING:
29+
if self.layout is not MISSING: # type: ignore[comparison-overlap]
3030
zcm.Multiscales(**self.model_dump())
3131

3232
return self
@@ -36,7 +36,7 @@ def valid_tms(self) -> Self:
3636
"""
3737
Ensure that the TMS metadata, if present, is valid
3838
"""
39-
if self.tile_matrix_set is not MISSING:
39+
if self.tile_matrix_set is not MISSING: # type: ignore[comparison-overlap]
4040
tms.Multiscales(**self.model_dump())
4141

4242
return self
@@ -55,7 +55,7 @@ class MultiscaleGroupAttrs(BaseModel):
5555
multiscales: MultiscaleAttrs
5656
"""
5757

58-
zarr_conventions: tuple[ConventionMetadataObject, ...] | MISSING = MISSING
58+
zarr_conventions: tuple[ConventionMetadataObject, ...] | MISSING = MISSING # type: ignore[valid-type]
5959
multiscales: MultiscaleMeta
6060

6161
_zcm_multiscales: zcm.Multiscales | None = None
@@ -67,12 +67,12 @@ def valid_zcm_and_tms(self) -> Self:
6767
Ensure that the ZCM metadata, if present, is valid, and that TMS metadata, if present,
6868
is valid, and that at least one of the two is present.
6969
"""
70-
if self.zarr_conventions is not MISSING:
70+
if self.zarr_conventions is not MISSING: # type: ignore[comparison-overlap]
7171
self._zcm_multiscales = zcm.Multiscales(
7272
layout=self.multiscales.layout,
7373
resampling_method=self.multiscales.resampling_method,
7474
)
75-
if self.multiscales.tile_matrix_limits is not MISSING:
75+
if self.multiscales.tile_matrix_limits is not MISSING: # type: ignore[comparison-overlap]
7676
self._tms_multiscales = tms.Multiscales(
7777
tile_matrix_limits=self.multiscales.tile_matrix_limits,
7878
resampling_method=self.multiscales.resampling_method, # type: ignore[arg-type]

src/eopf_geozarr/data_api/geozarr/multiscales/zcm.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,22 @@ class ZarrConventionAttrs(BaseModel):
2626

2727

2828
class Transform(BaseModel):
29-
scale: tuple[float, ...] | MISSING = MISSING
30-
translation: tuple[float, ...] | MISSING = MISSING
29+
scale: tuple[float, ...] | MISSING = MISSING # type: ignore[valid-type]
30+
translation: tuple[float, ...] | MISSING = MISSING # type: ignore[valid-type]
3131

3232

3333
class ScaleLevel(BaseModel):
3434
asset: str
35-
derived_from: str | MISSING = MISSING
36-
transform: Transform | MISSING = MISSING
37-
resampling_method: str | MISSING = MISSING
35+
derived_from: str | MISSING = MISSING # type: ignore[valid-type]
36+
transform: Transform | MISSING = MISSING # type: ignore[valid-type]
37+
resampling_method: str | MISSING = MISSING # type: ignore[valid-type]
3838

3939
model_config = {"extra": "allow"}
4040

4141

4242
class Multiscales(BaseModel):
4343
layout: tuple[ScaleLevel, ...]
44-
resampling_method: str | MISSING = MISSING
44+
resampling_method: str | MISSING = MISSING # type: ignore[valid-type]
4545

4646
model_config = {"extra": "allow"}
4747

src/eopf_geozarr/data_api/geozarr/v2.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
if TYPE_CHECKING:
2121
from collections.abc import Iterable, Mapping
2222

23+
from pydantic.experimental.missing_sentinel import MISSING as MISSING
24+
2325

2426
class DataArrayAttrs(BaseDataArrayAttrs):
2527
"""

src/eopf_geozarr/data_api/s1.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@
77
from __future__ import annotations
88

99
from collections.abc import Mapping
10-
from typing import Any
10+
from typing import TYPE_CHECKING, Any
1111

1212
from pydantic import BaseModel
1313
from typing_extensions import TypedDict
1414

15+
if TYPE_CHECKING:
16+
from pydantic.experimental.missing_sentinel import MISSING as MISSING
17+
1518
from eopf_geozarr.data_api.geozarr.common import (
1619
BaseDataArrayAttrs,
1720
CFStandardName,

src/eopf_geozarr/data_api/s2.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@
66

77
from __future__ import annotations
88

9-
from typing import Annotated, Any, Literal
9+
from typing import TYPE_CHECKING, Annotated, Any, Literal
1010

1111
from pydantic import BaseModel, Field
1212
from typing_extensions import TypedDict
1313

14+
if TYPE_CHECKING:
15+
from pydantic.experimental.missing_sentinel import MISSING as MISSING
16+
1417
from eopf_geozarr.data_api.geozarr.common import (
1518
BaseDataArrayAttrs,
1619
CFStandardName,

0 commit comments

Comments
 (0)