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

Bas Couwenberg (@sebastic) gitlab at salsa.debian.org
Tue Dec 13 08:02:41 GMT 2022



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


Commits:
668394b1 by Bas Couwenberg at 2022-12-13T08:48:45+01:00
New upstream version 2.0.0
- - - - -


19 changed files:

- CHANGES.txt
- CITATION.cff
- docs/release/2.x.rst
- shapely/_ragged_array.py
- shapely/_version.py
- shapely/tests/test_constructive.py
- src/pygeom.c
- + tests/data/emptypoint_1.8.5.post1.pickle
- + tests/data/emptypolygon_1.8.5.post1.pickle
- + tests/data/geometrycollection_1.8.5.post1.pickle
- + tests/data/linearring_1.8.5.post1.pickle
- + tests/data/linestring_1.8.5.post1.pickle
- + tests/data/multilinestring_1.8.5.post1.pickle
- + tests/data/multipoint_1.8.5.post1.pickle
- + tests/data/multipolygon_1.8.5.post1.pickle
- + tests/data/point2d_1.8.5.post1.pickle
- + tests/data/point3d_1.8.5.post1.pickle
- + tests/data/polygon_1.8.5.post1.pickle
- tests/test_pickle.py


Changes:

=====================================
CHANGES.txt
=====================================
@@ -1,7 +1,22 @@
 Changes
 =======
 
-2.0rc1 (2022-10-26)
+2.0.0 (2022-12-12)
+------------------
+
+Shapely version 2.0.0 is a major release featuring a complete refactor of the
+internals and new vectorized (element-wise) array operations providing
+considerable performance improvements. 
+
+For a full changelog, see
+https://shapely.readthedocs.io/en/latest/release/2.x.html#version-2-0-0
+
+
+Relevant changes in behaviour compared to 2.0rc3:
+
+- Added temporary support for unpickling shapely<2.0 geometries.
+
+2.0rc1 (2022-11-26)
 -------------------
 
 Relevant changes in behaviour compared to 2.0b2:
@@ -56,6 +71,28 @@ changelog, see https://shapely.readthedocs.io/en/latest/release/2.x.html#version
 
 Wheels for 2.0a1 published on PyPI include GEOS 3.10.3.
 
