diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 19bbaf97c..48ef4b4a9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,13 +1,13 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.2.2" + rev: "v0.15.8" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.19.0 + rev: v1.20.0 hooks: - id: mypy language_version: python diff --git a/CHANGES.md b/CHANGES.md index 9bb2d8ad3..cc40dddec 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- fix mypy type errors in transaction extension for Python 3.14 compatibility (mypy 1.20.0) ([#895](https://github.com/stac-utils/stac-fastapi/pull/895)) + ## [6.2.1] - 2026-02-10 ### Fixed diff --git a/stac_fastapi/api/stac_fastapi/api/app.py b/stac_fastapi/api/stac_fastapi/api/app.py index 11aa8e414..f25291c25 100644 --- a/stac_fastapi/api/stac_fastapi/api/app.py +++ b/stac_fastapi/api/stac_fastapi/api/app.py @@ -1,6 +1,5 @@ """Fastapi app creation.""" - import inspect from typing import Awaitable, Callable, Dict, List, Optional, Tuple, Type, Union diff --git a/stac_fastapi/api/tests/test_api.py b/stac_fastapi/api/tests/test_api.py index 5f9aa73e3..03c595eba 100644 --- a/stac_fastapi/api/tests/test_api.py +++ b/stac_fastapi/api/tests/test_api.py @@ -39,9 +39,9 @@ def _assert_dependency_applied(api, routes): with TestClient(api.app) as client: for route in routes: response = getattr(client, route["method"].lower())(route["path"]) - assert ( - response.status_code == 401 - ), "Unauthenticated requests should be rejected" + assert response.status_code == 401, ( + "Unauthenticated requests should be rejected" + ) assert response.json() == {"detail": "Not authenticated"} path = route["path"].format( @@ -54,9 +54,9 @@ def _assert_dependency_applied(api, routes): content=route["payload"], headers={"content-type": "application/json"}, ) - assert ( - 200 <= response.status_code < 300 - ), "Authenticated requests should be accepted" + assert 200 <= response.status_code < 300, ( + "Authenticated requests should be accepted" + ) assert response.json() == "dummy response" @staticmethod @@ -72,9 +72,9 @@ def _assert_dependency_not_applied(api, routes): content=route["payload"], headers={"content-type": "application/json"}, ) - assert ( - 200 <= response.status_code < 300 - ), "Authenticated requests should be accepted" + assert 200 <= response.status_code < 300, ( + "Authenticated requests should be accepted" + ) assert response.json() == "dummy response" def test_openapi_content_type(self): @@ -400,23 +400,17 @@ def test_add_default_method_route_dependencies_after_building_api( class DummyCoreClient(core.BaseCoreClient): - def all_collections(self, *args, **kwargs): - ... + def all_collections(self, *args, **kwargs): ... - def get_collection(self, *args, **kwargs): - ... + def get_collection(self, *args, **kwargs): ... - def get_item(self, *args, **kwargs): - ... + def get_item(self, *args, **kwargs): ... - def get_search(self, *args, **kwargs): - ... + def get_search(self, *args, **kwargs): ... - def post_search(self, *args, **kwargs): - ... + def post_search(self, *args, **kwargs): ... - def item_collection(self, *args, **kwargs): - ... + def item_collection(self, *args, **kwargs): ... class DummyTransactionsClient(BaseTransactionsClient): diff --git a/stac_fastapi/api/tests/test_app_prefix.py b/stac_fastapi/api/tests/test_app_prefix.py index f2289ccfc..cf51d002e 100644 --- a/stac_fastapi/api/tests/test_app_prefix.py +++ b/stac_fastapi/api/tests/test_app_prefix.py @@ -12,8 +12,9 @@ def get_link(landing_page, rel_type, method: Optional[str] = None): return next( filter( - lambda link: link["rel"] == rel_type - and (not method or link.get("method") == method), + lambda link: ( + link["rel"] == rel_type and (not method or link.get("method") == method) + ), landing_page["links"], ), None, diff --git a/stac_fastapi/extensions/stac_fastapi/extensions/core/aggregation/aggregation.py b/stac_fastapi/extensions/stac_fastapi/extensions/core/aggregation/aggregation.py index d646df45f..e8def85d3 100644 --- a/stac_fastapi/extensions/stac_fastapi/extensions/core/aggregation/aggregation.py +++ b/stac_fastapi/extensions/stac_fastapi/extensions/core/aggregation/aggregation.py @@ -1,4 +1,5 @@ """Aggregation Extension.""" + from enum import Enum from typing import List, Type, Union diff --git a/stac_fastapi/extensions/stac_fastapi/extensions/core/filter/filter.py b/stac_fastapi/extensions/stac_fastapi/extensions/core/filter/filter.py index e6f1a0deb..c7a170b4d 100644 --- a/stac_fastapi/extensions/stac_fastapi/extensions/core/filter/filter.py +++ b/stac_fastapi/extensions/stac_fastapi/extensions/core/filter/filter.py @@ -1,5 +1,6 @@ # encoding: utf-8 """Filter Extension.""" + from enum import Enum from typing import List, Type, Union diff --git a/stac_fastapi/extensions/stac_fastapi/extensions/core/transaction/transaction.py b/stac_fastapi/extensions/stac_fastapi/extensions/core/transaction/transaction.py index ca61c9e60..a30124d91 100644 --- a/stac_fastapi/extensions/stac_fastapi/extensions/core/transaction/transaction.py +++ b/stac_fastapi/extensions/stac_fastapi/extensions/core/transaction/transaction.py @@ -1,7 +1,7 @@ """Transaction extension.""" from enum import Enum -from typing import List, Optional, Type, Union +from typing import Any, Dict, List, Optional, Type, Union import attr from fastapi import APIRouter, Body, FastAPI @@ -108,7 +108,10 @@ class PatchCollection(CollectionUri): ] } # ref: https://github.com/pydantic/pydantic/issues/889 -_patch_item_schema["items"]["anyOf"] = list(_patch_item_schema["$defs"].values()) +_patch_item_schema_dict: Dict[str, Any] = _patch_item_schema +_patch_item_schema_dict["items"]["anyOf"] = list( + _patch_item_schema_dict["$defs"].values() +) _patch_collection_schema = TypeAdapter(List[PatchOperation]).json_schema() | { "examples": [ @@ -146,8 +149,9 @@ class PatchCollection(CollectionUri): ] } # ref: https://github.com/pydantic/pydantic/issues/889 -_patch_collection_schema["items"]["anyOf"] = list( - _patch_collection_schema["$defs"].values() +_patch_collection_schema_dict: Dict[str, Any] = _patch_collection_schema +_patch_collection_schema_dict["items"]["anyOf"] = list( + _patch_collection_schema_dict["$defs"].values() ) diff --git a/stac_fastapi/extensions/tests/test_free_text.py b/stac_fastapi/extensions/tests/test_free_text.py index 55f253a34..1e7955467 100644 --- a/stac_fastapi/extensions/tests/test_free_text.py +++ b/stac_fastapi/extensions/tests/test_free_text.py @@ -1,7 +1,6 @@ # noqa: E501 """test freetext extension.""" - from starlette.testclient import TestClient from stac_fastapi.api.app import StacApi diff --git a/stac_fastapi/types/stac_fastapi/types/search.py b/stac_fastapi/types/stac_fastapi/types/search.py index 83c4fd34a..d13fb0155 100644 --- a/stac_fastapi/types/stac_fastapi/types/search.py +++ b/stac_fastapi/types/stac_fastapi/types/search.py @@ -1,6 +1,5 @@ -"""stac_fastapi.types.search module. +"""stac_fastapi.types.search module.""" -""" from datetime import datetime as dt from typing import Dict, List, Optional, Union, cast diff --git a/stac_fastapi/types/tests/test_rfc3339.py b/stac_fastapi/types/tests/test_rfc3339.py index dc4c897d5..7ce353112 100644 --- a/stac_fastapi/types/tests/test_rfc3339.py +++ b/stac_fastapi/types/tests/test_rfc3339.py @@ -54,10 +54,10 @@ ] invalid_intervals = [ - "/" - "../" - "/.." - "../.." + "/", + "../", + "/..", + "../..", "/1984-04-12T23:20:50.52Z/1985-04-12T23:20:50.52Z", # extra start / "1984-04-12T23:20:50.52Z/1985-04-12T23:20:50.52Z/", # extra end / "1986-04-12T23:20:50.52Z/1985-04-12T23:20:50.52Z", # start > end @@ -89,39 +89,39 @@ def test_parse_valid_str_to_datetime(test_input): def test_str_to_interval_with_invalid_interval(test_input): with pytest.raises(HTTPException) as exc_info: str_to_interval(test_input) - assert ( - exc_info.value.status_code == 400 - ), "str_to_interval should return a 400 status code for invalid interval" + assert exc_info.value.status_code == 400, ( + "str_to_interval should return a 400 status code for invalid interval" + ) @pytest.mark.parametrize("test_input", invalid_datetimes) def test_str_to_interval_with_invalid_datetime(test_input): with pytest.raises(HTTPException) as exc_info: str_to_interval(test_input) - assert ( - exc_info.value.status_code == 400 - ), "str_to_interval should return a 400 status code for invalid datetime" + assert exc_info.value.status_code == 400, ( + "str_to_interval should return a 400 status code for invalid datetime" + ) @pytest.mark.parametrize("test_input", valid_intervals) def test_str_to_interval_with_valid_interval(test_input): - assert isinstance( - str_to_interval(test_input), tuple - ), "str_to_interval should return tuple for multi-value input" + assert isinstance(str_to_interval(test_input), tuple), ( + "str_to_interval should return tuple for multi-value input" + ) @pytest.mark.parametrize("test_input", valid_datetimes) def test_str_to_interval_with_valid_datetime(test_input): - assert isinstance( - str_to_interval(test_input), datetime - ), "str_to_interval should return single datetime for single-value input" + assert isinstance(str_to_interval(test_input), datetime), ( + "str_to_interval should return single datetime for single-value input" + ) def test_str_to_interval_with_none(): """Test that str_to_interval returns None when provided with None.""" - assert ( - str_to_interval(None) is None - ), "str_to_interval should return None when input is None" + assert str_to_interval(None) is None, ( + "str_to_interval should return None when input is None" + ) def test_now_functions() -> None: diff --git a/uv.lock b/uv.lock index b7c8f7c45..415f79f53 100644 --- a/uv.lock +++ b/uv.lock @@ -6,10 +6,6 @@ resolution-markers = [ "python_full_version < '3.12'", ] -[options] -exclude-newer = "2026-03-23T10:55:01.77892Z" -exclude-newer-span = "P3D" - [manifest] members = [ "stac-fastapi",