Switch to new try/with/except/finally structure

Also restructure the errors raised from cpl_errs.

Closes #600
This commit is contained in:
Sean Gillies 2016-03-23 22:17:42 -06:00
parent 801c8720dc
commit fdc6baab46
8 changed files with 327 additions and 200 deletions

View File

@ -21,7 +21,7 @@ cdef class DatasetReader:
cdef public object _read
cdef object env
cdef void *band(self, int bidx)
cdef void *band(self, int bidx) except NULL
cdef void *_osr_from_crs(object crs)

View File

@ -14,9 +14,11 @@ from libc.stdlib cimport malloc, free
from rasterio cimport _gdal, _ogr
from rasterio._drivers import driver_count, GDALEnv
from rasterio._err import cpl_errs, GDALError
from rasterio._err import (
cpl_errs, GDALError, CPLE_IllegalArg, CPLE_OpenFailed)
from rasterio import dtypes
from rasterio.coords import BoundingBox
from rasterio.errors import RasterioIOError
from rasterio.transform import Affine
from rasterio.enums import ColorInterp, Compression, Interleaving
from rasterio.vfs import parse_path, vsi_path
@ -71,10 +73,13 @@ cdef class DatasetReader(object):
name_b = path.encode('utf-8')
cdef const char *fname = name_b
with cpl_errs:
self._hds = _gdal.GDALOpen(fname, 0)
if self._hds == NULL:
raise ValueError("Null dataset")
try:
with cpl_errs:
self._hds = _gdal.GDALOpen(fname, 0)
except CPLE_OpenFailed as err:
self.env.stop()
raise RasterioIOError(str(err))
cdef void *drv
cdef const char *drv_name
@ -96,14 +101,26 @@ cdef class DatasetReader(object):
self._closed = False
cdef void *band(self, int bidx):
if self._hds == NULL:
raise ValueError("Null dataset")
cdef void *hband = _gdal.GDALGetRasterBand(self._hds, bidx)
if hband == NULL:
raise ValueError("Null band")
cdef void *band(self, int bidx) except NULL:
cdef void *hband = NULL
try:
with cpl_errs:
hband = _gdal.GDALGetRasterBand(self._hds, bidx)
except CPLE_IllegalArg as exc:
self.env.stop()
raise IndexError(str(exc))
return hband
def _has_band(self, bidx):
cdef void *hband = NULL
try:
with cpl_errs:
hband = _gdal.GDALGetRasterBand(self._hds, bidx)
except CPLE_IllegalArg:
self.env.stop()
return False
return True
def read_crs(self):
cdef char *proj_c = NULL
cdef const char * auth_key = NULL
@ -596,14 +613,9 @@ cdef class DatasetReader(object):
cdef void *hobj
cdef const char *domain_c
cdef char **papszStrList
if self._hds == NULL:
raise ValueError("can't read closed raster file")
if bidx > 0:
if bidx not in self.indexes:
raise ValueError("Invalid band index")
hobj = _gdal.GDALGetRasterBand(self._hds, bidx)
if hobj == NULL:
raise ValueError("NULL band")
hobj = self.band(bidx)
else:
hobj = self._hds
if ns:
@ -850,6 +862,8 @@ def tastes_like_gdal(t):
cdef void *_osr_from_crs(object crs):
"""Returns a reference to memory that must be deallocated
by the caller."""
cdef char *proj_c = NULL
cdef void *osr = _gdal.OSRNewSpatialReference(NULL)
params = []

View File

