Skip to content

Commit

Permalink
Improved messages in IndexErrors raised by GDAL objects.
Browse files Browse the repository at this point in the history
  • Loading branch information
ngnpope authored and timgraham committed Sep 4, 2017
1 parent 0d9e116 commit 66657eb
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 20 deletions.
4 changes: 2 additions & 2 deletions django/contrib/gis/gdal/datasource.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,12 @@ def __getitem__(self, index):
if isinstance(index, str):
layer = capi.get_layer_by_name(self.ptr, force_bytes(index))
if not layer:
raise IndexError('invalid OGR Layer name given: "%s"' % index)
raise IndexError('Invalid OGR layer name given: %s.' % index)
elif isinstance(index, int):
if 0 <= index < self.layer_count:
layer = capi.get_layer(self._ptr, index)
else:
raise IndexError('index out of range')
raise IndexError('Index out of range when accessing layers in a datasource: %s.' % index)
else:
raise TypeError('Invalid index type: %s' % type(index))
return Layer(layer, self)
Expand Down
4 changes: 2 additions & 2 deletions django/contrib/gis/gdal/feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def __getitem__(self, index):
elif 0 <= index < self.num_fields:
i = index
else:
raise IndexError('index out of range')
raise IndexError('Index out of range when accessing field in a feature: %s.' % index)
return Field(self, i)

def __len__(self):
Expand Down Expand Up @@ -111,5 +111,5 @@ def index(self, field_name):
"Return the index of the given field name."
i = capi.get_field_index(self.ptr, force_bytes(field_name))
if i < 0:
raise IndexError('invalid OFT field name given: "%s"' % field_name)
raise IndexError('Invalid OFT field name given: %s.' % field_name)
return i
6 changes: 3 additions & 3 deletions django/contrib/gis/gdal/geometries.py
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ def __getitem__(self, index):
elif dim == 3:
return (x.value, y.value, z.value)
else:
raise IndexError('index out of range: %s' % index)
raise IndexError('Index out of range when accessing points of a line string: %s.' % index)

def __len__(self):
"Return the number of points in the LineString."
Expand Down Expand Up @@ -616,7 +616,7 @@ def __getitem__(self, index):
if 0 <= index < self.geom_count:
return OGRGeometry(capi.clone_geom(capi.get_geom_ref(self.ptr, index)), self.srs)
else:
raise IndexError('index out of range: %s' % index)
raise IndexError('Index out of range when accessing rings of a polygon: %s.' % index)

# Polygon Properties
@property
Expand Down Expand Up @@ -655,7 +655,7 @@ def __getitem__(self, index):
if 0 <= index < self.geom_count:
return OGRGeometry(capi.clone_geom(capi.get_geom_ref(self.ptr, index)), self.srs)
else:
raise IndexError('index out of range: %s' % index)
raise IndexError('Index out of range when accessing geometry in a collection: %s.' % index)

def __len__(self):
"Return the number of geometries in this Geometry Collection."
Expand Down
24 changes: 16 additions & 8 deletions tests/gis_tests/gdal_tests/test_ds.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import os
import re
import unittest

from django.contrib.gis.gdal import (
GDAL_VERSION, DataSource, Envelope, GDALException, OGRGeometry,
)
from django.contrib.gis.gdal.field import OFTInteger, OFTReal, OFTString
from django.test import SimpleTestCase

from ..test_data import TEST_DATA, TestDS, get_ds_file

Expand Down Expand Up @@ -64,7 +64,7 @@
bad_ds = (TestDS('foo'),)


class DataSourceTest(unittest.TestCase):
class DataSourceTest(SimpleTestCase):

def test01_valid_shp(self):
"Testing valid SHP Data Source files."
Expand All @@ -83,11 +83,12 @@ def test01_valid_shp(self):
self.assertEqual(source.driver, str(ds.driver))

# Making sure indexing works
with self.assertRaises(IndexError):
ds[len(ds)]
msg = 'Index out of range when accessing layers in a datasource: %s.'
with self.assertRaisesMessage(IndexError, msg % len(ds)):
ds.__getitem__(len(ds))

