Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #9448 -- `Layer` objects now carry a reference to their parent …

…`DataSource`. Thanks, Matthew D. Hancher for the bug report.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@9284 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 0b6d214f481e5412da0edb6c940db86e520b04c3 1 parent cbeea83
Justin Bronn jbronn authored
2  django/contrib/gis/gdal/datasource.py
View
@@ -111,7 +111,7 @@ def __getitem__(self, index):
l = get_layer(self._ptr, index)
else:
raise TypeError('Invalid index type: %s' % type(index))
- return Layer(l)
+ return Layer(l, self)
def __len__(self):
"Returns the number of layers within the data source."
10 django/contrib/gis/gdal/layer.py
View
@@ -25,12 +25,18 @@ class Layer(object):
"A class that wraps an OGR Layer, needs to be instantiated from a DataSource object."
#### Python 'magic' routines ####
- def __init__(self, layer_ptr):
- "Needs a C pointer (Python/ctypes integer) in order to initialize."
+ def __init__(self, layer_ptr, ds):
+ """
+ Initializes on an OGR C pointer to the Layer and the `DataSource` object
+ that owns this layer. The `DataSource` object is required so that a
+ reference to it is kept with this Layer. This prevents garbage
+ collection of the `DataSource` while this Layer is still active.
+ """
self._ptr = None # Initially NULL
if not layer_ptr:
raise OGRException('Cannot create Layer, invalid pointer given')
self._ptr = layer_ptr
+ self._ds = ds
self._ldefn = get_layer_defn(self._ptr)
# Does the Layer support random reading?
self._random_read = self.test_capability('RandomRead')
17 django/contrib/gis/tests/test_gdal_ds.py
View
@@ -130,6 +130,23 @@ def test03b_layer_slice(self):
control_vals = source.field_values[fld_name][sl]
self.assertEqual(control_vals, test_vals)
+ def test03c_layer_references(self):
+ "Test to make sure Layer access is still available without the DataSource."
+ source = ds_list[0]
+
+ # See ticket #9448.
+ def get_layer():
+ # This DataSource object is not accessible outside this
+ # scope. However, a reference should still be kept alive
+ # on the `Layer` returned.
+ ds = DataSource(source.ds)
+ return ds[0]
+
+ # Making sure we can call OGR routines on the Layer returned.
+ lyr = get_layer()
+ self.assertEqual(source.nfeat, len(lyr))
+ self.assertEqual(source.gtype, lyr.geom_type.num)
+
def test04_features(self):
"Testing Data Source Features."
for source in ds_list:
Please sign in to comment.
Something went wrong with that request. Please try again.