@ -31,6 +31,8 @@ manager raises a more useful and informative error:
from enums import IntEnum
from rasterio.errors import RasterioIOError
# CPL function declarations.
cdef extern from "cpl_error.h":
@ -39,17 +41,59 @@ cdef extern from "cpl_error.h":
int CPLGetLastErrorType()
void CPLErrorReset()
class CPLError(Exception):
"""Base CPL error class"""
pass
class CPLE_AppDefined(CPLError):
pass
class CPLE_OutOfMemory(CPLError):
pass
class CPLE_FileIO(CPLError):
pass
class CPLE_OpenFailed(CPLError):
pass
class CPLE_IllegalArg(CPLError):
pass
class CPLE_NotSupported(CPLError):
pass
class CPLE_AssertionFailed(CPLError):
pass
class CPLE_NoWriteAccess(CPLError):
pass
class CPLE_UserInterrupt(CPLError):
pass
# Map GDAL error numbers to Python exceptions.
exception_map = {
1: RuntimeError, # CPLE_AppDefined
2: MemoryError, # CPLE_OutOfMemory
3: IOError, # CPLE_FileIO
4: IOError, # CPLE_OpenFailed
5: TypeError, # CPLE_IllegalArg
6: ValueError, # CPLE_NotSupported
7: AssertionError, # CPLE_AssertionFailed
8: IOError, # CPLE_NoWriteAccess
9: KeyboardInterrupt, # CPLE_UserInterrupt
1: CPLE_AppDefined, #
2: CPLE_OutOfMemory, #
3: CPLE_FileIO, #
4: CPLE_OpenFailed, #
5: CPLE_IllegalArg, #
6: CPLE_NotSupported, #
7: CPLE_AssertionFailed, #
8: CPLE_NoWriteAccess, #
9: CPLE_UserInterrupt, #
10: ValueError # ObjectNull
}
@ -62,11 +106,17 @@ cdef class GDALErrCtxManager:
return self
def __exit__(self, exc_type=None, exc_val=None, exc_tb=None):
cdef int err_type = CPLGetLastErrorType()
cdef int err_no = CPLGetLastErrorNo()
cdef const char *msg = CPLGetLastErrorMsg()
cdef const char *msg_c = NULL
err_type = CPLGetLastErrorType()
# TODO: warn for err_type 2?
if err_type >= 3:
err_no = CPLGetLastErrorNo()
msg_c = CPLGetLastErrorMsg()
msg_b = msg_c
msg = msg_b.decode('utf-8')
msg = msg.replace("`", "'")
msg = msg.replace("\n", " ")
raise exception_map[err_no](msg)

View File

