[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