diff --git a/django/contrib/gis/geos/__init__.py b/django/contrib/gis/geos/__init__.py index e8d70d07ad..4ebf9b2f12 100644 --- a/django/contrib/gis/geos/__init__.py +++ b/django/contrib/gis/geos/__init__.py @@ -5,7 +5,7 @@ for more details: https://docs.djangoproject.com/en/dev/ref/contrib/gis/geos/ from .collections import ( # NOQA GeometryCollection, MultiLineString, MultiPoint, MultiPolygon, ) -from .error import GEOSException, GEOSIndexError # NOQA +from .error import GEOSException # NOQA from .factory import fromfile, fromstr # NOQA from .geometry import GEOSGeometry, hex_regex, wkt_regex # NOQA from .io import WKBReader, WKBWriter, WKTReader, WKTWriter # NOQA diff --git a/django/contrib/gis/geos/coordseq.py b/django/contrib/gis/geos/coordseq.py index ae82908f5c..8722874099 100644 --- a/django/contrib/gis/geos/coordseq.py +++ b/django/contrib/gis/geos/coordseq.py @@ -7,7 +7,7 @@ from ctypes import byref, c_double, c_uint from django.contrib.gis.geos import prototypes as capi from django.contrib.gis.geos.base import GEOSBase -from django.contrib.gis.geos.error import GEOSException, GEOSIndexError +from django.contrib.gis.geos.error import GEOSException from django.contrib.gis.geos.libgeos import CS_PTR from django.contrib.gis.shortcuts import numpy from django.utils.six.moves import range @@ -74,7 +74,7 @@ class GEOSCoordSeq(GEOSBase): "Checks the given index." sz = self.size if (sz < 1) or (index < 0) or (index >= sz): - raise GEOSIndexError('invalid GEOS Geometry index: %s' % str(index)) + raise IndexError('invalid GEOS Geometry index: %s' % str(index)) def _checkdim(self, dim): "Checks the given dimension." diff --git a/django/contrib/gis/geos/error.py b/django/contrib/gis/geos/error.py index e19bf9a47a..af2ac2fd42 100644 --- a/django/contrib/gis/geos/error.py +++ b/django/contrib/gis/geos/error.py @@ -1,22 +1,3 @@ -""" - This module houses the GEOS exceptions, specifically, GEOSException and - GEOSGeometryIndexError. -""" - - class GEOSException(Exception): "The base GEOS exception, indicates a GEOS-related error." pass - - -class GEOSIndexError(GEOSException, KeyError): - """ - This exception is raised when an invalid index is encountered, and has - the 'silent_variable_feature' attribute set to true. This ensures that - django's templates proceed to use the next lookup type gracefully when - an Exception is raised. Fixes ticket #4740. - """ - # "If, during the method lookup, a method raises an exception, the exception - # will be propagated, unless the exception has an attribute - # `silent_variable_failure` whose value is True." -- Django template docs. - silent_variable_failure = True diff --git a/django/contrib/gis/geos/geometry.py b/django/contrib/gis/geos/geometry.py index 61bf590ac5..fbc7679830 100644 --- a/django/contrib/gis/geos/geometry.py +++ b/django/contrib/gis/geos/geometry.py @@ -12,7 +12,7 @@ from django.contrib.gis.geometry.regex import hex_regex, json_regex, wkt_regex from django.contrib.gis.geos import prototypes as capi from django.contrib.gis.geos.base import GEOSBase from django.contrib.gis.geos.coordseq import GEOSCoordSeq -from django.contrib.gis.geos.error import GEOSException, GEOSIndexError +from django.contrib.gis.geos.error import GEOSException from django.contrib.gis.geos.libgeos import GEOM_PTR from django.contrib.gis.geos.mutable_list import ListMixin from django.contrib.gis.geos.prepared import PreparedGeometry @@ -26,9 +26,6 @@ from django.utils.encoding import force_bytes, force_text class GEOSGeometry(GEOSBase, ListMixin): "A class that, generally, encapsulates a GEOS geometry." - # Raise GEOSIndexError instead of plain IndexError - # (see ticket #4740 and GEOSIndexError docstring) - _IndexError = GEOSIndexError _GEOS_CLASSES = None ptr_type = GEOM_PTR diff --git a/django/contrib/gis/geos/mutable_list.py b/django/contrib/gis/geos/mutable_list.py index cd639399f4..3fe9a4fbb6 100644 --- a/django/contrib/gis/geos/mutable_list.py +++ b/django/contrib/gis/geos/mutable_list.py @@ -4,7 +4,7 @@ This module contains a base type which provides list-style mutations without specific data storage methods. -See also http://www.aryehleib.com/MutableLists.html +See also http://static.aryehleib.com/oldsite/MutableLists.html Author: Aryeh Leib Taurog. """ @@ -55,14 +55,10 @@ class ListMixin(object): type or tuple _allowed: A type or tuple of allowed item types [Optional] - - class _IndexError: - The type of exception to be raise on invalid index [Optional] """ _minlength = 0 _maxlength = None - _IndexError = IndexError # ### Python initialization and special list interface methods ### @@ -113,11 +109,6 @@ class ListMixin(object): self._check_allowed((val,)) self._set_single(index, val) - def __iter__(self): - "Iterate over the items in the list" - for i in range(len(self)): - yield self[i] - # ### Special methods for arithmetic operations ### def __add__(self, other): 'add another list-like object' @@ -155,7 +146,7 @@ class ListMixin(object): for i in range(olen): try: c = self[i] == other[i] - except self._IndexError: + except IndexError: # self must be shorter return False if not c: @@ -167,7 +158,7 @@ class ListMixin(object): for i in range(olen): try: c = self[i] < other[i] - except self._IndexError: + except IndexError: # self must be shorter return True if c: @@ -254,7 +245,7 @@ class ListMixin(object): return index if correct and -length <= index < 0: return index + length - raise self._IndexError('invalid index: %s' % str(index)) + raise IndexError('invalid index: %s' % str(index)) def _check_allowed(self, items): if hasattr(self, '_allowed'): diff --git a/tests/gis_tests/geos_tests/test_geos.py b/tests/gis_tests/geos_tests/test_geos.py index 4fda24cc24..90d34bbad7 100644 --- a/tests/gis_tests/geos_tests/test_geos.py +++ b/tests/gis_tests/geos_tests/test_geos.py @@ -11,12 +11,14 @@ from unittest import skipUnless from django.contrib.gis import gdal from django.contrib.gis.gdal import HAS_GDAL from django.contrib.gis.geos import ( - HAS_GEOS, GeometryCollection, GEOSException, GEOSGeometry, GEOSIndexError, - LinearRing, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, - Polygon, fromfile, fromstr, geos_version_info, + HAS_GEOS, GeometryCollection, GEOSException, GEOSGeometry, LinearRing, + LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, + fromfile, fromstr, geos_version_info, ) from django.contrib.gis.geos.base import GEOSBase from django.contrib.gis.shortcuts import numpy +from django.template import Context +from django.template.engine import Engine from django.test import mock from django.utils import six from django.utils.encoding import force_bytes @@ -283,7 +285,7 @@ class GEOSTest(unittest.TestCase, TestDataMixin): self.assertAlmostEqual(mp.centroid[0], mpnt.centroid.tuple[0], 9) self.assertAlmostEqual(mp.centroid[1], mpnt.centroid.tuple[1], 9) - self.assertRaises(GEOSIndexError, mpnt.__getitem__, len(mpnt)) + self.assertRaises(IndexError, mpnt.__getitem__, len(mpnt)) self.assertEqual(mp.centroid, mpnt.centroid.tuple) self.assertEqual(mp.coords, tuple(m.tuple for m in mpnt)) for p in mpnt: @@ -308,7 +310,7 @@ class GEOSTest(unittest.TestCase, TestDataMixin): self.assertEqual(ls, fromstr(l.wkt)) self.assertEqual(False, ls == prev) # Use assertEqual to test __eq__ - self.assertRaises(GEOSIndexError, ls.__getitem__, len(ls)) + self.assertRaises(IndexError, ls.__getitem__, len(ls)) prev = ls # Creating a LineString from a tuple, list, and numpy array @@ -340,7 +342,7 @@ class GEOSTest(unittest.TestCase, TestDataMixin): self.assertEqual(ls.geom_typeid, 1) self.assertEqual(ls.empty, False) - self.assertRaises(GEOSIndexError, ml.__getitem__, len(ml)) + self.assertRaises(IndexError, ml.__getitem__, len(ml)) self.assertEqual(ml.wkt, MultiLineString(*tuple(s.clone() for s in ml)).wkt) self.assertEqual(ml, MultiLineString(*tuple(LineString(s.tuple) for s in ml))) @@ -409,9 +411,9 @@ class GEOSTest(unittest.TestCase, TestDataMixin): self.assertEqual(p.ext_ring_cs, poly[0].tuple) # Testing __getitem__ # Testing __getitem__ and __setitem__ on invalid indices - self.assertRaises(GEOSIndexError, poly.__getitem__, len(poly)) - self.assertRaises(GEOSIndexError, poly.__setitem__, len(poly), False) - self.assertRaises(GEOSIndexError, poly.__getitem__, -1 * len(poly) - 1) + self.assertRaises(IndexError, poly.__getitem__, len(poly)) + self.assertRaises(IndexError, poly.__setitem__, len(poly), False) + self.assertRaises(IndexError, poly.__getitem__, -1 * len(poly) - 1) # Testing __iter__ for r in poly: @@ -434,6 +436,14 @@ class GEOSTest(unittest.TestCase, TestDataMixin): self.assertEqual(poly.wkt, Polygon(*tuple(r for r in poly)).wkt) self.assertEqual(poly.wkt, Polygon(*tuple(LinearRing(r.tuple) for r in poly)).wkt) + def test_polygons_templates(self): + # Accessing Polygon attributes in templates should work. + engine = Engine() + template = engine.from_string('{{ polygons.0.wkt }}') + polygons = [fromstr(p.wkt) for p in self.geometries.multipolygons[:2]] + content = template.render(Context({'polygons': polygons})) + self.assertIn('MULTIPOLYGON (((100', content) + def test_polygon_comparison(self): p1 = Polygon(((0, 0), (0, 1), (1, 1), (1, 0), (0, 0))) p2 = Polygon(((0, 0), (0, 1), (1, 0), (0, 0))) @@ -458,7 +468,7 @@ class GEOSTest(unittest.TestCase, TestDataMixin): self.assertEqual(mp.num_geom, mpoly.num_geom) self.assertEqual(mp.n_p, mpoly.num_coords) self.assertEqual(mp.num_geom, len(mpoly)) - self.assertRaises(GEOSIndexError, mpoly.__getitem__, len(mpoly)) + self.assertRaises(IndexError, mpoly.__getitem__, len(mpoly)) for p in mpoly: self.assertEqual(p.geom_type, 'Polygon') self.assertEqual(p.geom_typeid, 3) @@ -806,15 +816,15 @@ class GEOSTest(unittest.TestCase, TestDataMixin): # Testing __getitem__ (doesn't work on Point or Polygon) if isinstance(g, Point): - self.assertRaises(GEOSIndexError, g.get_x) + self.assertRaises(IndexError, g.get_x) elif isinstance(g, Polygon): lr = g.shell self.assertEqual('LINEARRING EMPTY', lr.wkt) self.assertEqual(0, len(lr)) self.assertEqual(True, lr.empty) - self.assertRaises(GEOSIndexError, lr.__getitem__, 0) + self.assertRaises(IndexError, lr.__getitem__, 0) else: - self.assertRaises(GEOSIndexError, g.__getitem__, 0) + self.assertRaises(IndexError, g.__getitem__, 0) def test_collections_of_collections(self): "Testing GeometryCollection handling of other collections." diff --git a/tests/gis_tests/geos_tests/test_geos_mutation.py b/tests/gis_tests/geos_tests/test_geos_mutation.py index 51b19db9e4..81a6e975fe 100644 --- a/tests/gis_tests/geos_tests/test_geos_mutation.py +++ b/tests/gis_tests/geos_tests/test_geos_mutation.py @@ -8,7 +8,6 @@ from unittest import skipUnless from django.contrib.gis.geos import ( HAS_GEOS, LinearRing, LineString, MultiPoint, Point, Polygon, fromstr, ) -from django.contrib.gis.geos.error import GEOSIndexError def api_get_distance(x): @@ -79,12 +78,12 @@ class GEOSMutationTest(unittest.TestCase): """ def test00_GEOSIndexException(self): - 'Testing Geometry GEOSIndexError' + 'Testing Geometry IndexError' p = Point(1, 2) for i in range(-2, 2): p._checkindex(i) - self.assertRaises(GEOSIndexError, p._checkindex, 2) - self.assertRaises(GEOSIndexError, p._checkindex, -3) + self.assertRaises(IndexError, p._checkindex, 2) + self.assertRaises(IndexError, p._checkindex, -3) def test01_PointMutations(self): 'Testing Point mutations' diff --git a/tests/gis_tests/geos_tests/test_mutable_list.py b/tests/gis_tests/geos_tests/test_mutable_list.py index cde78045f1..67338ee865 100644 --- a/tests/gis_tests/geos_tests/test_mutable_list.py +++ b/tests/gis_tests/geos_tests/test_mutable_list.py @@ -337,9 +337,6 @@ class ListMixinTest(unittest.TestCase): for i in (-self.limit - 1, self.limit): self.assertRaises(IndexError, ul._checkindex, i) - ul._IndexError = TypeError - self.assertRaises(TypeError, ul._checkindex, -self.limit - 1) - def test_11_sorting(self): 'Sorting' pl, ul = self.lists_of_len()