[h5py] 43/455: More changes to exceptions 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 ab46e9b27399510bebe00207e77aa8bdb8ee7045
Author: andrewcollette <andrew.collette at gmail.com>
Date:   Sat Jun 7 04:42:21 2008 +0000

    More changes to exceptions API
---
 h5py/h5.pxd            |  9 +++----
 h5py/h5.pyx            | 22 +++++++----------
 h5py/h5a.pxd           |  2 +-
 h5py/h5a.pyx           |  9 ++++---
 h5py/h5e.pxd           | 23 +++++++++++-------
 h5py/h5e.pyx           | 66 ++++++++++++++++++++++++++++++++------------------
 h5py/h5t.pyx           |  2 --
 h5py/tests/__init__.py |  6 ++---
 h5py/tests/test_h5a.py | 43 +++++++++++++++-----------------
 h5py/utils_low.h       |  1 +
 10 files changed, 100 insertions(+), 83 deletions(-)

diff --git a/h5py/h5.pxd b/h5py/h5.pxd
index ce5bbf3..e11655f 100644
--- a/h5py/h5.pxd
+++ b/h5py/h5.pxd
@@ -35,15 +35,12 @@ cdef extern from "hdf5.h":
 
   int HADDR_UNDEF
 
-  herr_t H5open()
-  herr_t H5close()
+  herr_t H5open() except *
+  herr_t H5close() except *
 
   # --- Version functions -----------------------------------------------------
   herr_t H5get_libversion(unsigned *majnum, unsigned *minnum,
-                          unsigned *relnum )
-  herr_t H5check_version(unsigned majnum, unsigned minnum,
-                         unsigned relnum )
-  herr_t H5garbage_collect()
+                          unsigned *relnum ) except *
 
 
 
diff --git a/h5py/h5.pyx b/h5py/h5.pyx
index b8da8ed..e71ef8d 100644
--- a/h5py/h5.pyx
+++ b/h5py/h5.pyx
@@ -22,20 +22,18 @@
     - HDF5_VERS, HDF5_VERS_TPL:  Library version
     - API_VERS, API_VERS_TPL:  API version (1.6 or 1.8) used to compile
 """
-from h5t cimport H5Tset_overflow
-from errors import H5LibraryError
 
-import h5e
+from h5e cimport _enable_exceptions
 
 # === Library init ============================================================
 
-_hdf5_imported = False
-def import_hdf5():
-    global _hdf5_imported
-    if not _hdf5_imported:
-        H5open()
-        h5e._enable_exceptions()
-        _hdf5_imported = False
+cdef int import_hdf5() except -1:
+    if H5open() < 0:
+        raise RuntimeError("Failed to initialize the HDF5 library.")
+    _enable_exceptions()
+    return 0
+
+import_hdf5()
 
 # === API =====================================================================
 
@@ -49,9 +47,7 @@ def get_libversion():
     cdef unsigned int release
     cdef herr_t retval
     
-    retval = H5get_libversion(&major, &minor, &release)
-    if retval < 0:
-        raise H5LibraryError("Error determining HDF5 library version.")
+    H5get_libversion(&major, &minor, &release)
 
     return (major, minor, release)
     
diff --git a/h5py/h5a.pxd b/h5py/h5a.pxd
index 58057db..5aba0ec 100644
--- a/h5py/h5a.pxd
+++ b/h5py/h5a.pxd
@@ -30,7 +30,7 @@ cdef extern from "hdf5.h":
   herr_t    H5Awrite(hid_t attr_id, hid_t mem_type_id, void *buf  ) except *
 
   int       H5Aget_num_attrs(hid_t loc_id) except *
-  ssize_t    H5Aget_name(hid_t attr_id, size_t buf_size, char *buf) 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 *
 
diff --git a/h5py/h5a.pyx b/h5py/h5a.pyx
index 4b4f8f6..e31237c 100644
--- a/h5py/h5a.pyx
+++ b/h5py/h5a.pyx
@@ -32,7 +32,6 @@ import h5t
 import h5s
 from errors import H5AttributeError
 
-h5.import_hdf5()
 import_array()
 
 # === General attribute operations ============================================
@@ -61,7 +60,11 @@ def open_name(hid_t loc_id, char* name):
     return H5Aopen_name(loc_id, name)
 
 def close(hid_t attr_id, int force=0):
-    """ (INT attr_id)
+    """ (INT attr_id, BOOL force=0)
+
+        Close this attribute and release resources.  If "force" is True,
+        ignore any errors encountered when closing (e.g. when calling in
+        a finally clause or destructor).
     """
     cdef err_c cookie
     if force:
