diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5e78db3..d0b45cb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ on: - '*' pull_request: env: - LATEST_PY_VERSION: '3.12' + LATEST_PY_VERSION: '3.13' jobs: tests: @@ -16,11 +16,12 @@ jobs: strategy: matrix: python-version: - - '3.8' - '3.9' - '3.10' - '3.11' - '3.12' + - '3.13' + # - '3.14.0-alpha.2', waiting for shapely to support 3.14 steps: - uses: actions/checkout@v4 @@ -57,9 +58,9 @@ jobs: runs-on: ubuntu-latest if: startsWith(github.event.ref, 'refs/tags') || github.event_name == 'release' steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ env.LATEST_PY_VERSION }} @@ -71,11 +72,14 @@ jobs: - name: Set tag version id: tag - run: echo ::set-output name=tag::${GITHUB_REF#refs/*/} + run: | + echo "version=${GITHUB_REF#refs/*/}" + echo "version=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT - name: Set module version id: module - run: echo ::set-output name=version::$(python -c 'from importlib.metadata import version; print(version("geojson_pydantic"))') + run: | + echo version=$(python -c'import geojson_pydantic; print(geojson_pydantic.__version__)') >> $GITHUB_OUTPUT - name: Build and publish if: steps.tag.outputs.tag == steps.module.outputs.version diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cd3b553..55c3dfd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,26 +4,21 @@ repos: hooks: - id: validate-pyproject - - repo: https://github.com/psf/black - rev: 22.12.0 - hooks: - - id: black - language_version: python - - repo: https://github.com/PyCQA/isort - rev: 5.12.0 + rev: 5.13.2 hooks: - id: isort language_version: python - - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: v0.0.238 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.3.5 hooks: - id: ruff args: ["--fix"] + - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.4.1 + rev: v1.11.2 hooks: - id: mypy language_version: python diff --git a/CHANGELOG.md b/CHANGELOG.md index c261773..bd9fee9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/). Note: Minor version `0.X.0` update might break the API, It's recommended to pin geojson-pydantic to minor version: `geojson-pydantic>=0.6,<0.7` +## [unreleased] + +## [1.2.0] - 2024-12-19 + +* drop python 3.8 support +* add python 3.13 support + ## [1.1.2] - 2024-10-22 * relax `bbox` validation and allow antimeridian crossing bboxes @@ -369,7 +376,8 @@ Although the type file was added in `0.2.0` it wasn't included in the distribute ### Added - Initial Release -[unreleased]: https://github.com/developmentseed/geojson-pydantic/compare/1.1.2...HEAD +[unreleased]: https://github.com/developmentseed/geojson-pydantic/compare/1.2.0...HEAD +[1.2.0]: https://github.com/developmentseed/geojson-pydantic/compare/1.1.2...1.2.0 [1.1.2]: https://github.com/developmentseed/geojson-pydantic/compare/1.1.1...1.1.2 [1.1.1]: https://github.com/developmentseed/geojson-pydantic/compare/1.1.0...1.1.1 [1.1.0]: https://github.com/developmentseed/geojson-pydantic/compare/1.0.2...1.1.0 diff --git a/geojson_pydantic/base.py b/geojson_pydantic/base.py index 90c547b..c3289fc 100644 --- a/geojson_pydantic/base.py +++ b/geojson_pydantic/base.py @@ -1,4 +1,5 @@ """pydantic BaseModel for GeoJSON objects.""" + from __future__ import annotations import warnings @@ -42,6 +43,7 @@ def validate_bbox(cls, bbox: Optional[BBox]) -> Optional[BBox]: warnings.warn( f"BBOX crossing the Antimeridian line, Min X ({bbox[0]}) > Max X ({bbox[offset]}).", UserWarning, + stacklevel=1, ) # Check Y diff --git a/geojson_pydantic/geometries.py b/geojson_pydantic/geometries.py index ecd2d3a..b1f556a 100644 --- a/geojson_pydantic/geometries.py +++ b/geojson_pydantic/geometries.py @@ -1,4 +1,5 @@ """pydantic models for GeoJSON Geometry objects.""" + from __future__ import annotations import abc @@ -285,17 +286,20 @@ def check_geometries(cls, geometries: List) -> List: """Add warnings for conditions the spec does not explicitly forbid.""" if len(geometries) == 1: warnings.warn( - "GeometryCollection should not be used for single geometries." + "GeometryCollection should not be used for single geometries.", + stacklevel=1, ) if any(geom.type == "GeometryCollection" for geom in geometries): warnings.warn( - "GeometryCollection should not be used for nested GeometryCollections." + "GeometryCollection should not be used for nested GeometryCollections.", + stacklevel=1, ) if len({geom.type for geom in geometries}) == 1: warnings.warn( - "GeometryCollection should not be used for homogeneous collections." + "GeometryCollection should not be used for homogeneous collections.", + stacklevel=1, ) return geometries diff --git a/pyproject.toml b/pyproject.toml index d7d0b41..16e1ed0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,11 +12,11 @@ classifiers = [ "Intended Audience :: Information Technology", "Intended Audience :: Science/Research", "License :: OSI Approved :: MIT License", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Topic :: Scientific/Engineering :: GIS", "Typing :: Typed", ] @@ -81,7 +81,7 @@ warn_unused_ignores = true no_implicit_optional = true show_error_codes = true -[tool.ruff] +[tool.ruff.lint] select = [ "D1", # pydocstyle errors "E", # pycodestyle errors @@ -96,7 +96,7 @@ ignore = [ "B905", # ignore zip() without an explicit strict= parameter, only support with python >3.10 ] -[tool.ruff.per-file-ignores] +[tool.ruff.lint.per-file-ignores] "tests/*.py" = ["D1"] [tool.bumpversion] diff --git a/tests/test_features.py b/tests/test_features.py index ef311a8..9286bef 100644 --- a/tests/test_features.py +++ b/tests/test_features.py @@ -106,7 +106,7 @@ def test_generic_properties_is_dict(): feature = Feature(**test_feature) assert hasattr(feature, "__geo_interface__") assert feature.properties["id"] == test_feature["properties"]["id"] - assert type(feature.properties) == dict + assert isinstance(feature.properties, dict) assert not hasattr(feature.properties, "id") @@ -116,7 +116,7 @@ def test_generic_properties_is_dict_collection(): assert ( feature.properties["id"] == test_feature_geometry_collection["properties"]["id"] ) - assert type(feature.properties) == dict + assert isinstance(feature.properties, dict) assert not hasattr(feature.properties, "id") @@ -137,7 +137,7 @@ def test_generic_geometry(): feature = Feature[Polygon, Dict](**test_feature) assert type(feature.geometry) == Polygon assert feature.properties["id"] == test_feature["properties"]["id"] - assert type(feature.properties) == dict + assert isinstance(feature.properties, dict) assert not hasattr(feature.properties, "id") with pytest.raises(ValidationError): @@ -159,7 +159,7 @@ def test_generic_geometry_collection(): assert ( feature.properties["id"] == test_feature_geometry_collection["properties"]["id"] ) - assert type(feature.properties) == dict + assert isinstance(feature.properties, dict) assert not hasattr(feature.properties, "id") with pytest.raises(ValidationError): diff --git a/tests/test_geometries.py b/tests/test_geometries.py index a219dda..aac4dd3 100644 --- a/tests/test_geometries.py +++ b/tests/test_geometries.py @@ -596,8 +596,7 @@ def test_polygon_from_bounds(): def test_wkt_name(): """Make sure WKT name is derived from geometry Type.""" - class PointType(Point): - ... + class PointType(Point): ... assert ( PointType(type="Point", coordinates=(1.01, 2.01)).wkt