[Git][debian-gis-team/pyresample][upstream] New upstream version 1.35.0

Antonio Valentino (@antonio.valentino) gitlab at salsa.debian.org
Wed Dec 10 07:43:13 GMT 2025



Antonio Valentino pushed to branch upstream at Debian GIS Project / pyresample


Commits:
1b705922 by Antonio Valentino at 2025-12-05T18:55:49+00:00
New upstream version 1.35.0
- - - - -


20 changed files:

- .github/workflows/ci.yaml
- .github/workflows/deploy.yaml
- .pre-commit-config.yaml
- CHANGELOG.md
- pyproject.toml
- pyresample/_formatting_html.py
- pyresample/_spatial_mp.py
- pyresample/bilinear/xarr.py
- pyresample/boundary/legacy_boundary.py
- pyresample/bucket/__init__.py
- pyresample/geometry.py
- pyresample/resampler.py
- pyresample/slicer.py
- pyresample/spherical.py
- pyresample/spherical_utils.py
- pyresample/test/test_boundary/test_legacy_boundary.py
- pyresample/test/test_geometry/test_swath_boundary.py
- pyresample/utils/proj4.py
- pyresample/version.py
- setup.py


Changes:

=====================================
.github/workflows/ci.yaml
=====================================
@@ -30,7 +30,7 @@ jobs:
 
     steps:
       - name: Checkout source
-        uses: actions/checkout at v4
+        uses: actions/checkout at v6
 
       - name: Setup Conda Environment
         uses: conda-incubator/setup-miniconda at v3
@@ -89,7 +89,7 @@ jobs:
         uses: codecov/codecov-action at v5
         with:
           flags: unittests
-          file: ./coverage.xml
+          files: ./coverage.xml
           env_vars: OS,PYTHON_VERSION,UNSTABLE
 
       - name: Coveralls Parallel


=====================================
.github/workflows/deploy.yaml
=====================================
@@ -17,7 +17,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout source
-        uses: actions/checkout at v4
+        uses: actions/checkout at v6
 
       - name: Create sdist
         shell: bash -l {0}
@@ -28,7 +28,7 @@ jobs:
           python -m build -s
 
       - name: Upload sdist to build artifacts