@@ -288,7 +291,7 @@ def py_shape(hid_t attr_id):
     sid = 0
     
     try:
-        sid = H5Sget_space(attr_id)
+        sid = H5Aget_space(attr_id)
         tpl = h5s.get_simple_extent_dims(sid)
     finally:
         cookie = pause_errors()
diff --git a/h5py/h5e.pxd b/h5py/h5e.pxd
index 954ff68..3d265f6 100644
--- a/h5py/h5e.pxd
+++ b/h5py/h5e.pxd
@@ -55,10 +55,10 @@ cdef extern from "hdf5.h":
 
     #  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
+    H5E_UNSUPPORTED,            # feature is unsupported
+    H5E_BADTYPE,                # incorrect type found
+    H5E_BADRANGE,               # argument out of range
+    H5E_BADVALUE,               # bad value for argument
 
     #  Resource errors 
     H5E_NOSPACE,                # no space available for allocation
@@ -81,7 +81,7 @@ cdef extern from "hdf5.h":
     H5E_TRUNCATED,              # file has been truncated                    
     H5E_MOUNT,			        # file mount error			     
 
-    #  Generic low-level file I/O errors        All IOError
+    #  Generic low-level file I/O errors
     H5E_SEEKERROR,              # seek failed                                
     H5E_READERROR,              # read failed                                
     H5E_WRITEERROR,             # write failed                               
@@ -192,6 +192,8 @@ cdef extern from "hdf5.h":
 
 
   char      *H5Eget_major(H5E_major_t n)
+  char      *H5Eget_minor(H5E_minor_t n)
+  herr_t    H5Eclear()
   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)
@@ -199,10 +201,13 @@ cdef extern from "hdf5.h":
   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
+
+ctypedef H5E_auto_t err_c
+cdef int _enable_exceptions() except -1
+cdef int _disable_exceptions() except -1
+
+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 499d12e..2f12e9a 100644
--- a/h5py/h5e.pyx
+++ b/h5py/h5e.pyx
@@ -71,6 +71,10 @@ cdef class H5ErrorStackElement:
     cdef readonly unsigned int line
     cdef readonly object desc
 
+    def __str__(self):
+        return '%2d:%2d "%s" at %s (%s: %s)' % (self.maj_num, self.min_num,
+                self.desc, self.func_name, H5Eget_major(<H5E_major_t>self.maj_num),
+                H5Eget_minor(<H5E_minor_t>self.min_num) )
 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
 
@@ -91,24 +95,31 @@ cdef herr_t walk_cb(int n, H5E_error_t *err_desc, void* stack_in):
 def get_error_stack():
 
     stack = []
-    H5Ewalk(H5E_WALK_UPWARD, walk_cb, <void*>stack)
+    H5Ewalk(H5E_WALK_DOWNWARD, walk_cb, <void*>stack)
     return stack
 
 def get_error_string():
     """ Return the HDF5 error stack as a single string.
     """
     cdef int stacklen
+    cdef H5ErrorStackElement el
+
     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)
+        el = stack[0]
+        msg = "%s (%s: %s)" % (el.desc.capitalize(), el.func_name, 
+                                H5Eget_major(<H5E_major_t>el.maj_num))
         if stacklen > 1:
-            msg = msg + "\nHDF5 Error Stack:\n"
+            msg = msg + "\nHDF5 Error Stack:"
             for i from 0<=i<stacklen:
