diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a368421..4ad8024 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,16 +16,18 @@ jobs: strategy: matrix: python-version: - - '3.8' - - '3.9' - - '3.10' - - '3.11' - - '3.12' + - '3.8' + - '3.9' + - '3.10' + - '3.11' + - '3.12' + - '3.13' + # - '3.14.0-alpha.2' wait for pyproj and rasterio wheels to support 3.14 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} @@ -60,7 +62,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.12' + python-version: '3.13' - name: Install dependencies run: | @@ -92,9 +94,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 }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 16aa6ef..9673c9b 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/CHANGES.md b/CHANGES.md index d82944c..05432f9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,4 +1,9 @@ +## Unreleased + +* add python 3.13 support +* update pyproj dependency version to `>=3.1,<4.0` + ## 6.1.0 (2024-10-17) * add `_tile_matrices_idx: Dict[str, int]` private attribute to improve `matrices` lookup diff --git a/morecantile/defaults.py b/morecantile/defaults.py index d93f52f..a759efc 100644 --- a/morecantile/defaults.py +++ b/morecantile/defaults.py @@ -55,7 +55,7 @@ def register( """Register TileMatrixSet(s).""" for identifier in custom_tms.keys(): if identifier in self.tms and not overwrite: - raise Exception(f"{identifier} is already a registered TMS.") + raise InvalidIdentifier(f"{identifier} is already a registered TMS.") return TileMatrixSets({**self.tms, **custom_tms}) diff --git a/morecantile/models.py b/morecantile/models.py index 84bcd08..9f5f9ab 100644 --- a/morecantile/models.py +++ b/morecantile/models.py @@ -510,6 +510,7 @@ def __init__(self, **data): "Could not create coordinate Transformer from input CRS to the given geographic CRS" "some methods might not be available.", UserWarning, + stacklevel=1, ) self._to_geographic = None self._from_geographic = None @@ -537,10 +538,8 @@ def is_quadtree(self) -> bool: def is_variable(self) -> bool: """Check if TMS has variable width matrix.""" return any( - [ - True if matrix.variableMatrixWidths is not None else False - for matrix in self.tileMatrices - ] + True if matrix.variableMatrixWidths is not None else False + for matrix in self.tileMatrices ) def __iter__(self): @@ -800,6 +799,7 @@ def matrix(self, zoom: int) -> TileMatrix: warnings.warn( f"TileMatrix not found for level: {zoom} - Creating values from TMS Scale.", UserWarning, + stacklevel=1, ) # TODO: what if we want to construct a matrix for a level up ? @@ -894,6 +894,7 @@ def lnglat(self, x: float, y: float, truncate=False) -> Coords: warnings.warn( f"Point ({x}, {y}) is outside TMS bounds {list(self.xy_bbox)}.", PointOutsideTMSBounds, + stacklevel=1, ) lng, lat = self._to_geographic.transform(x, y) @@ -913,6 +914,7 @@ def xy(self, lng: float, lat: float, truncate=False) -> Coords: warnings.warn( f"Point ({lng}, {lat}) is outside TMS bounds {list(self.bbox)}.", PointOutsideTMSBounds, + stacklevel=1, ) x, y = self._from_geographic.transform(lng, lat) @@ -1372,6 +1374,7 @@ def feature( "CRS is no longer part of the GeoJSON specification." "Other projection than EPSG:4326 might not be supported.", UserWarning, + stacklevel=1, ) feat.update( { diff --git a/morecantile/utils.py b/morecantile/utils.py index 5da80cb..c078861 100644 --- a/morecantile/utils.py +++ b/morecantile/utils.py @@ -118,12 +118,10 @@ def is_power_of_two(number: int) -> bool: def check_quadkey_support(tms: List) -> bool: """Check if a Tile Matrix Set supports quadkeys""" return all( - [ - (t.matrixWidth == t.matrixHeight) - and is_power_of_two(t.matrixWidth) - and ((t.matrixWidth * 2) == tms[i + 1].matrixWidth) - for i, t in enumerate(tms[:-1]) - ] + (t.matrixWidth == t.matrixHeight) + and is_power_of_two(t.matrixWidth) + and ((t.matrixWidth * 2) == tms[i + 1].matrixWidth) + for i, t in enumerate(tms[:-1]) ) diff --git a/pyproject.toml b/pyproject.toml index 63d7bb0..609b10a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,12 +17,13 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Topic :: Scientific/Engineering :: GIS", ] dynamic = ["version"] dependencies = [ "attrs", - "pyproj~=3.1", + "pyproj>=3.1,<4.0", "pydantic~=2.0", ] @@ -95,7 +96,7 @@ default_section = "THIRDPARTY" [tool.mypy] no_strict_optional = true -[tool.ruff] +[tool.ruff.lint] select = [ "D1", # pydocstyle errors "E", # pycodestyle errors @@ -110,7 +111,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"] diff --git a/tests/test_morecantile.py b/tests/test_morecantile.py index c49f8cc..6530a72 100644 --- a/tests/test_morecantile.py +++ b/tests/test_morecantile.py @@ -43,7 +43,7 @@ def test_register(): assert "MyCustomGrid3031" in defaults.list() # Check it will raise an exception if TMS is already registered - with pytest.raises(Exception): + with pytest.raises(InvalidIdentifier): defaults = defaults.register({"MyCustomGrid3031": tms}) # Do not raise is overwrite=True