-        uses: actions/upload-artifact at v4
+        uses: actions/upload-artifact at v5
         with:
           name: sdist
           path: dist/*.tar.gz
@@ -41,9 +41,9 @@ jobs:
       fail-fast: false
       matrix:
         include:
-          - os: windows-2019
+          - os: windows-latest
             cibw_archs: "AMD64"
-          - os: windows-2019
+          - os: windows-latest
             cibw_archs: "ARM64"
           - os: macos-13
             cibw_archs: "x86_64"
@@ -55,21 +55,22 @@ jobs:
             cibw_archs: "x86_64"
 
     steps:
-      - uses: actions/checkout at v4
+      - uses: actions/checkout at v6
       - run: |
           git fetch --prune --unshallow
 
       - name: Build wheels
-        uses: pypa/cibuildwheel at v2.23.3
+        uses: pypa/cibuildwheel at v3.3.0
         env:
-          CIBW_SKIP: "cp36-* cp37-* cp38-* cp39-* cp310-* pp* *i686 *-musllinux*"
+          CIBW_SKIP: "cp39-* cp310-* *i686 *-musllinux*"
+          CIBW_ENABLE: cpython-freethreading
           CIBW_ARCHS: "${{ matrix.cibw_archs }}"
           CIBW_TEST_COMMAND: "python -c \"import pyresample; assert 'unknown' not in pyresample.__version__, 'incorrect version found'\""
           CIBW_TEST_SKIP: "*-win_arm64"
           CIBW_BUILD_VERBOSITY: 1
 
       - name: Upload wheel(s) as build artifacts
-        uses: actions/upload-artifact at v4
+        uses: actions/upload-artifact at v5
         with:
           name: "wheels-${{ matrix.os }}-${{ matrix.cibw_archs }}"
           path: ./wheelhouse/*.whl
@@ -81,19 +82,19 @@ jobs:
     if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/v')
     steps:
       - name: Download sdist artifact
-        uses: actions/download-artifact at v4
+        uses: actions/download-artifact at v6
         with:
           name: sdist
           path: dist
       - name: Download wheels artifact
-        uses: actions/download-artifact at v4
+        uses: actions/download-artifact at v6
         with:
           pattern: wheels-*
           merge-multiple: true
           path: dist
       - name: Publish package to PyPI
         if: github.event.action != 'published'
-        uses: pypa/gh-action-pypi-publish at v1.12.4
+        uses: pypa/gh-action-pypi-publish at v1.13.0
         with:
           user: __token__
           password: ${{ secrets.test_pypi_password }}
@@ -104,19 +105,19 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Download sdist artifact
-        uses: actions/download-artifact at v4
+        uses: actions/download-artifact at v6
         with:
           name: sdist
           path: dist
       - name: Download wheels artifact
-        uses: actions/download-artifact at v4
+        uses: actions/download-artifact at v6
         with:
           pattern: wheels-*
           merge-multiple: true
           path: dist
       - name: Publish package to PyPI
         if: github.event.action == 'published'
-        uses: pypa/gh-action-pypi-publish at v1.12.4
+        uses: pypa/gh-action-pypi-publish at v1.13.0
         with:
           user: __token__
           password: ${{ secrets.pypi_password }}


=====================================
.pre-commit-config.yaml
=====================================
@@ -2,23 +2,23 @@ exclude: '^$'
 fail_fast: false
 repos:
 - repo: https://github.com/astral-sh/ruff-pre-commit
-  rev: 'v0.11.8'
+  rev: 'v0.14.7'
   hooks:
   - id: ruff
 - repo: https://github.com/pre-commit/pre-commit-hooks
-  rev: v5.0.0
+  rev: v6.0.0
   hooks:
     - id: trailing-whitespace
     - id: end-of-file-fixer
     - id: check-yaml
       args: [--unsafe]
 - repo: https://github.com/PyCQA/bandit
-  rev: '1.8.3' # Update me!
+  rev: '1.9.2' # Update me!
   hooks:
     - id: bandit
       args: [--ini, .bandit]
 - repo: https://github.com/pre-commit/mirrors-mypy
-  rev: 'v1.15.0'  # Use the sha / tag you want to point at
+  rev: 'v1.19.0'  # Use the sha / tag you want to point at
   hooks:
     - id: mypy
       additional_dependencies:
@@ -32,7 +32,7 @@ repos:
         - pytest
       args: [ --warn-unused-configs ]
 - repo: https://github.com/pycqa/isort
-  rev: 6.0.1
+  rev: 7.0.0
   hooks:
     - id: isort
       language_version: python3


=====================================
CHANGELOG.md
=====================================
@@ -1,3 +1,28 @@
+## Version 1.35.0 (2025/12/01)
+
+### Issues Closed
+
+* [Issue 684](https://github.com/pytroll/pyresample/issues/684) - areas with non-matching descriptions compare equal
+* [Issue 666](https://github.com/pytroll/pyresample/issues/666) - data_reduce doesn't work for VIIRS L1B data
+* [Issue 664](https://github.com/pytroll/pyresample/issues/664) - How we define the "same" AreaDefinition?
+
+In this release 3 issues were closed.
+
+### Pull Requests Merged
+
+#### Bugs fixed
+
+* [PR 677](https://github.com/pytroll/pyresample/pull/677) - Fix boundaries losing precision for accurate polygon calculations
+* [PR 675](https://github.com/pytroll/pyresample/pull/675) - Fix BucketResampler using area's proj_dict instead crs
+* [PR 674](https://github.com/pytroll/pyresample/pull/674) - Revert change of map_blocks name= kwarg in favor of token=
+
+#### Features added
+
+* [PR 676](https://github.com/pytroll/pyresample/pull/676) - Enable free-threading in cython extensions
+
+In this release 4 pull requests were closed.
+
+
 ## Version 1.34.2 (2025/05/29)
 
 ### Pull Requests Merged


=====================================
pyproject.toml
=====================================
@@ -1,5 +1,5 @@
 [build-system]
-requires = ["setuptools", "wheel", "numpy>=2.0.0rc1,<2.3", "Cython>=3", "versioneer[toml]"]
+requires = ["setuptools", "wheel", "numpy>=2.0.0,<3", "Cython>=3.1", "versioneer[toml]"]
 build-backend = "setuptools.build_meta"
 
 [tool.ruff]


=====================================
pyresample/_formatting_html.py
=====================================
@@ -104,7 +104,7 @@ def plot_area_def(area: Union['geom.AreaDefinition', 'geom.SwathDefinition'], #
         crs = cartopy.crs.Mercator()
         fig, ax = plt.subplots(subplot_kw=dict(projection=crs))
 
-        poly = Polygon(list(zip(lx[::-1], ly[::-1])))  # make lat/lon counterclockwise for shapely
+        poly = Polygon(list(zip(lx[::-1], ly[::-1], strict=True)))  # make lat/lon counterclockwise for shapely
         ax.add_geometries([poly], crs=cartopy.crs.CRS(area.crs), facecolor="none", edgecolor="red")
         bounds = poly.buffer(5).bounds
         ax.set_extent([bounds[0], bounds[2], bounds[1], bounds[3]], crs=cartopy.crs.CRS(area.crs))


=====================================
pyresample/_spatial_mp.py
=====================================
@@ -188,7 +188,7 @@ def _run_jobs(target, args, nprocs):
         p.join()
     if ierr.value != 0:
         raise RuntimeError('%d errors in worker processes. Last one reported:\n%s' %
-                           (ierr.value, warn_msg.value._object_hook()))
+                           (ierr.value, warn_msg.value))
 
 # This is executed in an external process:
 


=====================================
pyresample/bilinear/xarr.py
=====================================
@@ -210,7 +210,7 @@ class XArrayBilinearResampler(BilinearBase):
     def load_resampling_info(self, filename):
         """Load bilinear resampling look-up tables and initialize the resampler."""
         try:
-            fid = zarr.open(filename, 'r')
+            fid = zarr.open(filename, mode='r')
             for val in BIL_COORDINATES:
                 cache = da.array(fid[val])
                 setattr(self, val, cache)


=====================================
pyresample/boundary/legacy_boundary.py
=====================================
@@ -45,8 +45,9 @@ class Boundary(object):
     def contour_poly(self):
         """Get the Spherical polygon corresponding to the Boundary."""
         if self._contour_poly is None:
+            # force 64-bit for more accuracy
             self._contour_poly = SphPolygon(
-                np.deg2rad(np.vstack(self.contour()).T))
+                np.deg2rad(np.vstack(self.contour()).T, dtype=np.float64))
         return self._contour_poly
 
     def draw(self, mapper, options, **more_options):
@@ -66,7 +67,7 @@ class AreaBoundary(Boundary):
         if len(sides) != 4:
             raise ValueError("AreaBoundary expects 4 sides.")
         # Retrieve sides
-        self.sides_lons, self.sides_lats = zip(*sides)
+        self.sides_lons, self.sides_lats = zip(*sides, strict=True)
         self.sides_lons = list(self.sides_lons)
         self.sides_lats = list(self.sides_lats)
 
@@ -81,7 +82,7 @@ class AreaBoundary(Boundary):
                  np.array([vmn, ..., vm1, vm0]),
                  np.array([vm0, ... ,v10, v00])]
         """
-        boundary = cls(*zip(lon_sides, lat_sides))
+        boundary = cls(*zip(lon_sides, lat_sides, strict=True))
         return boundary
 
     def contour(self):
@@ -125,7 +126,7 @@ class AreaDefBoundary(AreaBoundary):
                       "Use the Swath/AreaDefinition 'boundary' method instead!.",
                       PendingDeprecationWarning, stacklevel=2)
         AreaBoundary.__init__(self,
-                              *zip(lons, lats))
+                              *zip(lons, lats, strict=True))
 
         if frequency != 1:
             self.decimate(frequency)


=====================================
pyresample/bucket/__init__.py
=====================================
@@ -145,7 +145,7 @@ class BucketResampler(object):
         self.target_area = target_area
         self.source_lons = source_lons
         self.source_lats = source_lats
-        self.prj = Proj(self.target_area.proj_dict)
+        self.prj = Proj(self.target_area.crs)
         self.x_idxs = None
         self.y_idxs = None
         self.idxs = None


=====================================
pyresample/geometry.py
=====================================
@@ -1,7 +1,4 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-# Copyright (C) 2010-2023 Pyresample developers
+# Copyright (C) 2010-2025 Pyresample developers
 #
 # This program is free software: you can redistribute it and/or modify it under
 # the terms of the GNU Lesser General Public License as published by the Free
@@ -143,7 +140,13 @@ class BaseDefinition:
         return existing_hash
 
     def __eq__(self, other):
-        """Test for approximate equality."""
+        """Test for approximate equality.
+
+        Equality considers only the projection coordinates, not metadata such
+        as description or projection ID.  In other words, areas are considered
+        equal if they produce approximately the same output when used for
+        resampling, within floating point tolerances.
+        """
         if self is other:
             return True
         if not isinstance(other, BaseDefinition):
@@ -186,7 +189,7 @@ class BaseDefinition:
         return lons, lats
 
     def __ne__(self, other):
-        """Test for approximate equality."""
+        """Test for approximate inequality."""
         return not self.__eq__(other)
 
     def get_area_extent_for_subset(self, row_LR, col_LR, row_UL, col_UL):
@@ -345,7 +348,8 @@ class BaseDefinition:
         sides_dim1, sides_dim2 = zip(*[(top_dim1.squeeze(), top_dim2.squeeze()),
                                        (right_dim1.squeeze(), right_dim2.squeeze()),
                                        (bottom_dim1.squeeze(), bottom_dim2.squeeze()),
-                                       (left_dim1.squeeze(), left_dim2.squeeze())])
+                                       (left_dim1.squeeze(), left_dim2.squeeze())],
+                                     strict=True)
         if hasattr(sides_dim1[0], 'compute') and da is not None:
             sides_dim1, sides_dim2 = da.compute(sides_dim1, sides_dim2)
         return self._filter_sides_nans(sides_dim1, sides_dim2)
@@ -358,7 +362,7 @@ class BaseDefinition:
         """Remove nan and inf values present in each side."""
         new_dim1_sides = []
         new_dim2_sides = []
-        for dim1_side, dim2_side in zip(dim1_sides, dim2_sides):
+        for dim1_side, dim2_side in zip(dim1_sides, dim2_sides, strict=True):
             # FIXME: ~(~np.isfinite(dim1_side) | ~np.isfinite(dim1_side))
             is_valid_mask = ~(np.isnan(dim1_side) | np.isnan(dim2_side))
             if not is_valid_mask.any():
@@ -2109,7 +2113,12 @@ class AreaDefinition(_ProjectionDefinition):
         return area_def_str
 
     def __eq__(self, other):
-        """Test for equality."""
+        """Test for equality.
+
+        Equality considers only the projection coordinates, not metadata such
+        as description or projection ID.  In other words, areas are considered
+        equal if they produce the same output when used for resampling.
+        """
         try:
             return ((np.allclose(self.area_extent, other.area_extent)) and
                     (self.crs == other.crs) and
@@ -2118,7 +2127,7 @@ class AreaDefinition(_ProjectionDefinition):
             return super().__eq__(other)
 
     def __ne__(self, other):
-        """Test for equality."""
+        """Test for inequality."""
         return not self.__eq__(other)
 
     def update_hash(self, existing_hash: Optional[hashlib._Hash] = None) -> hashlib._Hash:


=====================================
pyresample/resampler.py
=====================================
@@ -355,7 +355,7 @@ def crop_source_area(source_geo_def, target_geo_def):
 def _enumerate_dst_area_chunks(dst_area, dst_chunks):
     """Enumerate the chunks in function of the dst_area."""
     for position, slices in _enumerate_chunk_slices(dst_chunks):
-        chunk_shape = tuple(chunk[pos] for pos, chunk in zip(position, dst_chunks))
+        chunk_shape = tuple(chunk[pos] for pos, chunk in zip(position, dst_chunks, strict=True))
         target_geo_def = dst_area[slices[-2:]]
         block_info = {"num-chunks": [len(chunk) for chunk in dst_chunks],
                       "chunk-location": position,


=====================================
pyresample/slicer.py
=====================================
@@ -105,7 +105,7 @@ class SwathSlicer(Slicer):
         from shapely.geometry import Polygon
 
         x, y = self.area_to_contain.get_edge_bbox_in_projection_coordinates(10)
-        poly = Polygon(zip(*self._source_transformer.transform(x, y)))
+        poly = Polygon(zip(*self._source_transformer.transform(x, y), strict=True))
         return poly
 
     def get_slices_from_polygon(self, poly):
@@ -121,7 +121,7 @@ class SwathSlicer(Slicer):
     @staticmethod
     def _assemble_slices(chunk_slices):
         """Assemble slices to one slice per dimension."""
-        lines, cols = zip(*chunk_slices)
+        lines, cols = zip(*chunk_slices, strict=True)
         line_slice = slice(min(slc.start for slc in lines), max(slc.stop for slc in lines))
         col_slice = slice(min(slc.start for slc in cols), max(slc.stop for slc in cols))
         slices = col_slice, line_slice
@@ -132,7 +132,7 @@ class SwathSlicer(Slicer):
         from shapely.geometry import Polygon
 
         for (lons, lats), (line_slice, col_slice) in _get_chunk_bboxes_for_swath_to_crop(swath_to_crop):
-            smaller_poly = Polygon(zip(*self._target_transformer.transform(lons, lats)))
+            smaller_poly = Polygon(zip(*self._target_transformer.transform(lons, lats), strict=True))
             yield (smaller_poly, (line_slice, col_slice))
 
 
@@ -176,14 +176,14 @@ class AreaSlicer(Slicer):
         if self.area_to_crop.is_geostationary:
             x_geos, y_geos = get_geostationary_bounding_box_in_proj_coords(self.area_to_crop, 360)
             x_geos, y_geos = self._source_transformer.transform(x_geos, y_geos, direction=TransformDirection.INVERSE)
-            geos_poly = Polygon(zip(x_geos, y_geos))
-            poly = Polygon(zip(x, y))
+            geos_poly = Polygon(zip(x_geos, y_geos, strict=True))
+            poly = Polygon(zip(x, y, strict=True))
             poly = poly.intersection(geos_poly)
             if poly.is_empty:
                 raise IncompatibleAreas("No slice on area.")
-            x, y = zip(*poly.exterior.coords)
+            x, y = zip(*poly.exterior.coords, strict=True)
 
-        return Polygon(zip(*self._source_transformer.transform(x, y)))
+        return Polygon(zip(*self._source_transformer.transform(x, y), strict=True))
 
     def get_slices_from_polygon(self, poly_to_contain):
         """Get the slices based on the polygon."""
@@ -201,7 +201,9 @@ class AreaSlicer(Slicer):
             raise InvalidArea("Invalid area") from err
         from shapely.geometry import Polygon
 
-        poly_to_crop = Polygon(zip(*self.area_to_crop.get_edge_bbox_in_projection_coordinates(frequency=10)))
+        poly_to_crop = Polygon(zip(
+            *self.area_to_crop.get_edge_bbox_in_projection_coordinates(frequency=10),
+            strict=True))
         if not poly_to_crop.intersects(buffered_poly):
             raise IncompatibleAreas("Areas not overlapping.")
         bounds = self._sanitize_polygon_bounds(bounds)
@@ -238,7 +240,7 @@ def _enumerate_chunk_slices(chunks):
     """Enumerate chunks with slices."""
     for position in np.ndindex(tuple(map(len, (chunks)))):
         slices = []
-        for pos, chunk in zip(position, chunks):
+        for pos, chunk in zip(position, chunks, strict=True):
             chunk_size = chunk[pos]
             offset = sum(chunk[:pos])
             slices.append(slice(offset, offset + chunk_size))


=====================================
pyresample/spherical.py
=====================================
@@ -229,7 +229,7 @@ class SCoordinate(object):
 
     def __iter__(self):
         """Get iterator over lon/lat pairs."""
-        return zip([self.lon, self.lat]).__iter__()
+        return zip([self.lon, self.lat], strict=True).__iter__()
 
     def plot(self, ax=None,
              projection_crs=None,


=====================================
pyresample/spherical_utils.py
=====================================
@@ -82,7 +82,7 @@ class GetNonOverlapUnionsBaseClass():
             return None
 
         for id_, komb_pair in zip(itertools.combinations(geoms.keys(), 2),
-                                  itertools.combinations(geoms.values(), 2)):
+                                  itertools.combinations(geoms.values(), 2), strict=True):
             if self._overlaps(komb_pair[0], komb_pair[1]):
                 return id_, komb_pair[0].union(komb_pair[1])
 


=====================================
pyresample/test/test_boundary/test_legacy_boundary.py
=====================================
@@ -42,10 +42,10 @@ class TestAreaBoundary(unittest.TestCase):
         boundary = AreaBoundary.from_lonlat_sides(lon_sides, lat_sides)
 
         # Assert sides coincides
-        for b_lon, src_lon in zip(boundary.sides_lons, lon_sides):
+        for b_lon, src_lon in zip(boundary.sides_lons, lon_sides, strict=True):
             assert np.allclose(b_lon, src_lon)
 
-        for b_lat, src_lat in zip(boundary.sides_lats, lat_sides):
+        for b_lat, src_lat in zip(boundary.sides_lats, lat_sides, strict=True):
             assert np.allclose(b_lat, src_lat)
 
     def test_creation(self):
@@ -61,10 +61,10 @@ class TestAreaBoundary(unittest.TestCase):
         boundary = AreaBoundary(*list_sides)
 
         # Assert sides coincides
-        for b_lon, src_lon in zip(boundary.sides_lons, lon_sides):
+        for b_lon, src_lon in zip(boundary.sides_lons, lon_sides, strict=True):
             assert np.allclose(b_lon, src_lon)
 
-        for b_lat, src_lat in zip(boundary.sides_lats, lat_sides):
+        for b_lat, src_lat in zip(boundary.sides_lats, lat_sides, strict=True):
             assert np.allclose(b_lat, src_lat)
 
     def test_number_sides_required(self):
@@ -108,3 +108,25 @@ class TestAreaBoundary(unittest.TestCase):
         lons, lats = boundary.contour()
         assert np.allclose(lons, np.array([1., 1.5, 2., 3., 3.5, 4.]))
         assert np.allclose(lats, np.array([6., 6.5, 7., 8., 8.5, 9.]))
+
+    def test_countour_poly_north_pole(self):
+        """Test that a polygon can be made with 32-bit north pole coordinates.
+
+        In a real world case, 32-bit geolocation including a point at exactly the
+        north pole lead to a validity check failure because the radians value for
+        90N was just barely above pi / 2.
+
+        """
+        list_sides = [
+            (np.array([1., 1.5, 2.], dtype=np.float32), np.array([87.0, 87.5, 88.0], dtype=np.float32)),
+            (np.array([2., 3.], dtype=np.float32), np.array([88.0, 89.0], dtype=np.float32)),
+            (np.array([3., 3.5, 4.], dtype=np.float32), np.array([89., 89.5, 90.0], dtype=np.float32)),
+            (np.array([4., 1.], dtype=np.float32), np.array([90.0, 87.0], dtype=np.float32)),
+        ]
+        boundary = AreaBoundary(*list_sides)
+        poly = boundary.contour_poly
+        # validity checks happen here:
+        aedges = list(poly.aedges())
+        # ensure 90 degree latitude coordinate is retained
+        np.testing.assert_allclose(aedges[4].end.lat, np.radians(90.0))
+        np.testing.assert_allclose(aedges[5].start.lat, np.radians(90.0))


=====================================
pyresample/test/test_geometry/test_swath_boundary.py
=====================================
@@ -138,7 +138,7 @@ def _check_bbox_structure_and_values(bbox_lons, bbox_lats):
     assert not any(np.isnan(side_lat).any() for side_lat in bbox_lats)
     assert len(bbox_lons) == len(bbox_lats)
     assert len(bbox_lons) == 4
-    for side_lons, side_lats in zip(bbox_lons, bbox_lats):
+    for side_lons, side_lats in zip(bbox_lons, bbox_lats, strict=True):
         assert isinstance(side_lons, np.ndarray)
         assert isinstance(side_lats, np.ndarray)
         assert side_lons.shape == side_lats.shape
@@ -163,7 +163,7 @@ def _is_clockwise(lons, lats):
     # https://stackoverflow.com/a/1165943/433202
     prev_point = (lons[0], lats[0])
     edge_sum = 0
-    for point in zip(lons[1:], lats[1:]):
+    for point in zip(lons[1:], lats[1:], strict=True):
         xdiff = point[0] - prev_point[0]
         ysum = point[1] + prev_point[1]
         edge_sum += xdiff * ysum


=====================================
pyresample/utils/proj4.py
=====================================
@@ -150,7 +150,7 @@ class DaskFriendlyTransformer:
                                crs_from.to_wkt(), crs_to.to_wkt(),
                                dtype=np.float64, chunks=x.chunks + ((num_results,),),
                                meta=np.array((), dtype=np.float64),
-                               name="transform_coords",
+                               token="transform_coords",  # nosec: B106
                                kwargs=self.kwargs,
                                transform_kwargs=kwargs,
                                new_axis=x.ndim)


=====================================
pyresample/version.py
=====================================
@@ -26,9 +26,9 @@ def get_keywords() -> Dict[str, str]:
     # setup.py/versioneer.py will grep for the variable names, so they must
     # each be defined on a line of their own. _version.py will just call
     # get_keywords().
-    git_refnames = " (tag: v1.34.2)"
-    git_full = "47f3fae0d2517249539c25b04bec2a9b08018125"
-    git_date = "2025-05-29 09:23:56 -0500"
+    git_refnames = " (HEAD -> main, tag: v1.35.0)"
+    git_full = "9c14be4cc720514991028ddb2a7a93152a8cf930"
+    git_date = "2025-12-01 20:45:30 -0600"
     keywords = {"refnames": git_refnames, "full": git_full, "date": git_date}
     return keywords
 


=====================================
setup.py
=====================================
@@ -25,13 +25,10 @@ from setuptools import find_packages, setup
 import versioneer
 
 requirements = ['pyproj>=3.0', 'configobj',
-                'pykdtree>=1.3.1', 'pyyaml', 'numpy>=1.21.0',
+                'pykdtree>=1.3.1', 'pyyaml', 'numpy>=1.25.0',
                 "shapely", "donfig", "platformdirs",
                 ]
 
-if sys.version_info < (3, 10):
-    requirements.append('importlib_metadata')
-
 test_requires = ['rasterio', 'dask', 'xarray', 'cartopy>=0.20.0', 'pillow', 'matplotlib', 'scipy', 'zarr',
                  'pytest-lazy-fixtures', 'shapely', 'odc-geo']
 extras_require = {'numexpr': ['numexpr'],
@@ -58,8 +55,8 @@ extensions = [
     Extension("pyresample.ewa._ll2cr", sources=["pyresample/ewa/_ll2cr.pyx"],
               include_dirs=[np.get_include()],
               extra_compile_args=extra_compile_args,
-              cython_directives={"language_level": 3},
-              define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")],
+              cython_directives={"language_level": 3, "freethreading_compatible": True},
+              define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_25_API_VERSION")],
               ),
     Extension("pyresample.ewa._fornav",
               sources=["pyresample/ewa/_fornav.pyx",
@@ -67,15 +64,15 @@ extensions = [
               include_dirs=[np.get_include()],
               language="c++", extra_compile_args=extra_compile_args,
               depends=["pyresample/ewa/_fornav_templates.h"],
-              cython_directives={"language_level": 3},
-              define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")],
+              cython_directives={"language_level": 3, "freethreading_compatible": True},
+              define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_25_API_VERSION")],
               ),
     Extension("pyresample.gradient._gradient_search",
               sources=["pyresample/gradient/_gradient_search.pyx"],
               include_dirs=[np.get_include()],
               extra_compile_args=extra_compile_args,
-              cython_directives={"language_level": 3},
-              define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")],
+              cython_directives={"language_level": 3, "freethreading_compatible": True},
+              define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_25_API_VERSION")],
               ),
 ]
 
@@ -109,13 +106,15 @@ if __name__ == "__main__":
           ext_modules=extensions,
           entry_points=entry_points,
           zip_safe=False,
+          license="LGPL-3.0-or-later",
+          license_files=["LICENSE.txt"],
           classifiers=[
               'Development Status :: 5 - Production/Stable',
-              'License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)',
               'Programming Language :: Python',
               'Programming Language :: Cython',
               'Operating System :: OS Independent',
               'Intended Audience :: Science/Research',
-              'Topic :: Scientific/Engineering'
+              'Topic :: Scientific/Engineering',
+              'Programming Language :: Python :: Free Threading :: 1 - Unstable',
           ]
           )



View it on GitLab: https://salsa.debian.org/debian-gis-team/pyresample/-/commit/1b70592297a2c0338279b675dce13e92bbccd226

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/pyresample/-/commit/1b70592297a2c0338279b675dce13e92bbccd226
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/20251210/9a2389de/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list