From 23f91ab79bd7d9dfa4c3f6090f65a7ba07d9dc3c Mon Sep 17 00:00:00 2001 From: Casper van der Wel Date: Thu, 8 Dec 2022 21:01:45 +0100 Subject: [PATCH 1/5] Add compat for unpickling shapely<2 geometries --- CHANGES.txt | 7 +++++ src/pygeom.c | 61 ++++++++++++++++++++++++++++++++++++++++++-- tests/test_pickle.py | 26 ++++++++++++++++--- 3 files changed, 89 insertions(+), 5 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index dc759e2dc..bad09f471 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,13 @@ Changes ======= + +2.0rc4 (2022-10-26) +------------------- + +- Added temporary for unpickling shapely<2.0 geometries. + + 2.0rc1 (2022-10-26) ------------------- diff --git a/src/pygeom.c b/src/pygeom.c index f95fbe2d4..43ef433f8 100644 --- a/src/pygeom.c +++ b/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,64 @@ 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; + } + + 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 (((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; + } +} + + static PyMethodDef GeometryObject_methods[] = { + {"__setstate__", (PyCFunction)GeometryObject_SetState, METH_O, + "For unpickling pre-shapely 2.0 pickles"}, {NULL} /* Sentinel */ }; diff --git a/tests/test_pickle.py b/tests/test_pickle.py index a20422b4d..6aab22a13 100644 --- a/tests/test_pickle.py +++ b/tests/test_pickle.py @@ -1,7 +1,8 @@ import pytest -from shapely.geometry import Point, LineString, LinearRing, Polygon, MultiPoint - +from shapely.geometry import Point, LineString, LinearRing, Polygon, MultiPoint, box from pickle import dumps, loads, HIGHEST_PROTOCOL +from shapely.testing import assert_geometries_equal +import warnings TEST_DATA = { "point2d": (Point, [(1.0, 2.0)]), @@ -17,8 +18,27 @@ def test_pickle_round_trip(cls, coords): geom1 = cls(coords) assert geom1.has_z == (len(coords[0]) == 3) 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 + + +SHAPELY_18_PICKLE = ( + b'\x80\x04\x95\x8c\x00\x00\x00\x00\x00\x00\x00\x8c\x18shapely.geometry.polygon' + b'\x94\x8c\x07Polygon\x94\x93\x94)R\x94C]\x01\x03\x00\x00\x00\x01\x00\x00\x00' + b'\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00$@\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00$@\x00\x00\x00\x00\x00\x00$@\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00$@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$@\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x94b.' +) + + +def test_unpickle_shapely_18(): + with pytest.warns(UserWarning): + geom = loads(SHAPELY_18_PICKLE) + assert_geometries_equal(geom, box(0, 0, 10, 10)) From f9827120b3090f1b04fdc5930f968ee63c5263c3 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Sun, 11 Dec 2022 11:17:54 +0100 Subject: [PATCH 2/5] add tests for various geom types and shapely versions + fix linearring --- src/pygeom.c | 23 ++++++ tests/data/emptypoint_1.8.5.post1.pickle | Bin 0 -> 75 bytes tests/data/emptypolygon_1.7.1.pickle | Bin 0 -> 67 bytes tests/data/emptypolygon_1.8.5.post1.pickle | Bin 0 -> 67 bytes .../geometrycollection_1.8.5.post1.pickle | Bin 0 -> 195 bytes tests/data/linearring_1.8.5.post1.pickle | Bin 0 -> 134 bytes tests/data/linestring_1.8.5.post1.pickle | Bin 0 -> 121 bytes tests/data/multilinestring_1.8.5.post1.pickle | Bin 0 -> 165 bytes tests/data/multipoint_1.8.5.post1.pickle | Bin 0 -> 136 bytes tests/data/multipolygon_1.8.5.post1.pickle | Bin 0 -> 263 bytes tests/data/point2d_1.8.5.post1.pickle | Bin 0 -> 75 bytes tests/data/point3d_1.8.5.post1.pickle | Bin 0 -> 83 bytes tests/data/polygon_1.8.5.post1.pickle | Bin 0 -> 135 bytes tests/test_pickle.py | 75 ++++++++++++++---- 14 files changed, 84 insertions(+), 14 deletions(-) create mode 100644 tests/data/emptypoint_1.8.5.post1.pickle create mode 100644 tests/data/emptypolygon_1.7.1.pickle create mode 100644 tests/data/emptypolygon_1.8.5.post1.pickle create mode 100644 tests/data/geometrycollection_1.8.5.post1.pickle create mode 100644 tests/data/linearring_1.8.5.post1.pickle create mode 100644 tests/data/linestring_1.8.5.post1.pickle create mode 100644 tests/data/multilinestring_1.8.5.post1.pickle create mode 100644 tests/data/multipoint_1.8.5.post1.pickle create mode 100644 tests/data/multipolygon_1.8.5.post1.pickle create mode 100644 tests/data/point2d_1.8.5.post1.pickle create mode 100644 tests/data/point3d_1.8.5.post1.pickle create mode 100644 tests/data/polygon_1.8.5.post1.pickle diff --git a/src/pygeom.c b/src/pygeom.c index 43ef433f8..088a0ce73 100644 --- a/src/pygeom.c +++ b/src/pygeom.c @@ -313,6 +313,16 @@ static PyObject* GeometryObject_SetState(PyObject* self, PyObject* value) { 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); @@ -325,6 +335,18 @@ static PyObject* GeometryObject_SetState(PyObject* self, PyObject* value) { errstate = PGERR_GEOS_EXCEPTION; goto finish; } + if (Py_IS_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); @@ -343,6 +365,7 @@ static PyObject* GeometryObject_SetState(PyObject* self, PyObject* value) { Py_INCREF(Py_None); return Py_None; } + return NULL; } diff --git a/tests/data/emptypoint_1.8.5.post1.pickle b/tests/data/emptypoint_1.8.5.post1.pickle new file mode 100644 index 0000000000000000000000000000000000000000..db17961a2a8e8371567de77fbb51e95c2a9d864c GIT binary patch literal 75 zcmZo*nd-m*0X<^H8Hoj{IhA_psrk97B}J8b1^JnIB~yA>1Hkm;DVjl3oJAQKp&A$% Oe$+#lKkBC>=>Y&jaurDc literal 0 HcmV?d00001 diff --git a/tests/data/emptypolygon_1.7.1.pickle b/tests/data/emptypolygon_1.7.1.pickle new file mode 100644 index 0000000000000000000000000000000000000000..c2ea8f37930ea59cd69891d65290aeff428efc6a GIT binary patch literal 67 zcmZo*nQFlR0X-7M8Hoj{IhA_psrk97B}J8b1^GFZ>G^q6de{S?tjSX}gQhrhGBPtT LG=Q{CNzwxVyqOe< literal 0 HcmV?d00001 diff --git a/tests/data/emptypolygon_1.8.5.post1.pickle b/tests/data/emptypolygon_1.8.5.post1.pickle new file mode 100644 index 0000000000000000000000000000000000000000..971cc3ddbb5406f46f2df1d9ab59b903e5c7dd32 GIT binary patch literal 67 zcmZo*nQFlR0X-7M8Hoj{IhA_psrk97B}J8b1^GFZ>G^q6de{S?tjSX}gQhrhGBQIo IO-a%N0JxbH2><{9 literal 0 HcmV?d00001 diff --git a/tests/data/geometrycollection_1.8.5.post1.pickle b/tests/data/geometrycollection_1.8.5.post1.pickle new file mode 100644 index 0000000000000000000000000000000000000000..c3fa5ae040b90d1f9ad7b032da29c7cfadd5a706 GIT binary patch literal 195 zcmZo*nYx1k0(zv2GZG6@b1L=HQ}c6EONuJ>lJj$NQj<$E^YfY?mSl literal 0 HcmV?d00001 diff --git a/tests/data/linearring_1.8.5.post1.pickle b/tests/data/linearring_1.8.5.post1.pickle new file mode 100644 index 0000000000000000000000000000000000000000..51ef63d6490f9dcab60046b5cbc8d795d9367952 GIT binary patch literal 134 zcmZo*nOe;N0X-7M8Hoj{IhA_psrk97B}J8b1^GFZ>G^q6dboTt^HLLwf->{cr%axr e88pS&laUFijRmR~llowfDhA`jXoT#PBs~D0+8H7M literal 0 HcmV?d00001 diff --git a/tests/data/linestring_1.8.5.post1.pickle b/tests/data/linestring_1.8.5.post1.pickle new file mode 100644 index 0000000000000000000000000000000000000000..688f26fe99ee88eda98fb25d1351dd269e0f9b82 GIT binary patch literal 121 zcmZo*nVQD{0X@>i8Hoj{IhA_psrk97B}J8bIhlE>#U(|VdFfMnxO{+|Ua!YecGIKKXQj1H9GV{`>^zi$FM0|iE v!4Q$jQ#6C7I7c(G0?l9oVnz@F!q~wFdx-c4do+bG2?hs<0uDGmB}oqep4%V1 literal 0 HcmV?d00001 diff --git a/tests/data/multipoint_1.8.5.post1.pickle b/tests/data/multipoint_1.8.5.post1.pickle new file mode 100644 index 0000000000000000000000000000000000000000..64dab2da4222143d354c0eda15ed5dc56ea1fcda GIT binary patch literal 136 zcmZo*nOe&L0X@>i8Hoj{IhA_psrk97B}J8bxurQJnFaZoc_mYNxO_pJ05E6r6wRP1 p&K`^`K%LA$%*Y5egMs0LJ(THyB*@_a5fnfc6oCp#I7~^>0{}BS8Oi_v literal 0 HcmV?d00001 diff --git a/tests/data/multipolygon_1.8.5.post1.pickle b/tests/data/multipolygon_1.8.5.post1.pickle new file mode 100644 index 0000000000000000000000000000000000000000..db8090fdee160b89e63163d267e8c2e9d4c015de GIT binary patch literal 263 zcmZo*nfiwT0(xYNGZG6@b1L=HQ}c6EONuJ>a!YecG7Iu^D%11xru6Xmg17-t?&K+& zK~tO$GqM47GXXIpGl&3URv?Ce5B4w?Dj%0Ps%i!XggPvSb2vbiLunWvMl+y^!}u^7 Jp>9f&9ssL$B69!$ literal 0 HcmV?d00001 diff --git a/tests/data/point2d_1.8.5.post1.pickle b/tests/data/point2d_1.8.5.post1.pickle new file mode 100644 index 0000000000000000000000000000000000000000..1dc7ae6d463e11fe5f5e292f9a6e2ccf0bebb348 GIT binary patch literal 75 zcmZo*nd-m*0X<^H8Hoj{IhA_psrk97B}J8b1^JnIB~yA>1Hkm;DVjl3oJAQKp&A$% MKG;K<4pWl!068`j$^ZZW literal 0 HcmV?d00001 diff --git a/tests/data/point3d_1.8.5.post1.pickle b/tests/data/point3d_1.8.5.post1.pickle new file mode 100644 index 0000000000000000000000000000000000000000..bf3f2fc2905058916cd6fd6f5f93a9950df78e64 GIT binary patch literal 83 zcmZo*nd-p+0X<^H8Hoj{IhA_psrk97B}J8b1^JnIB~yA>1Hkm;DVjl3oMjmq85kNM RT0YoA^*TUk4u>g8dH~@T6runC literal 0 HcmV?d00001 diff --git a/tests/data/polygon_1.8.5.post1.pickle b/tests/data/polygon_1.8.5.post1.pickle new file mode 100644 index 0000000000000000000000000000000000000000..d04ebfb7e60028ef6a697992dd8d669808f91547 GIT binary patch literal 135 zcmZo*nOegD0X-7M8Hoj{IhA_psrk97B}J8b1^GFZ>G^q6de{S?tjSX}gQht9GBN}8 YFaj|PR5K>^!5&o%#)r`e*(phS0B3d>BLDyZ literal 0 HcmV?d00001 diff --git a/tests/test_pickle.py b/tests/test_pickle.py index 6aab22a13..b7e5dc5a0 100644 --- a/tests/test_pickle.py +++ b/tests/test_pickle.py @@ -1,22 +1,34 @@ -import pytest -from shapely.geometry import Point, LineString, LinearRing, Polygon, MultiPoint, box +import pathlib +import pickle from pickle import dumps, loads, HIGHEST_PROTOCOL -from shapely.testing import assert_geometries_equal import warnings +import shapely +from shapely.geometry import Point, LineString, LinearRing, Polygon, MultiLineString, MultiPoint, MultiPolygon, GeometryCollection, box +from shapely import wkt + + +import pytest + + 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()) -@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()) + + +@pytest.mark.parametrize("geom1", TEST_GEOMS, ids=TEST_NAMES) +def test_pickle_round_trip(geom1): data = dumps(geom1, HIGHEST_PROTOCOL) with warnings.catch_warnings(): warnings.simplefilter("error") @@ -39,6 +51,41 @@ def test_pickle_round_trip(cls, coords): def test_unpickle_shapely_18(): + from shapely.testing import assert_geometries_equal + with pytest.warns(UserWarning): geom = loads(SHAPELY_18_PICKLE) assert_geometries_equal(geom, box(0, 0, 10, 10)) + + +HERE = pathlib.Path(__file__).parent + +@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__": + HERE = pathlib.Path(__file__).parent + 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) From 5d9645367a920b3a372bd6c46986d2f939928e77 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Sun, 11 Dec 2022 11:27:05 +0100 Subject: [PATCH 3/5] fix Py_IS_TYPE for older Python --- src/pygeom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pygeom.c b/src/pygeom.c index 088a0ce73..9d29e9041 100644 --- a/src/pygeom.c +++ b/src/pygeom.c @@ -335,7 +335,7 @@ static PyObject* GeometryObject_SetState(PyObject* self, PyObject* value) { errstate = PGERR_GEOS_EXCEPTION; goto finish; } - if (Py_IS_TYPE(self, linearring_type)) { + if (Py_TYPE(self) == linearring_type) { const GEOSCoordSequence* coord_seq = GEOSGeom_getCoordSeq_r(ctx, geom); if (coord_seq == NULL) { errstate = PGERR_GEOS_EXCEPTION; From 3a30ce102b09a5557ab3619c9fb9da0cbc3f49e2 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Sun, 11 Dec 2022 11:29:34 +0100 Subject: [PATCH 4/5] fixup test empty polygon --- tests/test_pickle.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_pickle.py b/tests/test_pickle.py index b7e5dc5a0..cd0e64f5a 100644 --- a/tests/test_pickle.py +++ b/tests/test_pickle.py @@ -71,6 +71,8 @@ def test_unpickle_pre_20(fname): with pytest.warns(UserWarning): result = pickle.load(f) + if geom_type == "emptypolygon" and "1.7.1" in fname.name: + expected = wkt.loads("POLYGON Z EMPTY") assert_geometries_equal(result, expected) From 89bc67b07980b18d78e758245232ff2f0f6625f4 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Sun, 11 Dec 2022 15:38:28 +0100 Subject: [PATCH 5/5] clean-up + remove 1.7.1 empty polygon case --- tests/data/emptypolygon_1.7.1.pickle | Bin 67 -> 0 bytes tests/test_pickle.py | 34 +++++---------------------- 2 files changed, 6 insertions(+), 28 deletions(-) delete mode 100644 tests/data/emptypolygon_1.7.1.pickle diff --git a/tests/data/emptypolygon_1.7.1.pickle b/tests/data/emptypolygon_1.7.1.pickle deleted file mode 100644 index c2ea8f37930ea59cd69891d65290aeff428efc6a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67 zcmZo*nQFlR0X-7M8Hoj{IhA_psrk97B}J8b1^GFZ>G^q6de{S?tjSX}gQhrhGBPtT LG=Q{CNzwxVyqOe< diff --git a/tests/test_pickle.py b/tests/test_pickle.py index cd0e64f5a..dd0431a44 100644 --- a/tests/test_pickle.py +++ b/tests/test_pickle.py @@ -7,10 +7,12 @@ from shapely.geometry import Point, LineString, LinearRing, Polygon, MultiLineString, MultiPoint, MultiPolygon, GeometryCollection, box from shapely import wkt - import pytest +HERE = pathlib.Path(__file__).parent + + TEST_DATA = { "point2d": Point([(1.0, 2.0)]), "point3d": Point([(1.0, 2.0, 3.0)]), @@ -39,48 +41,24 @@ def test_pickle_round_trip(geom1): assert geom2.wkt == geom1.wkt -SHAPELY_18_PICKLE = ( - b'\x80\x04\x95\x8c\x00\x00\x00\x00\x00\x00\x00\x8c\x18shapely.geometry.polygon' - b'\x94\x8c\x07Polygon\x94\x93\x94)R\x94C]\x01\x03\x00\x00\x00\x01\x00\x00\x00' - b'\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00$@\x00\x00\x00\x00\x00\x00\x00\x00' - b'\x00\x00\x00\x00\x00\x00$@\x00\x00\x00\x00\x00\x00$@\x00\x00\x00\x00\x00\x00' - b'\x00\x00\x00\x00\x00\x00\x00\x00$@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' - b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$@\x00\x00\x00\x00\x00\x00\x00\x00' - b'\x94b.' -) - - -def test_unpickle_shapely_18(): - from shapely.testing import assert_geometries_equal - - with pytest.warns(UserWarning): - geom = loads(SHAPELY_18_PICKLE) - assert_geometries_equal(geom, box(0, 0, 10, 10)) - - -HERE = pathlib.Path(__file__).parent - @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) - - if geom_type == "emptypolygon" and "1.7.1" in fname.name: - expected = wkt.loads("POLYGON Z EMPTY") + assert_geometries_equal(result, expected) if __name__ == "__main__": - HERE = pathlib.Path(__file__).parent datadir = HERE / "data" datadir.mkdir(exist_ok=True) - + shapely_version = shapely.__version__ print(shapely_version) print(shapely.geos.geos_version)