@ -17,10 +17,10 @@ from rasterio cimport _base, _gdal, _ogr, _io
from rasterio._base import (
crop_window, eval_window, window_shape, window_index, tastes_like_gdal)
from rasterio._drivers import driver_count, GDALEnv
from rasterio._err import cpl_errs, GDALError
from rasterio._err import cpl_errs, GDALError, CPLE_OpenFailed
from rasterio import dtypes
from rasterio.coords import BoundingBox
from rasterio.errors import DriverRegistrationError
from rasterio.errors import DriverRegistrationError, RasterioIOError
from rasterio.five import text_type, string_types
from rasterio.transform import Affine
from rasterio.enums import ColorInterp, MaskFlags, Resampling
@ -1288,9 +1288,13 @@ cdef class RasterUpdater(RasterReader):
driver_b = self.driver.encode('utf-8')
drv_name = driver_b
drv = _gdal.GDALGetDriverByName(drv_name)
if drv == NULL:
raise ValueError("NULL driver for %s", self.driver)
try:
with cpl_errs:
drv = _gdal.GDALGetDriverByName(drv_name)
except Exception as err:
self.env.stop()
raise DriverRegistrationError(str(err))
# Find the equivalent GDAL data type or raise an exception
# We've mapped numpy scalar types to GDAL types so see
@ -1328,12 +1332,16 @@ cdef class RasterUpdater(RasterReader):
"Option: %r\n",
(k, _gdal.CSLFetchNameValue(options, key_c)))
self._hds = _gdal.GDALCreate(
drv, fname, self.width, self.height, self._count,
gdal_dtype, options)
if self._hds == NULL:
raise ValueError("NULL dataset")
try:
with cpl_errs:
self._hds = _gdal.GDALCreate(
drv, fname, self.width, self.height, self._count,
gdal_dtype, options)
except Exception as err:
self.env.stop()
if options != NULL:
_gdal.CSLDestroy(options)
raise
if self._init_nodata is not None:
@ -1354,10 +1362,12 @@ cdef class RasterUpdater(RasterReader):
self.set_crs(self._crs)
elif self.mode == 'r+':
with cpl_errs:
self._hds = _gdal.GDALOpen(fname, 1)
if self._hds == NULL:
raise ValueError("NULL dataset")
try:
with cpl_errs:
self._hds = _gdal.GDALOpen(fname, 1)
except CPLE_OpenFailed as err:
self.env.stop()
raise RasterioIOError(str(err))
drv = _gdal.GDALGetDatasetDriver(self._hds)
drv_name = _gdal.GDALGetDriverShortName(drv)
@ -1659,14 +1669,8 @@ cdef class RasterUpdater(RasterReader):
cdef void *hobj = NULL
cdef const char *domain_c = NULL
cdef char **papszStrList = NULL
if self._hds == NULL:
raise ValueError("can't read closed raster file")
if bidx > 0:
if bidx not in self.indexes:
raise ValueError("Invalid band index")
hobj = _gdal.GDALGetRasterBand(self._hds, bidx)
if hobj == NULL:
raise ValueError("NULL band")
hobj = self.band(bidx)
else:
hobj = self._hds
if ns:
@ -1700,21 +1704,15 @@ cdef class RasterUpdater(RasterReader):
cdef void *hBand = NULL
cdef void *hTable
cdef _gdal.GDALColorEntry color
if self._hds == NULL:
raise ValueError("can't read closed raster file")
if bidx > 0:
if bidx not in self.indexes:
raise ValueError("Invalid band index")
hBand = _gdal.GDALGetRasterBand(self._hds, bidx)
if hBand == NULL:
raise ValueError("NULL band")
hBand = self.band(bidx)
# RGB only for now. TODO: the other types.
# GPI_Gray=0, GPI_RGB=1, GPI_CMYK=2, GPI_HLS=3
hTable = _gdal.GDALCreateColorTable(1)
vals = range(256)
for i, rgba in colormap.items():
if len(rgba) == 4 and self.driver in ('GTiff'):
warnings.warn(
"This format doesn't support alpha in colormap entries. "
@ -1745,18 +1743,18 @@ cdef class RasterUpdater(RasterReader):
specifying a raster subset to write into.
"""
cdef void *hband
cdef void *hmask
if self._hds == NULL:
raise ValueError("can't write closed raster file")
hband = _gdal.GDALGetRasterBand(self._hds, 1)
if hband == NULL:
raise ValueError("NULL band mask")
if _gdal.GDALCreateMaskBand(hband, 0x02) != 0:
raise RuntimeError("Failed to create mask")
hmask = _gdal.GDALGetMaskBand(hband)
if hmask == NULL:
raise ValueError("NULL band mask")
cdef void *hband = NULL
cdef void *hmask = NULL
hband = self.band(1)
if GDALError.success != _gdal.GDALCreateMaskBand(hband, 0x02):
raise RasterioIOError("Failed to create mask.")
try:
with cpl_errs:
hmask = _gdal.GDALGetMaskBand(hband)
except:
raise
log.debug("Created mask band")
if window:
@ -1788,23 +1786,20 @@ cdef class RasterUpdater(RasterReader):
cdef int *factors_c = NULL
cdef const char *resampling_c = NULL
if self._hds == NULL:
raise ValueError("can't write closed raster file")
# Allocate arrays.
if factors:
factors_c = <int *>_gdal.CPLMalloc(len(factors)*sizeof(int))
for i, factor in enumerate(factors):
factors_c[i] = factor
with cpl_errs:
resampling_b = resampling.value.encode('utf-8')
resampling_c = resampling_b
err = _gdal.GDALBuildOverviews(self._hds, resampling_c,
len(factors), factors_c, 0, NULL, NULL, NULL)
if factors_c != NULL:
_gdal.CPLFree(factors_c)
try:
with cpl_errs:
resampling_b = resampling.value.encode('utf-8')
resampling_c = resampling_b
err = _gdal.GDALBuildOverviews(self._hds, resampling_c,
len(factors), factors_c, 0, NULL, NULL, NULL)
finally:
if factors_c != NULL:
_gdal.CPLFree(factors_c)
cdef class InMemoryRaster:
@ -1845,27 +1840,25 @@ cdef class InMemoryRaster:
cdef int i = 0 # avoids Cython warning in for loop below
cdef const char *srcwkt = NULL
cdef void *osr = NULL
cdef void *memdriver = NULL
# Several GDAL operations require the array of band IDs as input
self.band_ids[0] = 1
cdef void *memdriver = _gdal.GDALGetDriverByName("MEM")
if memdriver == NULL:
raise DriverRegistrationError(
"MEM driver is not registered.")
try:
with cpl_errs:
memdriver = _gdal.GDALGetDriverByName("MEM")
except:
raise DriverRegistrationError("MEM driver is not registered.")
self.dataset = _gdal.GDALCreate(
memdriver,
"output",
image.shape[1],
image.shape[0],
1,
<_gdal.GDALDataType>dtypes.dtype_rev[image.dtype.name],
NULL
)
if self.dataset == NULL:
raise ValueError("NULL output datasource")
try:
with cpl_errs:
self.dataset = _gdal.GDALCreate(
memdriver, "output", image.shape[1], image.shape[0],
1, <_gdal.GDALDataType>dtypes.dtype_rev[image.dtype.name],
NULL)
except:
raise
if transform is not None:
for i in range(6):
@ -1951,14 +1944,19 @@ cdef class IndirectRasterUpdater(RasterUpdater):
gdal_dtype = dtypes.dtype_rev.get(tp)
else:
gdal_dtype = dtypes.dtype_rev.get(self._init_dtype)
self._hds = _gdal.GDALCreate(
memdrv, "temp", self.width, self.height, self._count,
gdal_dtype, NULL)
if self._hds == NULL:
raise ValueError("NULL dataset")
try:
with cpl_errs:
self._hds = _gdal.GDALCreate(
memdrv, "temp", self.width, self.height, self._count,
gdal_dtype, NULL)
except:
self.env.close()
raise
if self._init_nodata is not None:
for i in range(self._count):
hband = _gdal.GDALGetRasterBand(self._hds, i+1)
hband = self.band(i+1)
success = _gdal.GDALSetRasterNoDataValue(
hband, self._init_nodata)
if self._transform:
@ -1967,14 +1965,19 @@ cdef class IndirectRasterUpdater(RasterUpdater):
self.set_crs(self._crs)
elif self.mode == 'r+':
with cpl_errs:
temp = _gdal.GDALOpen(fname, 0)
if temp == NULL:
raise ValueError("Null dataset")
self._hds = _gdal.GDALCreateCopy(
memdrv, "temp", temp, 1, NULL, NULL, NULL)
if self._hds == NULL:
raise ValueError("NULL dataset")
try:
with cpl_errs:
temp = _gdal.GDALOpen(fname, 0)
except Exception as exc:
raise RasterioIOError(str(exc))
try:
with cpl_errs:
self._hds = _gdal.GDALCreateCopy(
memdrv, "temp", temp, 1, NULL, NULL, NULL)
except:
raise
drv = _gdal.GDALGetDatasetDriver(temp)
drv_name = _gdal.GDALGetDriverShortName(drv)
self.driver = drv_name.decode('utf-8')
@ -2031,16 +2034,19 @@ cdef class IndirectRasterUpdater(RasterUpdater):
log.debug(
"Option: %r\n",
(k, _gdal.CSLFetchNameValue(options, key_c)))
#self.update_tags(ns='rio_creation_kwds', **kwds)
temp = _gdal.GDALCreateCopy(
try:
with cpl_errs:
temp = _gdal.GDALCreateCopy(
drv, fname, self._hds, 1, options, NULL, NULL)
if options != NULL:
_gdal.CSLDestroy(options)
if temp != NULL:
_gdal.GDALClose(temp)
except:
raise
finally:
if options != NULL:
_gdal.CSLDestroy(options)
if temp != NULL:
_gdal.GDALClose(temp)
def writer(path, mode, **kwargs):
@ -2067,15 +2073,17 @@ def writer(path, mode, **kwargs):
# driver.
name_b = path.encode('utf-8')
fname = name_b
with cpl_errs:
hds = _gdal.GDALOpen(fname, 0)
if hds == NULL:
raise ValueError("NULL dataset")
drv = _gdal.GDALGetDatasetDriver(hds)
drv_name = _gdal.GDALGetDriverShortName(drv)
drv_name_b = drv_name
driver = drv_name_b.decode('utf-8')
_gdal.GDALClose(hds)
try:
with cpl_errs:
hds = _gdal.GDALOpen(fname, 0)
except CPLE_OpenFailed as exc:
raise RasterioIOError(str(exc))
drv = _gdal.GDALGetDatasetDriver(hds)
drv_name = _gdal.GDALGetDriverShortName(drv)
drv_name_b = drv_name
driver = drv_name_b.decode('utf-8')
_gdal.GDALClose(hds)
if driver == 'GTiff':
return RasterUpdater(path, mode)
@ -2091,7 +2099,13 @@ def virtual_file_to_buffer(filename):
filename_b = filename if not isinstance(filename, string_types) else filename.encode('utf-8')
cfilename = filename_b
buff = _gdal.VSIGetMemFileBuffer(cfilename, &buff_len, 0)
try:
with cpl_errs:
buff = _gdal.VSIGetMemFileBuffer(cfilename, &buff_len, 0)
except:
raise
n = buff_len
log.debug("Buffer length: %d bytes", n)
cdef np.uint8_t[:] buff_view = <np.uint8_t[:n]>buff

View File

@ -100,8 +100,15 @@ def _transform_geom(
src = _base._osr_from_crs(src_crs)
dst = _base._osr_from_crs(dst_crs)
transform = _gdal.OCTNewCoordinateTransformation(src, dst)
try:
with cpl_errs:
transform = _gdal.OCTNewCoordinateTransformation(src, dst)
except:
_gdal.OSRDestroySpatialReference(src)
_gdal.OSRDestroySpatialReference(dst)
raise
# Transform options.
val_b = str(antimeridian_offset).encode('utf-8')
val_c = val_b
@ -110,22 +117,24 @@ def _transform_geom(
if antimeridian_cutting:
options = _gdal.CSLSetNameValue(options, "WRAPDATELINE", "YES")
factory = new OGRGeometryFactory()
src_ogr_geom = _features.OGRGeomBuilder().build(geom)
dst_ogr_geom = factory.transformWithOptions(
try:
factory = new OGRGeometryFactory()
src_ogr_geom = _features.OGRGeomBuilder().build(geom)
with cpl_errs:
dst_ogr_geom = factory.transformWithOptions(
<const OGRGeometry *>src_ogr_geom,
<OGRCoordinateTransformation *>transform,
options)
del factory
g = _features.GeomBuilder().build(dst_ogr_geom)
_ogr.OGR_G_DestroyGeometry(dst_ogr_geom)
_ogr.OGR_G_DestroyGeometry(src_ogr_geom)
_gdal.OCTDestroyCoordinateTransformation(transform)
if options != NULL:
_gdal.CSLDestroy(options)
_gdal.OSRDestroySpatialReference(src)
_gdal.OSRDestroySpatialReference(dst)
g = _features.GeomBuilder().build(dst_ogr_geom)
finally:
del factory
_ogr.OGR_G_DestroyGeometry(dst_ogr_geom)
_ogr.OGR_G_DestroyGeometry(src_ogr_geom)
_gdal.OCTDestroyCoordinateTransformation(transform)
if options != NULL:
_gdal.CSLDestroy(options)
_gdal.OSRDestroySpatialReference(src)
_gdal.OSRDestroySpatialReference(dst)
if precision >= 0:
if g['type'] == 'Point':
@ -267,31 +276,39 @@ def _reproject(
# source is a masked array
src_nodata = source.fill_value
hrdriver = _gdal.GDALGetDriverByName("MEM")
if hrdriver == NULL:
try:
with cpl_errs:
hrdriver = _gdal.GDALGetDriverByName("MEM")
except:
raise DriverRegistrationError(
"'MEM' driver not found. Check that this call is contained "
"in a `with rasterio.drivers()` or `with rasterio.open()` "
"block.")
hdsin = _gdal.GDALCreate(
try:
with cpl_errs:
hdsin = _gdal.GDALCreate(
hrdriver, "input", cols, rows,
src_count, dtypes.dtype_rev[dtype], NULL)
if hdsin == NULL:
raise ValueError("NULL input datasource")
except:
raise
_gdal.GDALSetDescription(
hdsin, "Temporary source dataset for _reproject()")
log.debug("Created temp source dataset")
for i in range(6):
gt[i] = src_transform[i]
retval = _gdal.GDALSetGeoTransform(hdsin, gt)
log.debug("Set transform on temp source dataset: %d", retval)
osr = _base._osr_from_crs(src_crs)
_gdal.OSRExportToWkt(osr, &srcwkt)
_gdal.GDALSetProjection(hdsin, srcwkt)
log.debug("Set CRS on temp source dataset: %s", srcwkt)
_gdal.CPLFree(srcwkt)
_gdal.OSRDestroySpatialReference(osr)
try:
osr = _base._osr_from_crs(src_crs)
_gdal.OSRExportToWkt(osr, &srcwkt)
_gdal.GDALSetProjection(hdsin, srcwkt)
log.debug("Set CRS on temp source dataset: %s", srcwkt)
finally:
_gdal.CPLFree(srcwkt)
_gdal.OSRDestroySpatialReference(osr)
# Copy arrays to the dataset.
retval = _io.io_auto(source, hdsin, 1)
@ -315,19 +332,23 @@ def _reproject(
if destination.shape[0] != src_count:
raise ValueError("Destination's shape is invalid")
hrdriver = _gdal.GDALGetDriverByName("MEM")
if hrdriver == NULL:
try:
with cpl_errs:
hrdriver = _gdal.GDALGetDriverByName("MEM")
except:
raise DriverRegistrationError(
"'MEM' driver not found. Check that this call is contained "
"in a `with rasterio.drivers()` or `with rasterio.open()` "
"block.")
_, rows, cols = destination.shape
hdsout = _gdal.GDALCreate(
hrdriver, "output", cols, rows, src_count,
dtypes.dtype_rev[np.dtype(destination.dtype).name], NULL)
if hdsout == NULL:
raise ValueError("Failed to create temp destination dataset.")
try:
with cpl_errs:
hdsout = _gdal.GDALCreate(
hrdriver, "output", cols, rows, src_count,
dtypes.dtype_rev[np.dtype(destination.dtype).name], NULL)
except:
raise
_gdal.GDALSetDescription(
hdsout, "Temporary destination dataset for _reproject()")
log.debug("Created temp destination dataset.")
@ -339,16 +360,16 @@ def _reproject(
raise ValueError(
"Failed to set transform on temp destination dataset.")
osr = _base._osr_from_crs(dst_crs)
_gdal.OSRExportToWkt(osr, &dstwkt)
_gdal.OSRDestroySpatialReference(osr)
log.debug("CRS for temp destination dataset: %s.", dstwkt)
if not GDALError.success == _gdal.GDALSetProjection(hdsout, dstwkt):
raise ValueError(
"Failed to set projection on temp destination dataset.")
_gdal.CPLFree(dstwkt)
try:
osr = _base._osr_from_crs(dst_crs)
_gdal.OSRExportToWkt(osr, &dstwkt)
log.debug("CRS for temp destination dataset: %s.", dstwkt)
if not GDALError.success == _gdal.GDALSetProjection(
hdsout, dstwkt):
raise ("Failed to set projection on temp destination dataset.")
finally:
_gdal.OSRDestroySpatialReference(osr)
_gdal.CPLFree(dstwkt)
if dst_nodata is None and hasattr(destination, "fill_value"):
# destination is a masked array
@ -365,14 +386,18 @@ def _reproject(
cdef void *hTransformArg = NULL
cdef _gdal.GDALWarpOptions *psWOptions = NULL
hTransformArg = _gdal.GDALCreateGenImgProjTransformer(
hdsin, NULL, hdsout, NULL,
1, 1000.0, 0)
if hTransformArg == NULL:
raise ValueError("NULL transformer")
log.debug("Created transformer")
psWOptions = _gdal.GDALCreateWarpOptions()
try:
with cpl_errs:
hTransformArg = _gdal.GDALCreateGenImgProjTransformer(
hdsin, NULL, hdsout, NULL,
1, 1000.0, 0)
with cpl_errs:
psWOptions = _gdal.GDALCreateWarpOptions()
log.debug("Created transformer and options.")
except:
_gdal.GDALDestroyGenImgProjTransformer(hTransformArg)
_gdal.GDALDestroyWarpOptions(psWOptions)
raise
# Note: warp_extras is pointed to different memory locations on every
# call to CSLSetNameValue call below, but needs to be set here to
@ -534,22 +559,18 @@ def _calculate_default_transform(
with InMemoryRaster(
img, transform=transform.to_gdal(), crs=src_crs) as temp:
hTransformArg = _gdal.GDALCreateGenImgProjTransformer(
temp.dataset, NULL, NULL, wkt, 1, 1000.0, 0)
if hTransformArg == NULL:
if wkt != NULL:
_gdal.CPLFree(wkt)
raise ValueError("NULL transformer")
log.debug("Created transformer")
# geotransform, npixels, and nlines are modified by the
# function called below.
try:
if not GDALError.success == _gdal.GDALSuggestedWarpOutput2(
with cpl_errs:
hTransformArg = _gdal.GDALCreateGenImgProjTransformer(
temp.dataset, NULL, NULL, wkt,
1, 1000.0,0)
with cpl_errs:
result = _gdal.GDALSuggestedWarpOutput2(
temp.dataset, _gdal.GDALGenImgProjTransform, hTransformArg,
geotransform, &npixels, &nlines, extent, 0):
raise RuntimeError(
"Failed to compute a suggested warp output.")
geotransform, &npixels, &nlines, extent, 0)
log.debug("Created transformer and warp output.")
except:
raise
finally:
if wkt != NULL:
_gdal.CPLFree(wkt)

28
tests/test_err.py Normal file
View File

@ -0,0 +1,28 @@
# Testing use of cpl_errs
import pytest
import rasterio
from rasterio.errors import RasterioIOError
def test_io_error(tmpdir):
with pytest.raises(RasterioIOError) as exc_info:
rasterio.open(str(tmpdir.join('foo.tif')))
msg = exc_info.value.message
assert msg.startswith("'{0}'".format(tmpdir.join('foo.tif')))
assert ("does not exist in the file system, and is not recognised as a "
"supported dataset name.") in msg
def test_io_error_env(tmpdir):
with rasterio.drivers() as env:
drivers_start = env.drivers()
with pytest.raises(RasterioIOError):
rasterio.open(str(tmpdir.join('foo.tif')))
assert env.drivers() == drivers_start
def test_bogus_band_error():
with rasterio.open('tests/data/RGB.byte.tif') as src:
assert src._has_band(4) is False

View File

@ -13,7 +13,7 @@ def test_tags_read():
assert src.tags(ns='IMAGE_STRUCTURE') == {'INTERLEAVE': 'PIXEL'}
assert src.tags(ns='bogus') == {}
assert 'STATISTICS_MAXIMUM' in src.tags(1)
with pytest.raises(ValueError):
with pytest.raises(IndexError):
tags = src.tags(4)
def test_tags_update(tmpdir):
@ -29,7 +29,7 @@ def test_tags_update(tmpdir):
dst.update_tags(a='1', b='2')
dst.update_tags(1, c=3)
with pytest.raises(ValueError):
with pytest.raises(IndexError):
dst.update_tags(4, d=4)
assert dst.tags() == {'a': '1', 'b': '2'}

View File

@ -15,7 +15,7 @@ def test_update_tags(data):
with rasterio.open(tiffname, 'r+') as f:
f.update_tags(a='1', b='2')
f.update_tags(1, c=3)
with pytest.raises(ValueError):
with pytest.raises(IndexError):
f.update_tags(4, d=4)
assert f.tags() == {'AREA_OR_POINT': 'Area', 'a': '1', 'b': '2'}
assert ('c', '3') in f.tags(1).items()