-                el = stack[i]
-                msg = msg + '    %d: "%s" at %s\n' % (i, el.desc.capitalize(), el.func_name)
+                msg = msg + '\n' + str(stack[i])
+                #el = stack[i]
+                #msg = msg + '\n    %d: "%s" at %s' % \
+                #            (i, el.desc.capitalize(), el.func_name)
 
     return msg
 
@@ -138,18 +149,19 @@ cdef herr_t err_callback(void* client_data):
     mj = err_struct.maj_num
     mn = err_struct.min_num
 
-    # Most common minor errors
+    # Highest priority: really bad 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
 
+    # Map function argument exceptions to native Python exceptions.
+    # H5E_BADTYPE does not raise TypeError as this is too easily confused
+    # with the results of Pyrex auto-validation.
+    elif mj == H5E_ARGS and (mn == H5E_BADRANGE or mn == H5E_BADVALUE \
+                             or mn == H5E_BADTYPE):
+        exc = ValueError
+
     # Major errors which map to new h5e exception classes
     elif mj == H5E_FILE:
         exc = FileError
@@ -175,36 +187,44 @@ cdef herr_t err_callback(void* client_data):
     msg = get_error_string()
     PyErr_SetString(exc, msg)
 
+    return 1
 
-def _enable_exceptions():
+cdef int _enable_exceptions() except -1:
+    # Enable automatic exception handling, by registering the above callback
     if H5Eset_auto(err_callback, NULL) < 0:
         raise RuntimeError("Failed to register HDF5 exception callback.")
+    return 0
 
-def _disable_exceptions():
+cdef int _disable_exceptions() except -1:
+    # Disable automatic exception handling
     if H5Eset_auto(NULL, NULL) < 0:
         raise RuntimeError("Failed to unregister HDF5 exception callback.")
+    return 0
 
 cdef err_c pause_errors() except NULL:
+    # Temporarily disable automatic exception handling, and return a cookie
+    # which can later be used to re-enable it.
     cdef err_c cookie
     cdef void* whatever
-    cdef herr_t retval
     cookie = NULL
 
-    retval = H5Eget_auto(&cookie, &whatever)
-    if retval < 0:
+    if H5Eget_auto(&cookie, &whatever) < 0:
         raise RuntimeError("Failed to retrieve the current error handler.")
 
-    retval = H5Eset_auto(NULL, NULL)
-    if retval < 0:
+    if H5Eset_auto(NULL, NULL) < 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()
+    # Resume automatic exception handling, using a cookie from a previous
+    # call to pause_errors().  Also clears the error stack.
+    if H5Eset_auto(cookie, NULL) < 0:
+        raise RuntimeError("Failed to re-enable error handling.")
+    
+    if H5Eclear() < 0:
+        raise RuntimeError("Failed to clear error stack.")
+
     return 0
 
 # --- temporary test functions ---
diff --git a/h5py/h5t.pyx b/h5py/h5t.pyx
index 348b842..36c7f96 100644
--- a/h5py/h5t.pyx
+++ b/h5py/h5t.pyx
@@ -69,8 +69,6 @@ from h5 import DDict
 from errors import DatatypeError, ConversionError
 import sys
 
-H5Eset_auto(NULL,NULL)
-
 # === Public constants and data structures ====================================
 
 # Enumeration H5T_class_t
diff --git a/h5py/tests/__init__.py b/h5py/tests/__init__.py
index 7334db0..e741023 100644
--- a/h5py/tests/__init__.py
+++ b/h5py/tests/__init__.py
@@ -22,9 +22,9 @@ import test_h5
 
 from h5py import h5a, h5f, h5g, h5d, h5s, h5i, h5z, h5p, highlevel
 
-TEST_CASES = (test_h5a.TestH5A, test_h5f.TestH5F, test_h5g.TestH5G,
-              test_h5i.TestH5I, test_h5d.TestH5D, test_h5.TestH5,
-              test_h5p.TestH5P)
+TEST_CASES = (test_h5a.TestH5A,)# test_h5f.TestH5F, test_h5g.TestH5G,
+              #test_h5i.TestH5I, test_h5d.TestH5D, test_h5.TestH5,
+              #test_h5p.TestH5P)
 
 def buildsuite(cases):
 
