[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