Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions autotest/gcore/basic_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,60 @@ def test_ovr_band_use_after_dataset_close():
ovr.Checksum()


def test_sample_ovr_band_use_after_dataset_close():
with gdal.Open("data/byte_with_ovr.tif") as ds:
ovr = ds.GetRasterBand(1).GetSampleOverview(0)

# Make sure ds.__exit__() invalidation has propagated to sample overviews

with pytest.raises(
Exception,
match=r"in method 'Band_Checksum', argument 1 of type 'GDALRasterBandShadow \*'",
):
ovr.Checksum()


@pytest.mark.require_driver("HFA")
def test_rat_use_after_dataset_close():
with gdal.Open("data/rat.img") as ds:
rat = ds.GetRasterBand(1).GetDefaultRAT()

# Make sure ds.__exit__() invalidation has propagated to the RAT

with pytest.raises(
Exception,
match=r"in method 'RasterAttributeTable_GetRowCount', argument 1 of type 'GDALRasterAttributeTableShadow \*'",
):
rat.GetRowCount()


@pytest.mark.require_driver("BMP")
def test_color_table_use_after_dataset_close():
with gdal.Open("data/8bit_pal.bmp") as ds:
ct = ds.GetRasterBand(1).GetRasterColorTable()

# Make sure ds.__exit__() invalidation has propagated to the color table

with pytest.raises(
Exception,
match=r"in method 'ColorTable_GetCount', argument 1 of type 'GDALColorTableShadow \*'",
):
ct.GetCount()


def test_band_dataset_use_after_dataset_close():
with gdal.Open("data/byte.tif") as ds:
band_ds = ds.GetRasterBand(1).GetDataset()

# Make sure ds.__exit__() invalidation has propagated to Band.GetDataset()

with pytest.raises(
Exception,
match=r"in method 'Dataset_RasterXSize_get', argument 1 of type 'GDALDatasetShadow \*'",
):
assert band_ds.RasterXSize


@pytest.mark.slow()
def test_checksum_more_than_2billion_pixels():

Expand Down
70 changes: 70 additions & 0 deletions autotest/ogr/ogr_basic_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1384,3 +1384,73 @@ def test_ogr_setpoint_grows_geometry():
assert g.GetPointCount() == 16

g.SetPointZM(20, 1, 1, 1, 1)


###############################################################################
# Test that objects borrowed from a Dataset are invalidated when it closes


def test_field_domain_use_after_dataset_close():
with gdal.GetDriverByName("MEM").CreateVector("") as ds:
ds.AddFieldDomain(
ogr.CreateRangeFieldDomain(
"dom", "", ogr.OFTInteger, ogr.OFSTNone, 1, True, 2, True
)
)
dom = ds.GetFieldDomain("dom")

# Make sure ds.__exit__() invalidation has propagated to the field domain

with pytest.raises(
Exception,
match=r"in method 'FieldDomain_GetName', argument 1 of type 'OGRFieldDomainShadow \*'",
):
dom.GetName()


def test_style_table_use_after_dataset_close():
with gdal.GetDriverByName("MEM").CreateVector("") as ds:
st = ogr.StyleTable()
st.AddStyle("style", "PEN(c:#FF0000)")
ds.SetStyleTable(st)
style_table = ds.GetStyleTable()

# Make sure ds.__exit__() invalidation has propagated to the style table

with pytest.raises(
Exception,
match=r"in method 'StyleTable_Find', argument 1 of type 'OGRStyleTableShadow \*'",
):
style_table.Find("style")


def test_layer_style_table_use_after_dataset_close():
with gdal.GetDriverByName("MEM").CreateVector("") as ds:
lyr = ds.CreateLayer("lyr")
st = ogr.StyleTable()
st.AddStyle("style", "PEN(c:#FF0000)")
lyr.SetStyleTable(st)
style_table = lyr.GetStyleTable()

# Make sure ds.__exit__() invalidation has propagated to the layer style table

with pytest.raises(
Exception,
match=r"in method 'StyleTable_Find', argument 1 of type 'OGRStyleTableShadow \*'",
):
style_table.Find("style")


def test_spatial_filter_use_after_dataset_close():
with gdal.OpenEx("data/poly.shp") as ds:
lyr = ds.GetLayer(0)
lyr.SetSpatialFilterRect(0, 0, 1, 1)
filter_geom = lyr.GetSpatialFilter()

# Make sure ds.__exit__() invalidation has propagated to the spatial filter

with pytest.raises(
Exception,
match=r"in method 'Geometry_ExportToWkt', argument 1 of type 'OGRGeometryShadow \*'",
):
filter_geom.ExportToWkt()
33 changes: 33 additions & 0 deletions swig/include/python/gdal_python.i
Original file line number Diff line number Diff line change
Expand Up @@ -1346,6 +1346,31 @@ void wrapper_VSIGetMemFileBuffer(const char *utf8_string, GByte **out, vsi_l_off
self._parent_ds()._add_child_ref(val)
%}

%feature("pythonappend") GetSampleOverview %{
if hasattr(self, '_parent_ds') and self._parent_ds():
self._parent_ds()._add_child_ref(val)
%}

%feature("pythonappend") GetDefaultRAT %{
if hasattr(self, '_parent_ds') and self._parent_ds():
self._parent_ds()._add_child_ref(val)
%}

%feature("pythonappend") GetRasterColorTable %{
if hasattr(self, '_parent_ds') and self._parent_ds():
self._parent_ds()._add_child_ref(val)
%}

%feature("pythonappend") GetColorTable %{
if hasattr(self, '_parent_ds') and self._parent_ds():
self._parent_ds()._add_child_ref(val)
%}

%feature("pythonappend") GetDataset %{
if hasattr(self, '_parent_ds') and self._parent_ds():
self._parent_ds()._add_child_ref(val)
%}

%feature("shadow") ComputeStatistics %{
def ComputeStatistics(self, *args, **kwargs):
"""ComputeStatistics(Band self, bool approx_ok, callback=None, callback_data=None)
Expand Down Expand Up @@ -2604,6 +2629,14 @@ def ComputeInterBandCovarianceMatrix(self,
self._add_child_ref(val)
%}

%feature("pythonappend") GetFieldDomain %{
self._add_child_ref(val)
%}

%feature("pythonappend") GetStyleTable %{
self._add_child_ref(val)
%}

}

%extend GDALMajorObjectShadow {
Expand Down
10 changes: 10 additions & 0 deletions swig/include/python/ogr_python.i
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,16 @@ def _WarnIfUserHasNotSpecifiedIfUsingExceptions():

%}

%feature("pythonappend") GetSpatialFilter %{
if hasattr(self, '_parent_ds') and self._parent_ds():
self._parent_ds()._add_child_ref(val)
%}

%feature("pythonappend") GetStyleTable %{
if hasattr(self, '_parent_ds') and self._parent_ds():
self._parent_ds()._add_child_ref(val)
%}

}

%extend OGRFeatureShadow {
Expand Down
Loading