[h5py] 47/455: Updates & corrections; now compiles with Pyrex 0.9.8.3

Ghislain Vaillant ghisvail-guest at moszumanska.debian.org
Thu Jul 2 18:19:16 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 fc20d5c19133bb6c22f3b4b1eef0f2fb68101869
Author: andrewcollette <andrew.collette at gmail.com>
Date:   Wed Jun 11 00:25:12 2008 +0000

    Updates & corrections; now compiles with Pyrex 0.9.8.3
---
 h5py/__init__.py  |   2 +-
 h5py/h5a.pxd      |   3 +-
 h5py/h5a.pyx      |  25 +++++-------
 h5py/h5d.pxd      |   3 +-
 h5py/h5d.pyx      | 114 ++++++++++++++++++++++++++----------------------------
 h5py/h5e.pxd      |   3 +-
 h5py/h5e.pyx      |  30 ++++++++++++--
 h5py/h5f.pxd      |   3 +-
 h5py/h5f.pyx      |  21 +++++-----
 h5py/h5g.pxd      |   9 ++---
 h5py/h5g.pyx      |  12 +++---
 h5py/h5i.pxd      |   3 +-
 h5py/h5i.pyx      |   2 -
 h5py/h5p.pxd      |   4 +-
 h5py/h5p.pyx      |   2 -
 h5py/h5r.pxd      |   4 +-
 h5py/h5s.pxd      |   8 ++--
 h5py/h5s.pyx      |  16 ++++----
 h5py/h5t.pxd      |   3 +-
 h5py/h5t.pyx      |   1 -
 h5py/h5z.pxd      |   2 +-
 h5py/h5z.pyx      |   3 --
 h5py/python.pxd   |   1 +
 h5py/std_defs.pxi |   8 ++++
 h5py/utils.pxd    |  16 ++++----
 h5py/utils.pyx    |  24 +++++++++++-
 h5py/utils_low.c  |  78 ++++++++++++++++++++++++-------------
 27 files changed, 223 insertions(+), 177 deletions(-)

diff --git a/h5py/__init__.py b/h5py/__init__.py
index c6a3a69..b731752 100644
--- a/h5py/__init__.py
+++ b/h5py/__init__.py
@@ -22,7 +22,7 @@ __doc__ = \
     See the docstring for the "version" module for a longer introduction.
 """
 
-import h5, h5f, h5g, h5s, h5t, h5d, h5a, h5p, h5z, h5i#, highlevel, errors
+import utils, h5, h5f, h5g, h5s, h5t, h5d, h5a, h5p, h5z, h5i
 import tests
 import version
 
diff --git a/h5py/h5a.pxd b/h5py/h5a.pxd
index 5aba0ec..59168a8 100644
--- a/h5py/h5a.pxd
+++ b/h5py/h5a.pxd
@@ -14,8 +14,7 @@
 # license is available at licenses/pytables.txt, in the distribution root
 # directory.
 
-from defs_c  cimport size_t, ssize_t
-from h5 cimport hid_t, herr_t
+include "std_defs.pxi"
 
 cdef extern from "hdf5.h":
 
diff --git a/h5py/h5a.pyx b/h5py/h5a.pyx
index 731a725..574419a 100644
--- a/h5py/h5a.pyx
+++ b/h5py/h5a.pyx
@@ -12,12 +12,9 @@
 
 """
     Provides access to the low-level HDF5 "H5A" attribute interface.
-
-    Functions in this module will raise errors.H5AttributeError.
 """
 
 # Pyrex compile-time imports
-from h5  cimport herr_t, hid_t
 from h5p cimport H5P_DEFAULT
 from h5t cimport PY_H5Tclose
 from h5s cimport H5Sclose
@@ -87,20 +84,17 @@ def read(hid_t attr_id, ndarray arr_obj):
         conversion-compatible datatype.
 
         The Numpy array must be writable, C-contiguous and own its data.  If
-        this is not the case, ValueError will be raised and the read will fail.
+        this is not the case, an ValueError is raised and the read fails.
     """
     cdef hid_t mtype_id
     cdef hid_t space_id
-    cdef int array_ok
     mtype_id = 0
     space_id = 0
 
     try:
         mtype_id = h5t.py_dtype_to_h5t(arr_obj.dtype)
-        space_id = get_space(attr_id)
-        array_ok = check_numpy_write(arr_obj, space_id)
-        if array_ok <= 0:
-            raise ValueError("Numpy array is not set up correctly.")
+        space_id = H5Aget_space(attr_id)
+        check_numpy_write(arr_obj, space_id)
 
         H5Aread(attr_id, mtype_id, PyArray_DATA(arr_obj))
 
@@ -123,16 +117,13 @@ def write(hid_t attr_id, ndarray arr_obj):
     
     cdef hid_t mtype_id
     cdef hid_t space_id
-    cdef int array_ok
     mtype_id = 0
     space_id = 0
 
     try:
         mtype_id = h5t.py_dtype_to_h5t(arr_obj.dtype)
-        space_id = get_space(attr_id)
-        array_ok = check_numpy_read(arr_obj, space_id)
-        if array_ok <= 0:
-            raise ValueError("Given Numpy array is not set up correctly.")
+        space_id = H5Aget_space(attr_id)
+        check_numpy_read(arr_obj, space_id)
 
         H5Awrite(attr_id, mtype_id, PyArray_DATA(arr_obj))
 
@@ -202,7 +193,7 @@ cdef herr_t iter_cb(hid_t loc_id, char *attr_name, object int_tpl):
     return 0
 
 
-def iterate(hid_t loc_id, object func, object data=None, unsigned int startidx=0):
+def iterate(hid_t loc_id, object func, object data=None, int startidx=0):
     """ (INT loc_id, FUNCTION func, OBJECT data=None, UINT startidx=0)
         => INT last_attribute_index
 
@@ -220,6 +211,8 @@ def iterate(hid_t loc_id, object func, object data=None, unsigned int startidx=0
     """
     cdef unsigned int i
     cdef herr_t retval