+1.8.5.post1 (2022-10-13)
+------------------------
+
+Packaging:
+
+Wheels are provided for Python versions 3.6-3.11 and Cython 0.29.32 is used to
+generate C extension module code.
+
+1.8.5 (2022-10-12)
+------------------
+
+Packaging:
+
+Python 3.11 wheels have been added to the matrix for all platforms.
+
+Bug fixes:
+
+- Assign _lgeos in the macos frozen app check, fixing a bug introduced in 1.8.2
+  (#1528).
+- An exception is now raised when nan is passed to buffer and parallel_offset,
+  preventing segmentation faults (#1516).
+
 1.8.4 (2022-08-17)
 ------------------
 


=====================================
CITATION.cff
=====================================
@@ -2,9 +2,9 @@ cff-version: 1.2.0
 message: "Please cite this software using these metadata."
 type: software
 title: Shapely
-version: "2.0"
-# date-released: "2022-MM-DD"
-# doi: 10.5281/zenodo.#######
+version: "2.0.0"
+date-released: "2022-12-12"
+doi: 10.5281/zenodo.5597138
 abstract: "Manipulation and analysis of geometric objects in the Cartesian plane."
 repository-artifact: https://pypi.org/project/Shapely
 repository-code: https://github.com/shapely/shapely


=====================================
docs/release/2.x.rst
=====================================
@@ -3,8 +3,8 @@ Version 2.x
 
 .. _version-2-0-0:
 
-Version 2.0.0 (in progress)
----------------------------
+Version 2.0.0 (2022-12-12)
+--------------------------
 
 Shapely 2.0 version is a major release featuring a complete refactor of the
 internals and new vectorized (element-wise) array operations, providing
@@ -439,19 +439,30 @@ People with a "+" by their names contributed a patch for the first time.
 
 * Adam J. Stewart +
 * Alan D. Snow +
+* Ariel Kadouri
+* Bas Couwenberg
+* Ben Beasley
 * Brendan Ward +
 * Casper van der Wel +
+* Ewout ter Hoeven +
+* Geir Arne Hjelle +
+* James Gaboardi
 * James Myatt +
 * Joris Van den Bossche
 * Keith Jenkins +
 * Kian Meng Ang +
 * Krishna Chaitanya +
+* Kyle Barron
 * Martin Fleischmann +
 * Martin Lackner +
 * Mike Taves
+* Phil Chiu +
 * Tanguy Ophoff +
 * Tom Clancy
 * Sean Gillies
 * Giorgos Papadokostakis +
 * Mattijn van Hoek +
+* enrico ferreguti +
+* gpapadok +
+* mattijn +
 * odidev +


=====================================
shapely/_ragged_array.py
=====================================
@@ -417,7 +417,7 @@ def from_ragged_array(geometry_type, coords, offsets=None):
     geometry_type : GeometryType
         The type of geometry to create.
     coords : np.ndarray
-        Contiguous array of shape (n, 2) ro (n, 3) of all coordinates
+        Contiguous array of shape (n, 2) or (n, 3) of all coordinates
         for the geometries.
     offsets: tuple of np.ndarray
         Offset arrays that allow to reconstruct the geometries based on the


=====================================
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 = " (HEAD -> main, tag: 2.0rc3)"
-    git_full = "9ec5c16bfdcb3f282f227e2bb5a1ee13ccd4fa7d"
-    git_date = "2022-12-07 09:09:37 +0100"
+    git_refnames = " (HEAD -> main, tag: 2.0.0)"
+    git_full = "7c67808a05d92dc09440e270dd072dee83b27389"
+    git_date = "2022-12-12 13:28:37 +0100"
     keywords = {"refnames": git_refnames, "full": git_full, "date": git_date}
     return keywords
 


=====================================
shapely/tests/test_constructive.py
=====================================
@@ -345,11 +345,13 @@ def test_remove_repeated_points(geom, expected):
     assert_geometries_equal(shapely.remove_repeated_points(geom, 0), expected)
 
 
- at pytest.mark.skipif(shapely.geos_version < (3, 11, 0), reason="GEOS < 3.11")
+ at pytest.mark.skipif(shapely.geos_version < (3, 12, 0), reason="GEOS < 3.12")
 @pytest.mark.parametrize(
     "geom, tolerance", [[Polygon([(0, 0), (1, 0), (1, 1), (0, 1), (0, 0)]), 2]]
 )
 def test_remove_repeated_points_invalid_result(geom, tolerance):
+    # Requiring GEOS 3.12 instead of 3.11
+    # (GEOS 3.11 had a bug causing this to intermittently not fail)
     with pytest.raises(shapely.GEOSException, match="Invalid number of points"):
         shapely.remove_repeated_points(geom, tolerance)
 


=====================================
src/pygeom.c
=====================================
@@ -38,14 +38,14 @@ PyObject* GeometryObject_FromGEOS(GEOSGeometry* ptr, GEOSContextHandle_t ctx) {
   } else {
     self->ptr = ptr;
     self->ptr_prepared = NULL;
-    self->weakreflist = (PyObject *)NULL;
+    self->weakreflist = (PyObject*)NULL;
     return (PyObject*)self;
   }
 }
 
 static void GeometryObject_dealloc(GeometryObject* self) {
   if (self->weakreflist != NULL) {
-    PyObject_ClearWeakRefs((PyObject *)self);
+    PyObject_ClearWeakRefs((PyObject*)self);
   }
   if (self->ptr != NULL) {
     // not using GEOS_INIT, but using global context instead
@@ -291,7 +291,87 @@ static PyObject* GeometryObject_richcompare(GeometryObject* self, PyObject* othe
   return result;
 }
 
+
+static PyObject* GeometryObject_SetState(PyObject* self, PyObject* value) {
+  unsigned char* wkb = NULL;
+  Py_ssize_t size;
+  GEOSGeometry* geom = NULL;
+  GEOSWKBReader* reader = NULL;
+
+  PyErr_WarnFormat(PyExc_UserWarning, 0,
+                   "Unpickling a shapely <2.0 geometry object. Please save the pickle "
+                   "again; shapely 2.1 will not have this compatibility.");
+
+  /* Cast the PyObject bytes to char */
+  if (!PyBytes_Check(value)) {
+    PyErr_Format(PyExc_TypeError, "Expected bytes, found %s", value->ob_type->tp_name);
+    return NULL;
+  }
+  size = PyBytes_Size(value);
+  wkb = (unsigned char*)PyBytes_AsString(value);
+  if (wkb == NULL) {
+    return NULL;
+  }
+
+  PyObject* linearring_type_obj = PyList_GET_ITEM(geom_registry[0], 2);
+  if (linearring_type_obj == NULL) {
+    return NULL;
+  }
+  if (!PyType_Check(linearring_type_obj)) {
+    PyErr_Format(PyExc_RuntimeError, "Invalid registry value");
+    return NULL;
+  }
+  PyTypeObject* linearring_type = (PyTypeObject*)linearring_type_obj;
+
+  GEOS_INIT;
+
+  reader = GEOSWKBReader_create_r(ctx);
+  if (reader == NULL) {
+    errstate = PGERR_GEOS_EXCEPTION;
+    goto finish;
+  }
+  geom = GEOSWKBReader_read_r(ctx, reader, wkb, size);
+  if (geom == NULL) {
+    errstate = PGERR_GEOS_EXCEPTION;
+    goto finish;
+  }
+  if (Py_TYPE(self) == linearring_type) {
+    const GEOSCoordSequence* coord_seq = GEOSGeom_getCoordSeq_r(ctx, geom);
+    if (coord_seq == NULL) {
+      errstate = PGERR_GEOS_EXCEPTION;
+      goto finish;
+    }
+    geom = GEOSGeom_createLinearRing_r(ctx, (GEOSCoordSequence*)coord_seq);
+    if (geom == NULL) {
+      errstate = PGERR_GEOS_EXCEPTION;
+      goto finish;
+    }
+  }
+
+  if (((GeometryObject*)self)->ptr != NULL) {
+    GEOSGeom_destroy_r(ctx, ((GeometryObject*)self)->ptr);
+  }
+  ((GeometryObject*)self)->ptr = geom; 
+
+finish:
+
+  if (reader != NULL) {
+    GEOSWKBReader_destroy_r(ctx, reader);
+  }
+
+  GEOS_FINISH;
+
+  if (errstate == PGERR_SUCCESS) {
+    Py_INCREF(Py_None);
+    return Py_None;
+  }
+  return NULL;
+}
+
+
 static PyMethodDef GeometryObject_methods[] = {
+    {"__setstate__", (PyCFunction)GeometryObject_SetState, METH_O,
+     "For unpickling pre-shapely 2.0 pickles"},
     {NULL} /* Sentinel */
 };
 


=====================================
tests/data/emptypoint_1.8.5.post1.pickle
=====================================
Binary files /dev/null and b/tests/data/emptypoint_1.8.5.post1.pickle differ


=====================================
tests/data/emptypolygon_1.8.5.post1.pickle
=====================================
Binary files /dev/null and b/tests/data/emptypolygon_1.8.5.post1.pickle differ


=====================================
tests/data/geometrycollection_1.8.5.post1.pickle
=====================================
Binary files /dev/null and b/tests/data/geometrycollection_1.8.5.post1.pickle differ


=====================================
tests/data/linearring_1.8.5.post1.pickle
=====================================
Binary files /dev/null and b/tests/data/linearring_1.8.5.post1.pickle differ


=====================================
tests/data/linestring_1.8.5.post1.pickle
=====================================
Binary files /dev/null and b/tests/data/linestring_1.8.5.post1.pickle differ


=====================================
tests/data/multilinestring_1.8.5.post1.pickle
=====================================
Binary files /dev/null and b/tests/data/multilinestring_1.8.5.post1.pickle differ


=====================================
tests/data/multipoint_1.8.5.post1.pickle
=====================================
Binary files /dev/null and b/tests/data/multipoint_1.8.5.post1.pickle differ


=====================================
tests/data/multipolygon_1.8.5.post1.pickle
=====================================
Binary files /dev/null and b/tests/data/multipolygon_1.8.5.post1.pickle differ


=====================================
tests/data/point2d_1.8.5.post1.pickle
=====================================
Binary files /dev/null and b/tests/data/point2d_1.8.5.post1.pickle differ


=====================================
tests/data/point3d_1.8.5.post1.pickle
=====================================
Binary files /dev/null and b/tests/data/point3d_1.8.5.post1.pickle differ


=====================================
tests/data/polygon_1.8.5.post1.pickle
=====================================
Binary files /dev/null and b/tests/data/polygon_1.8.5.post1.pickle differ


=====================================
tests/test_pickle.py
=====================================
@@ -1,24 +1,71 @@
+import pathlib
+import pickle
+from pickle import dumps, loads, HIGHEST_PROTOCOL
+import warnings
+
+import shapely
+from shapely.geometry import Point, LineString, LinearRing, Polygon, MultiLineString, MultiPoint, MultiPolygon, GeometryCollection, box
+from shapely import wkt
+
 import pytest
-from shapely.geometry import Point, LineString, LinearRing, Polygon, MultiPoint
 
-from pickle import dumps, loads, HIGHEST_PROTOCOL
+
+HERE = pathlib.Path(__file__).parent
+
 
 TEST_DATA = {
-    "point2d": (Point, [(1.0, 2.0)]),
-    "point3d": (Point, [(1.0, 2.0, 3.0)]),
-    "linestring": (LineString, [(0.0, 0.0), (0.0, 1.0), (1.0, 1.0)]),
-    "linearring": (LinearRing, [(0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 0.0)]),
-    "polygon": (Polygon, [(0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 0.0)]),
-    "multipoint": (MultiPoint, [(1.0, 2.0), (3.0, 4.0), (5.0, 6.0)]),
+    "point2d": Point([(1.0, 2.0)]),
+    "point3d": Point([(1.0, 2.0, 3.0)]),
+    "linestring": LineString([(0.0, 0.0), (0.0, 1.0), (1.0, 1.0)]),
+    "linearring": LinearRing([(0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 0.0)]),
+    "polygon": Polygon([(0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 0.0)]),
+    "multipoint": MultiPoint([(1.0, 2.0), (3.0, 4.0), (5.0, 6.0)]),
+    "multilinestring": MultiLineString([[(0.0, 0.0), (1.0, 1.0)], [(1.0, 2.0), (3.0, 3.0)]]),
+    "multipolygon": MultiPolygon([box(0, 0, 1, 1), box(2, 2, 3, 3)]),
+    "geometrycollection": GeometryCollection([Point(1.0, 2.0), box(0, 0, 1, 1)]),
+    "emptypoint": wkt.loads("POINT EMPTY"),
+    "emptypolygon": wkt.loads("POLYGON EMPTY"),
 }
-TEST_NAMES, TEST_DATA = zip(*TEST_DATA.items())
- at pytest.mark.parametrize("cls,coords", TEST_DATA, ids=TEST_NAMES)
-def test_pickle_round_trip(cls, coords):
-    geom1 = cls(coords)
-    assert geom1.has_z == (len(coords[0]) == 3)
+TEST_NAMES, TEST_GEOMS = zip(*TEST_DATA.items())
+
+
+ at pytest.mark.parametrize("geom1", TEST_GEOMS, ids=TEST_NAMES)
+def test_pickle_round_trip(geom1):
     data = dumps(geom1, HIGHEST_PROTOCOL)
-    geom2 = loads(data)
+    with warnings.catch_warnings():
+        warnings.simplefilter("error")
+        geom2 = loads(data)
     assert geom2.has_z == geom1.has_z
     assert type(geom2) is type(geom1)
     assert geom2.geom_type == geom1.geom_type
     assert geom2.wkt == geom1.wkt
+
+
+ at pytest.mark.parametrize("fname", (HERE / "data").glob("*.pickle"), ids=lambda fname: fname.name)
+def test_unpickle_pre_20(fname):
+    from shapely.testing import assert_geometries_equal
+
+    geom_type = fname.name.split("_")[0]
+    expected = TEST_DATA[geom_type]
+
+    with open(fname, "rb") as f:
+        with pytest.warns(UserWarning):
+            result = pickle.load(f)
+
+    assert_geometries_equal(result, expected)
+
+
+if __name__ == "__main__":
+    datadir = HERE / "data"
+    datadir.mkdir(exist_ok=True)
+
+    shapely_version = shapely.__version__
+    print(shapely_version)
+    print(shapely.geos.geos_version)
+
+    for name, geom in TEST_DATA.items():
+        if name == "emptypoint" and shapely.geos.geos_version < (3, 9, 0):
+            # Empty Points cannot be represented in WKB
+            continue
+        with open(datadir / f"{name}_{shapely_version}.pickle", "wb") as f:
+            pickle.dump(geom, f)



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

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/python-shapely/-/commit/668394b160a24d59986c1d14d45c5710cfd1d21c
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/20221213/cb13de38/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list