[Git][debian-gis-team/python-shapely][upstream] New upstream version 2.0.7

Bas Couwenberg (@sebastic) gitlab at salsa.debian.org
Fri Jan 31 05:44:36 GMT 2025



Bas Couwenberg pushed to branch upstream at Debian GIS Project / python-shapely


Commits:
7eb9fe7c by Bas Couwenberg at 2025-01-31T06:27:01+01:00
New upstream version 2.0.7
- - - - -


16 changed files:

- .circleci/config.yml
- .github/workflows/release.yml
- .github/workflows/tests.yml
- − .travis.yml
- CHANGES.txt
- CITATION.cff
- README.rst
- docs/conf.py
- docs/release/2.x.rst
- pyproject.toml
- shapely/_version.py
- shapely/geometry/base.py
- shapely/tests/geometry/test_geometry_base.py
- shapely/tests/test_io.py
- src/pygeom.c
- src/ufuncs.c


Changes:

=====================================
.circleci/config.yml
=====================================
@@ -4,7 +4,7 @@ jobs:
   linux-aarch64-wheels:
     working_directory: ~/linux-aarch64-wheels
     machine:
-      image: ubuntu-2004:2022.04.1
+      image: default
     # resource_class is what tells CircleCI to use an ARM worker for native arm builds
     # https://circleci.com/product/features/resource-classes/
     resource_class: arm.medium
@@ -23,7 +23,7 @@ jobs:
       - run:
           name: Build the Linux aarch64 wheels.
           command: |
-            python3 -m pip install --user cibuildwheel==2.20.0
+            python3 -m pip install --user cibuildwheel==2.21.3
             echo 'export GEOS_INSTALL=~/linux-aarch64-wheels/geosinstall/geos-"$GEOS_VERSION"' >> "$BASH_ENV"
             echo 'export GEOS_CONFIG="$GEOS_INSTALL"/bin/geos-config' >> "$BASH_ENV"
             echo 'export LD_LIBRARY_PATH="$GEOS_INSTALL"/lib' >> "$BASH_ENV"