+    if startidx < 0:
+        raise ValueError("Starting index must be a non-negative integer.")
     i = startidx
 
     int_tpl = (func, data,[])
@@ -299,7 +292,7 @@ def py_dtype(hid_t attr_id):
     type_id = 0
     
     try:
-        type_id = get_type(attr_id)
+        type_id = H5Aget_type(attr_id)
         return h5t.py_h5t_to_dtype(type_id)
     finally:
         if type_id:
diff --git a/h5py/h5d.pxd b/h5py/h5d.pxd
index 3c77d7f..b0cd6aa 100644
--- a/h5py/h5d.pxd
+++ b/h5py/h5d.pxd
@@ -14,8 +14,7 @@
 # license is available at licenses/pytables.txt, in the distribution root
 # directory.
 
-from defs_c cimport size_t, time_t
-from h5 cimport hid_t, herr_t, hsize_t, haddr_t
+include "std_defs.pxi"
 
 cdef extern from "hdf5.h":
 
diff --git a/h5py/h5d.pyx b/h5py/h5d.pyx
index b592d0e..af9e77d 100644
--- a/h5py/h5d.pyx
+++ b/h5py/h5d.pyx
@@ -23,9 +23,10 @@
 """
 
 # Pyrex compile-time imports
-from h5  cimport hid_t, size_t, hsize_t, hssize_t
-from h5s cimport H5Sclose, H5S_ALL, H5S_UNLIMITED, H5S_SCALAR, H5S_SIMPLE
-from h5t cimport PY_H5Tclose
+from h5s cimport H5S_ALL, H5S_UNLIMITED, H5S_SCALAR, H5S_SIMPLE, \
+                    H5Sget_simple_extent_type, H5Sclose, H5Sselect_all, \
+                    H5Sget_simple_extent_ndims, H5Sget_select_npoints
+from h5t cimport PY_H5Tclose, H5Tget_size
 from h5p cimport H5P_DEFAULT, H5Pclose
 from numpy cimport import_array, ndarray, PyArray_DATA
 from utils cimport  check_numpy_read, check_numpy_write, \
@@ -91,9 +92,10 @@ def close(hid_t dset_id):
 
 # === Dataset I/O =============================================================
 
-def read(hid_t dset_id, hid_t mspace_id, hid_t fspace_id, ndarray arr_obj, hid_t plist=H5P_DEFAULT):
+def read(hid_t dset_id, hid_t mspace_id, hid_t fspace_id, ndarray arr_obj, 
+                                                    hid_t plist=H5P_DEFAULT):
     """ ( INT dset_id, INT mspace_id, INT fspace_id, NDARRAY arr_obj, 
-          INT plist=H5P_DEFAULT )
+          INT plist=H5P_DEFAULT)
 
         Read data from an HDF5 dataset into a Numpy array.  For maximum 
         flexibility, you can specify dataspaces for the file and the Numpy
