[Git][debian-gis-team/python-pyproj][upstream] New upstream version 3.7.1~rc0
Bas Couwenberg (@sebastic)
gitlab at salsa.debian.org
Sat Feb 15 06:38:03 GMT 2025
Bas Couwenberg pushed to branch upstream at Debian GIS Project / python-pyproj
Commits:
22cef166 by Bas Couwenberg at 2025-02-15T07:30:48+01:00
New upstream version 3.7.1~rc0
- - - - -
30 changed files:
- .github/workflows/build_docs.yaml
- .github/workflows/release.yaml
- .github/workflows/test_proj_latest.yaml
- .github/workflows/tests.yaml
- .pre-commit-config.yaml
- HOW_TO_RELEASE.md
- ci/proj-compile-wheels.sh
- ci/vcpkg.json
- docs/history.rst
- docs/index.rst
- docs/past_versions.rst
- pyproj/__init__.py
- pyproj/_crs.pyi
- pyproj/_crs.pyx
- pyproj/_geod.pyi
- pyproj/_geod.pyx
- pyproj/_transformer.pyi
- pyproj/_transformer.pyx
- pyproj/aoi.py
- pyproj/crs/coordinate_operation.py
- pyproj/crs/crs.py
- pyproj/database.pyx
- pyproj/geod.py
- pyproj/sync.py
- pyproj/transformer.py
- pyproject.toml
- test/crs/test_crs_cf.py
- test/crs/test_crs_coordinate_system.py
- test/test_proj.py
- test/test_sync.py
Changes:
=====================================
.github/workflows/build_docs.yaml
=====================================
@@ -21,7 +21,7 @@ jobs:
persist-credentials: false
- name: Setup Conda
- uses: mamba-org/setup-micromamba at v1
+ uses: mamba-org/setup-micromamba at v2
with:
init-shell: bash
environment-name: docs
=====================================
.github/workflows/release.yaml
=====================================
@@ -15,7 +15,7 @@ concurrency:
cancel-in-progress: true
env:
- PROJ_VERSION: "9.4.1"
+ PROJ_VERSION: "9.5.1"
DEBIAN_FRONTEND: noninteractive
jobs:
@@ -26,7 +26,7 @@ jobs:
- uses: actions/checkout at v4
- name: Setup Conda
- uses: mamba-org/setup-micromamba at v1
+ uses: mamba-org/setup-micromamba at v2
with:
init-shell: bash
environment-name: sdist_env
@@ -64,12 +64,12 @@ jobs:
include:
- os: ubuntu-22.04
arch: x86_64
- # - os: ubuntu-22.04
- # arch: i686
- - os: macos-12
+ - os: ubuntu-22.04-arm
+ arch: aarch64
+ - os: macos-13
arch: x86_64
cmake_osx_architectures: x86_64
- macos_deployment_target: "12.0"
+ macos_deployment_target: "13.0"
- os: macos-14
arch: arm64
cmake_osx_architectures: arm64
@@ -125,9 +125,9 @@ jobs:
cp "$VCPKG_INSTALLATION_ROOT/installed/${{ matrix.triplet }}/share/proj/"* ${GITHUB_WORKSPACE}/pyproj/proj_dir/share/proj/
- name: Build wheels
- uses: pypa/cibuildwheel at v2.21
+ uses: pypa/cibuildwheel at v2.22
env:
- CIBW_SKIP: "*musllinux* pp*-win* pp31*"
+ CIBW_SKIP: "pp*-win* pp31*"
CIBW_ARCHS: ${{ matrix.arch }}
CIBW_ENVIRONMENT_LINUX:
PROJ_WHEEL=true
@@ -185,7 +185,12 @@ jobs:
- uses: actions/download-artifact at v4
continue-on-error: ${{ github.event_name == 'push' && github.ref_type != 'tag' }}
with:
- name: wheels-macos-12-x86_64
+ name: wheels-ubuntu-22.04-arm-aarch64
+ path: dist
+ - uses: actions/download-artifact at v4
+ continue-on-error: ${{ github.event_name == 'push' && github.ref_type != 'tag' }}
+ with:
+ name: wheels-macos-13-x86_64
path: dist
- uses: actions/download-artifact at v4
continue-on-error: ${{ github.event_name == 'push' && github.ref_type != 'tag' }}
=====================================
.github/workflows/test_proj_latest.yaml
=====================================
@@ -1,4 +1,4 @@
-name: Test PROJ Latest
+name: Test PROJ and Cython Latest
on:
push:
@@ -41,7 +41,7 @@ jobs:
shell: bash
run: |
python -V
- python -m pip install cython
+ python -m pip install --upgrade --pre --only-binary :all: -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple cython
python -m pip install -e .
python -m pip install -r requirements-test.txt
pyproj -v
=====================================
.github/workflows/tests.yaml
=====================================
@@ -117,7 +117,7 @@ jobs:
- uses: actions/checkout at v4
- name: Setup Conda
- uses: mamba-org/setup-micromamba at v1
+ uses: mamba-org/setup-micromamba at v2
with:
# https://github.com/mamba-org/setup-micromamba/issues/225
micromamba-version: 1.5.10-0
@@ -198,4 +198,4 @@ jobs:
micromamba run -n test sphinx-build -b html docs/ docs/_build/
micromamba run -n test sphinx-build -b man docs/ docs/_build/
- - uses: codecov/codecov-action at v4
+ - uses: codecov/codecov-action at v5
=====================================
.pre-commit-config.yaml
=====================================
@@ -37,3 +37,7 @@ repos:
rev: v2.2.6
hooks:
- id: codespell
+ - repo: https://github.com/astral-sh/ruff-pre-commit
+ rev: v0.7.1
+ hooks:
+ - id: ruff
=====================================
HOW_TO_RELEASE.md
=====================================
@@ -18,10 +18,9 @@ The next step is to create a tag with the same name as the version just added. T
### Test the release builds
-1. Create a draft PR at https://github.com/pyproj4/pyproj-wheels and verify tests pass.
+1. Check the wheels built at https://github.com/pyproj4/pyproj using GitHub Actions.
2. Create a draft PR at https://github.com/conda-forge/pyproj-feedstock and verify tests pass.
-3. Check the wheels built at https://github.com/pyproj4/pyproj using GitHub Actions.
-4. Verify Debian builds were successful.
+3. Verify Debian builds were successful.
4. Verify Fedora builds were successful.
5. Verify the docs build successfully.
@@ -41,10 +40,7 @@ Next, go through the history and add release notes (see: [automatically generate
### The wheels
-Most of the wheels are tested with each merge to main and uploaded to pypi on release in GitHub Actions. However, the arm64 wheels are built separately. This provides instructions for those wheels:
-
-1. linux arm64: Update the PR at https://github.com/pyproj4/pyproj-wheels with the release tag & merge. The wheels will automatically upload to pypi when the CI runs succeed.
-2. macos arm64: Download the release wheel artifacts from the Cirrus CI build and upload manually to pypi.
+The wheels are tested with each merge to main and uploaded to https://pypi.anaconda.org/scientific-python-nightly-wheels/simple in GitHub Actions. They are uploaded to pypi on pre-release and release in GitHub Actions.
### Verify conda-forge build is correct
=====================================
ci/proj-compile-wheels.sh
=====================================
@@ -19,6 +19,10 @@ if [ $(uname) == "Darwin" ]; then
IS_MACOS=1;
fi
+if [ -f /etc/alpine-release ]; then
+ IS_ALPINE=1
+fi
+
if [ -z "$IS_MACOS" ]; then
# Strip all binaries after compilation.
STRIP_FLAGS=${STRIP_FLAGS:-"-Wl,-strip-all"}
@@ -100,6 +104,8 @@ function install_rsync {
if [ -n "$IS_MACOS" ]; then
# macOS. The colon in the next line is the null command
:
+ elif [ -n "$IS_ALPINE" ]; then
+ [[ $(type -P rsync) ]] || apk add rsync
elif [[ $MB_ML_VER == "_2_24" ]]; then
# debian:9 based distro
[[ $(type -P rsync) ]] || apt-get install -y rsync
@@ -177,6 +183,7 @@ function build_simple {
function get_modern_cmake {
# Install cmake >= 2.8
+ if [ -n "$IS_ALPINE" ]; then return; fi # alpine has modern cmake already
local cmake=cmake
if [ -n "$IS_MACOS" ]; then
brew install cmake > /dev/null
@@ -196,6 +203,7 @@ function get_modern_cmake {
function build_zlib {
# Gives an old but safe version
if [ -n "$IS_MACOS" ]; then return; fi # OSX has zlib already
+ if [ -n "$IS_ALPINE" ]; then return; fi # alpine has zlib already
if [ -e zlib-stamp ]; then return; fi
if [[ $MB_ML_VER == "_2_24" ]]; then
# debian:9 based distro
@@ -209,6 +217,7 @@ function build_zlib {
function build_perl {
if [ -n "$IS_MACOS" ]; then return; fi # OSX has perl already
+ if [ -n "$IS_ALPINE" ]; then return; fi # alpine has perl already
if [ -e perl-stamp ]; then return; fi
if [[ $MB_ML_VER == "_2_24" ]]; then
# debian:9 based distro
=====================================
ci/vcpkg.json
=====================================
@@ -1,11 +1,11 @@
{
"name": "pyproj",
- "version": "3.7.0",
+ "version": "3.7.1",
"dependencies": [
{
"name": "proj",
- "version>=": "9.4.1"
+ "version>=": "9.5.1"
}
],
- "builtin-baseline": "513aa7ceb3b5e9bf90882cb7edc06c9d5efcf0ee"
+ "builtin-baseline": "4ec74919dbf24931b29347b000c74374e8bbde35"
}
=====================================
docs/history.rst
=====================================
@@ -1,6 +1,16 @@
Change Log
==========
+3.7.1
+------
+- WHL: Add wheels for musllinux (pull #1461)
+- WHL: MacOS minimum deployment target moved to 13 (pull #1475)
+- WHL: Wheels contain PROJ 9.5.1 (pull #1477)
+- Cython 3.1+ fixes (pull #1452)
+- TST: remove checking is python >= 3.4 (pull #1446)
+- TST: Add assert statements at the end of tests (pull #1453)
+- LNT: Setup ruff & lint fixes (pull #1455 #1456)
+
3.7.0
------
- WHL: Wheels contain PROJ 9.4.1 (pull #1423)
=====================================
docs/index.rst
=====================================
@@ -5,7 +5,7 @@ Python interface to `PROJ <https://proj.org/>`_ (cartographic projections and c
GitHub Repository: https://github.com/pyproj4/pyproj
-.. note:: Minimum supported PROJ version is 9.0
+.. note:: Minimum supported PROJ version is 9.2
.. note:: Minimum supported Python version is 3.10
=====================================
docs/past_versions.rst
=====================================
@@ -1,6 +1,7 @@
Documentation Archive
=====================
+- `3.7.0 <https://pyproj4.github.io/pyproj/3.7.0/>`_
- `3.6.1 <https://pyproj4.github.io/pyproj/3.6.1/>`_
- `3.5.0 <https://pyproj4.github.io/pyproj/3.5.0/>`_
- `3.4.1 <https://pyproj4.github.io/pyproj/3.4.1/>`_
=====================================
pyproj/__init__.py
=====================================
@@ -71,7 +71,7 @@ from pyproj.transformer import ( # noqa: F401 pylint: disable=unused-import
transform,
)
-__version__ = "3.7.0"
+__version__ = "3.7.1rc0"
__all__ = [
"Proj",
"Geod",
=====================================
pyproj/_crs.pyi
=====================================
@@ -12,8 +12,6 @@ class Axis:
unit_name: str
unit_auth_code: str
unit_code: str
- def __str__(self) -> str: ...
- def __repr__(self) -> str: ...
class AreaOfUse:
west: float
@@ -21,8 +19,6 @@ class AreaOfUse:
east: float
north: float
name: str
- def __str__(self) -> str: ...
- def __repr__(self) -> str: ...
@property
def bounds(self) -> tuple[float, float, float, float]: ...
@@ -40,14 +36,12 @@ class Base:
) -> str: ...
def to_json(self, pretty: bool = False, indentation: int = 2) -> str: ...
def to_json_dict(self) -> dict: ...
- def __str__(self) -> str: ...
- def __repr__(self) -> str: ...
- def __eq__(self, other: Any) -> bool: ...
+ def __eq__(self, other: object) -> bool: ...
def is_exact_same(self, other: Any) -> bool: ...
class _CRSParts(Base):
@classmethod
- def from_user_input(cls, user_input: Any) -> "_CRSParts": ...
+ def from_user_input(cls, user_input: Any) -> _CRSParts: ...
class Ellipsoid(_CRSParts):
semi_major_metre: float
@@ -55,36 +49,36 @@ class Ellipsoid(_CRSParts):
is_semi_minor_computed: float
inverse_flattening: float
@staticmethod
- def from_authority(auth_name: str, code: int | str) -> "Ellipsoid": ...
+ def from_authority(auth_name: str, code: int | str) -> Ellipsoid: ...
@staticmethod
- def from_epsg(code: int | str) -> "Ellipsoid": ...
+ def from_epsg(code: int | str) -> Ellipsoid: ...
@staticmethod
- def from_string(ellipsoid_string: str) -> "Ellipsoid": ...
+ def from_string(ellipsoid_string: str) -> Ellipsoid: ...
@staticmethod
- def from_json_dict(ellipsoid_dict: dict) -> "Ellipsoid": ...
+ def from_json_dict(ellipsoid_dict: dict) -> Ellipsoid: ...
@staticmethod
- def from_json(ellipsoid_json_str: str) -> "Ellipsoid": ...
+ def from_json(ellipsoid_json_str: str) -> Ellipsoid: ...
@staticmethod
- def from_name(ellipsoid_name: str, auth_name: str | None = None) -> "Ellipsoid": ...
+ def from_name(ellipsoid_name: str, auth_name: str | None = None) -> Ellipsoid: ...
class PrimeMeridian(_CRSParts):
longitude: float
unit_conversion_factor: str
unit_name: str
@staticmethod
- def from_authority(auth_name: str, code: int | str) -> "PrimeMeridian": ...
+ def from_authority(auth_name: str, code: int | str) -> PrimeMeridian: ...
@staticmethod
- def from_epsg(code: int | str) -> "PrimeMeridian": ...
+ def from_epsg(code: int | str) -> PrimeMeridian: ...
@staticmethod
- def from_string(prime_meridian_string: str) -> "PrimeMeridian": ...
+ def from_string(prime_meridian_string: str) -> PrimeMeridian: ...
@staticmethod
- def from_json_dict(prime_meridian_dict: dict) -> "PrimeMeridian": ...
+ def from_json_dict(prime_meridian_dict: dict) -> PrimeMeridian: ...
@staticmethod
- def from_json(prime_meridian_json_str: str) -> "PrimeMeridian": ...
+ def from_json(prime_meridian_json_str: str) -> PrimeMeridian: ...
@staticmethod
def from_name(
prime_meridian_name: str, auth_name: str | None = None
- ) -> "PrimeMeridian": ...
+ ) -> PrimeMeridian: ...
class Datum(_CRSParts):
type_name: str
@@ -93,28 +87,28 @@ class Datum(_CRSParts):
@property
def prime_meridian(self) -> PrimeMeridian | None: ...
@staticmethod
- def from_authority(auth_name: str, code: int | str) -> "Datum": ...
+ def from_authority(auth_name: str, code: int | str) -> Datum: ...
@staticmethod
- def from_epsg(code: int | str) -> "Datum": ...
+ def from_epsg(code: int | str) -> Datum: ...
@staticmethod
- def from_string(datum_string: str) -> "Datum": ...
+ def from_string(datum_string: str) -> Datum: ...
@staticmethod
- def from_json_dict(datum_dict: dict) -> "Datum": ...
+ def from_json_dict(datum_dict: dict) -> Datum: ...
@staticmethod
- def from_json(datum_json_str: str) -> "Datum": ...
+ def from_json(datum_json_str: str) -> Datum: ...
@staticmethod
- def from_name(datum_name: str, auth_name: str | None = None) -> "Datum": ...
+ def from_name(datum_name: str, auth_name: str | None = None) -> Datum: ...
class CoordinateSystem(_CRSParts):
def __init__(self) -> None: ...
@property
def axis_list(self) -> Iterable[Axis]: ...
@staticmethod
- def from_string(coordinate_system_string: str) -> "CoordinateSystem": ...
+ def from_string(coordinate_system_string: str) -> CoordinateSystem: ...
@staticmethod
- def from_json_dict(coordinate_system_dict: dict) -> "CoordinateSystem": ...
+ def from_json_dict(coordinate_system_dict: dict) -> CoordinateSystem: ...
@staticmethod
- def from_json(coordinate_system_json_str: str) -> "CoordinateSystem": ...
+ def from_json(coordinate_system_json_str: str) -> CoordinateSystem: ...
def to_cf(self, rotated_pole: bool = False) -> list[dict]: ...
class Param:
@@ -127,8 +121,6 @@ class Param:
unit_auth_name: str
unit_code: str
unit_category: str
- def __str__(self) -> str: ...
- def __repr__(self) -> str: ...
class Grid:
short_name: str
@@ -138,8 +130,6 @@ class Grid:
direct_download: str
open_license: str
available: str
- def __str__(self) -> str: ...
- def __repr__(self) -> str: ...
class CoordinateOperation(_CRSParts):
method_name: str
@@ -158,19 +148,18 @@ class CoordinateOperation(_CRSParts):
@property
def towgs84(self) -> Iterable[float]: ...
@property
- def operations(self) -> tuple["CoordinateOperation"]: ...
+ def operations(self) -> tuple[CoordinateOperation]: ...
def __init__(self) -> None: ...
- def __repr__(self) -> str: ...
@staticmethod
- def from_authority(auth_name: str, code: int | str) -> "CoordinateOperation": ...
+ def from_authority(auth_name: str, code: int | str) -> CoordinateOperation: ...
@staticmethod
- def from_epsg(code: int | str) -> "CoordinateOperation": ...
+ def from_epsg(code: int | str) -> CoordinateOperation: ...
@staticmethod
- def from_string(ellipsoid_string: str) -> "CoordinateOperation": ...
+ def from_string(ellipsoid_string: str) -> CoordinateOperation: ...
@staticmethod
- def from_json_dict(ellipsoid_dict: dict) -> "CoordinateOperation": ...
+ def from_json_dict(ellipsoid_dict: dict) -> CoordinateOperation: ...
@staticmethod
- def from_json(ellipsoid_json_str: str) -> "CoordinateOperation": ...
+ def from_json(ellipsoid_json_str: str) -> CoordinateOperation: ...
def to_proj4(self, version: ProjVersion | int = ProjVersion.PROJ_5) -> str: ...
@staticmethod
def from_name(
@@ -179,7 +168,7 @@ class CoordinateOperation(_CRSParts):
coordinate_operation_type: (
CoordinateOperationType | str
) = CoordinateOperationType.CONVERSION,
- ) -> "CoordinateOperation": ...
+ ) -> CoordinateOperation: ...
class AuthorityMatchInfo(NamedTuple):
auth_name: str
@@ -201,13 +190,13 @@ class _CRS(Base):
@property
def datum(self) -> Datum | None: ...
@property
- def sub_crs_list(self) -> Iterable["_CRS"]: ...
+ def sub_crs_list(self) -> Iterable[_CRS]: ...
@property
- def source_crs(self) -> Optional["_CRS"]: ...
+ def source_crs(self) -> Optional[_CRS]: ...
@property
- def target_crs(self) -> Optional["_CRS"]: ...
+ def target_crs(self) -> Optional[_CRS]: ...
@property
- def geodetic_crs(self) -> Optional["_CRS"]: ...
+ def geodetic_crs(self) -> Optional[_CRS]: ...
@property
def coordinate_system(self) -> CoordinateSystem | None: ...
@property
@@ -218,8 +207,8 @@ class _CRS(Base):
def list_authority(
self, auth_name: str | None = None, min_confidence: int = 70
) -> list[AuthorityMatchInfo]: ...
- def to_3d(self, name: str | None = None) -> "_CRS": ...
- def to_2d(self, name: str | None = None) -> "_CRS": ...
+ def to_3d(self, name: str | None = None) -> _CRS: ...
+ def to_2d(self, name: str | None = None) -> _CRS: ...
@property
def is_geographic(self) -> bool: ...
@property
@@ -237,7 +226,7 @@ class _CRS(Base):
def equals(self, other: Any, ignore_axis_order: bool) -> bool: ...
@property
def is_deprecated(self) -> bool: ...
- def get_non_deprecated(self) -> list["_CRS"]: ...
+ def get_non_deprecated(self) -> list[_CRS]: ...
def is_proj(proj_string: str) -> bool: ...
def is_wkt(proj_string: str) -> bool: ...
=====================================
pyproj/_crs.pyx
=====================================
@@ -2352,13 +2352,13 @@ cdef class _CRS(Base):
self._coordinate_operation = None
self._type_name = None
- def __init__(self, const char *proj_string):
+ def __init__(self, str proj_string):
self.context = pyproj_context_create()
self._context_manager = get_context_manager()
# initialize projection
self.projobj = proj_create(
self.context,
- proj_string,
+ cstrencode(proj_string),
)
if self.projobj == NULL:
raise CRSError(f"Invalid projection: {proj_string}")
=====================================
pyproj/_geod.pyi
=====================================
@@ -20,8 +20,7 @@ class Geod:
def __init__(
self, a: float, f: float, sphere: bool, b: float, es: float
) -> None: ...
- def __reduce__(self) -> tuple[type["Geod"], str]: ...
- def __repr__(self) -> str: ...
+ def __reduce__(self) -> tuple[type[Geod], str]: ...
def _fwd(
self,
lons: Any,
=====================================
pyproj/_geod.pyx
=====================================
@@ -90,10 +90,7 @@ cdef class Geod:
geod_init(&self._geod_geodesic, <double> a, <double> f)
self.a = a
self.f = f
- # convert 'a' only for initstring
- a_str = int(a) if a.is_integer() else a
- f_str = int(f) if f.is_integer() else f
- self.initstring = f"+a={a_str} +f={f_str}"
+ self.initstring = f"+{a=} +{f=}"
self.sphere = sphere
self.b = b
self.es = es
=====================================
pyproj/_transformer.pyi
=====================================
@@ -83,9 +83,9 @@ class _Transformer(Base):
allow_ballpark: bool | None = None,
force_over: bool = False,
only_best: bool | None = None,
- ) -> "_Transformer": ...
+ ) -> _Transformer: ...
@staticmethod
- def from_pipeline(proj_pipeline: bytes) -> "_Transformer": ...
+ def from_pipeline(proj_pipeline: bytes) -> _Transformer: ...
def _transform(
self,
inx: Any,
=====================================
pyproj/_transformer.pyx
=====================================
@@ -151,7 +151,8 @@ cdef class _TransformerGroup:
double north_lat_degree
if authority is not None:
- c_authority = authority
+ tmp = cstrencode(authority)
+ c_authority = tmp
try:
operation_factory_context = proj_create_operation_factory_context(
=====================================
pyproj/aoi.py
=====================================
@@ -69,7 +69,7 @@ class AreaOfUse(NamedTuple):
return self.west, self.south, self.east, self.north
def __str__(self) -> str:
- return f"- name: {self.name}\n" f"- bounds: {self.bounds}"
+ return f"- name: {self.name}\n- bounds: {self.bounds}"
@dataclass
=====================================
pyproj/crs/coordinate_operation.py
=====================================
@@ -604,7 +604,7 @@ class LambertCylindricalEqualAreaScaleConversion(CoordinateOperation):
f"+k_0={scale_factor_natural_origin}"
)
return cls.from_json(
- CRS(proj_string).coordinate_operation.to_json() # type: ignore
+ CRS(proj_string).coordinate_operation.to_json() # type: ignore[union-attr]
)
=====================================
pyproj/crs/crs.py
=====================================
@@ -334,7 +334,7 @@ class CRS:
elif isinstance(projparams, (list, tuple)) and len(projparams) == 2:
projstring = _prepare_from_authority(*projparams)
elif hasattr(projparams, "to_wkt"):
- projstring = projparams.to_wkt() # type: ignore
+ projstring = projparams.to_wkt()
else:
raise CRSError(f"Invalid CRS input: {projparams!r}")
@@ -1590,7 +1590,7 @@ class CRS:
"""
return self._crs.get_non_deprecated()
- def __eq__(self, other: Any) -> bool:
+ def __eq__(self, other: object) -> bool:
return self.equals(other)
def __getstate__(self) -> dict[str, str]:
=====================================
pyproj/database.pyx
=====================================
@@ -460,7 +460,7 @@ def get_database_metadata(str key not None):
cdef const char* metadata = NULL
metadata = proj_context_get_database_metadata(
pyproj_context_create(),
- cstrdecode(key),
+ cstrencode(key),
)
if metadata == NULL:
return None
=====================================
pyproj/geod.py
=====================================
@@ -1003,7 +1003,7 @@ class Geod(_Geod):
The total geodesic length of the geometry (meters).
"""
try:
- return self.line_length(*geometry.xy, radians=radians) # type: ignore
+ return self.line_length(*geometry.xy, radians=radians) # type: ignore[misc]
except (AttributeError, NotImplementedError):
pass
if hasattr(geometry, "exterior"):
@@ -1074,7 +1074,7 @@ class Geod(_Geod):
The geodesic area (meters^2) and perimeter (meters) of the polygon.
"""
try:
- return self.polygon_area_perimeter( # type: ignore
+ return self.polygon_area_perimeter( # type: ignore[misc]
*geometry.xy, radians=radians
)
except (AttributeError, NotImplementedError):
@@ -1114,7 +1114,7 @@ class Geod(_Geod):
# no ellipse name found, call super class
return super().__repr__()
- def __eq__(self, other: Any) -> bool:
+ def __eq__(self, other: object) -> bool:
"""
equality operator == for Geod objects
=====================================
pyproj/sync.py
=====================================
@@ -30,6 +30,8 @@ def _bbox_from_coords(coords: list) -> BBox | None:
coord_bbox = None
for coord_set in coords:
bbox = _bbox_from_coords(coord_set)
+ if bbox is None:
+ continue
if coord_bbox is None:
coord_bbox = bbox
else:
@@ -199,8 +201,7 @@ def _load_grid_geojson(target_directory: str | Path | None = None) -> dict[str,
target_directory = get_user_data_dir(True)
local_path = Path(target_directory, "files.geojson")
if not local_path.exists() or (
- (datetime.utcnow() - datetime.fromtimestamp(local_path.stat().st_mtime)).days
- > 0
+ (datetime.now() - datetime.fromtimestamp(local_path.stat().st_mtime)).days > 0
):
_download_resource_file(
file_url=f"{get_proj_endpoint()}/files.geojson",
=====================================
pyproj/transformer.py
=====================================
@@ -1167,7 +1167,7 @@ class Transformer:
f"Area of Use:\n{self.area_of_use or '- undefined'}"
)
- def __eq__(self, other: Any) -> bool:
+ def __eq__(self, other: object) -> bool:
if not isinstance(other, Transformer):
return False
return self._transformer.__eq__(other._transformer)
=====================================
pyproject.toml
=====================================
@@ -64,3 +64,99 @@ version = {attr = "pyproj.__version__"}
[tool.black]
target_version = ["py310"]
+
+[tool.ruff]
+line-length = 88
+target-version = "py310"
+fix = true
+
+[tool.ruff.lint]
+unfixable = []
+
+select = [
+ # pyflakes
+ "F",
+ # pycodestyle
+ "E", "W",
+ # flake8-2020
+ "YTT",
+ # flake8-bugbear
+ "B",
+ # flake8-quotes
+ "Q",
+ # flake8-debugger
+ "T10",
+ # flake8-gettext
+ "INT",
+ # pylint
+# "PL",
+ # flake8-pytest-style
+# "PT",
+ # misc lints
+ "PIE",
+ # flake8-pyi
+ "PYI",
+ # tidy imports
+ "TID",
+ # implicit string concatenation
+ "ISC",
+ # type-checking imports
+ "TCH",
+ # comprehensions
+ "C4",
+ # pygrep-hooks
+ "PGH",
+ # Ruff-specific rules
+ "RUF",
+ # flake8-bandit: exec-builtin
+ "S102",
+ # NumPy-specific rules
+ "NPY",
+ # Perflint
+ "PERF",
+ # flynt
+ "FLY",
+ # flake8-logging-format
+ "G",
+ # flake8-future-annotations
+ "FA",
+ # flake8-slots
+ "SLOT",
+ # flake8-raise
+ "RSE",
+]
+
+ignore = [
+ ### Intentionally disabled
+ # Line too long
+ "E501",
+ # Unnecessary `dict` call (rewrite as a literal)
+ "C408",
+ # Consider iterable unpacking instead of concatenation
+ "RUF005",
+ # No explicit `stacklevel` keyword argument found
+ "B028",
+ # Unused `noqa` directive # Only work if ruff is the solve linter/formatter
+ "RUF100",
+ # `zip()` without an explicit `strict=` parameter
+ "B905",
+ # Only simple default values allowed for typed arguments
+ "PYI011",
+
+ ### TODO: Enable gradually
+ # Rename unused
+ "B007",
+ # Move standard library import into a type-checking block
+ "TCH003",
+ # Consider f-string instead of string join
+ "FLY002",
+ # Use a list comprehension to create a transformed list
+ "PERF401"
+
+]
+
+[tool.mypy]
+files = ["pyproj"]
+python_version = "3.10"
+ignore_errors = false
+enable_error_code = "ignore-without-code"
=====================================
test/crs/test_crs_cf.py
=====================================
@@ -1864,16 +1864,16 @@ def test_export_compound_crs_cs():
def test_ellipsoidal_cs__geodetic():
crs = CRS.from_epsg(4326)
- crs.cs_to_cf() == [
+ assert crs.cs_to_cf() == [
{
"standard_name": "latitude",
- "long_name": "geodetic latitude coordinate",
+ "long_name": "latitude coordinate",
"units": "degrees_north",
"axis": "Y",
},
{
"standard_name": "longitude",
- "long_name": "geodetic longitude coordinate",
+ "long_name": "longitude coordinate",
"units": "degrees_east",
"axis": "X",
},
@@ -1935,16 +1935,16 @@ def test_3d_ellipsoidal_cs_depth():
},
}
)
- crs.cs_to_cf() == [
+ assert crs.cs_to_cf() == [
{
"standard_name": "latitude",
- "long_name": "geodetic latitude coordinate",
+ "long_name": "latitude coordinate",
"units": "degrees_north",
"axis": "Y",
},
{
"standard_name": "longitude",
- "long_name": "geodetic longitude coordinate",
+ "long_name": "longitude coordinate",
"units": "degrees_east",
"axis": "X",
},
=====================================
test/crs/test_crs_coordinate_system.py
=====================================
@@ -210,7 +210,7 @@ def test_ellipsoidal3dcs_to_cf():
def test_cartesian2dcs_ft_to_cf():
csft = Cartesian2DCS(axis=Cartesian2DCSAxis.NORTHING_EASTING_FT)
- csft.to_cf() == [
+ assert csft.to_cf() == [
{
"axis": "Y",
"long_name": "Northing",
@@ -228,25 +228,25 @@ def test_cartesian2dcs_ft_to_cf():
def test_cartesian2dcs_to_cf():
csm = Cartesian2DCS(axis=Cartesian2DCSAxis.EASTING_NORTHING_FT)
- csm.to_cf() == [
- {
- "axis": "Y",
- "long_name": "Northing",
- "standard_name": "projection_y_coordinate",
- "units": "metre",
- },
+ assert csm.to_cf() == [
{
"axis": "X",
"long_name": "Easting",
"standard_name": "projection_x_coordinate",
- "units": "metre",
+ "units": "0.3048 metre",
+ },
+ {
+ "axis": "Y",
+ "long_name": "Northing",
+ "standard_name": "projection_y_coordinate",
+ "units": "0.3048 metre",
},
]
def test_verticalcs_depth_to_cf():
vcs = VerticalCS(axis=VerticalCSAxis.DEPTH)
- vcs.to_cf() == [
+ assert vcs.to_cf() == [
{
"standard_name": "height_above_reference_ellipsoid",
"long_name": "Depth",
@@ -259,7 +259,7 @@ def test_verticalcs_depth_to_cf():
def test_verticalcs_height_to_cf():
vcs = VerticalCS(axis=VerticalCSAxis.GRAVITY_HEIGHT_US_FT)
- vcs.to_cf() == [
+ assert vcs.to_cf() == [
{
"standard_name": "height_above_reference_ellipsoid",
"long_name": "Gravity-related height",
=====================================
test/test_proj.py
=====================================
@@ -1,7 +1,6 @@
import concurrent.futures
import math
import os
-import sys
import unittest
from unittest.mock import patch
@@ -159,9 +158,6 @@ class ProjLatLongTypeErrorTest(unittest.TestCase):
lon, lat = transform(p, p.to_latlong(), 200000, 400000)
- at unittest.skipIf(
- sys.version_info < (3, 4), "Python 3.4 or newer required for subTest()"
-)
class ForwardInverseTest(unittest.TestCase):
def test_fwd_inv(self):
for pj in pj_list.keys():
@@ -232,7 +228,7 @@ class ReprTests(unittest.TestCase):
def test_sphere(self):
# ellipse is Venus 2000 (IAU2000:29900), which is a sphere
g = Geod("+a=6051800 +b=6051800")
- self.assertEqual(repr(g), "Geod('+a=6051800 +f=0')")
+ self.assertEqual(repr(g), "Geod('+a=6051800.0 +f=0.0')")
# test __repr__ for Geod object
def test_ellps_name_round_trip(self):
=====================================
test/test_sync.py
=====================================
@@ -195,7 +195,7 @@ def test_download_resource_file__bad_sha256sum(urlretrieve_mock, tmp_path):
@patch("pyproj.sync.Path.stat")
def test__load_grid_geojson_old_file(stat_mock, tmp_path):
return_timestamp = MagicMock()
- return_timestamp.st_mtime = (datetime.utcnow() - timedelta(days=2)).timestamp()
+ return_timestamp.st_mtime = (datetime.now() - timedelta(days=2)).timestamp()
stat_mock.return_value = return_timestamp
tmp_path.joinpath("files.geojson").touch()
grids = _load_grid_geojson(target_directory=tmp_path)
View it on GitLab: https://salsa.debian.org/debian-gis-team/python-pyproj/-/commit/22cef1665c95015514259c9ef5c05483aafbda98
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/python-pyproj/-/commit/22cef1665c95015514259c9ef5c05483aafbda98
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20250215/dbcb64be/attachment-0001.htm>
More information about the Pkg-grass-devel
mailing list