[h5py] 42/455: Begin shift to automatic error API
Ghislain Vaillant
ghisvail-guest at moszumanska.debian.org
Thu Jul 2 18:19:15 UTC 2015
This is an automated email from the git hooks/post-receive script.
ghisvail-guest pushed a commit to annotated tag 1.3.0
in repository h5py.
commit a2f027f3b0d54b2c215405999dfa3a8c7ea58b4b
Author: andrewcollette <andrew.collette at gmail.com>
Date: Sat Jun 7 02:45:04 2008 +0000
Begin shift to automatic error API
---
h5py/errors.py | 11 +--
h5py/h5.pyx | 43 ++--------
h5py/h5a.pxd | 26 +++---
h5py/h5a.pyx | 124 ++++++++++++--------------
h5py/h5d.pxd | 36 ++++----
h5py/h5e.pxd | 157 +++++++++++++++++++++++++++++++--
h5py/h5e.pyx | 258 ++++++++++++++++++++++++++++++++-----------------------
h5py/python.pxd | 12 +++
h5py/utils_low.h | 5 ++
9 files changed, 409 insertions(+), 263 deletions(-)
diff --git a/h5py/errors.py b/h5py/errors.py
index dca35ea..f7bc2eb 100644
--- a/h5py/errors.py
+++ b/h5py/errors.py
@@ -10,8 +10,6 @@
#
#-
-from h5 import get_error_string
-
class H5Error(StandardError):
pass
@@ -19,14 +17,7 @@ class ConversionError(H5Error):
pass
class H5LibraryError(H5Error):
-
- def __init__(self, *args, **kwds):
- arglist = list(args)
- if len(arglist) == 0:
- arglist = [""]
- arglist[0] = arglist[0] + "\n" + get_error_string()
- args = tuple(arglist)
- H5Error.__init__(self, *args, **kwds)
+ pass
class FileError(H5LibraryError):
pass
diff --git a/h5py/h5.pyx b/h5py/h5.pyx
index 5a04c4f..b8da8ed 100644
--- a/h5py/h5.pyx
+++ b/h5py/h5.pyx
@@ -22,17 +22,20 @@
- HDF5_VERS, HDF5_VERS_TPL: Library version
- API_VERS, API_VERS_TPL: API version (1.6 or 1.8) used to compile
"""
-from h5e cimport H5Eset_auto, H5E_walk_t, H5Ewalk, H5E_error_t, \
- H5E_WALK_DOWNWARD
from h5t cimport H5Tset_overflow
from errors import H5LibraryError
-# === Library init ============================================================
+import h5e
-H5open()
+# === Library init ============================================================
-# Disable automatic error printing to stderr
-H5Eset_auto(NULL, NULL)
+_hdf5_imported = False
+def import_hdf5():
+ global _hdf5_imported
+ if not _hdf5_imported:
+ H5open()
+ h5e._enable_exceptions()
+ _hdf5_imported = False
# === API =====================================================================
@@ -71,31 +74,3 @@ class DDict(dict):
def __missing__(self, key):
return '*INVALID* (%s)' % str(key)
-# === Error functions =========================================================
-
-cdef herr_t walk_cb(int n, H5E_error_t *err_desc, void* elist_in):
-
- elist = <object>elist_in
- hstring = err_desc.desc
- if len(hstring) == 0:
- hstring = "Error"
- else:
- hstring = '"'+hstring.capitalize()+'"'
-
- elist.append(" "+str(n)+": "+hstring+" at "+err_desc.func_name)
-
- return 0
-
-def get_error_string():
- """ Internal function; don't use directly.
-
- Get the HDF5 error stack contents as a string.
- """
- elist = []
-
- H5Ewalk(H5E_WALK_DOWNWARD, walk_cb, <void*>elist)
-
- if len(elist) == 0:
- return ""
- return "HDF5 error stack:\n" + '\n'.join(elist)
-
diff --git a/h5py/h5a.pxd b/h5py/h5a.pxd
index dd18667..58057db 100644
--- a/h5py/h5a.pxd
+++ b/h5py/h5a.pxd
@@ -14,28 +14,28 @@
# license is available at licenses/pytables.txt, in the distribution root
# directory.
-from defs_c cimport size_t
+from defs_c cimport size_t, ssize_t
from h5 cimport hid_t, herr_t
cdef extern from "hdf5.h":
# --- Attribute operations --------------------------------------------------
- hid_t H5Acreate(hid_t loc_id, char *name, hid_t type_id, hid_t space_id, hid_t create_plist )
- hid_t H5Aopen_idx(hid_t loc_id, unsigned int idx)
- hid_t H5Aopen_name(hid_t loc_id, char *name)
- herr_t H5Aclose(hid_t attr_id)
- herr_t H5Adelete(hid_t loc_id, char *name)
+ hid_t H5Acreate(hid_t loc_id, char *name, hid_t type_id, hid_t space_id, hid_t create_plist) except *
+ hid_t H5Aopen_idx(hid_t loc_id, unsigned int idx) except *
+ hid_t H5Aopen_name(hid_t loc_id, char *name) except *
+ herr_t H5Aclose(hid_t attr_id) except *
+ herr_t H5Adelete(hid_t loc_id, char *name) except *
- herr_t H5Aread(hid_t attr_id, hid_t mem_type_id, void *buf)
- herr_t H5Awrite(hid_t attr_id, hid_t mem_type_id, void *buf )
+ herr_t H5Aread(hid_t attr_id, hid_t mem_type_id, void *buf) except *
+ herr_t H5Awrite(hid_t attr_id, hid_t mem_type_id, void *buf ) except *
- int H5Aget_num_attrs(hid_t loc_id)
- size_t H5Aget_name(hid_t attr_id, size_t buf_size, char *buf)
- hid_t H5Aget_space(hid_t attr_id)
- hid_t H5Aget_type(hid_t attr_id)
+ int H5Aget_num_attrs(hid_t loc_id) except *
+ ssize_t H5Aget_name(hid_t attr_id, size_t buf_size, char *buf) except *
+ hid_t H5Aget_space(hid_t attr_id) except *
+ hid_t H5Aget_type(hid_t attr_id) except *
ctypedef herr_t (*H5A_operator_t)(hid_t loc_id, char *attr_name, operator_data)
- herr_t H5Aiterate(hid_t loc_id, unsigned * idx, H5A_operator_t op, op_data )
+ herr_t H5Aiterate(hid_t loc_id, unsigned * idx, H5A_operator_t op, op_data) except *
diff --git a/h5py/h5a.pyx b/h5py/h5a.pyx
index faa244b..4b4f8f6 100644
--- a/h5py/h5a.pyx
+++ b/h5py/h5a.pyx
@@ -17,7 +17,6 @@
"""
# Pyrex compile-time imports
-cimport h5
from defs_c cimport malloc, free
from h5 cimport herr_t, hid_t
from h5p cimport H5P_DEFAULT
@@ -25,6 +24,7 @@ from h5t cimport H5Tclose
from h5s cimport H5Sclose
from numpy cimport ndarray, import_array, PyArray_DATA
from utils cimport check_numpy_read, check_numpy_write
+from h5e cimport err_c, pause_errors, resume_errors
# Runtime imports
import h5
@@ -32,6 +32,7 @@ import h5t
import h5s
from errors import H5AttributeError
+h5.import_hdf5()
import_array()
# === General attribute operations ============================================
@@ -43,53 +44,39 @@ def create(hid_t loc_id, char* name, hid_t type_id, hid_t space_id):
HDF5 datatype and dataspace. For a friendlier version of this function
try py_create().
"""
- cdef hid_t retval
- retval = H5Acreate(loc_id, name, type_id, space_id, H5P_DEFAULT)
- if retval < 0:
- raise H5AttributeError("Failed to create attribute '%s' on object %d" % (name, loc_id))
- return retval
+ return H5Acreate(loc_id, name, type_id, space_id, H5P_DEFAULT)
def open_idx(hid_t loc_id, unsigned int idx):
""" (INT loc_id, UINT idx) => INT attr_id
Open an exisiting attribute on an object, by zero-based index.
"""
- cdef hid_t retval
- retval = H5Aopen_idx(loc_id, idx)
- if retval < 0:
- raise H5AttributeError("Failed to open attribute at index %d on object %d" % (idx, loc_id))
- return retval
+ return H5Aopen_idx(loc_id, idx)
def open_name(hid_t loc_id, char* name):
""" (INT loc_id, STRING name) => INT attr_id
Open an existing attribute on an object, by name.
"""
- cdef hid_t retval
- retval = H5Aopen_name(loc_id, name)
- if retval < 0:
- raise H5AttributeError("Failed to open attribute '%s' on object %d" % (name, loc_id))
- return retval
+ return H5Aopen_name(loc_id, name)
-def close(hid_t attr_id):
+def close(hid_t attr_id, int force=0):
""" (INT attr_id)
"""
- cdef hid_t retval
- retval = H5Aclose(attr_id)
- if retval < 0:
- raise H5AttributeError("Failed to close attribute %d" % attr_id)
-
+ cdef err_c cookie
+ if force:
+ cookie = pause_errors()
+ H5Aclose(attr_id)
+ resume_errors(cookie)
+ else:
+ H5Aclose(attr_id)
def delete(hid_t loc_id, char* name):
""" (INT loc_id, STRING name)
Remove an attribute from an object.
"""
- cdef herr_t retval
- retval = H5Adelete(loc_id, name)
- if retval < 0:
- raise H5AttributeError("Failed delete attribute '%s' on object %d" % (name, loc_id))
-
+ H5Adelete(loc_id, name)
# === Attribute I/O ===========================================================
@@ -107,6 +94,7 @@ def read(hid_t attr_id, ndarray arr_obj):
cdef hid_t space_id
cdef herr_t retval
cdef int array_ok
+ cdef err_c cookie
mtype_id = 0
space_id = 0
@@ -117,14 +105,13 @@ def read(hid_t attr_id, ndarray arr_obj):
if array_ok <= 0:
raise ValueError("Numpy array is not set up correctly.")
- retval = H5Aread(attr_id, mtype_id, PyArray_DATA(arr_obj))
- if retval < 0:
- raise H5AttributeError("Error reading from attribute %d" % attr_id)
+ H5Aread(attr_id, mtype_id, PyArray_DATA(arr_obj))
+
finally:
- if mtype_id != 0:
- H5Tclose(mtype_id)
- if space_id != 0:
- H5Sclose(space_id)
+ cookie = pause_errors()
+ H5Tclose(mtype_id)
+ H5Sclose(space_id)
+ resume_errors(cookie)
def write(hid_t attr_id, ndarray arr_obj):
""" (INT attr_id, NDARRAY arr_obj)
@@ -141,6 +128,7 @@ def write(hid_t attr_id, ndarray arr_obj):
cdef hid_t space_id
cdef herr_t retval
cdef int array_ok
+ cdef err_c cookie
mtype_id = 0
space_id = 0
@@ -151,14 +139,13 @@ def write(hid_t attr_id, ndarray arr_obj):
if array_ok <= 0:
raise ValueError("Given Numpy array is not set up correctly.")
- retval = H5Awrite(attr_id, mtype_id, PyArray_DATA(arr_obj))
- if retval < 0:
- raise H5AttributeError("Error writing to attribute %d" % attr_id)
+ H5Awrite(attr_id, mtype_id, PyArray_DATA(arr_obj))
+
finally:
- if mtype_id != 0:
- H5Tclose(mtype_id)
- if space_id != 0:
- H5Sclose(space_id)
+ cookie = pause_errors()
+ H5Tclose(mtype_id)
+ H5Sclose(space_id)
+ resume_errors(cookie)
# === Attribute inspection ====================================================
@@ -167,11 +154,7 @@ def get_num_attrs(hid_t loc_id):
Determine the number of attributes attached to an HDF5 object.
"""
- cdef int retval
- retval = H5Aget_num_attrs(loc_id)
- if retval < 0:
- raise H5AttributeError("Failed to enumerate attributes of object %d" % loc_id)
- return retval
+ return H5Aget_num_attrs(loc_id)
def get_name(hid_t attr_id):
""" (INT attr_id) => STRING name
@@ -182,14 +165,13 @@ def get_name(hid_t attr_id):
cdef char* buf
buf = NULL
- blen = H5Aget_name(attr_id, 0, NULL)
- if blen < 0:
- raise H5AttributeError("Failed to get name of attribute %d" % attr_id)
-
- buf = <char*>malloc(sizeof(char)*blen+1)
- blen = H5Aget_name(attr_id, blen+1, buf)
- strout = buf
- free(buf)
+ try:
+ blen = H5Aget_name(attr_id, 0, NULL)
+ buf = <char*>malloc(sizeof(char)*blen+1)
+ blen = H5Aget_name(attr_id, blen+1, buf)
+ strout = buf
+ finally:
+ free(buf)
return strout
@@ -198,22 +180,14 @@ def get_space(hid_t attr_id):
Create and return a copy of the attribute's dataspace.
"""
- cdef hid_t retval
- retval = H5Aget_space(attr_id)
- if retval < 0:
- raise H5AttributeError("Failed to retrieve dataspace of attribute %d" % attr_id)
- return retval
+ return H5Aget_space(attr_id)
def get_type(hid_t attr_id):
""" (INT attr_id) => INT type_id
Create and return a copy of the attribute's datatype.
"""
- cdef hid_t retval
- retval = H5Aget_type(attr_id)
- if retval < 0:
- raise H5AttributeError("Failed to retrieve datatype of attribute %d" % attr_id)
- return retval
+ return H5Aget_type(attr_id)
cdef herr_t iter_cb(hid_t loc_id, char *attr_name, object int_tpl):
@@ -260,7 +234,6 @@ def iterate(hid_t loc_id, object func, object data=None, unsigned int startidx=0
if retval < 0:
if len(int_tpl[2]) != 0:
raise int_tpl[2][0]
- raise H5AttributeError("Error occured during iteration")
# === Python extensions =======================================================
@@ -287,6 +260,7 @@ def py_create(hid_t loc_id, char* name, object dtype_in, object shape):
cdef hid_t sid
cdef hid_t type_id
cdef hid_t aid
+ cdef err_c cookie
sid = 0
type_id = 0
@@ -296,11 +270,12 @@ def py_create(hid_t loc_id, char* name, object dtype_in, object shape):
aid = create(loc_id, name, type_id, sid)
finally:
+ cookie = pause_errors()
if sid:
- h5s.close(sid)
+ H5Sclose(sid)
if type_id:
H5Tclose(type_id)
-
+ resume_errors(cookie)
return aid
def py_shape(hid_t attr_id):
@@ -309,14 +284,17 @@ def py_shape(hid_t attr_id):
Retrieve the dataspace of this attribute, as a Numpy-style shape tuple.
"""
cdef hid_t sid
+ cdef err_c cookie
sid = 0
try:
- sid = get_space(attr_id)
+ sid = H5Sget_space(attr_id)
tpl = h5s.get_simple_extent_dims(sid)
finally:
+ cookie = pause_errors()
if sid:
- h5s.close(sid)
+ H5Sclose(sid)
+ resume_errors(cookie)
return tpl
def py_dtype(hid_t attr_id):
@@ -383,8 +361,14 @@ def py_exists(hid_t parent_id, char* name):
py_set().
"""
cdef hid_t attr_id
- response = None
+ cdef err_c cookie
+ attr_id = 0
+
+
+ cookie = pause_errors()
attr_id = H5Aopen_name(parent_id, name)
+ resume_errors(cookie)
+
if attr_id < 0:
response = False
else:
diff --git a/h5py/h5d.pxd b/h5py/h5d.pxd
index a19f91f..40fef57 100644
--- a/h5py/h5d.pxd
+++ b/h5py/h5d.pxd
@@ -15,7 +15,7 @@
# directory.
from defs_c cimport size_t, time_t
-from h5 cimport hid_t, hbool_t, herr_t, htri_t, hsize_t, hssize_t, hvl_t, haddr_t
+from h5 cimport hid_t, hbool_t, herr_t, htri_t, hsize_t, hssize_t, hvl_t, haddr_t, HADDR_UNDEF
cdef extern from "hdf5.h":
@@ -54,34 +54,34 @@ cdef extern from "hdf5.h":
# --- Dataset operations ----------------------------------------------------
- hid_t H5Dcreate(hid_t loc, char* name, hid_t type_id, hid_t space_id, hid_t create_plist_id)
- hid_t H5Dopen(hid_t file_id, char *name)
- herr_t H5Dclose(hid_t dset_id)
-
- hid_t H5Dget_space(hid_t dset_id)
- herr_t H5Dget_space_status(hid_t dset_id, H5D_space_status_t *status)
- hid_t H5Dget_type(hid_t dset_id)
- hid_t H5Dget_create_plist(hid_t dataset_id)
+ hid_t H5Dcreate(hid_t loc, char* name, hid_t type_id, hid_t space_id, hid_t create_plist_id) except *
+ hid_t H5Dopen(hid_t file_id, char *name) except *
+ herr_t H5Dclose(hid_t dset_id) except *
+
+ hid_t H5Dget_space(hid_t dset_id) except *
+ herr_t H5Dget_space_status(hid_t dset_id, H5D_space_status_t *status) except *
+ hid_t H5Dget_type(hid_t dset_id) except *
+ hid_t H5Dget_create_plist(hid_t dataset_id) except *
- haddr_t H5Dget_offset(hid_t dset_id)
- hsize_t H5Dget_storage_size(hid_t dset_id)
+ haddr_t H5Dget_offset(hid_t dset_id) except *
+ hsize_t H5Dget_storage_size(hid_t dset_id) except? 0
herr_t H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
- hid_t file_space_id, hid_t plist_id, void *buf)
+ hid_t file_space_id, hid_t plist_id, void *buf) except *
herr_t H5Dwrite(hid_t dset_id, hid_t mem_type, hid_t mem_space, hid_t
- file_space, hid_t xfer_plist, void* buf)
+ file_space, hid_t xfer_plist, void* buf) except *
- herr_t H5Dextend(hid_t dataset_id, hsize_t *size)
+ herr_t H5Dextend(hid_t dataset_id, hsize_t *size) except *
# These are not for the external API
herr_t H5Dfill(void *fill, hid_t fill_type_id, void *buf,
- hid_t buf_type_id, hid_t space_id )
- herr_t H5Dvlen_get_buf_size(hid_t dset_id, hid_t type_id, hid_t space_id, hsize_t *size)
- herr_t H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist, void *buf)
+ hid_t buf_type_id, hid_t space_id ) except *
+ herr_t H5Dvlen_get_buf_size(hid_t dset_id, hid_t type_id, hid_t space_id, hsize_t *size) except *
+ herr_t H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist, void *buf) except *
ctypedef herr_t (*H5D_operator_t)(void *elem, hid_t type_id, unsigned ndim,
hsize_t *point, void *operator_data)
herr_t H5Diterate(void *buf, hid_t type_id, hid_t space_id,
- H5D_operator_t operator, void* operator_data)
+ H5D_operator_t operator, void* operator_data) except *
diff --git a/h5py/h5e.pxd b/h5py/h5e.pxd
index 6d802ea..954ff68 100644
--- a/h5py/h5e.pxd
+++ b/h5py/h5e.pxd
@@ -16,6 +16,7 @@
from defs_c cimport size_t, time_t
from h5 cimport hid_t, hbool_t, herr_t, htri_t, hsize_t, hssize_t, hvl_t
+from python cimport BaseException, PyErr_SetNone
cdef extern from "hdf5.h":
@@ -52,17 +53,140 @@ cdef extern from "hdf5.h":
ctypedef enum H5E_minor_t:
H5E_NONE_MINOR = 0
+ # Argument errors
+ H5E_UNINITIALIZED, # information is unitialized
+ H5E_UNSUPPORTED, # feature is unsupported: NotImplementedError
+ H5E_BADTYPE, # incorrect type found TypeError
+ H5E_BADRANGE, # argument out of range ValueError
+ H5E_BADVALUE, # bad value for argument ValueError
+
+ # Resource errors
+ H5E_NOSPACE, # no space available for allocation
+ H5E_CANTCOPY, # unable to copy object
+ H5E_CANTFREE, # unable to free object
+ H5E_ALREADYEXISTS, # Object already exists
+ H5E_CANTLOCK, # Unable to lock object
+ H5E_CANTUNLOCK, # Unable to unlock object
+ H5E_CANTGC, # Unable to garbage collect
+ H5E_CANTGETSIZE, # Unable to compute size
+
+ # File accessability errors
+ H5E_FILEEXISTS, # file already exists
+ H5E_FILEOPEN, # file already open
+ H5E_CANTCREATE, # Can't create file
+ H5E_CANTOPENFILE, # Can't open file
+ H5E_CANTCLOSEFILE, # Can't close file
+ H5E_NOTHDF5, # not an HDF5 format file
+ H5E_BADFILE, # bad file ID accessed
+ H5E_TRUNCATED, # file has been truncated
+ H5E_MOUNT, # file mount error
+
+ # Generic low-level file I/O errors All IOError
+ H5E_SEEKERROR, # seek failed
+ H5E_READERROR, # read failed
+ H5E_WRITEERROR, # write failed
+ H5E_CLOSEERROR, # close failed
+ H5E_OVERFLOW, # address overflowed
+ H5E_FCNTL, # file fcntl failed
+
+ # Function entry/exit interface errors
+ H5E_CANTINIT, # Can't initialize object
+ H5E_ALREADYINIT, # object already initialized
+ H5E_CANTRELEASE, # Can't release object
+
+ # Object atom related errors
+ H5E_BADATOM, # Can't find atom information
+ H5E_BADGROUP, # Can't find group information
+ H5E_CANTREGISTER, # Can't register new atom
+ H5E_CANTINC, # Can't increment reference count
+ H5E_CANTDEC, # Can't decrement reference count
+ H5E_NOIDS, # Out of IDs for group
+
+ # Cache related errors
+ H5E_CANTFLUSH, # Can't flush object from cache
+ H5E_CANTSERIALIZE, # Unable to serialize data from cache
+ H5E_CANTLOAD, # Can't load object into cache
+ H5E_PROTECT, # protected object error
+ H5E_NOTCACHED, # object not currently cached
+ H5E_SYSTEM, # Internal error detected
+ H5E_CANTINS, # Unable to insert metadata into cache
+ H5E_CANTRENAME, # Unable to rename metadata
+ H5E_CANTPROTECT, # Unable to protect metadata
+ H5E_CANTUNPROTECT, # Unable to unprotect metadata
+
+ # B-tree related errors
+ H5E_NOTFOUND, # object not found
+ H5E_EXISTS, # object already exists
+ H5E_CANTENCODE, # Can't encode value
+ H5E_CANTDECODE, # Can't decode value
+ H5E_CANTSPLIT, # Can't split node
+ H5E_CANTINSERT, # Can't insert object
+ H5E_CANTLIST, # Can't list node
+
+ # Object header related errors
+ H5E_LINKCOUNT, # bad object header link count
+ H5E_VERSION, # wrong version number
+ H5E_ALIGNMENT, # alignment error
+ H5E_BADMESG, # unrecognized message
+ H5E_CANTDELETE, # Can't delete message
+ H5E_BADITER, # Iteration failed
+
+ # Group related errors
+ H5E_CANTOPENOBJ, # Can't open object
+ H5E_CANTCLOSEOBJ, # Can't close object
+ H5E_COMPLEN, # name component is too long
+ H5E_LINK, # link count failure
+ H5E_SLINK, # symbolic link error
+ H5E_PATH, # Problem with path to object
+
+ # Datatype conversion errors
+ H5E_CANTCONVERT, # Can't convert datatypes TypeError?
+ H5E_BADSIZE, # Bad size for object
+
+ # Dataspace errors
+ H5E_CANTCLIP, # Can't clip hyperslab region
+ H5E_CANTCOUNT, # Can't count elements
+ H5E_CANTSELECT, # Can't select hyperslab
+ H5E_CANTNEXT, # Can't move to next iterator location
+ H5E_BADSELECT, # Invalid selection
+ H5E_CANTCOMPARE, # Can't compare objects
+
+ # Property list errors
+ H5E_CANTGET, # Can't get value
+ H5E_CANTSET, # Can't set value
+ H5E_DUPCLASS, # Duplicate class name in parent class
+
+ # Parallel errors
+ H5E_MPI, # some MPI function failed
+ H5E_MPIERRSTR, # MPI Error String
+
+ # Heap errors
+ H5E_CANTRESTORE, # Can't restore condition
+
+ # TBBT errors
+ H5E_CANTMAKETREE, # Can't create TBBT tree
+
+ # I/O pipeline errors
+ H5E_NOFILTER, # requested filter is not available
+ H5E_CALLBACK, # callback failed
+ H5E_CANAPPLY, # error from filter "can apply" callback
+ H5E_SETLOCAL, # error from filter "set local" callback
+ H5E_NOENCODER, # Filter present, but encoding disabled
+
+ # System level errors
+ H5E_SYSERRSTR # System error message
+
cdef enum H5E_direction_t:
- H5E_WALK_UPWARD = 0 #/*begin deep, end at API function */
- H5E_WALK_DOWNWARD = 1 #/*begin at API function, end deep */
+ H5E_WALK_UPWARD = 0 # begin deep, end at API function
+ H5E_WALK_DOWNWARD = 1 # begin at API function, end deep
ctypedef struct H5E_error_t:
- H5E_major_t maj_num # /*major error number */
- H5E_minor_t min_num # /*minor error number */
- char *func_name # /*function in which error occurred */
- char *file_name # /*file in which error occurred */
- unsigned line # /*line in file where error occurs */
- char *desc # /*optional supplied description */
+ H5E_major_t maj_num # major error number
+ H5E_minor_t min_num # minor error number
+ char *func_name # function in which error occurred
+ char *file_name # file in which error occurred
+ unsigned line # line in file where error occurs
+ char *desc # optional supplied description
# --- Error handling --------------------------------------------------------
@@ -70,7 +194,22 @@ cdef extern from "hdf5.h":
char *H5Eget_major(H5E_major_t n)
ctypedef herr_t (*H5E_auto_t)(void *client_data)
herr_t H5Eset_auto(H5E_auto_t func, void *client_data )
-
+ herr_t H5Eget_auto(H5E_auto_t *func, void** client_data)
ctypedef herr_t (*H5E_walk_t)(int n, H5E_error_t *err_desc, void* client_data)
herr_t H5Ewalk(H5E_direction_t direction, H5E_walk_t func, void* client_data )
+# Custom error-handling functions
+cdef public:
+ ctypedef H5E_auto_t err_c
+ cdef err_c pause_errors() except NULL
+ cdef int resume_errors(err_c cookie) except -1
+
+
+
+
+
+
+
+
+
+
diff --git a/h5py/h5e.pyx b/h5py/h5e.pyx
index bab4a09..499d12e 100644
--- a/h5py/h5e.pyx
+++ b/h5py/h5e.pyx
@@ -1,33 +1,63 @@
-from h5 cimport herr_t, htri_t
+#+
+#
+# This file is part of h5py, a low-level Python interface to the HDF5 library.
+#
+# Copyright (C) 2008 Andrew Collette
+# http://h5py.alfven.org
+# License: BSD (See LICENSE.txt for full license)
+#
+# $Date$
+#
+#-
+
+from python cimport PyExc_Exception, PyErr_SetString
+
+# === Public exception hierarchy ==============================================
+
+class H5Error(StandardError):
+ """ Base class for internal HDF5 library exceptions
+ """
+ pass
+class ConversionError(StandardError):
+ """ Indicates error on Python side of dtype transformation.
+ """
+ pass
-cdef extern from "Python.h":
+class FileError(H5Error):
+ """ HDF5 file I/0 error
+ """
+ pass
- ctypedef extern class __builtin__.BaseException [object PyBaseExceptionObject]:
- cdef object dict
- cdef object args
- cdef object message
+class GroupError(H5Error):
+ pass
-cdef extern from "Python.h":
- void PyErr_SetString(object type_, object msg)
- void PyErr_SetNone(object type_)
+class DataspaceError(H5Error):
+ pass
-# === Base exception hierarchy ================================================
+class DatatypeError(H5Error):
+ pass
-cdef class H5Error(BaseException):
- """
- Base class for all HDF5 exceptions.
- """
+class DatasetError(H5Error):
pass
+class PropertyError(H5Error):
+ pass
-cdef class ConversionError(H5Error):
- """
- Represents a Python-side error performing data conversion between
- Numpy arrays or dtypes and their HDF5 equivalents.
- """
+class H5AttributeError(H5Error):
pass
+class FilterError(H5Error):
+ pass
+
+class IdentifierError(H5Error):
+ pass
+
+class H5ReferenceError(H5Error):
+ pass
+
+
+# === Error stack inspection ==================================================
cdef class H5ErrorStackElement:
"""
@@ -41,7 +71,6 @@ cdef class H5ErrorStackElement:
cdef readonly unsigned int line
cdef readonly object desc
-
cdef herr_t walk_cb(int n, H5E_error_t *err_desc, void* stack_in):
# Callback function to extract elements from the HDF5 error stack
@@ -59,119 +88,125 @@ cdef herr_t walk_cb(int n, H5E_error_t *err_desc, void* stack_in):
return 0
-cdef class LibraryError(H5Error):
- """
- Base class for exceptions which include an HDF5 library traceback.
- Upon instantiation, takes a snapshot of the HDF5 error stack and
- stores it internally.
- """
- cdef readonly object hdf5_stack
-
- def __init__(self, *args):
- cdef int i
- cdef int stacklen
-
- H5Error.__init__(self)
- stack = []
- H5Ewalk(H5E_WALK_DOWNWARD, walk_cb, <void*>stack)
- self.hdf5_stack = stack
-
- # Stringify the stack
- stacklen = len(stack)
- if stacklen == 0:
- msg = "Unspecified HDF5 error"
- else:
- msg = "%s (%s)" % (stack[0].desc.capitalize(), stack[0].func_name)
- if stacklen > 1:
- msg = msg + "\nHDF5 Error Stack:\n"
- for i from 0<=i<stacklen:
- el = stack[i]
- msg = msg + ' %d: "%s" at %s' % (i, el.desc.capitalize(), el.func_name)
-
- self.args = (msg,)
-
-# === Public exception classes ================================================
-
-cdef class InternalError(LibraryError):
- """
- Catchall class for major error numbers which don't have their
- own exception class.
- """
- pass
+def get_error_stack():
-cdef class InvalidArgsError(LibraryError):
- pass
-
-cdef class DatatypeError(LibraryError):
- pass
-
-cdef class DataspaceError(LibraryError):
- pass
-
-cdef class DatasetError(LibraryError):
- pass
+ stack = []
+ H5Ewalk(H5E_WALK_UPWARD, walk_cb, <void*>stack)
+ return stack
-cdef class StorageError(LibraryError):
- pass
-
-cdef class PropertyListError(LibraryError):
- pass
-
-cdef class AttributeError_H5(LibraryError):
- pass
-
-cdef class FilterError_H5(LibraryError):
- pass
+def get_error_string():
+ """ Return the HDF5 error stack as a single string.
+ """
+ cdef int stacklen
+ stack = get_error_stack()
+ stacklen = len(stack)
+ if stacklen == 0:
+ msg = "Unspecified HDF5 error"
+ else:
+ msg = "%s (%s)" % (stack[0].desc.capitalize(), stack[0].func_name)
+ if stacklen > 1:
+ msg = msg + "\nHDF5 Error Stack:\n"
+ for i from 0<=i<stacklen:
+ el = stack[i]
+ msg = msg + ' %d: "%s" at %s\n' % (i, el.desc.capitalize(), el.func_name)
+
+ return msg
# === Automatic exception API =================================================
-cdef herr_t maj_cb(int n, H5E_error_t *err_desc, void* num_in):
- # Callback to determine the major error number at either the top
- # or bottom of the stack
- cdef H5E_major_t *num
- num = <H5E_major_t*>num_in
- num[0] = err_desc.maj_num
+cdef herr_t extract_cb(int n, H5E_error_t *err_desc, void* data_in):
+ # Callback to determine error information at top/bottom of stack
+ cdef H5E_error_t *err_struct
+ err_struct = <H5E_error_t*>data_in
+ err_struct.maj_num = err_desc.maj_num
+ err_struct.min_num = err_desc.min_num
return 1
cdef herr_t err_callback(void* client_data):
- # Callback which does nothing but set a Python exception
+ # Callback which sets Python exception based on the current error stack.
+
# Can't use the standard Pyrex raise because then the traceback
# points here!
- cdef H5E_major_t num
-
- # Determine the major error number for the first entry on the stack.
- H5Ewalk(H5E_WALK_DOWNWARD, maj_cb, &num)
-
- exc = InternalError
- if num == H5E_ARGS:
- exc = InvalidArgsError
- elif num == H5E_DATATYPE:
+ cdef H5E_error_t err_struct
+ cdef H5E_major_t mj
+ cdef H5E_minor_t mn
+
+ # Determine the error numbers for the first entry on the stack.
+ H5Ewalk(H5E_WALK_UPWARD, extract_cb, &err_struct)
+ mj = err_struct.maj_num
+ mn = err_struct.min_num
+
+ # Most common minor errors
+ if mn == H5E_UNSUPPORTED:
+ exc = NotImplementedError
+ elif mn == H5E_BADTYPE:
+ exc = TypeError
+ elif mn == H5E_BADRANGE or mn == H5E_BADVALUE:
+ exc = ValueError
+
+ # Major errors which map to native Python exceptions
+ elif mj == H5E_IO:
+ exc = IOError
+
+ # Major errors which map to new h5e exception classes
+ elif mj == H5E_FILE:
+ exc = FileError
+ elif mj == H5E_DATATYPE:
exc = DatatypeError
- elif num == H5E_DATASPACE:
+ elif mj == H5E_DATASPACE:
exc = DataspaceError
- elif num == H5E_DATASET:
+ elif mj == H5E_DATASET:
exc = DatasetError
- elif num == H5E_STORAGE:
- exc = StorageError
- elif num == H5E_PLIST:
+ elif mj == H5E_PLIST:
exc = PropertyListError
- elif num == H5E_ATTR:
- exc = AttributeError_H5
- elif num == H5E_PLINE:
- exc = FilterError_H5
+ elif mj == H5E_ATTR:
+ exc = H5AttributeError
+ elif mj == H5E_PLINE:
+ exc = FilterError
+ elif mj == H5E_REFERENCE:
+ exc = H5ReferenceError
- PyErr_SetNone(exc)
+ # Catchall: base H5Error
+ else:
+ exc = H5Error
-def enable_exceptions():
+ msg = get_error_string()
+ PyErr_SetString(exc, msg)
+
+
+def _enable_exceptions():
if H5Eset_auto(err_callback, NULL) < 0:
raise RuntimeError("Failed to register HDF5 exception callback.")
-def disable_exceptions():
+def _disable_exceptions():
if H5Eset_auto(NULL, NULL) < 0:
raise RuntimeError("Failed to unregister HDF5 exception callback.")
+cdef err_c pause_errors() except NULL:
+ cdef err_c cookie
+ cdef void* whatever
+ cdef herr_t retval
+ cookie = NULL
+
+ retval = H5Eget_auto(&cookie, &whatever)
+ if retval < 0:
+ raise RuntimeError("Failed to retrieve the current error handler.")
+
+ retval = H5Eset_auto(NULL, NULL)
+ if retval < 0:
+ raise RuntimeError("Failed to temporarily disable error handling.")
+
+ return cookie
+
+cdef int resume_errors(err_c cookie) except -1:
+ cdef herr_t retval
+ retval = H5Eset_auto(cookie, NULL)
+ if retval < 0:
+ raise RuntimeError()
+ return 0
+
# --- temporary test functions ---
cdef extern from "hdf5.h":
@@ -185,6 +220,11 @@ def test_error():
def test_2():
H5Tclose(H5T_STD_I8LE)
+cdef void ctest3() except *:
+ PyErr_SetString(Foobar, "foo")
+
+def test_3():
+ ctest3()
diff --git a/h5py/python.pxd b/h5py/python.pxd
index 3515e10..dd7e920 100644
--- a/h5py/python.pxd
+++ b/h5py/python.pxd
@@ -64,6 +64,18 @@ cdef extern from "Python.h":
int PyObject_Compare(object o1, object o2)
int PyObject_AsReadBuffer(object obj, void **buffer, Py_ssize_t *buffer_len)
+ # Exception handling (manual)
+ ctypedef extern class __builtin__.BaseException [object PyBaseExceptionObject]:
+ cdef object dict
+ cdef object args
+ cdef object message
+
+ void* PyExc_Exception # Not allowed to declare objects "extern C" (why not?)
+ void PyErr_SetString(object type_, char* msg)
+ void PyErr_SetNone(object type_)
+
+ object PyErr_NewException(char* name, object base, object dict_)
+
diff --git a/h5py/utils_low.h b/h5py/utils_low.h
index 5f58027..6ace59f 100644
--- a/h5py/utils_low.h
+++ b/h5py/utils_low.h
@@ -16,6 +16,9 @@
distribution root directory.
*/
+#ifndef H5PY_UTILS_LOW
+#define H5PY_UTILS_LOW
+
#include "Python.h"
#include "hdf5.h"
#include "numpy/arrayobject.h"
@@ -30,3 +33,5 @@ PyObject* dims_to_tuple(hsize_t* dims, hsize_t rank);
int check_numpy_read(PyArrayObject* arr, hid_t space_id);
int check_numpy_write(PyArrayObject* arr, hid_t space_id);
+#endif
+
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/h5py.git
More information about the debian-science-commits
mailing list