@@ -112,22 +114,20 @@ def read(hid_t dset_id, hid_t mspace_id, hid_t fspace_id, ndarray arr_obj, hid_t
         For a friendlier version of this function, try py_read_slab().
     """
     cdef hid_t mtype_id
-    cdef int array_ok
     mtype_id = 0
 
     try:
         mtype_id = h5t.py_dtype_to_h5t(arr_obj.dtype)
-        array_ok = check_numpy_write(arr_obj, -1)
-        if array_ok <= 0:
-            raise ValueError("Numpy array is not set up correctly.")
+        check_numpy_write(arr_obj, -1)
 
         H5Dread(dset_id, mtype_id, mspace_id, fspace_id, plist, PyArray_DATA(arr_obj))
 
     finally:
-        if mtype_id != 0:
+        if mtype_id:
             PY_H5Tclose(mtype_id)
         
-def write(hid_t dset_id, hid_t mspace_id, hid_t fspace_id, ndarray arr_obj, hid_t plist=H5P_DEFAULT):
+def write(hid_t dset_id, hid_t mspace_id, hid_t fspace_id, ndarray arr_obj, 
+                                                    hid_t plist=H5P_DEFAULT):
     """ ( INT dset_id, INT mspace_id, INT fspace_id, NDARRAY arr_obj, 
           INT plist=H5P_DEFAULT )
 
@@ -140,14 +140,11 @@ def write(hid_t dset_id, hid_t mspace_id, hid_t fspace_id, ndarray arr_obj, hid_
         For a friendlier version of this function, try py_write_slab()
     """
     cdef hid_t mtype_id
-    cdef int array_ok
     mtype_id = 0
 
     try:
         mtype_id = h5t.py_dtype_to_h5t(arr_obj.dtype)
-        array_ok = check_numpy_read(arr_obj, -1)
-        if array_ok <= 0:
-            raise ValueError("Numpy array is not set up correctly.")
+        check_numpy_read(arr_obj, -1)
 
         H5Dwrite(dset_id, mtype_id, mspace_id, fspace_id, plist, PyArray_DATA(arr_obj))
 
@@ -188,16 +185,19 @@ def extend(hid_t dset_id, object shape):
 def get_space(hid_t dset_id):
     """ (INT dset_id) => INT space_id
 
-        Create and return a new copy of the dataspace for this dataset.  You're
-        responsible for closing it.
+        Create and return a new copy of the dataspace for this dataset.  
+        You're responsible for closing it.
     """
     return H5Dget_space(dset_id)
 
 def get_space_status(hid_t dset_id):
     """ (INT dset_id) => INT space_status_code
 
-        Determine if space has been allocated for a dataset.  Return value is
-        one of SPACE_STATUS_*.
+        Determine if space has been allocated for a dataset.  
+        Return value is one of:
+            SPACE_STATUS_NOT_ALLOCATED
+            SPACE_STATUS_PART_ALLOCATED
+            SPACE_STATUS_ALLOCATED 
     """
     cdef H5D_space_status_t status
     H5Dget_space_status(dset_id, &status)
@@ -206,8 +206,8 @@ def get_space_status(hid_t dset_id):
 def get_type(hid_t dset_id):
     """ (INT dset_id) => INT type_id
 
-        Create and return a new copy of the datatype for this dataset.You're
-        responsible for closing it.
+        Create and return a new copy of the datatype for this dataset.
+        You're responsible for closing it.
     """
     return H5Dget_type(dset_id)
 
@@ -231,7 +231,7 @@ def get_storage_size(hid_t dset_id):
 
         Determine the amount of file space required for a dataset.  Note this
         only counts the space which has actually been allocated; it may even
-        be zero.  Because of this, this function will never raise an exception.
+        be zero.
     """
     return H5Dget_storage_size(dset_id)
 
@@ -252,14 +252,14 @@ def py_create(hid_t parent_id, char* name, object data=None, object dtype=None,
 
         This function also works for scalar arrays; providing a "shape" tuple 
         of () or a 0-dimensional array for "data" will result in a scalar 
-        (h5s.CLASS_SCALAR) dataspace for the new dataset, rather than a 
-        slab (h5s.CLASS_SIMPLE).
-
-        Additional options:
-        chunks          A tuple containing chunk sizes, or None
-        compression     Enable DEFLATE compression at this level (0-9), or None
-        shuffle         Enable/disable shuffle filter (default disabled)
-        fletcher32      Enable/disable Fletcher32 error detection (default disabled)
+        (h5s.SCALAR) dataspace for the new dataset, rather than a slab
+        (h5s.SIMPLE).
+
+        Additional options (* is default):
+        chunks          A tuple containing chunk sizes, or *None
+        compression     Enable DEFLATE compression at this level (0-9) or *None
+        shuffle         Enable/*disable shuffle filter
+        fletcher32      Enable/*disable Fletcher32 error detection
     """
     cdef hid_t dset_id
     cdef hid_t type_id
@@ -279,7 +279,7 @@ def py_create(hid_t parent_id, char* name, object data=None, object dtype=None,
 
     try:
         if len(shape) == 0:
-            space_id = h5s.create(h5s.CLASS_SCALAR)  # let's be explicit
+            space_id = h5s.create(H5S_SCALAR)  # let's be explicit
         else:
             space_id = h5s.create_simple(shape)
 
@@ -354,11 +354,11 @@ def py_read_slab(hid_t ds_id, object start, object count,
     try:
         # Obtain the Numpy dtype of the array
         if dtype is None:
-            type_id = get_type(ds_id)
+            type_id = H5Dget_type(ds_id)
             dtype = h5t.py_h5t_to_dtype(type_id)
 
-        file_space = get_space(ds_id)
-        space_type = h5s.get_simple_extent_type(file_space)
+        file_space = H5Dget_space(ds_id)
+        space_type = H5Sget_simple_extent_type(file_space)
         
         if space_type == H5S_SCALAR:
 
@@ -389,10 +389,9 @@ def py_read_slab(hid_t ds_id, object start, object count,
             read(ds_id, mem_space, file_space, arr)
 
         else:
-            raise ValueError("Dataspace type %d is unsupported" % space_type)
+            raise NotImplementedError("Dataspace type %d is unsupported" % space_type)
 
     finally:
-        # ignore return values on cleanup
         if mem_space:
             H5Sclose(mem_space)
         if file_space:
@@ -432,8 +431,8 @@ def py_write_slab(hid_t ds_id, ndarray arr, object start, object stride=None):
     count = arr_obj.shape
 
     try:
-        file_space = get_space(ds_id)
-        space_type = h5s.get_simple_extent_type(file_space)
+        file_space = H5Dget_space(ds_id)
+        space_type = H5Sget_simple_extent_type(file_space)
         
         if space_type == H5S_SCALAR:
 
@@ -455,7 +454,6 @@ def py_write_slab(hid_t ds_id, ndarray arr, object start, object stride=None):
             raise ValueError("Dataspace type %d is unsupported" % space_type)
 
     finally:
-        # ignore return values on cleanup
         if mem_space:
             H5Sclose(mem_space)
         if file_space:
@@ -468,14 +466,14 @@ def py_shape(hid_t dset_id):
     """
     cdef int space_id
     space_id = 0
-    shape = None
+
     try:
-        space_id = get_space(dset_id)
+        space_id = H5Dget_space(dset_id)
         shape = h5s.get_simple_extent_dims(space_id)
+        return shape
     finally:
         if space_id:
             H5Sclose(space_id)
-    return shape
 
 def py_rank(hid_t dset_id):
     """ (INT dset_id) => INT rank
@@ -484,14 +482,13 @@ def py_rank(hid_t dset_id):
     """
     cdef int space_id
     space_id = 0
-    rank = None
+
     try:
-        space_id = get_space(dset_id)
-        rank = h5s.get_simple_extent_ndims(space_id)
+        space_id = H5Dget_space(dset_id)
+        return H5Sget_simple_extent_ndims(space_id)
     finally:
         if space_id:
             H5Sclose(space_id)
-    return rank
 
 def py_dtype(hid_t dset_id):
     """ (INT dset_id) => DTYPE numpy_dtype
@@ -500,14 +497,13 @@ def py_dtype(hid_t dset_id):
     """
     cdef hid_t type_id
     type_id = 0
-    dtype_out = None
+
     try:
-        type_id = get_type(dset_id)
-        dtype_out = h5t.py_h5t_to_dtype(type_id)
+        type_id = H5Dget_type(dset_id)
+        return h5t.py_h5t_to_dtype(type_id)
     finally:
         if type_id:
             PY_H5Tclose(type_id)
-    return dtype_out
 
 def py_patch(hid_t ds_source, hid_t ds_sink, hid_t transfer_space):
     """ (INT ds_source, INT ds_sink, INT transfer_space)
@@ -520,7 +516,7 @@ def py_patch(hid_t ds_source, hid_t ds_sink, hid_t transfer_space):
         entire selection at once.  Looping and memory limitation constraints 
         are the caller's responsibility.
     """
-    cdef hid_t source_space
+    cdef hid_t source_space 
     cdef hid_t sink_space
     cdef hid_t mem_space
     cdef hid_t source_type
@@ -536,15 +532,15 @@ def py_patch(hid_t ds_source, hid_t ds_sink, hid_t transfer_space):
     xfer_buf = NULL
 
     try:
-        source_space = get_space(ds_source)
-        sink_space = get_space(sink)
-        source_type = get_type(source)
+        source_space = H5Dget_space(ds_source)
+        sink_space = H5Dget_space(sink)
+        source_type = H5Dget_type(source)
 
-        npoints = h5s.get_select_npoints(space_id)
-        type_size = h5t.get_size(source_type)
+        npoints = H5Sget_select_npoints(space_id)
+        type_size = H5Tget_size(source_type)
 
         mem_space = h5s.create_simple((npoints,))
-        h5s.select_all(mem_space)
+        H5Sselect_all(mem_space)
 
         # This assumes that reading into a contiguous buffer and then writing
         # out again to the same selection preserves the arrangement of data
@@ -559,6 +555,7 @@ def py_patch(hid_t ds_source, hid_t ds_sink, hid_t transfer_space):
         H5Dwrite(ds_sink, source_type, mem_space, transfer_space, H5P_DEFAULT, xfer_buf)
 
     finally:
+        efree(xfer_buf)
         if source_space:
             H5Sclose(source_space)
         if sink_space:
@@ -567,8 +564,7 @@ def py_patch(hid_t ds_source, hid_t ds_sink, hid_t transfer_space):
             H5Sclose(mem_space)
         if source_type:
             PY_H5Tclose(source_type)
-        if xfer_buf != NULL:
-            efree(xfer_buf)
+
 
 PY_LAYOUT = DDict({ H5D_COMPACT: 'COMPACT LAYOUT', 
                H5D_CONTIGUOUS: 'CONTIGUOUS LAYOUT',
diff --git a/h5py/h5e.pxd b/h5py/h5e.pxd
index fb58493..edd4e9b 100644
--- a/h5py/h5e.pxd
+++ b/h5py/h5e.pxd
@@ -14,8 +14,7 @@
 # license is available in the file licenses/hdf5.txt in the distribution
 # root directory.
 
-from h5 cimport herr_t
-from python cimport BaseException, PyErr_SetNone
+include "std_defs.pxi"
 
 cdef extern from "hdf5.h":
 
diff --git a/h5py/h5e.pyx b/h5py/h5e.pyx
index 4b39e9c..aeee447 100644
--- a/h5py/h5e.pyx
+++ b/h5py/h5e.pyx
@@ -10,6 +10,12 @@
 # 
 #-
 
+"""
+    Provides a Python exception hierarchy modeled on HDF5 major error numbers,
+    and exports a C interface which automatically raises exceptions when
+    an error is detected in the HDF5 library.
+"""
+
 from python cimport PyErr_SetObject
 
 # === Public exception hierarchy ==============================================
@@ -32,6 +38,20 @@ class ConversionError(StandardError):
 
 # H5E_ARGS => ValueError
 
+class FileError(H5Error, IOError):
+    """ H5E_FILE
+
+        Subclass of both H5Error and IOError.
+    """
+    pass
+
+class H5IOError(H5Error, IOError):
+    """ H5E_IO
+
+        Subclass of both H5Error and IOError.
+    """
+    pass
+
 class ResourceError(H5Error):
     """ H5E_RESOURCE
     """
@@ -221,7 +241,6 @@ cdef herr_t err_callback(void* client_data):
     # Can't use the standard Pyrex raise because then the traceback
     # points here!
 
-    print "Error callback"
     cdef H5E_error_t err_struct
     cdef H5E_major_t mj
     cdef H5E_minor_t mn
@@ -232,9 +251,12 @@ cdef herr_t err_callback(void* client_data):
     mn = err_struct.min_num
 
     # File-related errors traditionally raise IOError.
-    # Also raise IOError for low-level disk I/O errors
-    if mj == H5E_FILE or mj == H5E_IO:
-        exc = IOError
+    # These exceptions are both subclasses of H5Error
+    # and IOError.
+    if mj == H5E_FILE:
+        exc = FileError
+    elif mj == H5E_IO:
+        exc = H5IOError
 
     # All errors which result from illegal function arguments
     elif mj == H5E_ARGS:
diff --git a/h5py/h5f.pxd b/h5py/h5f.pxd
index 58b6547..4165d48 100644
--- a/h5py/h5f.pxd
+++ b/h5py/h5f.pxd
@@ -14,8 +14,7 @@
 # license is available at licenses/pytables.txt, in the distribution root
 # directory.
 
-from defs_c cimport size_t, time_t, ssize_t
-from h5 cimport hid_t, hbool_t, herr_t, htri_t, hsize_t, hssize_t, hvl_t
+include "std_defs.pxi"
 
 cdef extern from "hdf5.h":
 
diff --git a/h5py/h5f.pyx b/h5py/h5f.pyx
index 4f7e20b..2d59c17 100644
--- a/h5py/h5f.pyx
+++ b/h5py/h5f.pyx
@@ -15,7 +15,6 @@
 """
 
 # Pyrex compile-time imports
-from h5  cimport herr_t, hid_t, htri_t, hssize_t
 from h5p cimport H5P_DEFAULT
 from utils cimport emalloc, efree
 
@@ -33,8 +32,8 @@ ACC_RDONLY  = H5F_ACC_RDONLY
 SCOPE_LOCAL     = H5F_SCOPE_LOCAL
 SCOPE_GLOBAL    = H5F_SCOPE_GLOBAL
 
-CLOSE_WEAK = H5F_CLOSE_WEAK
-CLOSE_SEMI = H5F_CLOSE_SEMI
+CLOSE_WEAK  = H5F_CLOSE_WEAK
+CLOSE_SEMI  = H5F_CLOSE_SEMI
 CLOSE_STRONG = H5F_CLOSE_STRONG
 CLOSE_DEFAULT = H5F_CLOSE_DEFAULT
 
@@ -62,7 +61,8 @@ def close(hid_t file_id):
     """
     H5Fclose(file_id)
 
-def create(char* name, int flags=H5F_ACC_TRUNC, hid_t create_id=H5P_DEFAULT, hid_t access_id=H5P_DEFAULT):
+def create(char* name, int flags=H5F_ACC_TRUNC, hid_t create_id=H5P_DEFAULT, 
+                                                hid_t access_id=H5P_DEFAULT):
     """ (STRING name, INT flags=ACC_TRUNC, INT create_id=H5P_DEFAULT,
             INT access_id=H5P_DEFAULT)
         => INT file_id
@@ -99,7 +99,7 @@ def reopen(hid_t file_id):
     return H5Freopen(file_id)
 
 def mount(hid_t loc_id, char* name, hid_t file_id, hid_t plist_id=H5P_DEFAULT):
-    """ (INT loc_id, STRING name, INT file_id, INT, plist_id=H5P_DEFAULT)
+    """ (INT loc_id, STRING name, INT file_id, INT plist_id=H5P_DEFAULT)
     
         Mount an open file as "name" under group loc_id.  If present, plist_id 
         is a mount property list.
@@ -183,29 +183,26 @@ def get_obj_ids(hid_t file_id, int types):
         OBJ_FILE | OBJ_ATTR).  The special value OBJ_ALL matches all object
         types, and OBJ_LOCAL will only match objects opened through this
         specific identifier.
-
     """
     cdef int count
-    cdef int retval
     cdef hid_t *obj_list
     cdef int i
-
     obj_list = NULL
-    py_obj_list = []
 
+    py_obj_list = []
     try:
         count = H5Fget_obj_count(file_id, types)
-
         obj_list = <hid_t*>emalloc(sizeof(hid_t)*count)
-        H5Fget_obj_ids(file_id, types, count, obj_list)
 
+        H5Fget_obj_ids(file_id, types, count, obj_list)
         for i from 0<=i<count:
             py_obj_list.append(obj_list[i])
+        return py_obj_list
 
     finally:
         efree(obj_list)
 
-    return py_obj_list
+
 
 # === Python extensions =======================================================
 
diff --git a/h5py/h5g.pxd b/h5py/h5g.pxd
index b63c6b8..ecdc146 100644
--- a/h5py/h5g.pxd
+++ b/h5py/h5g.pxd
@@ -14,8 +14,7 @@
 # license is available at licenses/pytables.txt, in the distribution root
 # 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
+include "std_defs.pxi"
 
 cdef extern from "hdf5.h":
 
@@ -44,13 +43,13 @@ cdef extern from "hdf5.h":
   hid_t  H5Gcreate(hid_t loc_id, char *name, size_t size_hint ) except *
   hid_t  H5Gopen(hid_t loc_id, char *name ) except *
   herr_t H5Gclose(hid_t group_id) except *
-  herr_t H5Glink (hid_t file_id, H5G_link_t link_type,
-                  char *current_name, char *new_name) except *
+#  herr_t H5Glink (hid_t file_id, H5G_link_t link_type,
+#                  char *current_name, char *new_name) except *
   herr_t H5Glink2( hid_t curr_loc_id, char *current_name, 
                    H5G_link_t link_type, hid_t new_loc_id, char *new_name ) except *
 
   herr_t H5Gunlink (hid_t file_id, char *name) except *
-  herr_t H5Gmove(hid_t loc_id, char *src, char *dst) except *
+#  herr_t H5Gmove(hid_t loc_id, char *src, char *dst) except *
   herr_t H5Gmove2(hid_t src_loc_id, char *src_name,
                   hid_t dst_loc_id, char *dst_name ) except *
   herr_t H5Gget_num_objs(hid_t loc_id, hsize_t*  num_obj) except *
diff --git a/h5py/h5g.pyx b/h5py/h5g.pyx
index 9ecfb45..bfcf12f 100644
--- a/h5py/h5g.pyx
+++ b/h5py/h5g.pyx
@@ -15,8 +15,6 @@
 """
 
 # Pyrex compile-time imports
-from defs_c cimport time_t
-from h5  cimport herr_t, hid_t, size_t, hsize_t
 from utils cimport emalloc, efree
 
 # Runtime imports
@@ -139,8 +137,7 @@ def get_objname_by_idx(hid_t loc_id, hsize_t idx):
     buf = NULL
 
     size = H5Gget_objname_by_idx(loc_id, idx, NULL, 0)
-    if size <= 0:
-        raise RuntimeError("Failed to raise exception at get_objname_by_idx.")
+    assert size > 0
 
     buf = <char*>emalloc(sizeof(char)*(size+1))
     try:
@@ -284,8 +281,7 @@ def get_comment(hid_t loc_id, char* name):
     cmnt = NULL
 
     cmnt_len = H5Gget_comment(loc_id, name, 0, NULL)
-    if cmnt_len < 0:
-        raise RuntimeError("Failed to raise exception at get_comment")
+    assert cmnt_len > 0
 
     cmnt = <char*>emalloc(sizeof(char)*(cmnt_len+1))
     try:
@@ -357,10 +353,12 @@ def py_exists(hid_t group_id, char* name, int follow_link=1):
 
         Determine if a named member exists in the given group.  If follow_link
         is True (default), symbolic links will be dereferenced. Note this
-        function will not raise GroupError, even if the group ID is bad.
+        function will not raise an exception, unless the group ID is bad.
     """
     try:
         H5Gget_objinfo(group_id, name, follow_link, NULL)
+    except ValueError:
+        raise
     except:
         return False
     return True
diff --git a/h5py/h5i.pxd b/h5py/h5i.pxd
index b785229..024641b 100644
--- a/h5py/h5i.pxd
+++ b/h5py/h5i.pxd
@@ -14,8 +14,7 @@
 # license is available in the file licenses/hdf5.txt in the distribution
 # root directory.
 
-from defs_c cimport size_t, time_t, ssize_t
-from h5 cimport hid_t, hbool_t, herr_t, htri_t, hsize_t, hssize_t, hvl_t
+include "std_defs.pxi"
 
 cdef extern from "hdf5.h":
 
diff --git a/h5py/h5i.pyx b/h5py/h5i.pyx
index 7b36d2c..8aaa52c 100644
--- a/h5py/h5i.pyx
+++ b/h5py/h5i.pyx
@@ -15,8 +15,6 @@
 """
 
 # Pyrex compile-time imports
-from defs_c cimport size_t
-from h5  cimport hid_t
 from utils cimport emalloc, efree
 
 # Runtime imports
diff --git a/h5py/h5p.pxd b/h5py/h5p.pxd
index 0208a71..d807e1c 100644
--- a/h5py/h5p.pxd
+++ b/h5py/h5p.pxd
@@ -14,8 +14,8 @@
 # license is available at licenses/pytables.txt, in the distribution root
 # 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
+include "std_defs.pxi"
+
 from h5d cimport H5D_layout_t, H5D_fill_value_t, H5D_fill_time_t, H5D_alloc_time_t
 from h5z cimport H5Z_filter_t, H5Z_EDC_t
 from h5f cimport H5F_close_degree_t
diff --git a/h5py/h5p.pyx b/h5py/h5p.pyx
index 2fa87eb..7810989 100644
--- a/h5py/h5p.pyx
+++ b/h5py/h5p.pyx
@@ -16,8 +16,6 @@
 """
 
 # Pyrex compile-time imports
-from defs_c cimport size_t
-from h5  cimport herr_t, hid_t, htri_t, herr_t, hsize_t
 from h5d cimport H5D_layout_t
 from h5z cimport H5Z_filter_t
 
diff --git a/h5py/h5r.pxd b/h5py/h5r.pxd
index edc1d8d..7a50f1d 100644
--- a/h5py/h5r.pxd
+++ b/h5py/h5r.pxd
@@ -10,8 +10,8 @@
 # 
 #-
 
-from defs_c cimport size_t
-from h5 cimport hid_t, herr_t, haddr_t
+include "std_defs.pxi"
+
 from h5g cimport H5G_obj_t
 
 cdef extern from "hdf5.h":
diff --git a/h5py/h5s.pxd b/h5py/h5s.pxd
index 0cb7c13..4636e47 100644
--- a/h5py/h5s.pxd
+++ b/h5py/h5s.pxd
@@ -18,12 +18,12 @@
 # license is available in the file licenses/hdf5.txt in the distribution
 # root 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
+include "std_defs.pxi"
 
 cdef extern from "hdf5.h":
 
-  int H5S_ALL, H5S_UNLIMITED, H5S_MAX_RANK
+  int H5S_ALL, H5S_MAX_RANK
+  hsize_t H5S_UNLIMITED
 
   # Codes for defining selections
   ctypedef enum H5S_seloper_t:
@@ -88,7 +88,7 @@ cdef extern from "hdf5.h":
   herr_t    H5Sget_select_elem_pointlist(hid_t space_id, hsize_t startpoint, 
                 hsize_t numpoints, hsize_t *buf) except *
   herr_t    H5Sselect_elements(hid_t space_id, H5S_seloper_t op, 
-                size_t num_elements, hsize_t *coord[] ) except *
+                size_t num_elements, hsize_t **coord) except *
 
   hssize_t  H5Sget_select_hyper_nblocks(hid_t space_id  ) except *
   herr_t    H5Sget_select_hyper_blocklist(hid_t space_id, 
diff --git a/h5py/h5s.pyx b/h5py/h5s.pyx
index a2ff157..432a4d9 100644
--- a/h5py/h5s.pyx
+++ b/h5py/h5s.pyx
@@ -18,8 +18,7 @@
 """
 
 # Pyrex compile-time imports
-from h5  cimport herr_t, htri_t, hid_t, size_t, hsize_t, hssize_t
-from utils cimport  require_tuple, convert_dims, convert_tuple, \
+from utils cimport  require_tuple, require_list, convert_dims, convert_tuple, \
                     emalloc, efree
 
 # Runtime imports
@@ -365,20 +364,21 @@ def select_elements(hid_t space_id, object coord_list, int op=H5S_SELECT_SET):
     """
     cdef size_t nelements       # Number of point coordinates
     cdef hsize_t *coords        # Contiguous 2D array nelements x rank x sizeof(hsize_t)
-    cdef size_t element_size    # Size of a point record: sizeof(hsize_t)*rank
 
     cdef int rank
     cdef int i_point
     cdef int i_entry
     coords = NULL
 
-    rank = H5Sget_simple_extent_ndims(space_id)
-
+    require_list(coord_list, 0, -1, "coord_list")
     nelements = len(coord_list)
-    element_size = sizeof(hsize_t)*rank
 
-    # HDF5 docs say this has to be a contiguous 2D array
-    coords = <hsize_t*>emalloc(element_size*nelements)
+    rank = H5Sget_simple_extent_ndims(space_id)
+
+    # HDF5 expects the coordinates array to be a static, contiguous
+    # array.  We'll simulate that by malloc'ing a contiguous chunk
+    # and using pointer arithmetic to initialize it.
+    coords = <hsize_t*>emalloc(sizeof(hsize_t)*rank*nelements)
 
     try:
         for i_point from 0<=i_point<nelements:
diff --git a/h5py/h5t.pxd b/h5py/h5t.pxd
index f3cdba6..aee72e3 100644
--- a/h5py/h5t.pxd
+++ b/h5py/h5t.pxd
@@ -14,8 +14,7 @@
 # license is available at licenses/pytables.txt, in the distribution root
 # 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
+include "std_defs.pxi"
 
 cdef extern from "hdf5.h":
 
diff --git a/h5py/h5t.pyx b/h5py/h5t.pyx
index 91836d2..9de293d 100644
--- a/h5py/h5t.pyx
+++ b/h5py/h5t.pyx
@@ -54,7 +54,6 @@
 
 # Pyrex compile-time imports
 from defs_c cimport free
-from h5  cimport herr_t, hid_t, size_t, hsize_t, htri_t
 from h5p cimport H5P_DEFAULT
 from h5e cimport err_c, pause_errors, resume_errors
 from numpy cimport dtype, ndarray
diff --git a/h5py/h5z.pxd b/h5py/h5z.pxd
index 0a9e9de..d8b3bc9 100644
--- a/h5py/h5z.pxd
+++ b/h5py/h5z.pxd
@@ -10,7 +10,7 @@
 # 
 #-
 
-from h5 cimport herr_t, htri_t
+include "std_defs.pxi"
 
 cdef extern from "hdf5.h":
 
diff --git a/h5py/h5z.pyx b/h5py/h5z.pyx
index 161e3d7..730ac7a 100644
--- a/h5py/h5z.pyx
+++ b/h5py/h5z.pyx
@@ -15,9 +15,6 @@
     Filter API and constants
 """
 
-# Pyrex compile-time imports
-from h5  cimport herr_t, htri_t
-
 # Runtime imports
 import h5
 from h5 import DDict
diff --git a/h5py/python.pxd b/h5py/python.pxd
index ef1aabe..767078f 100644
--- a/h5py/python.pxd
+++ b/h5py/python.pxd
@@ -44,6 +44,7 @@ cdef extern from "Python.h":
 
   # Functions for lists
   int PyList_Append(object list, object item)
+  int PyList_Check(object list_)
 
   # Functions for tuples
   object PyTuple_New(int)
diff --git a/h5py/std_defs.pxi b/h5py/std_defs.pxi
new file mode 100644
index 0000000..6623c1c
--- /dev/null
+++ b/h5py/std_defs.pxi
@@ -0,0 +1,8 @@
+# "Boilerplate" includes which are so common I don't want to repeat them
+# in every file.
+
+from h5 cimport hid_t, hbool_t, herr_t, htri_t, hsize_t, \
+                hssize_t, haddr_t, hvl_t
+
+from defs_c cimport size_t, time_t, ssize_t
+
diff --git a/h5py/utils.pxd b/h5py/utils.pxd
index aee1676..7a88189 100644
--- a/h5py/utils.pxd
+++ b/h5py/utils.pxd
@@ -10,23 +10,23 @@
 # 
 #-
 
-from defs_c cimport size_t
-from h5 cimport hid_t, hsize_t
+include "std_defs.pxi"
+
 from numpy cimport ndarray
 
 cdef extern from "utils_low.h":
 
     # Python to HDF5 complex conversion
-    hid_t create_ieee_complex64(char byteorder, char* real_name, char* img_name)
-    hid_t create_ieee_complex128(char byteorder, char* real_name, char* img_name)
+    hid_t create_ieee_complex64(char byteorder, char* real_name, char* img_name) except -1
+    hid_t create_ieee_complex128(char byteorder, char* real_name, char* img_name) except -1
 
     # Tuple conversion
     int convert_tuple(object tpl, hsize_t *dims, hsize_t rank) except -1
-    object convert_dims(hsize_t* dims, hsize_t rank)
+    object convert_dims(hsize_t* dims, hsize_t rank) # automatic except
 
     # Numpy array validation
-    int check_numpy_read(ndarray arr, hid_t space_id)
-    int check_numpy_write(ndarray arr, hid_t space_id)
+    int check_numpy_read(ndarray arr, hid_t space_id) except 0
+    int check_numpy_write(ndarray arr, hid_t space_id) except 0
 
     # Memory handling
     void* emalloc(size_t size) except? NULL
@@ -35,5 +35,5 @@ cdef extern from "utils_low.h":
 # === Custom API ==============================================================
 
 cdef int require_tuple(object tpl, int none_allowed, int size, char* name) except -1
-
+cdef int require_list(object lst, int none_allowed, int size, char* name) except -1
 
diff --git a/h5py/utils.pyx b/h5py/utils.pyx
index b8e3618..8eaf565 100644
--- a/h5py/utils.pyx
+++ b/h5py/utils.pyx
@@ -10,7 +10,7 @@
 # 
 #-
 
-from python cimport PyTuple_Check
+from python cimport PyTuple_Check, PyList_Check
 
 cdef int require_tuple(object tpl, int none_allowed, int size, char* name) except -1:
     # Ensure that tpl is in fact a tuple, or None if none_allowed is nonzero.
@@ -29,3 +29,25 @@ cdef int require_tuple(object tpl, int none_allowed, int size, char* name) excep
         nmsg = " or None"
 
     raise ValueError("%s must be a tuple%s%s." % (name, smsg, nmsg))
+
+cdef int require_list(object lst, int none_allowed, int size, char* name) except -1:
+    # Counterpart of require_tuple, for lists
+
+    if (lst is None and none_allowed) or \
+      ( PyList_Check(lst) and (size < 0 or len(lst) == size)):
+        return 1
+
+    nmsg = ""
+    smsg = ""
+    if size >= 0:
+        smsg = " of size %d" % size
+    if none_allowed:
+        nmsg = " or None"
+
+    raise ValueError("%s must be a list%s%s." % (name, smsg, nmsg))
+
+
+
+
+
+
diff --git a/h5py/utils_low.c b/h5py/utils_low.c
index 983b189..bd3c7a2 100644
--- a/h5py/utils_low.c
+++ b/h5py/utils_low.c
@@ -136,8 +136,7 @@ int convert_tuple(PyObject* tpl, hsize_t *dims, hsize_t rank_in){
 
    Return values:
     1:  Can read/write
-    0:  Can't read/write
-   -1:  Failed to determine (i.e. either the array or the space object is bad)
+    0: Failed (Python error raised.)
 */
 int check_numpy(PyArrayObject* arr, hid_t space_id, int write){
 
@@ -147,21 +146,32 @@ int check_numpy(PyArrayObject* arr, hid_t space_id, int write){
     hsize_t *space_dims = NULL;
     int i;
 
-    required_flags = NPY_C_CONTIGUOUS | NPY_OWNDATA;
-    /* That's not how you spell "writable" */
-    if(write) required_flags = required_flags | NPY_WRITEABLE;  
-
-    int retval = 0;  /* Default = not OK */
+    /* Validate array flags */
+
+    if(write){
+        if(!(arr->flags & (NPY_C_CONTIGUOUS | NPY_OWNDATA | NPY_WRITEABLE))){
+            PyErr_SetString(PyExc_ValueError, "Array must be writable, C-contiguous and own its data.");
+            goto failed;
+        } 
+    } else {
+        if(!(arr->flags & (NPY_C_CONTIGUOUS | NPY_OWNDATA))){
+            PyErr_SetString(PyExc_ValueError, "Array must be C-contiguous and own its data.");
+            goto failed;
+        }
+    }
 
-    if(!(arr->flags & required_flags)) goto out;
+    /* Validate dataspace compatibility, if it's provided. */
 
     if(space_id > 0){
 
         arr_rank = arr->nd;
         space_rank = H5Sget_simple_extent_ndims(space_id);
-
         if(space_rank < 0) goto failed;
-        if( arr_rank != space_rank) goto out;
+
+        if( arr_rank != space_rank){
+            PyErr_SetString(PyExc_ValueError, "Numpy array rank must match dataspace rank.");
+            goto failed;
+        }
 
         space_dims = (hsize_t*)malloc(sizeof(hsize_t)*space_rank);
         space_rank = H5Sget_simple_extent_dims(space_id, space_dims, NULL);
@@ -169,24 +179,28 @@ int check_numpy(PyArrayObject* arr, hid_t space_id, int write){
 
         for(i=0; i<space_rank; i++){
             if(write){
-                if(PyArray_DIM(arr,i) < space_dims[i]) goto out;
+                if(PyArray_DIM(arr,i) < space_dims[i]){
+                    PyErr_SetString(PyExc_ValueError, "Array dimensions incompatible with dataspace.");
+                    goto failed;
+                }
             } else {
-                if(PyArray_DIM(arr,i) > space_dims[i]) goto out;
-            }
-        }
-
-    }
+                if(PyArray_DIM(arr,i) > space_dims[i]) {
+                    PyErr_SetString(PyExc_ValueError, "Array dimensions incompatible with dataspace.");
+                    goto failed;
+                }
+            } /* if(write) */
+        } /* for */
+    } /* if(space_id > 0) */
 
-    retval = 1;  /* got here == success */
-
-  out:
-    if(space_dims != NULL) free(space_dims);
-    return retval; 
+  free(space_dims);
+  return 1;
 
   failed:
-    /* could optionally print an error message */
-    if(space_dims != NULL) free(space_dims);
-    return -1;
+    free(space_dims);
+    if(!PyErr_Occurred()){
+        PyErr_SetString(PyExc_ValueError, "Numpy array is incompatible.");
+    }
+    return 0;
 }
 
 int check_numpy_write(PyArrayObject* arr, hid_t space_id){
@@ -201,7 +215,7 @@ int check_numpy_read(PyArrayObject* arr, hid_t space_id){
 /* Rewritten versions of create_ieee_complex64/128 from Pytables, to support 
    standard array-interface typecodes and variable names for real/imag parts.  
    Also removed unneeded datatype copying.
-   Both return -1 on failure.
+   Both return -1 on failure, and raise Python exceptions.
 */
 hid_t create_ieee_complex64(const char byteorder, const char* real_name, const char* img_name) {
   hid_t float_id = -1;
@@ -217,8 +231,10 @@ hid_t create_ieee_complex64(const char byteorder, const char* real_name, const c
     float_id = H5T_IEEE_F32BE;
   else if (byteorder == '=' || byteorder == '|')
     float_id = H5T_NATIVE_FLOAT;
-  else
+  else {
+    PyErr_SetString(PyExc_ValueError, "Byte order must be one of <, > or |");
     goto err;
+  }
 
   retval = H5Tinsert(complex_id, real_name, HOFFSET(npy_complex64, real), float_id);
   if(retval<0) goto err;
@@ -229,6 +245,9 @@ hid_t create_ieee_complex64(const char byteorder, const char* real_name, const c
   return complex_id;
 
   err:
+    if(!PyErr_Occurred()){
+        PyErr_SetString(PyExc_RuntimeError, "Failed to propagate exception at create_ieee_complex64.");
+    }
     if(complex_id > 0)
         H5Tclose(complex_id);
     return -1;
@@ -248,8 +267,10 @@ hid_t create_ieee_complex128(const char byteorder, const char* real_name, const
     float_id = H5T_IEEE_F64BE;
   else if (byteorder == '=' || byteorder == '|')
     float_id = H5T_NATIVE_DOUBLE;
-  else
+  else {
+    PyErr_SetString(PyExc_ValueError, "Byte order must be one of <, > or |");
     goto err;
+  }
 
   retval = H5Tinsert(complex_id, real_name, HOFFSET(npy_complex128, real), float_id);
   if(retval<0) goto err;
@@ -260,6 +281,9 @@ hid_t create_ieee_complex128(const char byteorder, const char* real_name, const
   return complex_id;
 
   err:
+    if(!PyErr_Occurred()){
+        PyErr_SetString(PyExc_RuntimeError, "Failed to propagate exception at create_ieee_complex128.");
+    }
     if(complex_id > 0)
         H5Tclose(complex_id);
     return -1;

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