Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-Shapely for openSUSE:Factory checked in at 2024-09-02 13:14:23 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-Shapely (Old) and /work/SRC/openSUSE:Factory/.python-Shapely.new.2698 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-Shapely" Mon Sep 2 13:14:23 2024 rev:29 rq:1198076 version:2.0.6 Changes: -------- --- /work/SRC/openSUSE:Factory/python-Shapely/python-Shapely.changes 2024-07-09 20:06:00.837121973 +0200 +++ /work/SRC/openSUSE:Factory/.python-Shapely.new.2698/python-Shapely.changes 2024-09-02 13:14:30.710505551 +0200 @@ -1,0 +2,8 @@ +Sat Aug 31 11:24:25 UTC 2024 - Ben Greiner <c...@bnavigator.de> + +- Update to 2.0.6 + * Fix compatibility with NumPy 2.1.0 (#2099). +- Release 2.0.5 + * Fix Point x/y/z attributes to return Python floats (#2074). + +------------------------------------------------------------------- Old: ---- shapely-2.0.4.tar.gz New: ---- shapely-2.0.6.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-Shapely.spec ++++++ --- /var/tmp/diff_new_pack.rkPHfl/_old 2024-09-02 13:14:31.322531003 +0200 +++ /var/tmp/diff_new_pack.rkPHfl/_new 2024-09-02 13:14:31.322531003 +0200 @@ -18,13 +18,13 @@ %{?sle15_python_module_pythons} Name: python-Shapely -Version: 2.0.4 +Version: 2.0.6 Release: 0 Summary: Geospatial geometries, predicates, and operations License: BSD-3-Clause URL: https://github.com/shapely/shapely Source: https://files.pythonhosted.org/packages/source/s/shapely/shapely-%{version}.tar.gz -# PATCH-FIX-UPSTREAM Fix incompatible pointer type passed to GEOSPolygonize_r +# PATCH-FIX-UPSTREAM Fix incompatible pointer type passed to GEOSPolygonize_r gh#shapely/shapely#1945 Patch: https://github.com/shapely/shapely/pull/1945.patch BuildRequires: %{python_module Cython} BuildRequires: %{python_module devel >= 3.8} ++++++ shapely-2.0.4.tar.gz -> shapely-2.0.6.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/CHANGES.txt new/shapely-2.0.6/CHANGES.txt --- old/shapely-2.0.4/CHANGES.txt 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/CHANGES.txt 2024-08-19 23:35:37.000000000 +0200 @@ -1,6 +1,28 @@ Changes ======= +2.0.6 (2024-08-19) +------------------ + +Bug fixes: + +- Fix compatibility with NumPy 2.1.0 (#2099). + +Wheels are available for Python 3.13 (and still include GEOS 3.11.4). + +2.0.5 (2024-07-13) +------------------ + +Binary wheels on PyPI include GEOS 3.11.4 from 2024-06-05. Furthermore, +universal2 wheels are removed for macOS since both x86_64 and arm64 wheels are +provided. + +Bug fixes: + +- Fix Point x/y/z attributes to return Python floats (#2074). +- Fix affinity for Apple silicon with NumPy 2.0 by reverting matmul, and + use direct matrix multiplication instead (#2085). + 2.0.4 (2024-04-16) ------------------ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/CITATION.cff new/shapely-2.0.6/CITATION.cff --- old/shapely-2.0.4/CITATION.cff 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/CITATION.cff 2024-08-19 23:35:37.000000000 +0200 @@ -2,8 +2,8 @@ message: "Please cite this software using these metadata." type: software title: Shapely -version: "2.0.4" -date-released: "2024-04-16" +version: "2.0.6" +date-released: "2024-08-19" doi: 10.5281/zenodo.5597138 abstract: "Manipulation and analysis of geometric objects in the Cartesian plane." repository-artifact: https://pypi.org/project/Shapely diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/PKG-INFO new/shapely-2.0.6/PKG-INFO --- old/shapely-2.0.4/PKG-INFO 2024-04-17 00:01:12.009678400 +0200 +++ new/shapely-2.0.6/PKG-INFO 2024-08-19 23:35:49.932155600 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: shapely -Version: 2.0.4 +Version: 2.0.6 Summary: Manipulation and analysis of geometric objects Author: Sean Gillies Maintainer: Shapely contributors diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/docs/geometry.rst new/shapely-2.0.6/docs/geometry.rst --- old/shapely-2.0.4/docs/geometry.rst 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/docs/geometry.rst 2024-08-19 23:35:37.000000000 +0200 @@ -173,3 +173,38 @@ 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. + +.. _canonical-form: + +Canonical form +-------------- +When operations are applied on geometries the result is returned according to +some conventions. + +In most cases, geometries will be returned in "mild" canonical form. There is no +goal to keep this form stable, so it is expected to change in future versions of +GEOS: + +- the coordinates of exterior rings follow a clockwise orientation and interior + rings have a counter-clockwise orientation. This is the opposite of the OGC + specifications because the choice was made before this was included in the + standard. +- the starting point of rings can be changed in the output, but the exact order + is undefined and should not be relied upon +- the order of geometry types in a collection can be changed, but the order is + undefined + +When :func:`~shapely.normalize` is used, the "strict" canonical form is applied. +This type of normalization is meant to be stable, so changes to it will be +avoided if possible: + +- the coordinates of exterior rings follow a clockwise orientation and interior + rings have a counter-clockwise orientation +- the starting point of rings is lower left +- elements in collections are ordered by geometry type: by descending dimension + and multi-types first (MultiPolygon, Polygon, MultiLineString, LineString, + MultiPoint, Point). Multiple elements from the same type are ordered from + right to left and from top to bottom. + +It is important to note that input geometries do not have to follow these +conventions. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/docs/installation.rst new/shapely-2.0.6/docs/installation.rst --- old/shapely-2.0.4/docs/installation.rst 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/docs/installation.rst 2024-08-19 23:35:37.000000000 +0200 @@ -26,8 +26,8 @@ $ conda install shapely --channel conda-forge -Installation from source with custom GEOS libary ------------------------------------------------- +Installation from source with custom GEOS library +------------------------------------------------- You may want to use a specific GEOS version or a GEOS distribution that is already present on your system (for compatibility with other modules that diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/docs/migration_pygeos.rst new/shapely-2.0.6/docs/migration_pygeos.rst --- old/shapely-2.0.4/docs/migration_pygeos.rst 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/docs/migration_pygeos.rst 2024-08-19 23:35:37.000000000 +0200 @@ -14,7 +14,7 @@ Generally speaking, this should be a smooth experience because all functionality of PyGEOS was added to Shapely. All vectorized functions -availabe in ``pygeos`` have been added to the top-level ``shapely`` module, +available in ``pygeos`` have been added to the top-level ``shapely`` module, with only minor differences (see below). Migrating from PyGEOS to Shapely 2.0 can thus be done by replacing the ``pygeos`` import and module calls:: @@ -87,4 +87,4 @@ - 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``. +- The ``radius`` keyword of the ``buffer()`` function was renamed to ``distance``. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/pyproject.toml new/shapely-2.0.6/pyproject.toml --- old/shapely-2.0.4/pyproject.toml 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/pyproject.toml 2024-08-19 23:35:37.000000000 +0200 @@ -3,7 +3,7 @@ "Cython", # Starting with NumPy 1.25, NumPy is (by default) as far back compatible # as oldest-support-numpy was (customizable with a NPY_TARGET_VERSION - # define). For older Python versions (where NumPy 1.25 is not yet avaiable) + # define). For older Python versions (where NumPy 1.25 is not yet available) # continue using oldest-support-numpy. "oldest-supported-numpy; python_version<'3.9'", "numpy>=1.25; python_version>='3.9'", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/setup.py new/shapely-2.0.6/setup.py --- old/shapely-2.0.4/setup.py 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/setup.py 2024-08-19 23:35:37.000000000 +0200 @@ -5,8 +5,7 @@ import sys from pathlib import Path -from pkg_resources import parse_version -from setuptools import Extension, find_packages, setup +from setuptools import Extension, setup from setuptools.command.build_ext import build_ext as _build_ext # ensure the current directory is on sys.path so versioneer can be imported @@ -42,15 +41,13 @@ """ cmd = os.environ.get("GEOS_CONFIG", "geos-config") try: - stdout, stderr = subprocess.Popen( - [cmd, option], stdout=subprocess.PIPE, stderr=subprocess.PIPE - ).communicate() + proc = subprocess.run([cmd, option], capture_output=True, text=True) except OSError: return - if stderr and not stdout: - log.warning("geos-config %s returned '%s'", option, stderr.decode().strip()) + if proc.stderr and not proc.stdout: + log.warning("geos-config %s returned '%s'", option, proc.stderr.strip()) return - result = stdout.decode().strip() + result = proc.stdout.strip() log.debug("geos-config %s returned '%s'", option, result) return result @@ -86,11 +83,12 @@ ) return {} - if parse_version(geos_version) < parse_version(MIN_GEOS_VERSION): + def version_tuple(ver): + return tuple(int(itm) if itm.isnumeric() else itm for itm in ver.split(".")) + + if version_tuple(geos_version) < version_tuple(MIN_GEOS_VERSION): raise ImportError( - "GEOS version should be >={}, found {}".format( - MIN_GEOS_VERSION, geos_version - ) + f"GEOS version should be >={MIN_GEOS_VERSION}, found {geos_version}" ) libraries = [] @@ -133,7 +131,7 @@ import numpy - self.include_dirs.append(numpy.get_include()) + self.include_dirs.insert(0, numpy.get_include()) ext_modules = [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/shapely/_geometry.py new/shapely-2.0.6/shapely/_geometry.py --- old/shapely-2.0.4/shapely/_geometry.py 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/shapely/_geometry.py 2024-08-19 23:35:37.000000000 +0200 @@ -728,20 +728,26 @@ By default, geometries use double precision coordinates (grid_size = 0). - Coordinates will be rounded if a precision grid is less precise than the - input geometry. Duplicated vertices will be dropped from lines and + Coordinates will be rounded if the precision grid specified is less precise + than the input geometry. Duplicated vertices will be dropped from lines and polygons for grid sizes greater than 0. Line and polygon geometries may collapse to empty geometries if all vertices are closer together than - grid_size. Z values, if present, will not be modified. - - Note: subsequent operations will always be performed in the precision of - the geometry with higher precision (smaller "grid_size"). That same - precision will be attached to the operation outputs. - - Also note: input geometries should be geometrically valid; unexpected - results may occur if input geometries are not. - - Returns None if geometry is None. + ``grid_size`` or if a polygon becomes significantly narrower than + ``grid_size``. Spikes or sections in polygons narrower than ``grid_size`` + after rounding the vertices will be removed, which can lead to multipolygons + or empty geometries. Z values, if present, will not be modified. + + Notes: + + * subsequent operations will always be performed in the precision of the + geometry with higher precision (smaller "grid_size"). That same precision + will be attached to the operation outputs. + * input geometries should be geometrically valid; unexpected results may + occur if input geometries are not. + * the geometry returned will be in + :ref:`mild canonical form <canonical-form>`, and the order of vertices can + change and should not be relied upon. + * returns None if geometry is None. Parameters ---------- @@ -752,21 +758,24 @@ value is more precise than input geometry, the input geometry will not be modified. mode : {'valid_output', 'pointwise', 'keep_collapsed'}, default 'valid_output' - This parameter determines how to handle invalid output geometries. There are three modes: + This parameter determines the way a precision reduction is applied on + the geometry. There are three modes: - 1. `'valid_output'` (default): The output is always valid. Collapsed geometry elements - (including both polygons and lines) are removed. Duplicate vertices are removed. - 2. `'pointwise'`: Precision reduction is performed pointwise. Output geometry - may be invalid due to collapse or self-intersection. Duplicate vertices are not - removed. In GEOS this option is called NO_TOPO. + 1. `'valid_output'` (default): The output is always valid. Collapsed + geometry elements (including both polygons and lines) are removed. + Duplicate vertices are removed. + 2. `'pointwise'`: Precision reduction is performed pointwise. Output + geometry may be invalid due to collapse or self-intersection. + Duplicate vertices are not removed. In GEOS this option is called + NO_TOPO. .. note:: - 'pointwise' mode requires at least GEOS 3.10. It is accepted in earlier versions, - but the results may be unexpected. - 3. `'keep_collapsed'`: Like the default mode, except that collapsed linear geometry - elements are preserved. Collapsed polygonal input elements are removed. Duplicate - vertices are removed. + 'pointwise' mode requires at least GEOS 3.10. It is accepted in + earlier versions, but the results may be unexpected. + 3. `'keep_collapsed'`: Like the default mode, except that collapsed + linear geometry elements are preserved. Collapsed polygonal input + elements are removed. Duplicate vertices are removed. **kwargs See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/shapely/_geometry_helpers.pyx new/shapely-2.0.6/shapely/_geometry_helpers.pyx --- old/shapely-2.0.4/shapely/_geometry_helpers.pyx 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/shapely/_geometry_helpers.pyx 2024-08-19 23:35:37.000000000 +0200 @@ -302,7 +302,7 @@ cdef int[:] collection_size = np.bincount(indices).astype(np.int32) # A temporary array for the geometries that will be given to CreateCollection. - # Its size equals max(collection_size) to accomodate the largest collection. + # Its size equals max(collection_size) to accommodate the largest collection. temp_geoms = np.empty(shape=(np.max(collection_size), ), dtype=np.intp) cdef np.intp_t[:] temp_geoms_view = temp_geoms diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/shapely/_version.py new/shapely-2.0.6/shapely/_version.py --- old/shapely-2.0.4/shapely/_version.py 2024-04-17 00:01:12.009678400 +0200 +++ new/shapely-2.0.6/shapely/_version.py 2024-08-19 23:35:49.932155600 +0200 @@ -8,11 +8,11 @@ version_json = ''' { - "date": "2024-04-16T23:57:44+0200", + "date": "2024-08-19T23:29:00+0200", "dirty": false, "error": null, - "full-revisionid": "3853e1170173125b7e86cbb5cc8dab1c274c3999", - "version": "2.0.4" + "full-revisionid": "5a4207d2fb74b25d7bb2fb5d04813f68a3a612f4", + "version": "2.0.6" } ''' # END VERSION_JSON diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/shapely/affinity.py new/shapely-2.0.6/shapely/affinity.py --- old/shapely-2.0.4/shapely/affinity.py 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/shapely/affinity.py 2024-08-19 23:35:37.000000000 +0200 @@ -61,15 +61,31 @@ ndim = 2 else: raise ValueError("'matrix' expects either 6 or 12 coefficients") - if ndim == 2: - A = np.array([[a, b], [d, e]], dtype=float) - off = np.array([xoff, yoff], dtype=float) - else: - A = np.array([[a, b, c], [d, e, f], [g, h, i]], dtype=float) - off = np.array([xoff, yoff, zoff], dtype=float) + + # if ndim == 2: + # A = np.array([[a, b], [d, e]], dtype=float) + # off = np.array([xoff, yoff], dtype=float) + # else: + # A = np.array([[a, b, c], [d, e, f], [g, h, i]], dtype=float) + # off = np.array([xoff, yoff, zoff], dtype=float) def _affine_coords(coords): - return np.matmul(A, coords.T).T + off + # These are equivalent, but unfortunately not robust + # result = np.matmul(coords, A.T) + off + # result = np.matmul(A, coords.T).T + off + # Therefore, manual matrix multiplication is needed + if ndim == 2: + x, y = coords.T + xp = a * x + b * y + xoff + yp = d * x + e * y + yoff + result = np.stack([xp, yp]).T + elif ndim == 3: + x, y, z = coords.T + xp = a * x + b * y + c * z + xoff + yp = d * x + e * y + f * z + yoff + zp = g * x + h * y + i * z + zoff + result = np.stack([xp, yp, zp]).T + return result return shapely.transform(geom, _affine_coords, include_z=ndim == 3) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/shapely/constructive.py new/shapely-2.0.6/shapely/constructive.py --- old/shapely-2.0.4/shapely/constructive.py 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/shapely/constructive.py 2024-08-19 23:35:37.000000000 +0200 @@ -412,17 +412,18 @@ -------- >>> from shapely import GeometryCollection, LineString, MultiPoint, Polygon >>> points = MultiPoint([(50, 30), (60, 30), (100, 100)]) - >>> delaunay_triangles(points) - <GEOMETRYCOLLECTION (POLYGON ((50 30, 60 30, 100 100, 50 30)))> + >>> delaunay_triangles(points).normalize() + <GEOMETRYCOLLECTION (POLYGON ((50 30, 100 100, 60 30, 50 30)))> >>> delaunay_triangles(points, only_edges=True) <MULTILINESTRING ((50 30, 100 100), (50 30, 60 30), ...> >>> delaunay_triangles(MultiPoint([(50, 30), (51, 30), (60, 30), (100, 100)]), \ -tolerance=2) - <GEOMETRYCOLLECTION (POLYGON ((50 30, 60 30, 100 100, 50 30)))> - >>> delaunay_triangles(Polygon([(50, 30), (60, 30), (100, 100), (50, 30)])) - <GEOMETRYCOLLECTION (POLYGON ((50 30, 60 30, 100 100, 50 30)))> - >>> delaunay_triangles(LineString([(50, 30), (60, 30), (100, 100)])) - <GEOMETRYCOLLECTION (POLYGON ((50 30, 60 30, 100 100, 50 30)))> +tolerance=2).normalize() + <GEOMETRYCOLLECTION (POLYGON ((50 30, 100 100, 60 30, 50 30)))> + >>> delaunay_triangles(Polygon([(50, 30), (60, 30), (100, 100), (50, 30)]))\ +.normalize() + <GEOMETRYCOLLECTION (POLYGON ((50 30, 100 100, 60 30, 50 30)))> + >>> delaunay_triangles(LineString([(50, 30), (60, 30), (100, 100)])).normalize() + <GEOMETRYCOLLECTION (POLYGON ((50 30, 100 100, 60 30, 50 30)))> >>> delaunay_triangles(GeometryCollection([])) <GEOMETRYCOLLECTION EMPTY> """ @@ -533,11 +534,11 @@ @multithreading_enabled def normalize(geometry, **kwargs): - """Converts Geometry to normal form (or canonical form). + """Converts Geometry to strict normal form (or canonical form). - This method orders the coordinates, rings of a polygon and parts of - multi geometries consistently. Typically useful for testing purposes - (for example in combination with ``equals_exact``). + In :ref:`strict canonical form <canonical-form>`, the coordinates, rings of a polygon and + parts of multi geometries are ordered consistently. Typically useful for testing + purposes (for example in combination with ``equals_exact``). Parameters ---------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/shapely/coords.py new/shapely-2.0.6/shapely/coords.py --- old/shapely-2.0.4/shapely/coords.py 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/shapely/coords.py 2024-08-19 23:35:37.000000000 +0200 @@ -46,8 +46,13 @@ else: raise TypeError("key must be an index or slice") - def __array__(self, dtype=None): - return self._coords + def __array__(self, dtype=None, copy=None): + if copy is False: + raise ValueError("`copy=False` isn't supported. A copy is always created.") + elif copy is True: + return self._coords.copy() + else: + return self._coords @property def xy(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/shapely/creation.py new/shapely-2.0.6/shapely/creation.py --- old/shapely-2.0.4/shapely/creation.py 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/shapely/creation.py 2024-08-19 23:35:37.000000000 +0200 @@ -353,7 +353,7 @@ ): geometries = points(geometries) if indices is None: - return lib.create_collection(geometries, typ, out=out, **kwargs) + return lib.create_collection(geometries, np.intc(typ), out=out, **kwargs) else: return collections_1d(geometries, indices, typ, out=out) @@ -390,7 +390,7 @@ geometries = linestrings(geometries) if indices is None: - return lib.create_collection(geometries, typ, out=out, **kwargs) + return lib.create_collection(geometries, np.intc(typ), out=out, **kwargs) else: return collections_1d(geometries, indices, typ, out=out) @@ -426,7 +426,7 @@ ): geometries = polygons(geometries) if indices is None: - return lib.create_collection(geometries, typ, out=out, **kwargs) + return lib.create_collection(geometries, np.intc(typ), out=out, **kwargs) else: return collections_1d(geometries, indices, typ, out=out) @@ -457,7 +457,7 @@ """ typ = GeometryType.GEOMETRYCOLLECTION if indices is None: - return lib.create_collection(geometries, typ, out=out, **kwargs) + return lib.create_collection(geometries, np.intc(typ), out=out, **kwargs) else: return collections_1d(geometries, indices, typ, out=out) @@ -511,7 +511,7 @@ Parameters ---------- geometry : Geometry or array_like - Geometries are changed inplace + Geometries are changed in-place **kwargs See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/shapely/geometry/point.py new/shapely-2.0.6/shapely/geometry/point.py --- old/shapely-2.0.4/shapely/geometry/point.py 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/shapely/geometry/point.py 2024-08-19 23:35:37.000000000 +0200 @@ -85,12 +85,12 @@ @property def x(self): """Return x coordinate.""" - return shapely.get_x(self) + return float(shapely.get_x(self)) @property def y(self): """Return y coordinate.""" - return shapely.get_y(self) + return float(shapely.get_y(self)) @property def z(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/shapely/io.py new/shapely-2.0.6/shapely/io.py --- old/shapely-2.0.4/shapely/io.py 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/shapely/io.py 2024-08-19 23:35:37.000000000 +0200 @@ -139,12 +139,12 @@ ---------- geometry : Geometry or array_like hex : bool, default False - If true, export the WKB as a hexidecimal string. The default is to + If true, export the WKB as a hexadecimal string. The default is to return a binary bytes object. output_dimension : int, default 3 The output dimension for the WKB. Supported values are 2 and 3. Specifying 3 means that up to 3 dimensions will be written but 2D - geometries will still be represented as 2D in the WKB represenation. + geometries will still be represented as 2D in the WKB representation. byte_order : int, default -1 Defaults to native machine byte order (-1). Use 0 to force big endian and 1 for little endian. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/shapely/plotting.py new/shapely-2.0.6/shapely/plotting.py --- old/shapely-2.0.4/shapely/plotting.py 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/shapely/plotting.py 2024-08-19 23:35:37.000000000 +0200 @@ -1,7 +1,7 @@ """ Plot single geometries using Matplotlib. -Note: this module is experimental, and mainly targetting (interactive) +Note: this module is experimental, and mainly targeting (interactive) exploration, debugging and illustration purposes. """ @@ -38,7 +38,7 @@ """ Gets a Matplotlib patch from a (Multi)Polygon. - Note: this function is experimental, and mainly targetting (interactive) + Note: this function is experimental, and mainly targeting (interactive) exploration, debugging and illustration purposes. Parameters @@ -69,7 +69,7 @@ """ Plot a (Multi)Polygon. - Note: this function is experimental, and mainly targetting (interactive) + Note: this function is experimental, and mainly targeting (interactive) exploration, debugging and illustration purposes. Parameters @@ -132,7 +132,7 @@ """ Plot a (Multi)LineString/LinearRing. - Note: this function is experimental, and mainly targetting (interactive) + Note: this function is experimental, and mainly targeting (interactive) exploration, debugging and illustration purposes. Parameters @@ -144,7 +144,7 @@ add_points : bool, default True If True, also plot the coordinates (vertices) as points. color : matplotlib color specification - Color for the line (edgecolor under the hood) and pointes. + Color for the line (edgecolor under the hood) and points. linewidth : float, default 2 The line width for the polygon boundary. **kwargs diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/shapely/predicates.py new/shapely-2.0.6/shapely/predicates.py --- old/shapely-2.0.4/shapely/predicates.py 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/shapely/predicates.py 2024-08-19 23:35:37.000000000 +0200 @@ -81,7 +81,7 @@ Parameters ---------- geometry : Geometry or array_like - This function will return False for non-linear goemetries and for + This function will return False for non-linear geometries and for lines with fewer than 4 points (including the closing point). **kwargs See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments. @@ -748,7 +748,7 @@ def intersects(a, b, **kwargs): """Returns True if A and B share any portion of space. - Intersects implies that overlaps, touches and within are True. + Intersects implies that overlaps, touches, covers, or within are True. Parameters ---------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/shapely/set_operations.py new/shapely-2.0.6/shapely/set_operations.py --- old/shapely-2.0.4/shapely/set_operations.py 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/shapely/set_operations.py 2024-08-19 23:35:37.000000000 +0200 @@ -403,7 +403,9 @@ geometries = np.rollaxis(geometries, axis=axis, start=geometries.ndim) # create_collection acts on the inner axis - collections = lib.create_collection(geometries, GeometryType.GEOMETRYCOLLECTION) + collections = lib.create_collection( + geometries, np.intc(GeometryType.GEOMETRYCOLLECTION) + ) if grid_size is not None: if lib.geos_version < (3, 9, 0): @@ -501,5 +503,7 @@ np.asarray(geometries), axis=axis, start=geometries.ndim ) # create_collection acts on the inner axis - collections = lib.create_collection(geometries, GeometryType.GEOMETRYCOLLECTION) + collections = lib.create_collection( + geometries, np.intc(GeometryType.GEOMETRYCOLLECTION) + ) return lib.coverage_union(collections, **kwargs) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/shapely/tests/geometry/test_coords.py new/shapely-2.0.6/shapely/tests/geometry/test_coords.py --- old/shapely-2.0.4/shapely/tests/geometry/test_coords.py 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/shapely/tests/geometry/test_coords.py 2024-08-19 23:35:37.000000000 +0200 @@ -2,6 +2,7 @@ import pytest from shapely import LineString +from shapely.tests.common import line_string, line_string_z, point, point_z class TestCoords: @@ -84,3 +85,18 @@ assert list(x) == [0.0, 1.0] assert len(y) == 2 assert list(y) == [0.0, 1.0] + + +@pytest.mark.parametrize("geom", [point, point_z, line_string, line_string_z]) +def test_coords_array_copy(geom): + """Test CoordinateSequence.__array__ method.""" + coord_seq = geom.coords + assert np.array(coord_seq) is not np.array(coord_seq) + assert np.array(coord_seq, copy=True) is not np.array(coord_seq, copy=True) + + # Behaviour of copy=False is different between NumPy 1.x and 2.x + if int(np.version.short_version.split(".", 1)[0]) >= 2: + with pytest.raises(ValueError, match="A copy is always created"): + np.array(coord_seq, copy=False) + else: + assert np.array(coord_seq, copy=False) is np.array(coord_seq, copy=False) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/shapely/tests/geometry/test_format.py new/shapely-2.0.6/shapely/tests/geometry/test_format.py --- old/shapely-2.0.4/shapely/tests/geometry/test_format.py 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/shapely/tests/geometry/test_format.py 2024-08-19 23:35:37.000000000 +0200 @@ -47,7 +47,7 @@ ("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 + # without precisions 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), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/shapely/tests/geometry/test_point.py new/shapely-2.0.6/shapely/tests/geometry/test_point.py --- old/shapely-2.0.4/shapely/tests/geometry/test_point.py 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/shapely/tests/geometry/test_point.py 2024-08-19 23:35:37.000000000 +0200 @@ -101,7 +101,9 @@ # Test 2D points p = Point(1.0, 2.0) assert p.x == 1.0 + assert type(p.x) is float assert p.y == 2.0 + assert type(p.y) is float assert p.coords[:] == [(1.0, 2.0)] assert str(p) == p.wkt assert p.has_z is False @@ -114,6 +116,7 @@ assert str(p) == p.wkt assert p.has_z is True assert p.z == 3.0 + assert type(p.z) is float # Coordinate access p = Point((3.0, 4.0)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/shapely/tests/legacy/test_operations.py new/shapely-2.0.6/shapely/tests/legacy/test_operations.py --- old/shapely-2.0.4/shapely/tests/legacy/test_operations.py 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/shapely/tests/legacy/test_operations.py 2024-08-19 23:35:37.000000000 +0200 @@ -3,6 +3,7 @@ import pytest import shapely +from shapely import geos_version from shapely.errors import TopologicalError from shapely.geometry import GeometryCollection, LineString, MultiPoint, Point, Polygon from shapely.wkt import loads @@ -79,8 +80,11 @@ "POLYGON ((40 100, 80 100, 80 60, 40 60, 40 100), (60 60, 80 60, 80 40, 60 40, 60 60))" ) assert not invalid_polygon.is_valid - with pytest.raises((TopologicalError, shapely.GEOSException)): - invalid_polygon.relate(invalid_polygon) + if geos_version < (3, 13, 0): + with pytest.raises((TopologicalError, shapely.GEOSException)): + invalid_polygon.relate(invalid_polygon) + else: # resolved with RelateNG + assert invalid_polygon.relate(invalid_polygon) == "2FFF1FFF2" def test_hausdorff_distance(self): point = Point(1, 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/shapely/tests/legacy/test_predicates.py new/shapely-2.0.6/shapely/tests/legacy/test_predicates.py --- old/shapely-2.0.4/shapely/tests/legacy/test_predicates.py 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/shapely/tests/legacy/test_predicates.py 2024-08-19 23:35:37.000000000 +0200 @@ -5,6 +5,7 @@ import pytest import shapely +from shapely import geos_version from shapely.geometry import Point, Polygon @@ -67,8 +68,15 @@ (339, 207), ] - with pytest.raises(shapely.GEOSException): - Polygon(p1).within(Polygon(p2)) + g1 = Polygon(p1) + g2 = Polygon(p2) + assert not g1.is_valid + assert not g2.is_valid + if geos_version < (3, 13, 0): + with pytest.raises(shapely.GEOSException): + g1.within(g2) + else: # resolved with RelateNG + assert not g1.within(g2) def test_relate_pattern(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/shapely/tests/test_geometry.py new/shapely-2.0.6/shapely/tests/test_geometry.py --- old/shapely-2.0.4/shapely/tests/test_geometry.py 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/shapely/tests/test_geometry.py 2024-08-19 23:35:37.000000000 +0200 @@ -255,7 +255,7 @@ def test_set_nan_same_objects(): # You can't put identical objects in a set. - # x = float("nan"); set([x, x]) also retuns a set with 1 element + # x = float("nan"); set([x, x]) also returns a set with 1 element a = set([line_string_nan] * 10) assert len(a) == 1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/shapely/tests/test_linear.py new/shapely-2.0.6/shapely/tests/test_linear.py --- old/shapely-2.0.4/shapely/tests/test_linear.py 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/shapely/tests/test_linear.py 2024-08-19 23:35:37.000000000 +0200 @@ -178,7 +178,7 @@ def _prepare_input(geometry, prepare): - """Prepare without modifying inplace""" + """Prepare without modifying in-place""" if prepare: geometry = shapely.transform(geometry, lambda x: x) # makes a copy shapely.prepare(geometry) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/shapely/tests/test_predicates.py new/shapely-2.0.6/shapely/tests/test_predicates.py --- old/shapely-2.0.4/shapely/tests/test_predicates.py 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/shapely/tests/test_predicates.py 2024-08-19 23:35:37.000000000 +0200 @@ -298,7 +298,7 @@ def _prepare_with_copy(geometry): - """Prepare without modifying inplace""" + """Prepare without modifying in-place""" geometry = shapely.transform(geometry, lambda x: x) # makes a copy shapely.prepare(geometry) return geometry diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/shapely/tests/test_set_operations.py new/shapely-2.0.6/shapely/tests/test_set_operations.py --- old/shapely-2.0.4/shapely/tests/test_set_operations.py 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/shapely/tests/test_set_operations.py 2024-08-19 23:35:37.000000000 +0200 @@ -22,14 +22,14 @@ shapely.intersection, shapely.symmetric_difference, shapely.union, - # shapely.coverage_union is tested seperately + # shapely.coverage_union is tested separately ) REDUCE_SET_OPERATIONS = ( (shapely.intersection_all, shapely.intersection), (shapely.symmetric_difference_all, shapely.symmetric_difference), (shapely.union_all, shapely.union), - # shapely.coverage_union_all, shapely.coverage_union) is tested seperately + # shapely.coverage_union_all, shapely.coverage_union) is tested separately ) # operations that support fixed precision @@ -277,7 +277,7 @@ @pytest.mark.parametrize("n", range(1, 4)) def test_coverage_union_reduce_1dim(n): """ - This is tested seperately from other set operations as it differs in two ways: + This is tested separately from other set operations as it differs in two ways: 1. It expects only non-overlapping polygons 2. It expects GEOS 3.8.0+ """ @@ -314,7 +314,7 @@ other = Polygon([(1, 0), (0.9, 1), (2, 1), (2, 0), (1, 0)]) if shapely.geos_version >= (3, 12, 0): - # Return mostly unchaged output + # Return mostly unchanged output result = shapely.coverage_union(polygon, other) expected = shapely.multipolygons([polygon, other]) assert_geometries_equal(result, expected, normalize=True) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/shapely/tests/test_strtree.py new/shapely-2.0.6/shapely/tests/test_strtree.py --- old/shapely-2.0.4/shapely/tests/test_strtree.py 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/shapely/tests/test_strtree.py 2024-08-19 23:35:37.000000000 +0200 @@ -368,39 +368,51 @@ @pytest.mark.parametrize( - "predicate", + "predicate,expected", [ - # intersects is intentionally omitted; it does not raise an exception + pytest.param( + "intersects", + [1], + marks=pytest.mark.xfail(geos_version < (3, 13, 0), reason="GEOS < 3.13"), + ), pytest.param( "within", + [], marks=pytest.mark.xfail(geos_version < (3, 8, 0), reason="GEOS < 3.8"), ), pytest.param( "contains", + [], marks=pytest.mark.xfail(geos_version < (3, 8, 0), reason="GEOS < 3.8"), ), - "overlaps", - "crosses", - "touches", + ("overlaps", []), + ("crosses", [1]), + ("touches", []), pytest.param( "covers", + [], marks=pytest.mark.xfail(geos_version < (3, 8, 0), reason="GEOS < 3.8"), ), pytest.param( "covered_by", + [], marks=pytest.mark.xfail(geos_version < (3, 8, 0), reason="GEOS < 3.8"), ), pytest.param( "contains_properly", + [], marks=pytest.mark.xfail(geos_version < (3, 8, 0), reason="GEOS < 3.8"), ), ], ) -def test_query_predicate_errors(tree, predicate): +def test_query_predicate_errors(tree, predicate, expected): with ignore_invalid(): line_nan = shapely.linestrings([1, 1], [1, float("nan")]) - with pytest.raises(shapely.GEOSException): - tree.query(line_nan, predicate=predicate) + if geos_version < (3, 13, 0): + with pytest.raises(shapely.GEOSException): + tree.query(line_nan, predicate=predicate) + else: + assert_array_equal(tree.query(line_nan, predicate=predicate), expected) ### predicate == 'intersects' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/shapely.egg-info/PKG-INFO new/shapely-2.0.6/shapely.egg-info/PKG-INFO --- old/shapely-2.0.4/shapely.egg-info/PKG-INFO 2024-04-17 00:01:11.000000000 +0200 +++ new/shapely-2.0.6/shapely.egg-info/PKG-INFO 2024-08-19 23:35:49.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: shapely -Version: 2.0.4 +Version: 2.0.6 Summary: Manipulation and analysis of geometric objects Author: Sean Gillies Maintainer: Shapely contributors diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/src/coords.c new/shapely-2.0.6/src/coords.c --- old/shapely-2.0.4/src/coords.c 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/src/coords.c 2024-08-19 23:35:37.000000000 +0200 @@ -371,7 +371,7 @@ result = -1; goto finish; } - /* skip incase obj was None */ + /* skip in case obj was None */ if (geom == NULL) { continue; } @@ -519,7 +519,7 @@ PyObject* new_obj; GEOSGeometry *geom, *new_geom; - /* SetCoords acts implace: if the array is zero-sized, just return the + /* SetCoords acts in-place: if the array is zero-sized, just return the same object */ if (PyArray_SIZE(geoms) == 0) { Py_INCREF((PyObject*)geoms); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/src/geos.c new/shapely-2.0.6/src/geos.c --- old/shapely-2.0.4/src/geos.c 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/src/geos.c 2024-08-19 23:35:37.000000000 +0200 @@ -306,7 +306,7 @@ /* Checks whether the geometry is a 3D empty geometry and, if so, create the WKT string * - * GEOS 3.9.* is able to distiguish 2D and 3D simple geometries (non-collections). But the + * GEOS 3.9.* is able to distinguish 2D and 3D simple geometries (non-collections). But the * but the WKT serialization never writes a 3D empty geometry. This function fixes that. * It only makes sense to use this for GEOS versions >= 3.9. * diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/src/strtree.c new/shapely-2.0.6/src/strtree.c --- old/shapely-2.0.4/src/strtree.c 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/src/strtree.c 2024-08-19 23:35:37.000000000 +0200 @@ -128,7 +128,7 @@ /* get the geometry */ ptr = PyArray_GETPTR1((PyArrayObject*)arr, i); obj = *(GeometryObject**)ptr; - /* fail and cleanup incase obj was no geometry */ + /* fail and cleanup in case obj was no geometry */ if (!get_geom(obj, &geom)) { errstate = PGERR_NOT_A_GEOMETRY; GEOSSTRtree_destroy_r(ctx, tree); @@ -977,7 +977,7 @@ index_vec_t src_indexes; // Addresses in tree geometries (_geoms) that overlap with expanded bboxes around - // intput geometries + // input geometries tree_geom_vec_t query_geoms; // Addresses in tree geometries (_geoms) that meet DistanceWithin predicate diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shapely-2.0.4/src/ufuncs.c new/shapely-2.0.6/src/ufuncs.c --- old/shapely-2.0.4/src/ufuncs.c 2024-04-17 00:00:57.000000000 +0200 +++ new/shapely-2.0.6/src/ufuncs.c 2024-08-19 23:35:37.000000000 +0200 @@ -522,7 +522,7 @@ return ret; } static void* get_exterior_ring_data[1] = {GetExteriorRing}; -/* the normalize funcion acts inplace */ +/* the normalize function acts in-place */ static void* GEOSNormalize_r_with_clone(void* context, void* geom) { int ret; void* new_geom = GEOSGeom_clone_r(context, geom); @@ -841,7 +841,7 @@ return ret; } static void* get_geometry_data[1] = {GetGeometryN}; -/* the set srid funcion acts inplace */ +/* the set srid function acts in-place */ static void* GEOSSetSRID_r_with_clone(void* context, void* geom, int srid) { void* ret = GEOSGeom_clone_r(context, geom); if (ret == NULL) { @@ -1310,7 +1310,7 @@ errstate = PGERR_GEOS_EXCEPTION; goto finish; } - /* incase the outcome is 0.0, check the inputs for emptyness */ + /* in case the outcome is 0.0, check the inputs for emptyness */ if (*op1 == 0.0) { if (GEOSisEmpty_r(ctx, in1) || GEOSisEmpty_r(ctx, in2)) { *(double*)op1 = NPY_NAN;