diff --git a/h5py/tests/test_h5a.py b/h5py/tests/test_h5a.py
index 506e481..b1d81eb 100644
--- a/h5py/tests/test_h5a.py
+++ b/h5py/tests/test_h5a.py
@@ -14,12 +14,13 @@ import unittest
 from numpy import array, ndarray, dtype, all, ones
 import os
 
+import h5py
 from h5py import h5a
 from h5py import h5f, h5g, h5i, h5t, h5s
-import h5py
+from h5py.h5e import H5Error
+
 from common import getcopy, deletecopy, errstr
 
-from h5py.errors import DatatypeError, H5AttributeError
 
 HDFNAME = os.path.join(os.path.dirname(h5py.__file__), 'tests/data/attributes.hdf5')
 OBJECTNAME = 'Group'
@@ -63,16 +64,12 @@ class TestH5A(unittest.TestCase):
 
             arr_val = h5a.py_get(obj,name)
             self.assert_(all(arr_val == arr_ref), errstr(arr_val, arr_ref))
-            try:
-                h5t.close(tid)
-            except DatatypeError:
-                pass
             h5s.close(sid)
         h5g.close(obj)
         deletecopy(fid, filename)
         
-        self.assertRaises(H5AttributeError, h5a.create, -1, "FOOBAR", -1, -1)
-        self.assertRaises(H5AttributeError, h5a.write, -1, arr_ref)
+        self.assertRaises(TypeError, h5a.create, -1, "FOOBAR", -1, -1)
+        self.assertRaises(TypeError, h5a.write, -1, arr_ref)
 
     def test_open_idx(self):
         for idx, name in enumerate(ATTRIBUTES_ORDER):
@@ -80,7 +77,7 @@ class TestH5A(unittest.TestCase):
             self.assert_(self.is_attr(aid), "Open: index %d" % idx)
             h5a.close(aid)
     
-        self.assertRaises(H5AttributeError, h5a.open_idx, -1, 0)
+        self.assertRaises(TypeError, h5a.open_idx, -1, 0)
 
     def test_open_name(self):
         for name in ATTRIBUTES:
@@ -88,7 +85,7 @@ class TestH5A(unittest.TestCase):
             self.assert_(self.is_attr(aid), 'Open: name "%s"' % name)
             h5a.close(aid)
 
-        self.assertRaises(H5AttributeError, h5a.open_name, -1, "foo")
+        self.assertRaises(TypeError, h5a.open_name, -1, "foo")
 
     def test_close(self):
         aid = h5a.open_idx(self.obj, 0)
@@ -96,7 +93,7 @@ class TestH5A(unittest.TestCase):
         h5a.close(aid)
         self.assert_(not self.is_attr(aid))
     
-        self.assertRaises(H5AttributeError, h5a.close, -1)
+        self.assertRaises(TypeError, h5a.close, -1)
 
     def test_delete(self):
         fid, filename = getcopy(HDFNAME)
@@ -106,7 +103,7 @@ class TestH5A(unittest.TestCase):
         self.assert_(not h5a.py_exists(obj, ATTRIBUTES_ORDER[0]))
         deletecopy(fid, filename)
 
-        self.assertRaises(H5AttributeError, h5a.delete, -1, "foo")
+        self.assertRaises(TypeError, h5a.delete, -1, "foo")
 
     # === Attribute I/O =======================================================
 
@@ -128,7 +125,7 @@ class TestH5A(unittest.TestCase):
 
             h5a.close(aid)
         
-        self.assertRaises(H5AttributeError, h5a.read, -1, arr_holder)
+        self.assertRaises(TypeError, h5a.read, -1, arr_holder)
 
     # h5a.write is done by test_create_write
 
@@ -137,7 +134,7 @@ class TestH5A(unittest.TestCase):
     def test_get_num_attrs(self):
         n = h5a.get_num_attrs(self.obj)
         self.assertEqual(n, len(ATTRIBUTES))
-        self.assertRaises(H5AttributeError, h5a.get_num_attrs, -1)
+        self.assertRaises(H5Error, h5a.get_num_attrs, -1)
 
     def test_get_name(self):
     