=====================================
.github/workflows/release.yml
=====================================
@@ -37,7 +37,7 @@ jobs:
           python -m build --sdist
           twine check --strict dist/*
 
-      - uses: actions/upload-artifact at v3
+      - uses: actions/upload-artifact at v4
         with:
           path: ./dist/*.tar.gz
           retention-days: 30
@@ -56,7 +56,7 @@ jobs:
         # Numpy no longer builds i686 packages
         # - os: ubuntu-20.04
         #   arch: i686
-        # The aarch64 build has been transferred to Travis
+        # The aarch64 build has been transferred to CircleCI
         # - os: ubuntu-20.04
         #   arch: aarch64
         #   qemu_platform: arm64
@@ -111,19 +111,17 @@ jobs:
         if: ${{ matrix.msvc_arch }}
 
       - name: Build wheels
-        uses: pypa/cibuildwheel at v2.20.0
+        uses: pypa/cibuildwheel at v2.21.3
         env:
           CIBW_ARCHS: ${{ matrix.arch }}
           CIBW_SKIP: cp36-* pp* *musllinux* *-manylinux_i686
           CIBW_TEST_SKIP: "cp38-macosx_arm64"
           CIBW_ENVIRONMENT_LINUX:
-            PIP_PRE=1
             GEOS_VERSION=${{ env.GEOS_VERSION }}
             GEOS_INSTALL=/host${{ runner.temp }}/geos-${{ env.GEOS_VERSION }}
             GEOS_CONFIG=/host${{ runner.temp }}/geos-${{ env.GEOS_VERSION }}/bin/geos-config
             LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/host${{ runner.temp }}/geos-${{ env.GEOS_VERSION }}/lib
           CIBW_ENVIRONMENT_MACOS:
-            PIP_PRE=1
             GEOS_INSTALL=${{ runner.temp }}/geos-${{ env.GEOS_VERSION }}
             GEOS_CONFIG=${{ runner.temp }}/geos-${{ env.GEOS_VERSION }}/bin/geos-config
             LDFLAGS=-Wl,-rpath,${{ runner.temp }}/geos-${{ env.GEOS_VERSION }}/lib
@@ -131,7 +129,6 @@ jobs:
             CMAKE_OSX_ARCHITECTURES='${{ matrix.cmake_osx_architectures }}'
             CFLAGS='-Wno-error=incompatible-function-pointer-types'
           CIBW_ENVIRONMENT_WINDOWS:
-            PIP_PRE=1
             GEOS_INSTALL='${{ runner.temp }}\geos-${{ env.GEOS_VERSION }}'
             GEOS_LIBRARY_PATH='${{ runner.temp }}\geos-${{ env.GEOS_VERSION }}\lib'
             GEOS_INCLUDE_PATH='${{ runner.temp }}\geos-${{ env.GEOS_VERSION }}\include'
@@ -144,7 +141,7 @@ jobs:
           CIBW_BUILD_VERBOSITY: 1
 
       - name: Upload artifacts
-        uses: actions/upload-artifact at v3
+        uses: actions/upload-artifact at v4
         with:
           path: ./wheelhouse/*.whl
           retention-days: 5


=====================================
.github/workflows/tests.yml
=====================================
@@ -14,7 +14,7 @@ jobs:
       matrix:
         os: [ubuntu-latest, macos-13, windows-2019]
         architecture: [x64]
-        geos: [3.6.6, 3.7.5, 3.8.4, 3.9.5, 3.10.6, 3.11.4, 3.12.2, main]
+        geos: [3.6.6, 3.7.5, 3.8.4, 3.9.5, 3.10.6, 3.11.4, 3.12.2, 3.13.0, main]
         include:
           # 2017
           - python: 3.7  # 3.6 is dropped
@@ -49,8 +49,8 @@ jobs:
             numpy: 1.26.0
           # 2024
           - python: "3.13"
-            geos: 3.12.2
-            numpy: 2.1.0
+            geos: 3.13.0
+            numpy: 2.1.1
           # apple silicon
           - os: macos-14
             python: "3.12"
@@ -77,6 +77,13 @@ jobs:
             python: "pypy3.8"
             geos: 3.11.4
             numpy: 1.23.4
+        exclude:
+          # 2017
+          - os: ubuntu-latest
+            geos: 3.6.6
+          # 2018
+          - os: ubuntu-latest
+            geos: 3.7.5
 
     env:
       GEOS_VERSION: ${{ matrix.geos }}
@@ -136,7 +143,7 @@ jobs:
       - name: Install python dependencies
         run: |
           python -m pip install --disable-pip-version-check --upgrade pip
-          pip install --upgrade wheel setuptools
+          pip install wheel setuptools
           if [ -z "${{ matrix.numpy }}" ]; then
             pip install --upgrade --pre Cython numpy pytest pytest-cov coveralls;
           else


=====================================
.travis.yml deleted
=====================================
@@ -1,34 +0,0 @@
-os: linux
-dist: focal
-language: python
-python: '3.8'
-
-if: (branch = main OR tag IS present) AND (type = push)
-
-env:
-  global:
-  - GEOS_VERSION=3.11.4
-
-cache:
-  directories:
-  - "$HOME/geosinstall"
-  - "~/.cache/pip"
-
-jobs:
-  include:
-  - arch: ppc64le
-  - arch: s390x
-  - arch: arm64
-
-install:
-- |
-  export GEOS_INSTALL=$HOME/geosinstall/geos-$GEOS_VERSION
-  ./ci/install_geos.sh
-  export PATH=$HOME/geosinstall/geos-$GEOS_VERSION/bin:$PATH
-  pip install .[test]
-
-script:
-- |
-  export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/geosinstall/geos-$GEOS_VERSION/lib
-  cd ..
-  pytest -v --pyargs shapely.tests


=====================================
CHANGES.txt
=====================================
@@ -1,6 +1,18 @@
 Changes
 =======
 
+2.0.7 (2025-01-30)
+------------------
+
+Bug fixes:
+
+- Fix compilation error on certain Linux platforms, such as Alpine (#1945).
+- Fixes crash when reading nonlinear geometry types (CircularString,
+  CompoundCurve, MultiCurve, CurvePolygon, MultiSurface) from WKB/WKT with
+  GEOS >= 3.13; these types are not yet supported in Shapely and now raise a
+  ``NotImplementedError`` (#2160)
+- Fix the ``project`` method to return a Python float (#2093).
+
 2.0.6 (2024-08-19)
 ------------------
 


=====================================
CITATION.cff
=====================================
@@ -2,8 +2,8 @@ cff-version: 1.2.0
 message: "Please cite this software using these metadata."
 type: software
 title: Shapely
-version: "2.0.6"
-date-released: "2024-08-19"
+version: "2.0.7"
+date-released: "2025-01-30"
 doi: 10.5281/zenodo.5597138
 abstract: "Manipulation and analysis of geometric objects in the Cartesian plane."
 repository-artifact: https://pypi.org/project/Shapely


=====================================
README.rst
=====================================
@@ -14,12 +14,6 @@ Shapely
    :alt: Github Actions status
    :target: https://github.com/shapely/shapely/actions?query=branch%3Amain
 
-.. Travis CI status -- https://travis-ci.com
-
-.. image:: https://travis-ci.com/shapely/shapely.svg?branch=main
-   :alt: Travis CI status
-   :target: https://travis-ci.com/github/shapely/shapely
-
 .. PyPI
 
 .. image:: https://img.shields.io/pypi/v/shapely.svg


=====================================
docs/conf.py
=====================================
@@ -12,7 +12,7 @@ os.environ["SPHINX_DOC_BUILD"] = "1"
 # -- Project information -----------------------------------------------------
 
 project = 'Shapely'
-copyright = '2011-2024, Sean Gillies and Shapely contributors'
+copyright = '2011-2025, Sean Gillies and Shapely contributors'
 
 # The full version, including alpha/beta/rc tags.
 import shapely


=====================================
docs/release/2.x.rst
=====================================
@@ -1,6 +1,20 @@
 Version 2.x
 ===========
 
+.. _version-2-0-7:
+
+Version 2.0.7 (2025-01-30)
+--------------------------
+
+Bug fixes:
+
+- Fix compilation error on certain Linux platforms, such as Alpine (#1945).
+- Fixes crash when reading nonlinear geometry types (CircularString,
+  CompoundCurve, MultiCurve, CurvePolygon, MultiSurface) from WKB/WKT with
+  GEOS >= 3.13; these types are not yet supported in Shapely and now raise a
+  ``NotImplementedError`` (#2160)
+- Fix the ``project`` method to return a Python float (#2093).
+
 .. _version-2-0-6:
 
 Version 2.0.6 (2024-08-19)


=====================================
pyproject.toml
=====================================
@@ -39,6 +39,7 @@ 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",
 ]
 requires-python = ">=3.7"


=====================================
shapely/_version.py
=====================================
@@ -25,9 +25,9 @@ def get_keywords():
     # 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: 2.0.6)"
-    git_full = "5a4207d2fb74b25d7bb2fb5d04813f68a3a612f4"
-    git_date = "2024-08-19 23:29:00 +0200"
+    git_refnames = " (tag: 2.0.7, maint-2.0)"
+    git_full = "ec8f6cd42d2f36a75808f8f44f4b8f08405f181a"
+    git_date = "2025-01-30 19:28:22 -0700"
     keywords = {"refnames": git_refnames, "full": git_full, "date": git_date}
     return keywords
 


=====================================
shapely/geometry/base.py
=====================================
@@ -830,7 +830,9 @@ class BaseGeometry(shapely.Geometry):
 
         Alias of `project`.
         """
-        return shapely.line_locate_point(self, other, normalized=normalized)
+        return _maybe_unpack(
+            shapely.line_locate_point(self, other, normalized=normalized)
+        )
 
     def project(self, other, normalized=False):
         """Returns the distance along this geometry to a point nearest the
@@ -841,7 +843,9 @@ class BaseGeometry(shapely.Geometry):
 
         Alias of `line_locate_point`.
         """
-        return shapely.line_locate_point(self, other, normalized=normalized)
+        return _maybe_unpack(
+            shapely.line_locate_point(self, other, normalized=normalized)
+        )
 
     def line_interpolate_point(self, distance, normalized=False):
         """Return a point at the specified distance along a linear geometry


=====================================
shapely/tests/geometry/test_geometry_base.py
=====================================
@@ -164,6 +164,10 @@ def test_array_argument_binary_predicates(op):
     expected = np.array([getattr(polygon, op)(p) for p in points], dtype=bool)
     np.testing.assert_array_equal(result, expected)
 
+    # check scalar
+    result = getattr(polygon, op)(points[0])
+    assert type(result) is bool
+
 
 @pytest.mark.parametrize(
     "op, kwargs",
@@ -188,6 +192,10 @@ def test_array_argument_binary_predicates2(op, kwargs):
     expected = np.array([getattr(polygon, op)(p, **kwargs) for p in points], dtype=bool)
     np.testing.assert_array_equal(result, expected)
 
+    # check scalar
+    result = getattr(polygon, op)(points[0], **kwargs)
+    assert type(result) is bool
+
 
 @pytest.mark.parametrize(
     "op",
@@ -207,6 +215,10 @@ def test_array_argument_binary_geo(op):
     expected = np.array([getattr(box, op)(g) for g in polygons], dtype=object)
     assert_geometries_equal(result, expected)
 
+    # check scalar
+    result = getattr(box, op)(polygons[0])
+    assert isinstance(result, (Polygon, MultiPolygon))
+
 
 @pytest.mark.parametrize("op", ["distance", "hausdorff_distance"])
 def test_array_argument_float(op):
@@ -218,23 +230,42 @@ def test_array_argument_float(op):
     expected = np.array([getattr(polygon, op)(p) for p in points], dtype="float64")
     np.testing.assert_array_equal(result, expected)
 
+    # check scalar
+    result = getattr(polygon, op)(points[0])
+    assert type(result) is float
 
-def test_array_argument_linear():
+
+ at pytest.mark.parametrize("op", ["line_interpolate_point", "interpolate"])
+def test_array_argument_linear_point(op):
     line = LineString([(0, 0), (0, 1), (1, 1)])
     distances = np.array([0, 0.5, 1])
-    result = line.line_interpolate_point(distances)
+
+    result = getattr(line, op)(distances)
     assert isinstance(result, np.ndarray)
     expected = np.array(
         [line.line_interpolate_point(d) for d in distances], dtype=object
     )
     assert_geometries_equal(result, expected)
 
+    # check scalar
+    result = getattr(line, op)(distances[0])
+    assert isinstance(result, Point)
+
+
+ at pytest.mark.parametrize("op", ["line_locate_point", "project"])
+def test_array_argument_linear_float(op):
+    line = LineString([(0, 0), (0, 1), (1, 1)])
     points = shapely.points([(0, 0), (0.5, 0.5), (1, 1)])
-    result = line.line_locate_point(points)
+
+    result = getattr(line, op)(points)
     assert isinstance(result, np.ndarray)
     expected = np.array([line.line_locate_point(p) for p in points], dtype="float64")
     np.testing.assert_array_equal(result, expected)
 
+    # check scalar
+    result = getattr(line, op)(points[0])
+    assert type(result) is float
+
 
 def test_array_argument_buffer():
     point = Point(1, 1)
@@ -244,3 +275,7 @@ def test_array_argument_buffer():
     assert isinstance(result, np.ndarray)
     expected = np.array([point.buffer(d) for d in distances], dtype=object)
     assert_geometries_equal(result, expected)
+
+    # check scalar
+    result = point.buffer(distances[0])
+    assert isinstance(result, Polygon)


=====================================
shapely/tests/test_io.py
=====================================
@@ -157,6 +157,31 @@ def test_from_wkt_empty(wkt):
     assert shapely.to_wkt(geom) == wkt
 
 
+# WKT from https://github.com/libgeos/geos/blob/main/tests/unit/io/WKBReaderTest.cpp
+ at pytest.mark.parametrize(
+    "wkt",
+    (
+        "CIRCULARSTRING(1 3,2 4,3 1)",
+        "COMPOUNDCURVE(CIRCULARSTRING(1 3,2 4,3 1),(3 1,0 0))",
+        "CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0,2 1,2 3,4 3),(4 3,4 5,1 4,0 0)),CIRCULARSTRING(1.7 1,1.4 0.4,1.6 0.4,1.6 0.5,1.7 1))",  # noqa: E501
+        "MULTICURVE((0 0,5 5),COMPOUNDCURVE((-1 -1,0 0),CIRCULARSTRING(0 0,1 1,2 0)),CIRCULARSTRING(4 0,4 4,8 4))",  # noqa: E501
+        "MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(0 0,4 0,4 4,0 4,0 0),(1 1,3 3,3 1,1 1)),((10 10,14 12,11 10,10 10),(11 11,11.5 11,11 11.5,11 11)))",  # noqa: E501
+    ),
+)
+def test_from_wkt_nonlinear_unsupported(wkt):
+    if shapely.geos_version >= (3, 13, 0):
+        with pytest.raises(
+            NotImplementedError,
+            match="Nonlinear geometry types are not currently supported",
+        ):
+            shapely.from_wkt(wkt)
+
+    else:
+        # prior to GEOS 3.13 nonlinear types were rejected by GEOS on read from WKT
+        with pytest.raises(shapely.errors.GEOSException, match="Unknown type"):
+            shapely.from_wkt(wkt)
+
+
 def test_from_wkb():
     expected = shapely.points(1, 1)
     actual = shapely.from_wkb(POINT11_WKB)
@@ -255,6 +280,36 @@ def test_from_wkb_empty(geom):
     assert shapely.to_wkb(geom) == wkb
 
 
+# WKB from https://github.com/libgeos/geos/blob/main/tests/unit/io/WKBReaderTest.cpp
+ at pytest.mark.parametrize(
+    "wkb",
+    (
+        # "CIRCULARSTRING(1 3,2 4,3 1)",
+        "010800000003000000000000000000F03F0000000000000840000000000000004000000000000010400000000000000840000000000000F03F",
+        # "COMPOUNDCURVE(CIRCULARSTRING(1 3,2 4,3 1),(3 1,0 0))",
+        "01090000200E16000002000000010800000003000000000000000000F03F0000000000000840000000000000004000000000000010400000000000000840000000000000F03F0102000000020000000000000000000840000000000000F03F00000000000000000000000000000000",
+        # "CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0,2 1,2 3,4 3),(4 3,4 5,1 4,0 0)),CIRCULARSTRING(1.7 1,1.4 0.4,1.6 0.4,1.6 0.5,1.7 1))",  # noqa: E501
+        "010A0000200E1600000200000001090000000200000001080000000500000000000000000000000000000000000000000000000000004000000000000000000000000000000040000000000000F03F00000000000000400000000000000840000000000000104000000000000008400102000000040000000000000000001040000000000000084000000000000010400000000000001440000000000000F03F000000000000104000000000000000000000000000000000010800000005000000333333333333FB3F000000000000F03F666666666666F63F9A9999999999D93F9A9999999999F93F9A9999999999D93F9A9999999999F93F000000000000E03F333333333333FB3F000000000000F03F",
+        # "MULTICURVE((0 0,5 5),COMPOUNDCURVE((-1 -1,0 0),CIRCULARSTRING(0 0,1 1,2 0)),CIRCULARSTRING(4 0,4 4,8 4))",  # noqa: E501
+        "010B000000030000000102000000020000000000000000000000000000000000000000000000000014400000000000001440010900000002000000010200000002000000000000000000F0BF000000000000F0BF0000000000000000000000000000000001080000000300000000000000000000000000000000000000000000000000F03F000000000000F03F00000000000000400000000000000000010800000003000000000000000000104000000000000000000000000000001040000000000000104000000000000020400000000000001040",
+        # "MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(0 0,4 0,4 4,0 4,0 0),(1 1,3 3,3 1,1 1)),((10 10,14 12,11 10,10 10),(11 11,11.5 11,11 11.5,11 11)))",  # noqa: E501
+        "010C00000002000000010A000000020000000108000000050000000000000000000000000000000000000000000000000010400000000000000000000000000000104000000000000010400000000000000000000000000000104000000000000000000000000000000000010200000004000000000000000000F03F000000000000F03F000000000000084000000000000008400000000000000840000000000000F03F000000000000F03F000000000000F03F01030000000200000004000000000000000000244000000000000024400000000000002C40000000000000284000000000000026400000000000002440000000000000244000000000000024400400000000000000000026400000000000002640000000000000274000000000000026400000000000002640000000000000274000000000000026400000000000002640",
+    ),
+)
+def test_from_wkb_nonlinear_unsupported(wkb):
+    if shapely.geos_version >= (3, 13, 0):
+        with pytest.raises(
+            NotImplementedError,
+            match="Nonlinear geometry types are not currently supported",
+        ):
+            shapely.from_wkb(wkb)
+
+    else:
+        # prior to GEOS 3.13 nonlinear types were rejected by GEOS on read from WKB
+        with pytest.raises(shapely.errors.GEOSException, match="Unknown WKB type"):
+            shapely.from_wkb(wkb)
+
+
 def test_to_wkt():
     point = shapely.points(1, 1)
     actual = shapely.to_wkt(point)


=====================================
src/pygeom.c
=====================================
@@ -23,6 +23,16 @@ PyObject* GeometryObject_FromGEOS(GEOSGeometry* ptr, GEOSContextHandle_t ctx) {
   if (type_id == -1) {
     return NULL;
   }
+
+  // Nonlinear types (CircularString, CompoundCurve, MultiCurve, CurvePolygon,
+  // MultiSurface are not currently supported
+  // TODO: this can be removed once these types are added to the type registry
+  if (type_id >= 8) {
+    PyErr_Format(PyExc_NotImplementedError,
+                 "Nonlinear geometry types are not currently supported");
+    return NULL;
+  }
+
   PyObject* type_obj = PyList_GET_ITEM(geom_registry[0], type_id);
   if (type_obj == NULL) {
     return NULL;


=====================================
src/ufuncs.c
=====================================
@@ -2178,7 +2178,7 @@ static void polygonize_func(char** args, const npy_intp* dimensions, const npy_i
 
   GEOS_INIT;
 
-  GEOSGeometry** geoms = malloc(sizeof(void*) * dimensions[1]);
+  const GEOSGeometry** geoms = malloc(sizeof(void*) * dimensions[1]);
   if (geoms == NULL) {
     errstate = PGERR_NO_MALLOC;
     goto finish;



View it on GitLab: https://salsa.debian.org/debian-gis-team/python-shapely/-/commit/7eb9fe7c1826591edd800f17e6006e4cf36fcbbf

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/python-shapely/-/commit/7eb9fe7c1826591edd800f17e6006e4cf36fcbbf
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/20250131/64cbb5df/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list