[Git][debian-gis-team/python-shapely][experimental] 4 commits: New upstream version 2.0~b2
Bas Couwenberg (@sebastic)
gitlab at salsa.debian.org
Sat Oct 29 13:03:34 BST 2022
Bas Couwenberg pushed to branch experimental at Debian GIS Project / python-shapely
Commits:
5be11660 by Bas Couwenberg at 2022-10-29T13:50:58+02:00
New upstream version 2.0~b2
- - - - -
a9f7c592 by Bas Couwenberg at 2022-10-29T13:51:00+02:00
Update upstream source from tag 'upstream/2.0_b2'
Update to upstream version '2.0~b2'
with Debian dir 95a8a0719212c39dab8644fa3c8a2777cd64072b
- - - - -
27795f05 by Bas Couwenberg at 2022-10-29T13:52:35+02:00
New upstream beta release.
- - - - -
5d8be325 by Bas Couwenberg at 2022-10-29T13:53:42+02:00
Set distribution to experimental.
- - - - -
20 changed files:
- .github/workflows/tests.yml
- .travis.yml
- CHANGES.txt
- debian/changelog
- docs/geometry.rst
- docs/migration_pygeos.rst
- shapely/constructive.py
- shapely/geometry/base.py
- shapely/geometry/linestring.py
- shapely/geometry/point.py
- + shapely/tests/geometry/test_format.py
- shapely/tests/geometry/test_geometry_base.py
- shapely/tests/geometry/test_hash.py
- shapely/tests/geometry/test_point.py
- src/pygeom.c
- src/pygeom.h
- − tests/test_binascii_hex.txt
- tests/test_buffer.py
- − tests/test_doctests.py
- tests/test_parallel_offset.py
Changes:
=====================================
.github/workflows/tests.yml
=====================================
@@ -58,6 +58,11 @@ jobs:
python: 3.9
geos: 3.10.3
numpy: 1.19.5
+ # pypy
+ - os: ubuntu-latest
+ python: "pypy3.8"
+ geos: 3.11.0
+ numpy: 1.23.3
env:
GEOS_VERSION: ${{ matrix.geos }}
=====================================
.travis.yml
=====================================
@@ -61,5 +61,7 @@ deploy:
secure: "hU7JzC2F1GomDVpSOw9L3WHV/qwVWkc3NI6YCkkqUArMyYnJPSMBJck9ugeZIJ6OrIKORs50vIAdGrYQnjbhcntQzwc384mfnNO3FNPMnkBaxi4y0ofERy/ygqysM+tEOXINzJpFcYyylpknQdSnuzLSgYhdm+OXfob5Sqy/ABX+dXEuz1pb7UWvK0oYcLC1PYkfneFK4IcUIHYuMhia48y0jfxlez9gFZMAos3PKtn6m9CRN4xU370RgNjvy7Ey/hXwiTlm4rrX4KbEFj1q/SoaXvgK+mQqofM7n/4MakA8VFzKtz5a/L64f4iiJy0V2WgO/DiO2fLFwfEFmr+23WY8TTkMV/p7IAjZzeMY9ZmODymzXRKaJxIVt0MerLiwdul7nVCmXbJ/HkQwW2p32IUxzL37XaEk6ZN4lTb+5BhPA9e6jCZdgRY8sfJrrOzFxNNVm0wuf9nbve662PYhmgq9sETk4sdvqK8ODem/TSqMZzsq6FPRf2JCeFGZn+2TAKp+nwAFTByoJ/mMNsTc3TjtAzFhhtd2DUQriGadD+aNPZexA+yKCVSY/EGDYxpbnyS1h1fJv17kgyLxQfUi5FDBwrcGX0Ld01IyqcQbaw57DLDTQYYK4yvrfsYaQJDIQlySe8BkwgtJ5Dz9WP13MUZJ7VrISYMdTRU805eTvRE="
skip_cleanup: true
skip_existing: true
+ distributions: ""
on:
tags: true
+ condition: $CIBUILDWHEEL = 1
=====================================
CHANGES.txt
=====================================
@@ -1,6 +1,17 @@
Changes
=======
+2.0b2 (2022-10-29)
+------------------
+
+Relevant changes in behaviour compared to 2.0b1:
+
+- Fix for compatibility with PyPy (#1577).
+- Fix to the ``Point()`` constructor to accept arrays of length 1 for the x and y
+ coordinates (fix compatibility with Shapely 1.8).
+- Raise ValueError for non-finite distance in the ``buffer()`` and ``offset_curve()``
+ methods on the Geometry classes (consistent with Shapely 1.8).
+
2.0b1 (2022-10-17)
------------------
=====================================
debian/changelog
=====================================
@@ -1,3 +1,9 @@
+python-shapely (2.0~b2-1~exp1) experimental; urgency=medium
+
+ * New upstream beta release.
+
+ -- Bas Couwenberg <sebastic at debian.org> Sat, 29 Oct 2022 13:53:30 +0200
+
python-shapely (2.0~b1-1~exp1) experimental; urgency=medium
* New upstream beta release.
=====================================
docs/geometry.rst
=====================================
@@ -68,7 +68,7 @@ Geometries can be serialized using pickle:
<POINT (1 1)>
.. warning:: Pickling will convert linearrings to linestrings.
- See :func:`shapely.io.to_wkb` for a complete list of limitations.
+ See :func:`shapely.to_wkb` for a complete list of limitations.
Hashing
~~~~~~~
@@ -88,7 +88,7 @@ Therefore, geometries are equal if and only if their WKB representations are equ
{<POINT (1 1)>, <POINT (5.2 52.1)>}
.. warning:: Due to limitations of WKB, linearrings will equal linestrings if they contain the exact same points.
- See :func:`shapely.io.to_wkb`.
+ See :func:`shapely.to_wkb`.
Comparing two geometries directly is also supported.
This is the same as using :func:`shapely.predicates.equals_exact` with a ``tolerance`` value of zero.
@@ -99,3 +99,77 @@ This is the same as using :func:`shapely.predicates.equals_exact` with a ``toler
True
>>> point_1 != point_2
True
+
+Formatting
+~~~~~~~~~~
+
+Geometries can be formatted to strings using properties, functions,
+or a Python format specification.
+
+The most convenient is to use ``.wkb_hex`` and ``.wkt`` properties.
+
+.. code:: python
+
+ >>> from shapely import Point, to_wkb, to_wkt, to_geojson
+ >>> pt = Point(-169.910918, -18.997564)
+ >>> pt.wkb_hex
+ 0101000000CF6A813D263D65C0BDAAB35A60FF32C0
+ >>> pt.wkt
+ POINT (-169.910918 -18.997564)
+
+More output options can be found using using :func:`~shapely.to_wkb`,
+:func:`~shapely.to_wkt`, and :func:`~shapely.to_geojson` functions.
+
+.. code:: python
+
+ >>> to_wkb(pt, hex=True, byte_order=0)
+ 0000000001C0653D263D816ACFC032FF605AB3AABD
+ >>> to_wkt(pt, rounding_precision=3)
+ POINT (-169.911 -18.998)
+ >>> print(to_geojson(pt, indent=2))
+ {
+ "type": "Point",
+ "coordinates": [
+ -169.910918,
+ -18.997564
+ ]
+ }
+
+A format specification may also be used to control the format and precision.
+
+.. code:: python
+
+ >>> print(f"Cave near {pt:.3f}")
+ Cave near POINT (-169.911 -18.998)
+ >>> print(f"or hex-encoded as {pt:x}")
+ or hex-encoded as 0101000000cf6a813d263d65c0bdaab35a60ff32c0
+
+Shapely has a format specification inspired from Python's
+`Format Specification Mini-Language
+<https://docs.python.org/3/library/string.html#formatspec>`_ described next.
+
+Semantic for format specification
+---------------------------------
+
+.. productionlist:: format-spec
+ format_spec: [0][.`precision`][`type`]
+ precision: `digit`+
+ type: "f" | "F" | "g" | "G" | "x" | "X"
+
+Format types ``'f'`` and ``'F'`` are to use a fixed-point notation, which is
+activated by setting GEOS' trim option off.
+The upper case variant converts ``nan`` to ``NAN`` and ``inf`` to ``INF``.
+
+Format types ``'g'`` and ``'G'`` are to use a "general format",
+where unnecessary digits are trimmed. This notation is activated by setting
+GEOS' trim option on. The upper case variant is similar to
+``'F'``, and may also display an upper-case ``"E"`` if scientific notation
+is required. Note that this representation may be different for GEOS 3.10.0
+and later, which does not use scientific notation.
+
+For numeric outputs ``'f'`` and ``'g'``, the precision is optional, and if not
+specified, rounding precision will be disabled showing full precision.
+
+Format types ``'x'`` and ``'X'`` show a hex-encoded string representation of
+WKB or Well-Known Binary, with the case of the output matched the
+case of the format type character.
=====================================
docs/migration_pygeos.rst
=====================================
@@ -87,3 +87,4 @@ Other differences
- The behaviour of ``union_all()`` / ``intersection_all()`` / ``symmetric_difference_all``
was changed to return an empty GeometryCollection for an empty or all-None
sequence as input (instead of returning None).
+- The ``radius`` keyword of the ``buffer()`` funtion was renamed to ``distance``.
=====================================
shapely/constructive.py
=====================================
@@ -83,7 +83,7 @@ MultiLineString, MultiPoint, Point, Polygon
@multithreading_enabled
def buffer(
geometry,
- radius,
+ distance,
quad_segs=8,
cap_style="round",
join_style="round",
@@ -92,11 +92,11 @@ def buffer(
**kwargs
):
"""
- Computes the buffer of a geometry for positive and negative buffer radius.
+ Computes the buffer of a geometry for positive and negative buffer distance.
The buffer of a geometry is defined as the Minkowski sum (or difference,
- for negative width) of the geometry with a circle with radius equal to the
- absolute value of the buffer radius.
+ for negative distance) of the geometry with a circle with radius equal
+ to the absolute value of the buffer distance.
The buffer operation always returns a polygonal result. The negative
or zero-distance buffer of lines and points is always empty.
@@ -104,7 +104,7 @@ def buffer(
Parameters
----------
geometry : Geometry or array_like
- width : float or array_like
+ distance : float or array_like
Specifies the circle radius in the Minkowski sum (or difference)..
quad_segs : int, default 8
Specifies the number of linear segments in a quarter circle in the
@@ -178,7 +178,7 @@ def buffer(
raise TypeError("single_sided only accepts scalar values")
return lib.buffer(
geometry,
- radius,
+ distance,
np.intc(quad_segs),
np.intc(cap_style),
np.intc(join_style),
=====================================
shapely/geometry/base.py
=====================================
@@ -5,6 +5,7 @@ geometry objects, but has no effect on geometric analysis. All
operations are performed in the x-y plane. Thus, geometries with
different z values may intersect or be equal.
"""
+import re
from warnings import warn
import numpy as np
@@ -81,7 +82,7 @@ class BaseGeometry(shapely.Geometry):
"""
- __slots__ = ["__weakref__"]
+ __slots__ = []
def __new__(self):
warn(
@@ -103,6 +104,51 @@ class BaseGeometry(shapely.Geometry):
def __nonzero__(self):
return self.__bool__()
+ def __format__(self, format_spec):
+ """Format a geometry using a format specification."""
+ # bypass reqgexp for simple cases
+ if format_spec == "":
+ return shapely.to_wkt(self, rounding_precision=-1)
+ elif format_spec == "x":
+ return shapely.to_wkb(self, hex=True).lower()
+ elif format_spec == "X":
+ return shapely.to_wkb(self, hex=True)
+
+ # fmt: off
+ format_spec_regexp = (
+ "(?:0?\\.(?P<prec>[0-9]+))?"
+ "(?P<fmt_code>[fFgGxX]?)"
+ )
+ # fmt: on
+ match = re.fullmatch(format_spec_regexp, format_spec)
+ if match is None:
+ raise ValueError(f"invalid format specifier: {format_spec}")
+
+ prec, fmt_code = match.groups()
+
+ if prec:
+ prec = int(prec)
+ else:
+ # GEOS has a default rounding_precision -1
+ prec = -1
+
+ if not fmt_code:
+ fmt_code = "g"
+
+ if fmt_code in ("g", "G"):
+ res = shapely.to_wkt(self, rounding_precision=prec, trim=True)
+ elif fmt_code in ("f", "F"):
+ res = shapely.to_wkt(self, rounding_precision=prec, trim=False)
+ elif fmt_code in ("x", "X"):
+ raise ValueError("hex representation does not specify precision")
+ else:
+ raise NotImplementedError(f"unhandled fmt_code: {fmt_code}")
+
+ if fmt_code.isupper():
+ return res.upper()
+ else:
+ return res
+
def __repr__(self):
try:
wkt = super().__str__()
@@ -464,6 +510,8 @@ class BaseGeometry(shapely.Geometry):
if mitre_limit == 0.0:
raise ValueError("Cannot compute offset from zero-length line segment")
+ elif not np.isfinite(distance):
+ raise ValueError("buffer distance must be finite")
return shapely.buffer(
self,
=====================================
shapely/geometry/linestring.py
=====================================
@@ -1,5 +1,6 @@
"""Line strings and related utilities
"""
+import numpy as np
import shapely
from shapely.geometry.base import BaseGeometry, JOIN_STYLE
@@ -146,6 +147,8 @@ class LineString(BaseGeometry):
"""
if mitre_limit == 0.0:
raise ValueError("Cannot compute offset from zero-length line segment")
+ elif not np.isfinite(distance):
+ raise ValueError("offset_curve distance must be finite")
return shapely.offset_curve(self, distance, quad_segs, join_style, mitre_limit)
def parallel_offset(
=====================================
shapely/geometry/point.py
=====================================
@@ -65,14 +65,12 @@ class Point(BaseGeometry):
if not hasattr(coords, "__getitem__"): # generators
coords = list(coords)
- if isinstance(coords[0], tuple):
- coords = coords[0]
-
- geom = shapely.points(coords)
+ coords = np.asarray(coords).squeeze()
else:
# 2 or 3 args
- geom = shapely.points(np.array(args))
+ coords = np.array(args).squeeze()
+ geom = shapely.points(coords)
if not isinstance(geom, Point):
raise ValueError("Invalid values passed to Point constructor")
return geom
=====================================
shapely/tests/geometry/test_format.py
=====================================
@@ -0,0 +1,111 @@
+import pytest
+
+from shapely import Point, Polygon
+from shapely.geos import geos_version
+
+
+def test_format_invalid():
+ # check invalid spec formats
+ pt = Point(1, 2)
+ test_list = [
+ ("5G", ValueError, "invalid format specifier"),
+ (".f", ValueError, "invalid format specifier"),
+ ("0.2e", ValueError, "invalid format specifier"),
+ (".1x", ValueError, "hex representation does not specify precision"),
+ ]
+ for format_spec, err, match in test_list:
+ with pytest.raises(err, match=match):
+ format(pt, format_spec)
+
+
+def test_format_point():
+ # example coordinate data
+ xy1 = (0.12345678901234567, 1.2345678901234567e10)
+ xy2 = (-169.910918, -18.997564)
+ xyz3 = (630084, 4833438, 76)
+
+ # list of tuples to test; see structure at top of the for-loop
+ test_list = [
+ (".0f", xy1, "POINT (0 12345678901)", True),
+ (".1f", xy1, "POINT (0.1 12345678901.2)", True),
+ ("0.2f", xy2, "POINT (-169.91 -19.00)", True),
+ (".3F", (float("inf"), -float("inf")), "POINT (INF -INF)", True),
+ ]
+ if geos_version < (3, 10, 0):
+ # 'g' format varies depending on GEOS version
+ test_list += [
+ (".1g", xy1, "POINT (0.1 1e+10)", True),
+ (".6G", xy1, "POINT (0.123457 1.23457E+10)", True),
+ ("0.12g", xy1, "POINT (0.123456789012 12345678901.2)", True),
+ ("0.4g", xy2, "POINT (-169.9 -19)", True),
+ ]
+ else:
+ test_list += [
+ (".1g", xy1, "POINT (0.1 12345678901.2)", False),
+ (".6G", xy1, "POINT (0.123457 12345678901.234568)", False),
+ ("0.12g", xy1, "POINT (0.123456789012 12345678901.234568)", False),
+ ("g", xy2, "POINT (-169.910918 -18.997564)", False),
+ ("0.2g", xy2, "POINT (-169.91 -19)", False),
+ ]
+ # without precsions test GEOS rounding_precision=-1; different than Python
+ test_list += [
+ ("f", (1, 2), f"POINT ({1:.16f} {2:.16f})", False),
+ ("F", xyz3, "POINT Z ({:.16f} {:.16f} {:.16f})".format(*xyz3), False),
+ ("g", xyz3, "POINT Z (630084 4833438 76)", False),
+ ]
+ for format_spec, coords, expt_wkt, same_python_float in test_list:
+ pt = Point(*coords)
+ # basic checks
+ assert f"{pt}" == pt.wkt
+ assert format(pt, "") == pt.wkt
+ assert format(pt, "x") == pt.wkb_hex.lower()
+ assert format(pt, "X") == pt.wkb_hex
+ # check formatted WKT to expected
+ assert format(pt, format_spec) == expt_wkt, format_spec
+ # check Python's format consistency
+ text_coords = expt_wkt[expt_wkt.index("(") + 1 : expt_wkt.index(")")]
+ is_same = []
+ for coord, expt_coord in zip(coords, text_coords.split()):
+ py_fmt_float = format(float(coord), format_spec)
+ if same_python_float:
+ assert py_fmt_float == expt_coord, format_spec
+ else:
+ is_same.append(py_fmt_float == expt_coord)
+ if not same_python_float:
+ assert not all(is_same), f"{format_spec!r} with {expt_wkt}"
+
+
+def test_format_polygon():
+ # check basic cases
+ poly = Point(0, 0).buffer(10, 2)
+ assert f"{poly}" == poly.wkt
+ assert format(poly, "") == poly.wkt
+ assert format(poly, "x") == poly.wkb_hex.lower()
+ assert format(poly, "X") == poly.wkb_hex
+
+ # Use f-strings with extra characters and rounding precision
+ assert f"<{poly:.2f}>" == (
+ "<POLYGON ((10.00 0.00, 7.07 -7.07, 0.00 -10.00, -7.07 -7.07, "
+ "-10.00 -0.00, -7.07 7.07, -0.00 10.00, 7.07 7.07, 10.00 0.00))>"
+ )
+
+ # 'g' format varies depending on GEOS version
+ if geos_version < (3, 10, 0):
+ expected_2G = (
+ "POLYGON ((10 0, 7.1 -7.1, 1.6E-14 -10, -7.1 -7.1, "
+ "-10 -3.2E-14, -7.1 7.1, -4.6E-14 10, 7.1 7.1, 10 0))"
+ )
+ else:
+ expected_2G = (
+ "POLYGON ((10 0, 7.07 -7.07, 0 -10, -7.07 -7.07, "
+ "-10 0, -7.07 7.07, 0 10, 7.07 7.07, 10 0))"
+ )
+ assert f"{poly:.2G}" == expected_2G
+
+ # check empty
+ empty = Polygon()
+ assert f"{empty}" == "POLYGON EMPTY"
+ assert format(empty, "") == empty.wkt
+ assert format(empty, ".2G") == empty.wkt
+ assert format(empty, "x") == empty.wkb_hex.lower()
+ assert format(empty, "X") == empty.wkb_hex
=====================================
shapely/tests/geometry/test_geometry_base.py
=====================================
@@ -1,3 +1,4 @@
+import platform
import weakref
import numpy as np
@@ -45,6 +46,10 @@ geometries_all_types = [
]
+ at pytest.mark.skipif(
+ platform.python_implementation() == "PyPy",
+ reason="Setting custom attributes doesn't fail on PyPy",
+)
@pytest.mark.parametrize("geom", geometries_all_types)
def test_setattr_disallowed(geom):
with pytest.raises(AttributeError):
=====================================
shapely/tests/geometry/test_hash.py
=====================================
@@ -1,35 +1,28 @@
-from shapely import GeometryCollection, LineString, MultiPoint, Point
-
-
-def test_point():
- g = Point(1, 2)
- assert hash(g) == hash(Point(1, 2))
- assert hash(g) != hash(Point(1, 3))
-
-
-def test_multipoint():
- g = MultiPoint([(1, 2), (3, 4)])
- assert hash(g) == hash(MultiPoint([(1, 2), (3, 4)]))
- assert hash(g) != hash(MultiPoint([(1, 2), (3, 3)]))
-
-
-def test_linestring():
- g = LineString([(1, 2), (3, 4)])
- assert hash(g) == hash(LineString([(1, 2), (3, 4)]))
- assert hash(g) != hash(LineString([(1, 2), (3, 3)]))
-
-
-def test_polygon():
- g = Point(0, 0).buffer(1.0)
- assert hash(g) == hash(Point(0, 0).buffer(1.0))
- assert hash(g) != hash(Point(0, 0).buffer(1.1))
-
-
-def test_collection():
- g = GeometryCollection([Point(1, 2), LineString([(1, 2), (3, 4)])])
- assert hash(g) == hash(
- GeometryCollection([Point(1, 2), LineString([(1, 2), (3, 4)])])
- )
- assert hash(g) != hash(
- GeometryCollection([Point(1, 2), LineString([(1, 2), (3, 3)])])
- )
+import pytest
+
+import shapely
+from shapely.affinity import translate
+from shapely.geometry import GeometryCollection, LineString, MultiPoint, Point
+
+
+ at pytest.mark.parametrize(
+ "geom",
+ [
+ Point(1, 2),
+ MultiPoint([(1, 2), (3, 4)]),
+ LineString([(1, 2), (3, 4)]),
+ Point(0, 0).buffer(1.0),
+ GeometryCollection([Point(1, 2), LineString([(1, 2), (3, 4)])]),
+ ],
+ ids=[
+ "Point",
+ "MultiPoint",
+ "LineString",
+ "Polygon",
+ "GeometryCollection",
+ ],
+)
+def test_hash(geom):
+ h1 = hash(geom)
+ assert h1 == hash(shapely.from_wkb(geom.wkb))
+ assert h1 != hash(translate(geom, 1.0, 2.0))
=====================================
shapely/tests/geometry/test_point.py
=====================================
@@ -34,6 +34,8 @@ def test_from_sequence():
# From coordinate sequence
p = Point([(3.0, 4.0)])
assert p.coords[:] == [(3.0, 4.0)]
+ p = Point([[3.0, 4.0]])
+ assert p.coords[:] == [(3.0, 4.0)]
# 3D
p = Point((3.0, 4.0, 5.0))
@@ -53,6 +55,17 @@ def test_from_numpy():
assert p.coords[:] == [(1.0, 2.0, 3.0)]
+def test_from_numpy_xy():
+ # Construct from separate x, y numpy arrays - if those are length 1,
+ # this is allowed for compat with shapely 1.8
+ # (https://github.com/shapely/shapely/issues/1587)
+ p = Point(np.array([1.0]), np.array([2.0]))
+ assert p.coords[:] == [(1.0, 2.0)]
+
+ p = Point(np.array([1.0]), np.array([2.0]), np.array([3.0]))
+ assert p.coords[:] == [(1.0, 2.0, 3.0)]
+
+
def test_from_point():
# From another point
p = Point(3.0, 4.0)
=====================================
src/pygeom.c
=====================================
@@ -38,11 +38,15 @@ PyObject* GeometryObject_FromGEOS(GEOSGeometry* ptr, GEOSContextHandle_t ctx) {
} else {
self->ptr = ptr;
self->ptr_prepared = NULL;
+ self->weakreflist = (PyObject *)NULL;
return (PyObject*)self;
}
}
static void GeometryObject_dealloc(GeometryObject* self) {
+ if (self->weakreflist != NULL) {
+ PyObject_ClearWeakRefs((PyObject *)self);
+ }
if (self->ptr != NULL) {
// not using GEOS_INIT, but using global context instead
GEOSContextHandle_t ctx = geos_context[0];
@@ -396,6 +400,7 @@ PyTypeObject GeometryType = {
.tp_repr = (reprfunc)GeometryObject_repr,
.tp_hash = (hashfunc)GeometryObject_hash,
.tp_richcompare = (richcmpfunc)GeometryObject_richcompare,
+ .tp_weaklistoffset = offsetof(GeometryObject, weakreflist),
.tp_str = (reprfunc)GeometryObject_str,
};
=====================================
src/pygeom.h
=====================================
@@ -6,8 +6,11 @@
#include "geos.h"
typedef struct {
- PyObject_HEAD void* ptr;
+ PyObject_HEAD
+ void* ptr;
void* ptr_prepared;
+ /* For weak references */
+ PyObject *weakreflist;
} GeometryObject;
extern PyTypeObject GeometryType;
=====================================
tests/test_binascii_hex.txt deleted
=====================================
@@ -1,47 +0,0 @@
-Round-tripping geometries through hex-encoded binary
-====================================================
-
-Hex-encoded binary is the PostGIS geometry representation, and so this is a
-test of the ability to store Shapely geometries in PostGIS.
-
-Point
------
-
- >>> from shapely.geometry import Point
- >>> point = Point(0.0, 0.0)
- >>> from binascii import a2b_hex, b2a_hex
- >>> x = b2a_hex(point.wkb)
- >>> from shapely import wkb
- >>> shape = wkb.loads(a2b_hex(x))
- >>> shape # doctest: +ELLIPSIS
- <POINT (0 0)>
-
-LineString
-----------
-
- >>> from shapely.geometry import LineString
- >>> line = LineString([(0.0, 0.0), (1.0, 1.0)])
- >>> x = b2a_hex(line.wkb)
- >>> shape = wkb.loads(a2b_hex(x))
- >>> shape # doctest: +ELLIPSIS
- <LINESTRING (0 0, 1 1)>
-
-Polygon
-----------
-
- >>> from shapely.geometry import Polygon
- >>> polygon = Polygon([(0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0)])
- >>> x = b2a_hex(polygon.wkb)
- >>> shape = wkb.loads(a2b_hex(x))
- >>> shape # doctest: +ELLIPSIS
- <POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))>
-
-Polygon with hole
------------------
-
- >>> polygon = Polygon([(0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0)], [[(0.1,0.1), (0.1,0.2), (0.2,0.2), (0.2,0.1)]])
- >>> x = b2a_hex(polygon.wkb)
- >>> shape = wkb.loads(a2b_hex(x))
- >>> shape.wkt # doctest: +ELLIPSIS
- 'POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0), (0.1 0.1, 0.1 0.2, 0.2 0.2, 0.2 0.1, 0.1 0.1))'
-
=====================================
tests/test_buffer.py
=====================================
@@ -6,6 +6,13 @@ from shapely.geometry.base import CAP_STYLE, JOIN_STYLE
from shapely.constructive import BufferCapStyle, BufferJoinStyle
+ at pytest.mark.parametrize("distance", [float("nan"), float("inf")])
+def test_non_finite_distance(distance):
+ g = geometry.Point(0, 0)
+ with pytest.raises(ValueError, match="distance must be finite"):
+ g.buffer(distance)
+
+
class BufferTests(unittest.TestCase):
"""Test Buffer Point/Line/Polygon with and without single_sided params"""
=====================================
tests/test_doctests.py deleted
=====================================
@@ -1,36 +0,0 @@
-import os
-import doctest
-from . import unittest
-from glob import glob
-
-optionflags = (doctest.REPORT_ONLY_FIRST_FAILURE |
- doctest.NORMALIZE_WHITESPACE |
- doctest.ELLIPSIS)
-
-
-def list_doctests():
- print(__file__)
- source_files = glob(os.path.join(os.path.dirname(__file__), '*.txt'))
- return [filename for filename in source_files]
-
-
-def open_file(filename, mode='r'):
- """Helper function to open files from within the tests package."""
- return open(os.path.join(os.path.dirname(__file__), filename), mode)
-
-
-def setUp(test):
- test.globs.update(dict(open_file=open_file,))
-
-
-def test_suite():
- return unittest.TestSuite(
- [doctest.DocFileSuite(os.path.basename(filename),
- optionflags=optionflags,
- setUp=setUp)
- for filename
- in list_doctests()])
-
-if __name__ == "__main__":
- runner = unittest.TextTestRunner(verbosity=1)
- runner.run(test_suite())
=====================================
tests/test_parallel_offset.py
=====================================
@@ -1,8 +1,17 @@
+import pytest
+
from . import unittest
from shapely.geometry import LineString, LinearRing
from shapely.testing import assert_geometries_equal
+ at pytest.mark.parametrize("distance", [float("nan"), float("inf")])
+def test_non_finite_distance(distance):
+ g = LineString([(0, 0), (10, 0)])
+ with pytest.raises(ValueError, match="distance must be finite"):
+ g.parallel_offset(distance)
+
+
class OperationsTestCase(unittest.TestCase):
def test_parallel_offset_linestring(self):
View it on GitLab: https://salsa.debian.org/debian-gis-team/python-shapely/-/compare/aa946a47498792eac2f8c971efc9c9a82bb5febd...5d8be325bfb0baa14cf9e19dc110d8837f3af5a4
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/python-shapely/-/compare/aa946a47498792eac2f8c971efc9c9a82bb5febd...5d8be325bfb0baa14cf9e19dc110d8837f3af5a4
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/20221029/9a5bb66a/attachment-0001.htm>
More information about the Pkg-grass-devel
mailing list