@@ -147,7 +144,7 @@ class TestH5A(unittest.TestCase):
             self.assertEqual(supposed_name, name)
             h5a.close(aid)
 
-        self.assertRaises(H5AttributeError, h5a.get_name, -1)
+        self.assertRaises(TypeError, h5a.get_name, -1)
 
     def test_get_space(self):
 
@@ -159,7 +156,7 @@ class TestH5A(unittest.TestCase):
             h5s.close(sid)
             h5a.close(aid)
 
-        self.assertRaises(H5AttributeError, h5a.get_space, -1)
+        self.assertRaises(TypeError, h5a.get_space, -1)
 
     def test_get_type(self):
 
@@ -171,7 +168,7 @@ class TestH5A(unittest.TestCase):
             h5t.close(tid)
             h5a.close(aid)
 
-        self.assertRaises(H5AttributeError, h5a.get_type, -1)
+        self.assertRaises(TypeError, h5a.get_type, -1)
 
     def test_iterate(self):
 
@@ -204,14 +201,14 @@ class TestH5A(unittest.TestCase):
         h5a.iterate(self.obj, iterate_two, namelist, 1)
         self.assertEqual(namelist, ATTRIBUTES_ORDER[1:3])
 
-        self.assertRaises(H5AttributeError, h5a.iterate, -1, iterate_two, namelist)
+        self.assertRaises(TypeError, h5a.iterate, -1, iterate_two, namelist)
 
 
     # === Python extensions ===================================================
 
     def test_py_listattrs(self):
         self.assertEqual(h5a.py_listattrs(self.obj), ATTRIBUTES_ORDER)
-        self.assertRaises(H5AttributeError, h5a.py_listattrs, -1)
+        self.assertRaises(TypeError, h5a.py_listattrs, -1)
 
     def test_py_shape(self):
         
@@ -220,7 +217,7 @@ class TestH5A(unittest.TestCase):
             retshape = h5a.py_shape(aid)
             self.assertEqual(retshape, shape) 
             h5a.close(aid)
-        self.assertRaises(H5AttributeError, h5a.py_shape, -1)
+        self.assertRaises(TypeError, h5a.py_shape, -1)
 
     def test_py_dtype(self):
 
@@ -228,7 +225,7 @@ class TestH5A(unittest.TestCase):
             aid = h5a.open_name(self.obj, name)
             self.assertEqual(h5a.py_dtype(aid),dt)
             h5a.close(aid)
-        self.assertRaises(H5AttributeError, h5a.py_dtype, -1)
+        self.assertRaises(TypeError, h5a.py_dtype, -1)
 
     def test_py_get(self):
 
@@ -237,7 +234,7 @@ class TestH5A(unittest.TestCase):
             arr_returned = h5a.py_get(self.obj, name)
             self.assert_(all(arr_returned == arr_reference), 
                 errstr(arr_reference, arr_returned))
-        self.assertRaises(H5AttributeError, h5a.py_get, -1, "foo")
+        self.assertRaises(TypeError, h5a.py_get, -1, "foo")
 
     def test_py_set(self):
 
@@ -252,7 +249,7 @@ class TestH5A(unittest.TestCase):
         h5g.close(obj)
         deletecopy(fid, filename)
 
-        self.assertRaises(H5AttributeError, h5a.py_set, -1, "foo", arr_reference)
+        self.assertRaises(TypeError, h5a.py_set, -1, "foo", arr_reference)
 
 
     def test_py_exists(self):
diff --git a/h5py/utils_low.h b/h5py/utils_low.h
index 6ace59f..53dab9e 100644
--- a/h5py/utils_low.h
+++ b/h5py/utils_low.h
@@ -23,6 +23,7 @@
 #include "hdf5.h"
 #include "numpy/arrayobject.h"
 
+
 hid_t create_ieee_complex64(const char byteorder, const char* real_name, const char* img_name);
 hid_t create_ieee_complex128(const char byteorder, const char* real_name, const char* img_name);
 

-- 
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