[h5py] 41/455: Revised error API based on HDF5 error stack
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 d1b69a3125d303e55b322a66cb95fb5e2919d45e
Author: andrewcollette <andrew.collette at gmail.com>
Date: Fri Jun 6 06:18:28 2008 +0000
Revised error API based on HDF5 error stack
---
h5py/h5.pyx | 5 +--
h5py/h5e.pxd | 37 +++++++++++---------
h5py/h5e.pyx | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++---------
3 files changed, 119 insertions(+), 35 deletions(-)
diff --git a/h5py/h5.pyx b/h5py/h5.pyx
index 6e0a618..5a04c4f 100644
--- a/h5py/h5.pyx
+++ b/h5py/h5.pyx
@@ -73,8 +73,9 @@ class DDict(dict):
# === Error functions =========================================================
-cdef herr_t walk_cb(int n, H5E_error_t *err_desc, elist):
+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"
@@ -92,7 +93,7 @@ def get_error_string():
"""
elist = []
- H5Ewalk(H5E_WALK_DOWNWARD, walk_cb, elist)
+ H5Ewalk(H5E_WALK_DOWNWARD, walk_cb, <void*>elist)
if len(elist) == 0:
return ""
diff --git a/h5py/h5e.pxd b/h5py/h5e.pxd
index 47f9d4b..6d802ea 100644
--- a/h5py/h5e.pxd
+++ b/h5py/h5e.pxd
@@ -19,21 +19,6 @@ from h5 cimport hid_t, hbool_t, herr_t, htri_t, hsize_t, hssize_t, hvl_t
cdef extern from "hdf5.h":
- 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 */
-
- ctypedef struct H5E_error_t:
- int maj_num # /*major error number */
- int 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 --------------------------------------------------------
-
-
ctypedef enum H5E_major_t:
H5E_NONE_MAJOR = 0,
H5E_ARGS,
@@ -64,10 +49,28 @@ cdef extern from "hdf5.h":
H5E_ERROR,
H5E_SLIST
+ ctypedef enum H5E_minor_t:
+ H5E_NONE_MINOR = 0
+
+ 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 */
+
+ 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 */
+
+ # --- Error handling --------------------------------------------------------
+
+
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 )
- ctypedef herr_t (*H5E_walk_t)(int n, H5E_error_t *err_desc, client_data)
- herr_t H5Ewalk(H5E_direction_t direction, H5E_walk_t func, 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 )
diff --git a/h5py/h5e.pyx b/h5py/h5e.pyx
index cf78352..bab4a09 100644
--- a/h5py/h5e.pyx
+++ b/h5py/h5e.pyx
@@ -8,6 +8,11 @@ cdef extern from "Python.h":
cdef object args
cdef object message
+cdef extern from "Python.h":
+ void PyErr_SetString(object type_, object msg)
+ void PyErr_SetNone(object type_)
+
+# === Base exception hierarchy ================================================
cdef class H5Error(BaseException):
"""
@@ -24,7 +29,7 @@ cdef class ConversionError(H5Error):
pass
-cdef class ErrorStackElement:
+cdef class H5ErrorStackElement:
"""
Represents an entry in the HDF5 error stack.
Loosely modeled on the H5E_error_t struct.
@@ -37,12 +42,13 @@ cdef class ErrorStackElement:
cdef readonly object desc
-cdef herr_t walk_cb(int n, H5E_error_t *err_desc, stack):
+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
- cdef ErrorStackElement element
+ stack = <object>stack_in
+ cdef H5ErrorStackElement element
- element = ErrorStackElement()
+ element = H5ErrorStackElement()
element.maj_num = err_desc.maj_num
element.min_num = err_desc.min_num
element.func_name = err_desc.func_name
@@ -53,7 +59,7 @@ cdef herr_t walk_cb(int n, H5E_error_t *err_desc, stack):
return 0
-cdef class H5LibraryError(H5Error):
+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
@@ -63,32 +69,100 @@ cdef class H5LibraryError(H5Error):
def __init__(self, *args):
cdef int i
+ cdef int stacklen
H5Error.__init__(self)
stack = []
- H5Ewalk(H5E_WALK_DOWNWARD, walk_cb, stack)
+ H5Ewalk(H5E_WALK_DOWNWARD, walk_cb, <void*>stack)
self.hdf5_stack = stack
# Stringify the stack
- if len(stack) == 0:
+ stacklen = len(stack)
+ if stacklen == 0:
msg = "Unspecified HDF5 error"
else:
- msg = stack[0].desc.capitalize() + "\nHDF5 Error Stack:\n"
- for i from 0<=i<len(stack):
- el = stack[i]
- msg = msg + ' %d: "%s" at %s' % (i, el.desc.capitalize(), el.func_name)
+ 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,)
-cdef extern from "Python.h":
- void PyErr_SetString(object type_, object msg)
- void PyErr_SetNone(object type_)
+# === Public exception classes ================================================
+
+cdef class InternalError(LibraryError):
+ """
+ Catchall class for major error numbers which don't have their
+ own exception class.
+ """
+ pass
+
+cdef class InvalidArgsError(LibraryError):
+ pass
+
+cdef class DatatypeError(LibraryError):
+ pass
+
+cdef class DataspaceError(LibraryError):
+ pass
+
+cdef class DatasetError(LibraryError):
+ pass
+
+cdef class StorageError(LibraryError):
+ pass
+
+cdef class PropertyListError(LibraryError):
+ pass
+
+cdef class AttributeError_H5(LibraryError):
+ pass
+
+cdef class FilterError_H5(LibraryError):
+ pass
+
+# === 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
+ return 1
+
cdef herr_t err_callback(void* client_data):
# Callback which does nothing but set a Python exception
# Can't use the standard Pyrex raise because then the traceback
# points here!
- PyErr_SetNone(H5LibraryError)
+
+ 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:
+ exc = DatatypeError
+ elif num == H5E_DATASPACE:
+ exc = DataspaceError
+ elif num == H5E_DATASET:
+ exc = DatasetError
+ elif num == H5E_STORAGE:
+ exc = StorageError
+ elif num == H5E_PLIST:
+ exc = PropertyListError
+ elif num == H5E_ATTR:
+ exc = AttributeError_H5
+ elif num == H5E_PLINE:
+ exc = FilterError_H5
+
+ PyErr_SetNone(exc)
def enable_exceptions():
if H5Eset_auto(err_callback, NULL) < 0:
@@ -98,12 +172,18 @@ def disable_exceptions():
if H5Eset_auto(NULL, NULL) < 0:
raise RuntimeError("Failed to unregister HDF5 exception callback.")
+# --- temporary test functions ---
+
cdef extern from "hdf5.h":
- htri_t H5Pexist( hid_t id, char *name) except? -1
+ htri_t H5Pexist( hid_t id, char *name) except *
+ herr_t H5Tclose(hid_t type_id ) except *
+ hid_t H5T_STD_I8LE
def test_error():
H5Pexist(-1, "foobar")
+def test_2():
+ H5Tclose(H5T_STD_I8LE)
--
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