that's too much!
This commit is contained in:
246
.venv/lib/python3.12/site-packages/pyogrio/_err.pyx
Normal file
246
.venv/lib/python3.12/site-packages/pyogrio/_err.pyx
Normal file
@@ -0,0 +1,246 @@
|
||||
# ported from fiona::_err.pyx
|
||||
from enum import IntEnum
|
||||
import warnings
|
||||
|
||||
from pyogrio._ogr cimport (
|
||||
CE_None, CE_Debug, CE_Warning, CE_Failure, CE_Fatal, CPLErrorReset,
|
||||
CPLGetLastErrorType, CPLGetLastErrorNo, CPLGetLastErrorMsg, OGRErr,
|
||||
CPLErr, CPLErrorHandler, CPLDefaultErrorHandler, CPLPushErrorHandler)
|
||||
|
||||
|
||||
# CPL Error types as an enum.
|
||||
class GDALError(IntEnum):
|
||||
none = CE_None
|
||||
debug = CE_Debug
|
||||
warning = CE_Warning
|
||||
failure = CE_Failure
|
||||
fatal = CE_Fatal
|
||||
|
||||
|
||||
|
||||
class CPLE_BaseError(Exception):
|
||||
"""Base CPL error class.
|
||||
For internal use within Cython only.
|
||||
"""
|
||||
|
||||
def __init__(self, error, errno, errmsg):
|
||||
self.error = error
|
||||
self.errno = errno
|
||||
self.errmsg = errmsg
|
||||
|
||||
def __str__(self):
|
||||
return self.__unicode__()
|
||||
|
||||
def __unicode__(self):
|
||||
return u"{}".format(self.errmsg)
|
||||
|
||||
@property
|
||||
def args(self):
|
||||
return self.error, self.errno, self.errmsg
|
||||
|
||||
|
||||
class CPLE_AppDefinedError(CPLE_BaseError):
|
||||
pass
|
||||
|
||||
|
||||
class CPLE_OutOfMemoryError(CPLE_BaseError):
|
||||
pass
|
||||
|
||||
|
||||
class CPLE_FileIOError(CPLE_BaseError):
|
||||
pass
|
||||
|
||||
|
||||
class CPLE_OpenFailedError(CPLE_BaseError):
|
||||
pass
|
||||
|
||||
|
||||
class CPLE_IllegalArgError(CPLE_BaseError):
|
||||
pass
|
||||
|
||||
|
||||
class CPLE_NotSupportedError(CPLE_BaseError):
|
||||
pass
|
||||
|
||||
|
||||
class CPLE_AssertionFailedError(CPLE_BaseError):
|
||||
pass
|
||||
|
||||
|
||||
class CPLE_NoWriteAccessError(CPLE_BaseError):
|
||||
pass
|
||||
|
||||
|
||||
class CPLE_UserInterruptError(CPLE_BaseError):
|
||||
pass
|
||||
|
||||
|
||||
class ObjectNullError(CPLE_BaseError):
|
||||
pass
|
||||
|
||||
|
||||
class CPLE_HttpResponseError(CPLE_BaseError):
|
||||
pass
|
||||
|
||||
|
||||
class CPLE_AWSBucketNotFoundError(CPLE_BaseError):
|
||||
pass
|
||||
|
||||
|
||||
class CPLE_AWSObjectNotFoundError(CPLE_BaseError):
|
||||
pass
|
||||
|
||||
|
||||
class CPLE_AWSAccessDeniedError(CPLE_BaseError):
|
||||
pass
|
||||
|
||||
|
||||
class CPLE_AWSInvalidCredentialsError(CPLE_BaseError):
|
||||
pass
|
||||
|
||||
|
||||
class CPLE_AWSSignatureDoesNotMatchError(CPLE_BaseError):
|
||||
pass
|
||||
|
||||
|
||||
class NullPointerError(CPLE_BaseError):
|
||||
"""
|
||||
Returned from exc_wrap_pointer when a NULL pointer is passed, but no GDAL
|
||||
error was raised.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
|
||||
# Map of GDAL error numbers to the Python exceptions.
|
||||
exception_map = {
|
||||
1: CPLE_AppDefinedError,
|
||||
2: CPLE_OutOfMemoryError,
|
||||
3: CPLE_FileIOError,
|
||||
4: CPLE_OpenFailedError,
|
||||
5: CPLE_IllegalArgError,
|
||||
6: CPLE_NotSupportedError,
|
||||
7: CPLE_AssertionFailedError,
|
||||
8: CPLE_NoWriteAccessError,
|
||||
9: CPLE_UserInterruptError,
|
||||
10: ObjectNullError,
|
||||
|
||||
# error numbers 11-16 are introduced in GDAL 2.1. See
|
||||
# https://github.com/OSGeo/gdal/pull/98.
|
||||
11: CPLE_HttpResponseError,
|
||||
12: CPLE_AWSBucketNotFoundError,
|
||||
13: CPLE_AWSObjectNotFoundError,
|
||||
14: CPLE_AWSAccessDeniedError,
|
||||
15: CPLE_AWSInvalidCredentialsError,
|
||||
16: CPLE_AWSSignatureDoesNotMatchError
|
||||
}
|
||||
|
||||
|
||||
cdef inline object exc_check():
|
||||
"""Checks GDAL error stack for fatal or non-fatal errors
|
||||
Returns
|
||||
-------
|
||||
An Exception, SystemExit, or None
|
||||
"""
|
||||
cdef const char *msg_c = NULL
|
||||
|
||||
err_type = CPLGetLastErrorType()
|
||||
err_no = CPLGetLastErrorNo()
|
||||
err_msg = CPLGetLastErrorMsg()
|
||||
|
||||
if err_msg == NULL:
|
||||
msg = "No error message."
|
||||
else:
|
||||
# Reformat messages.
|
||||
msg_b = err_msg
|
||||
msg = msg_b.decode('utf-8')
|
||||
msg = msg.replace("`", "'")
|
||||
msg = msg.replace("\n", " ")
|
||||
|
||||
if err_type == 3:
|
||||
CPLErrorReset()
|
||||
return exception_map.get(
|
||||
err_no, CPLE_BaseError)(err_type, err_no, msg)
|
||||
|
||||
if err_type == 4:
|
||||
return SystemExit("Fatal error: {0}".format((err_type, err_no, msg)))
|
||||
|
||||
else:
|
||||
return
|
||||
|
||||
|
||||
cdef void *exc_wrap_pointer(void *ptr) except NULL:
|
||||
"""Wrap a GDAL/OGR function that returns GDALDatasetH etc (void *)
|
||||
Raises an exception if a non-fatal error has be set or if pointer is NULL.
|
||||
"""
|
||||
if ptr == NULL:
|
||||
exc = exc_check()
|
||||
if exc:
|
||||
raise exc
|
||||
else:
|
||||
# null pointer was passed, but no error message from GDAL
|
||||
raise NullPointerError(-1, -1, "NULL pointer error")
|
||||
return ptr
|
||||
|
||||
|
||||
cdef int exc_wrap_int(int err) except -1:
|
||||
"""Wrap a GDAL/OGR function that returns CPLErr or OGRErr (int)
|
||||
Raises an exception if a non-fatal error has be set.
|
||||
|
||||
Copied from Fiona (_err.pyx).
|
||||
"""
|
||||
if err:
|
||||
exc = exc_check()
|
||||
if exc:
|
||||
raise exc
|
||||
else:
|
||||
# no error message from GDAL
|
||||
raise CPLE_BaseError(-1, -1, "Unspecified OGR / GDAL error")
|
||||
return err
|
||||
|
||||
|
||||
cdef int exc_wrap_ogrerr(int err) except -1:
|
||||
"""Wrap a function that returns OGRErr (int) but does not use the
|
||||
CPL error stack.
|
||||
|
||||
Adapted from Fiona (_err.pyx).
|
||||
"""
|
||||
if err != 0:
|
||||
raise CPLE_BaseError(3, err, f"OGR Error code {err}")
|
||||
|
||||
return err
|
||||
|
||||
|
||||
cdef void error_handler(CPLErr err_class, int err_no, const char* err_msg) nogil:
|
||||
"""Custom CPL error handler to match the Python behaviour.
|
||||
|
||||
Generally we want to suppress error printing to stderr (behaviour of the
|
||||
default GDAL error handler) because we already raise a Python exception
|
||||
that includes the error message.
|
||||
"""
|
||||
if err_class == CE_Fatal:
|
||||
# If the error class is CE_Fatal, we want to have a message issued
|
||||
# because the CPL support code does an abort() before any exception
|
||||
# can be generated
|
||||
CPLDefaultErrorHandler(err_class, err_no, err_msg)
|
||||
return
|
||||
|
||||
elif err_class == CE_Failure:
|
||||
# For Failures, do nothing as those are explicitly caught
|
||||
# with error return codes and translated into Python exceptions
|
||||
return
|
||||
|
||||
elif err_class == CE_Warning:
|
||||
with gil:
|
||||
msg_b = err_msg
|
||||
msg = msg_b.decode('utf-8')
|
||||
warnings.warn(msg, RuntimeWarning)
|
||||
return
|
||||
|
||||
# Fall back to the default handler for non-failure messages since
|
||||
# they won't be translated into exceptions.
|
||||
CPLDefaultErrorHandler(err_class, err_no, err_msg)
|
||||
|
||||
|
||||
def _register_error_handler():
|
||||
CPLPushErrorHandler(<CPLErrorHandler>error_handler)
|
||||
Reference in New Issue
Block a user