with self.assertRaises(IndexError):
ds['invalid']
with self.assertRaisesMessage(IndexError, 'Invalid OGR layer name given: invalid.'):
ds.__getitem__('invalid')

def test02_invalid_shp(self):
"Testing invalid SHP files for the Data Source."
Expand Down Expand Up @@ -122,9 +123,9 @@ def test03a_layers(self):
self.assertIn(f, source.fields)

# Negative FIDs are not allowed.
with self.assertRaises(IndexError):
with self.assertRaisesMessage(IndexError, 'Negative indices are not allowed on OGR Layers.'):
layer.__getitem__(-1)
with self.assertRaises(IndexError):
with self.assertRaisesMessage(IndexError, 'Invalid feature id: 50000.'):
layer.__getitem__(50000)

if hasattr(source, 'field_values'):
Expand All @@ -141,6 +142,13 @@ def test03a_layers(self):
for fld_name, fld_value in source.field_values.items():
self.assertEqual(fld_value[i], feat.get(fld_name))

msg = 'Index out of range when accessing field in a feature: %s.'
with self.assertRaisesMessage(IndexError, msg % len(feat)):
feat.__getitem__(len(feat))

with self.assertRaisesMessage(IndexError, 'Invalid OFT field name given: invalid.'):
feat.__getitem__('invalid')

def test03b_layer_slice(self):
"Test indexing and slicing on Layers."
# Using the first data-source because the same slice
Expand Down
16 changes: 11 additions & 5 deletions tests/gis_tests/gdal_tests/test_geom.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import json
import pickle
import unittest
from binascii import b2a_hex

from django.contrib.gis.gdal import (
CoordTransform, GDALException, OGRGeometry, OGRGeomType, SpatialReference,
)
from django.template import Context
from django.template.engine import Engine
from django.test import SimpleTestCase

from ..test_data import TestDataMixin


class OGRGeomTest(unittest.TestCase, TestDataMixin):
class OGRGeomTest(SimpleTestCase, TestDataMixin):
"This tests the OGR Geometry."

def test_geomtype(self):
Expand Down Expand Up @@ -158,7 +158,8 @@ def test_linestring(self):
self.assertEqual(ls.coords, linestr.tuple)
self.assertEqual(linestr, OGRGeometry(ls.wkt))
self.assertNotEqual(linestr, prev)
with self.assertRaises(IndexError):
msg = 'Index out of range when accessing points of a line string: %s.'
with self.assertRaisesMessage(IndexError, msg % len(linestr)):
linestr.__getitem__(len(linestr))
prev = linestr

Expand All @@ -183,7 +184,8 @@ def test_multilinestring(self):
for ls in mlinestr:
self.assertEqual(2, ls.geom_type)
self.assertEqual('LINESTRING', ls.geom_name)
with self.assertRaises(IndexError):
msg = 'Index out of range when accessing geometry in a collection: %s.'
with self.assertRaisesMessage(IndexError, msg % len(mlinestr)):
mlinestr.__getitem__(len(mlinestr))

def test_linearring(self):
Expand Down Expand Up @@ -213,6 +215,9 @@ def test_polygons(self):
self.assertEqual('POLYGON', poly.geom_name)
self.assertEqual(p.n_p, poly.point_count)
self.assertEqual(p.n_i + 1, len(poly))
msg = 'Index out of range when accessing rings of a polygon: %s.'
with self.assertRaisesMessage(IndexError, msg % len(poly)):
poly.__getitem__(len(poly))

# Testing area & centroid.
self.assertAlmostEqual(p.area, poly.area, 9)
Expand Down Expand Up @@ -263,7 +268,8 @@ def test_multipolygons(self):
if mp.valid:
self.assertEqual(mp.n_p, mpoly.point_count)
self.assertEqual(mp.num_geom, len(mpoly))
with self.assertRaises(IndexError):
msg = 'Index out of range when accessing geometry in a collection: %s.'
with self.assertRaisesMessage(IndexError, msg % len(mpoly)):
mpoly.__getitem__(len(mpoly))
for p in mpoly:
self.assertEqual('POLYGON', p.geom_name)
Expand Down

0 comments on commit 66657eb

Please sign in to comment.