Skip to content

Commit 55bf523

Browse files
authored
Merge branch 'master' into issue1106
2 parents 39e7217 + 1991a72 commit 55bf523

15 files changed

Lines changed: 82 additions & 44 deletions

CHANGES.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ New features:
1212

1313
- The STRtree nearest*() methods now take an optional argument that
1414
specifies exclusion of the input geometry from results (#1115).
15+
- A GeometryTypeError has been added to shapely.errors and is consistently
16+
raised instead of TypeError or ValueError as in version 1.7. For backwards
17+
compatibility, the new exception will derive from TypeError and Value error
18+
until version 2.0 (#1099).
1519
- The STRtree class constructor now takes an optional second argument, a
1620
sequence of objects to be stored in the tree. If not provided, the sequence
1721
indices of the geometries will be stored, as before (#1112).

shapely/affinity.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Affine transforms, both in general and specific, named transforms."""
22

33
from math import sin, cos, tan, pi
4+
from shapely.errors import GeometryTypeError
45

56
__all__ = ['affine_transform', 'rotate', 'scale', 'skew', 'translate']
67

@@ -92,7 +93,7 @@ def affine_pts(pts):
9293
return type(geom)([affine_transform(part, matrix)
9394
for part in geom.geoms])
9495
else:
95-
raise ValueError('Type %r not recognized' % geom.type)
96+
raise GeometryTypeError('Type %r not recognized' % geom.type)
9697

9798

9899
def interpret_origin(geom, origin, ndim):

shapely/errors.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Shapely errors."""
2+
import warnings
23

34

45
class ShapelyError(Exception):
@@ -42,3 +43,22 @@ class ShapelyDeprecationWarning(FutureWarning):
4243

4344
class EmptyPartError(ShapelyError):
4445
"""An error signifying an empty part was encountered when creating a multi-part."""
46+
47+
48+
class GeometryTypeError(ShapelyError, TypeError, ValueError):
49+
"""
50+
An error raised when the type of the geometry in question is
51+
unrecognized or inappropriate.
52+
"""
53+
def __init__(self, msg):
54+
warnings.warn("GeometryTypeError will derive from ShapelyError and not TypeError or ValueError in Shapely 2.0.", ShapelyDeprecationWarning, stacklevel=2)
55+
super().__init__(msg)
56+
57+
58+
class InvalidGeometryError(ShapelyError, TypeError, ValueError):
59+
"""
60+
An error raised when an operation is attempted on a null geometry
61+
"""
62+
def __init__(self, msg):
63+
warnings.warn("InvalidGeometryError will derive from ShapelyError and not TypeError or ValueError in Shapely 2.0.", ShapelyDeprecationWarning, stacklevel=2)
64+
super().__init__(msg)

shapely/geometry/base.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
from shapely.affinity import affine_transform
1919
from shapely.coords import CoordinateSequence
20-
from shapely.errors import WKBReadingError, WKTReadingError
20+
from shapely.errors import GeometryTypeError, WKBReadingError, WKTReadingError
2121
from shapely.errors import ShapelyDeprecationWarning
2222
from shapely.geos import WKBWriter, WKTWriter
2323
from shapely.geos import lgeos
@@ -57,7 +57,7 @@ def dump_coords(geom):
5757
# Recursive call
5858
return [dump_coords(part) for part in geom.geoms]
5959
else:
60-
raise ValueError('Unhandled geometry type: ' + repr(geom.type))
60+
raise GeometryTypeError('Unhandled geometry type: ' + repr(geom.type))
6161

6262

6363
def geometry_type_name(g):
@@ -653,7 +653,7 @@ def normalize(self):
653653
"""
654654
# self.impl['normalize'](self)
655655
if self._geom is None:
656-
raise ValueError("Null geometry supports no operations")
656+
raise InvalidGeometryError("Null geometry supports no operations")
657657
geom_cloned = lgeos.GEOSGeom_clone(self._geom)
658658
lgeos.GEOSNormalize(geom_cloned)
659659
return geom_factory(geom_cloned)
@@ -1007,7 +1007,7 @@ def __getitem__(self, key):
10071007
return self._get_geom_item(i)
10081008
elif isinstance(key, slice):
10091009
if type(self) == HeterogeneousGeometrySequence:
1010-
raise TypeError(
1010+
raise GeometryTypeError(
10111011
"Heterogenous geometry collections are not sliceable")
10121012
res = []
10131013
start, stop, stride = key.indices(m)

shapely/geometry/geo.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"""
44
import warnings
55

6+
from shapely.errors import GeometryTypeError
67
from shapely.errors import ShapelyDeprecationWarning
78

89
from .point import Point, asPoint
@@ -52,7 +53,7 @@ def _empty_shape_for_no_coordinates(geom_type):
5253
elif geom_type == 'multipolygon':
5354
return MultiPolygon()
5455
else:
55-
raise ValueError("Unknown geometry type: %s" % geom_type)
56+
raise GeometryTypeError("Unknown geometry type: %s" % geom_type)
5657

5758

5859
def box(minx, miny, maxx, maxy, ccw=True):
@@ -117,7 +118,7 @@ def shape(context):
117118
geoms = [shape(g) for g in ob.get("geometries", [])]
118119
return GeometryCollection(geoms)
119120
else:
120-
raise ValueError("Unknown geometry type: %s" % geom_type)
121+
raise GeometryTypeError("Unknown geometry type: %s" % geom_type)
121122

122123

123124
def asShape(context):
@@ -196,7 +197,7 @@ def asShape(context):
196197
ShapelyDeprecationWarning, stacklevel=2)
197198
return GeometryCollection(geoms)
198199
else:
199-
raise ValueError("Unknown geometry type: %s" % geom_type)
200+
raise GeometryTypeError("Unknown geometry type: %s" % geom_type)
200201

201202

202203
def mapping(ob):

shapely/geos.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from functools import partial
1616

1717
from .ctypes_declarations import prototype, EXCEPTION_HANDLER_FUNCTYPE
18-
from .errors import WKBReadingError, WKTReadingError, TopologicalError, PredicateError
18+
from .errors import InvalidGeometryError, WKBReadingError, WKTReadingError, TopologicalError, PredicateError
1919

2020

2121
# Add message handler to this module's logger
@@ -395,7 +395,7 @@ def __del__(self):
395395
def write(self, geom):
396396
"""Returns WKT string for geometry"""
397397
if geom is None or geom._geom is None:
398-
raise ValueError("Null geometry supports no operations")
398+
raise InvalidGeometryError("Null geometry supports no operations")
399399
result = self._lgeos.GEOSWKTWriter_write(self._writer, geom._geom)
400400
text = string_at(result)
401401
lgeos.GEOSFree(result)
@@ -515,7 +515,7 @@ def __del__(self):
515515
def write(self, geom):
516516
"""Returns WKB byte string for geometry"""
517517
if geom is None or geom._geom is None:
518-
raise ValueError("Null geometry supports no operations")
518+
raise InvalidGeometryError("Null geometry supports no operations")
519519
size = c_size_t()
520520
result = self._lgeos.GEOSWKBWriter_write(
521521
self._writer, geom._geom, pointer(size))
@@ -526,7 +526,7 @@ def write(self, geom):
526526
def write_hex(self, geom):
527527
"""Returns WKB hex string for geometry"""
528528
if geom is None or geom._geom is None:
529-
raise ValueError("Null geometry supports no operations")
529+
raise InvalidGeometryError("Null geometry supports no operations")
530530
size = c_size_t()
531531
result = self._lgeos.GEOSWKBWriter_writeHEX(
532532
self._writer, geom._geom, pointer(size))

shapely/iterops.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"""
44
import warnings
55

6-
from shapely.errors import ShapelyDeprecationWarning
6+
from shapely.errors import InvalidGeometryError, ShapelyDeprecationWarning
77
from shapely.topology import Delegating
88

99

@@ -18,15 +18,15 @@ def __call__(self, context, iterator, value=True):
1818
"Shapely 2.0".format(self._name),
1919
ShapelyDeprecationWarning, stacklevel=2)
2020
if context._geom is None:
21-
raise ValueError("Null geometry supports no operations")
21+
raise InvalidGeometryError("Null geometry supports no operations")
2222
for item in iterator:
2323
try:
2424
this_geom, ob = item
2525
except TypeError:
2626
this_geom = item
2727
ob = this_geom
2828
if not this_geom._geom:
29-
raise ValueError("Null geometry supports no operations")
29+
raise InvalidGeometryError("Null geometry supports no operations")
3030
try:
3131
retval = self.fn(context._geom, this_geom._geom)
3232
except Exception as err:

shapely/linref.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
"""Linear referencing
22
"""
33

4+
from shapely.errors import GeometryTypeError
45
from shapely.topology import Delegating
56

67

78
class LinearRefBase(Delegating):
89
def _validate_line(self, ob):
910
super()._validate(ob)
1011
if not ob.geom_type in ['LinearRing', 'LineString', 'MultiLineString']:
11-
raise TypeError("Only linear types support this operation")
12+
raise GeometryTypeError("Only linear types support this operation")
1213

1314
class ProjectOp(LinearRefBase):
1415
def __call__(self, this, other):

shapely/ops.py

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from ctypes import byref, c_void_p, c_double
55
from warnings import warn
66

7-
from shapely.errors import ShapelyDeprecationWarning
7+
from shapely.errors import GeometryTypeError, ShapelyDeprecationWarning
88
from shapely.prepared import prep
99
from shapely.geos import lgeos
1010
from shapely.geometry.base import geom_factory, BaseGeometry, BaseMultipartGeometry
@@ -322,7 +322,7 @@ def id_func(x, y, z=None):
322322
elif geom.type.startswith('Multi') or geom.type == 'GeometryCollection':
323323
return type(geom)([transform(func, part) for part in geom.geoms])
324324
else:
325-
raise ValueError('Type %r not recognized' % geom.type)
325+
raise GeometryTypeError('Type %r not recognized' % geom.type)
326326

327327

328328
def nearest_points(g1, g2):
@@ -391,9 +391,9 @@ def shared_paths(g1, g2):
391391
The second geometry
392392
"""
393393
if not isinstance(g1, LineString):
394-
raise TypeError("First geometry must be a LineString")
394+
raise GeometryTypeError("First geometry must be a LineString")
395395
if not isinstance(g2, LineString):
396-
raise TypeError("Second geometry must be a LineString")
396+
raise GeometryTypeError("Second geometry must be a LineString")
397397
return(geom_factory(lgeos.methods['shared_paths'](g1._geom, g2._geom)))
398398

399399

@@ -402,9 +402,10 @@ class SplitOp:
402402
@staticmethod
403403
def _split_polygon_with_line(poly, splitter):
404404
"""Split a Polygon with a LineString"""
405-
406-
assert(isinstance(poly, Polygon))
407-
assert(isinstance(splitter, LineString))
405+
if not isinstance(poly, Polygon):
406+
raise GeometryTypeError("First argument must be a Polygon")
407+
if not isinstance(splitter, LineString):
408+
raise GeometryTypeError("Second argument must be a LineString")
408409

409410
union = poly.boundary.union(splitter)
410411

@@ -426,8 +427,10 @@ def _split_line_with_line(line, splitter):
426427
if splitter.type in ('Polygon', 'MultiPolygon'):
427428
splitter = splitter.boundary
428429

429-
assert(isinstance(line, LineString))
430-
assert(isinstance(splitter, LineString) or isinstance(splitter, MultiLineString))
430+
if not isinstance(line, LineString):
431+
raise GeometryTypeError("First argument must be a LineString")
432+
if not isinstance(splitter, LineString) and not isinstance(splitter, MultiLineString):
433+
raise GeometryTypeError("Second argument must be either a LineString or a MultiLineString")
431434

432435
# | s\l | Interior | Boundary | Exterior |
433436
# |----------|----------|----------|----------|
@@ -448,9 +451,10 @@ def _split_line_with_line(line, splitter):
448451
@staticmethod
449452
def _split_line_with_point(line, splitter):
450453
"""Split a LineString with a Point"""
451-
452-
assert(isinstance(line, LineString))
453-
assert(isinstance(splitter, Point))
454+
if not isinstance(line, LineString):
455+
raise GeometryTypeError("First argument must be a LineString")
456+
if not isinstance(splitter, Point):
457+
raise GeometryTypeError("Second argument must be a Point")
454458

455459
# check if point is in the interior of the line
456460
if not line.relate_pattern(splitter, '0********'):
@@ -494,8 +498,10 @@ def _split_line_with_point(line, splitter):
494498
def _split_line_with_multipoint(line, splitter):
495499
"""Split a LineString with a MultiPoint"""
496500

497-
assert(isinstance(line, LineString))
498-
assert(isinstance(splitter, MultiPoint))
501+
if not isinstance(line, LineString):
502+
raise GeometryTypeError("First argument must be a LineString")
503+
if not isinstance(splitter, MultiPoint):
504+
raise GeometryTypeError("Second argument must be a MultiPoint")
499505

500506
chunks = [line]
501507
for pt in splitter.geoms:
@@ -549,16 +555,16 @@ def split(geom, splitter):
549555
elif splitter.type in ('MultiPoint'):
550556
split_func = SplitOp._split_line_with_multipoint
551557
else:
552-
raise ValueError("Splitting a LineString with a %s is not supported" % splitter.type)
558+
raise GeometryTypeError("Splitting a LineString with a %s is not supported" % splitter.type)
553559

554560
elif geom.type == 'Polygon':
555561
if splitter.type == 'LineString':
556562
split_func = SplitOp._split_polygon_with_line
557563
else:
558-
raise ValueError("Splitting a Polygon with a %s is not supported" % splitter.type)
564+
raise GeometryTypeError("Splitting a Polygon with a %s is not supported" % splitter.type)
559565

560566
else:
561-
raise ValueError("Splitting %s geometry is not supported" % geom.type)
567+
raise GeometryTypeError("Splitting %s geometry is not supported" % geom.type)
562568

563569
return GeometryCollection(split_func(geom, splitter))
564570

@@ -625,7 +631,7 @@ def substring(geom, start_dist, end_dist, normalized=False):
625631
"""
626632

627633
if not isinstance(geom, LineString):
628-
raise TypeError("Can only calculate a substring of LineString geometries. A %s was provided." % geom.type)
634+
raise GeometryTypeError("Can only calculate a substring of LineString geometries. A %s was provided." % geom.type)
629635

630636
# Filter out cases in which to return a point
631637
if start_dist == end_dist:

shapely/speedups/_speedups.pyx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import logging
1313
from shapely.geos import lgeos
1414
from shapely.geometry import Point, LineString, LinearRing
1515
from shapely.geometry.base import geom_factory
16-
from shapely.errors import TopologicalError
16+
from shapely.errors import GeometryTypeError, TopologicalError
1717

1818

1919
include "../_geos.pxi"
@@ -573,4 +573,4 @@ cpdef affine_transform(geom, matrix):
573573
elif geom.type.startswith('Multi') or geom.type == 'GeometryCollection':
574574
return type(geom)([affine_transform(part, matrix) for part in geom.geoms])
575575
else:
576-
raise ValueError('Type %r not recognized' % geom.type)
576+
raise GeometryTypeError('Type %r not recognized' % geom.type)

0 commit comments

Comments
 (0)