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
This commit is contained in:
Justin Bronn 2008-10-26 22:24:21 +00:00
parent cbeea83107
commit 0b6d214f48
3 changed files with 26 additions and 3 deletions

View File

@ -111,7 +111,7 @@ class DataSource(object):
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."

View File

@ -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')

View File

@ -130,6 +130,23 @@ class DataSourceTest(unittest.TestCase):
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: