[h5py] 126/455: More cleanup & consolidation
Ghislain Vaillant
ghisvail-guest at moszumanska.debian.org
Thu Jul 2 18:19:24 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 249dcbb7de271708a438ebd295c76e273d3a761d
Author: andrewcollette <andrew.collette at gmail.com>
Date: Wed Sep 24 06:21:42 2008 +0000
More cleanup & consolidation
---
h5py/defs.pxd | 219 +++++++++++++++++++++++++++++++--------------------------
h5py/h5.pxd | 6 +-
h5py/h5.pyx | 156 +++++++++++++++++++++-------------------
h5py/h5a.pyx | 20 +++---
h5py/h5d.pyx | 13 ++--
h5py/h5f.pyx | 3 +
h5py/h5g.pyx | 4 +-
h5py/h5l.pyx | 11 ++-
h5py/h5o.pyx | 5 +-
h5py/h5p.pyx | 109 ++++++++++++++++++++++------
h5py/h5r.pyx | 5 ++
h5py/h5s.pyx | 35 ++++++++-
h5py/h5t.pxd | 8 +++
h5py/h5t.pyx | 204 +++++++++++++++++++++++++++++++++--------------------
h5py/h5z.pyx | 3 +
h5py/sync.pxi | 18 +++--
h5py/utils.pyx | 7 +-
17 files changed, 519 insertions(+), 307 deletions(-)
diff --git a/h5py/defs.pxd b/h5py/defs.pxd
index f9e76bd..278733b 100644
--- a/h5py/defs.pxd
+++ b/h5py/defs.pxd
@@ -12,8 +12,16 @@
# This file provides all external libraries for h5py.
+# Originally each HDF5 subsection was attached to its own .pxd file, but this
+# proved much too complicated as the definitions are interdependent.
+
+# This file contains code or comments from the HDF5 library, as well as some
+# PyTables definitions. Licenses for both these packages are located in
+# the "licenses" folder in the distribution root directory.
+
include "config.pxi" # Needed for H5PY_*API defines
+
# === Standard C library types and functions ==================================
cdef extern from "stdlib.h":
@@ -45,6 +53,7 @@ cdef extern from "stdint.h":
ctypedef signed long long int int64_t
ctypedef signed long long int uint64_t
+
# === H5 - Common definitions and library functions ===========================
cdef extern from "hdf5.h":
@@ -71,6 +80,22 @@ cdef extern from "hdf5.h":
herr_t H5get_libversion(unsigned *majnum, unsigned *minnum,
unsigned *relnum ) except *
+ # New in 1.8.X
+ IF H5PY_18API:
+
+ ctypedef enum H5_iter_order_t:
+ H5_ITER_UNKNOWN = -1, # Unknown order
+ H5_ITER_INC, # Increasing order
+ H5_ITER_DEC, # Decreasing order
+ H5_ITER_NATIVE, # No particular order, whatever is fastest
+ H5_ITER_N # Number of iteration orders
+
+ ctypedef enum H5_index_t:
+ H5_INDEX_UNKNOWN = -1, # Unknown index type
+ H5_INDEX_NAME, # Index on names
+ H5_INDEX_CRT_ORDER, # Index on creation order
+ H5_INDEX_N # Number of indices defined
+
# === H5E - Error handling API ================================================
@@ -135,58 +160,35 @@ cdef extern from "hdf5.h":
herr_t H5Ewalk(H5E_direction_t direction, H5E_walk_t func, void* client_data)
-# === H5A - Attributes API ====================================================
-
-cdef extern from "hdf5.h":
-
- 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) except *
- 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 *
- 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) except -1
- herr_t H5Aiterate(hid_t loc_id, unsigned * idx, H5A_operator_t op, op_data) except *
-
-
# === H5D - Dataset API =======================================================
cdef extern from "hdf5.h":
- # HDF5 layouts
ctypedef enum H5D_layout_t:
H5D_LAYOUT_ERROR = -1,
- H5D_COMPACT = 0, # raw data is very small
- H5D_CONTIGUOUS = 1, # the default
- H5D_CHUNKED = 2, # slow and fancy
- H5D_NLAYOUTS = 3 # this one must be last!
+ H5D_COMPACT = 0,
+ H5D_CONTIGUOUS = 1,
+ H5D_CHUNKED = 2,
+ H5D_NLAYOUTS = 3
ctypedef enum H5D_alloc_time_t:
- H5D_ALLOC_TIME_ERROR =-1,
+ H5D_ALLOC_TIME_ERROR =-1,
H5D_ALLOC_TIME_DEFAULT =0,
- H5D_ALLOC_TIME_EARLY =1,
- H5D_ALLOC_TIME_LATE =2,
- H5D_ALLOC_TIME_INCR =3
+ H5D_ALLOC_TIME_EARLY =1,
+ H5D_ALLOC_TIME_LATE =2,
+ H5D_ALLOC_TIME_INCR =3
ctypedef enum H5D_space_status_t:
- H5D_SPACE_STATUS_ERROR =-1,
- H5D_SPACE_STATUS_NOT_ALLOCATED =0,
- H5D_SPACE_STATUS_PART_ALLOCATED =1,
- H5D_SPACE_STATUS_ALLOCATED =2
+ H5D_SPACE_STATUS_ERROR =-1,
+ H5D_SPACE_STATUS_NOT_ALLOCATED =0,
+ H5D_SPACE_STATUS_PART_ALLOCATED =1,
+ H5D_SPACE_STATUS_ALLOCATED =2
ctypedef enum H5D_fill_time_t:
- H5D_FILL_TIME_ERROR =-1,
+ H5D_FILL_TIME_ERROR =-1,
H5D_FILL_TIME_ALLOC =0,
- H5D_FILL_TIME_NEVER =1,
- H5D_FILL_TIME_IFSET =2
+ H5D_FILL_TIME_NEVER =1,
+ H5D_FILL_TIME_IFSET =2
ctypedef enum H5D_fill_value_t:
H5D_FILL_VALUE_ERROR =-1,
@@ -224,8 +226,9 @@ cdef extern from "hdf5.h":
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)
+ 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) except *
@@ -287,8 +290,8 @@ cdef extern from "hdf5.h":
cdef extern from "hdf5.h":
ctypedef enum H5FD_mem_t:
- H5FD_MEM_NOLIST = -1,
- H5FD_MEM_DEFAULT = 0,
+ H5FD_MEM_NOLIST = -1,
+ H5FD_MEM_DEFAULT = 0,
H5FD_MEM_SUPER = 1,
H5FD_MEM_BTREE = 2,
H5FD_MEM_DRAW = 3,
@@ -298,7 +301,7 @@ cdef extern from "hdf5.h":
H5FD_MEM_NTYPES
# HDF5 uses a clever scheme wherein these are actually init() calls
- # Hopefully Pyrex won't have a problem with this.
+ # Hopefully Cython won't have a problem with this.
# Thankfully they are defined but -1 if unavailable
hid_t H5FD_CORE
hid_t H5FD_FAMILY
@@ -389,6 +392,7 @@ cdef extern from "hdf5.h":
# New extensions in 1.8.X
IF H5PY_18API:
+
ctypedef enum H5G_storage_type_t:
H5G_STORAGE_TYPE_UNKNOWN = -1,
H5G_STORAGE_TYPE_SYMBOL_TABLE,
@@ -396,15 +400,16 @@ cdef extern from "hdf5.h":
H5G_STORAGE_TYPE_DENSE
ctypedef struct H5G_info_t:
- H5G_storage_type_t storage_type
- hsize_t nlinks
- long int max_corder # FIXME: not really long int
+ H5G_storage_type_t storage_type
+ hsize_t nlinks
+ int64_t max_corder
- hid_t H5Gcreate_anon( hid_t loc_id, hid_t gcpl_id, hid_t gapl_id ) except *
- hid_t H5Gcreate2(hid_t loc_id, char *name, hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id) except *
- hid_t H5Gopen2( hid_t loc_id, char * name, hid_t gapl_id ) except *
- herr_t H5Gget_info( hid_t group_id, H5G_info_t *group_info ) except *
- herr_t H5Gget_info_by_name( hid_t loc_id, char *group_name, H5G_info_t *group_info, hid_t lapl_id ) except *
+ hid_t H5Gcreate_anon( hid_t loc_id, hid_t gcpl_id, hid_t gapl_id) except *
+ hid_t H5Gcreate2(hid_t loc_id, char *name, hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id) except *
+ hid_t H5Gopen2( hid_t loc_id, char * name, hid_t gapl_id) except *
+ herr_t H5Gget_info( hid_t group_id, H5G_info_t *group_info) except *
+ herr_t H5Gget_info_by_name( hid_t loc_id, char *group_name, H5G_info_t *group_info, hid_t lapl_id) except *
+ hid_t H5Gget_create_plist(hid_t group_id) except *
# === H5I - Identifier and reflection interface ===============================
@@ -478,16 +483,7 @@ IF H5PY_18API:
ctypedef herr_t (*H5L_iterate_t) (hid_t group, char *name, H5L_info_t *info,
void *op_data)
- ctypedef enum H5_index_t:
- H5_INDEX_NAME,
- H5_INDEX_CRT_ORDER
-
- ctypedef enum H5_iter_order_t:
- H5_ITER_INC, # Increasing order
- H5_ITER_DEC, # Decreasing order
- H5_ITER_NATIVE # Fastest available order
-
- # API
+ # Links API
herr_t H5Lmove(hid_t src_loc, char *src_name, hid_t dst_loc,
char *dst_name, hid_t lcpl_id, hid_t lapl_id) except *
@@ -543,13 +539,16 @@ IF H5PY_18API:
# === H5O - General object operations (1.8.X only) ============================
IF H5PY_18API:
+
cdef extern from "hdf5.h":
+ ctypedef uint32_t H5O_msg_crt_idx_t
+
ctypedef enum H5O_type_t:
- H5O_TYPE_UNKNOWN = -1, # Unknown object type
- H5O_TYPE_GROUP, # Object is a group
- H5O_TYPE_DATASET, # Object is a dataset
- H5O_TYPE_NAMED_DATATYPE, # Object is a named data type
+ H5O_TYPE_UNKNOWN = -1, # Unknown object type
+ H5O_TYPE_GROUP, # Object is a group
+ H5O_TYPE_DATASET, # Object is a dataset
+ H5O_TYPE_NAMED_DATATYPE, # Object is a named data type
H5O_TYPE_NTYPES # Number of different object types (must be last!)
# --- Components for the H5O_info_t struct ----------------------------------
@@ -573,12 +572,12 @@ IF H5PY_18API:
mesg mesg
ctypedef struct H5_ih_info_t:
- hsize_t index_size, # /* btree and/or list */
+ hsize_t index_size, # btree and/or list
hsize_t heap_size
cdef struct meta_size:
- H5_ih_info_t obj, # /* v1/v2 B-tree & local/fractal heap for groups, B-tree for chunked datasets */
- H5_ih_info_t attr # /* v2 B-tree & heap for attributes */
+ H5_ih_info_t obj, # v1/v2 B-tree & local/fractal heap for groups, B-tree for chunked datasets
+ H5_ih_info_t attr # v2 B-tree & heap for attributes
ctypedef struct H5O_info_t:
unsigned long fileno # File number that object is located in
@@ -593,15 +592,6 @@ IF H5PY_18API:
hdr hdr
meta_size meta_size
- ctypedef enum H5_index_t:
- H5_INDEX_NAME,
- H5_INDEX_CRT_ORDER
-
- ctypedef enum H5_iter_order_t:
- H5_ITER_INC, # Increasing order
- H5_ITER_DEC, # Decreasing order
- H5_ITER_NATIVE # Fastest available order
-
ctypedef herr_t (*H5O_iterate_t)(hid_t obj, char *name, H5O_info_t *info,
void *op_data)
@@ -610,6 +600,7 @@ IF H5PY_18API:
herr_t H5Oget_info(hid_t loc_id, H5O_info_t *oinfo) except *
+
# === H5P - Property list API =================================================
cdef extern from "hdf5.h":
@@ -627,23 +618,23 @@ cdef extern from "hdf5.h":
H5D_NLAYOUTS = 3 # this one must be last!
ctypedef enum H5D_alloc_time_t:
- H5D_ALLOC_TIME_ERROR =-1,
+ H5D_ALLOC_TIME_ERROR =-1,
H5D_ALLOC_TIME_DEFAULT =0,
- H5D_ALLOC_TIME_EARLY =1,
- H5D_ALLOC_TIME_LATE =2,
- H5D_ALLOC_TIME_INCR =3
+ H5D_ALLOC_TIME_EARLY =1,
+ H5D_ALLOC_TIME_LATE =2,
+ H5D_ALLOC_TIME_INCR =3
ctypedef enum H5D_space_status_t:
- H5D_SPACE_STATUS_ERROR =-1,
- H5D_SPACE_STATUS_NOT_ALLOCATED =0,
- H5D_SPACE_STATUS_PART_ALLOCATED =1,
- H5D_SPACE_STATUS_ALLOCATED =2
+ H5D_SPACE_STATUS_ERROR =-1,
+ H5D_SPACE_STATUS_NOT_ALLOCATED =0,
+ H5D_SPACE_STATUS_PART_ALLOCATED =1,
+ H5D_SPACE_STATUS_ALLOCATED =2
ctypedef enum H5D_fill_time_t:
- H5D_FILL_TIME_ERROR =-1,
+ H5D_FILL_TIME_ERROR =-1,
H5D_FILL_TIME_ALLOC =0,
- H5D_FILL_TIME_NEVER =1,
- H5D_FILL_TIME_IFSET =2
+ H5D_FILL_TIME_NEVER =1,
+ H5D_FILL_TIME_IFSET =2
ctypedef enum H5D_fill_value_t:
H5D_FILL_VALUE_ERROR =-1,
@@ -664,8 +655,8 @@ cdef extern from "hdf5.h":
H5F_CLOSE_DEFAULT = 3
ctypedef enum H5FD_mem_t:
- H5FD_MEM_NOLIST = -1,
- H5FD_MEM_DEFAULT = 0,
+ H5FD_MEM_NOLIST = -1,
+ H5FD_MEM_DEFAULT = 0,
H5FD_MEM_SUPER = 1,
H5FD_MEM_BTREE = 2,
H5FD_MEM_DRAW = 3,
@@ -807,19 +798,19 @@ cdef extern from "hdf5.h":
H5S_SELECT_INVALID # Must be the last one
ctypedef enum H5S_class_t:
- H5S_NO_CLASS = -1, #/*error */
- H5S_SCALAR = 0, #/*scalar variable */
- H5S_SIMPLE = 1, #/*simple data space */
+ H5S_NO_CLASS = -1, #/*error
+ H5S_SCALAR = 0, #/*scalar variable
+ H5S_SIMPLE = 1, #/*simple data space
# no longer defined in 1.8
- #H5S_COMPLEX = 2 #/*complex data space */
+ #H5S_COMPLEX = 2 #/*complex data space
ctypedef enum H5S_sel_type:
- H5S_SEL_ERROR = -1, #/* Error */
- H5S_SEL_NONE = 0, #/* Nothing selected */
- H5S_SEL_POINTS = 1, #/* Sequence of points selected */
- H5S_SEL_HYPERSLABS = 2, #/* "New-style" hyperslab selection defined */
- H5S_SEL_ALL = 3, #/* Entire extent selected */
- H5S_SEL_N = 4 #/*THIS MUST BE LAST */
+ H5S_SEL_ERROR = -1, #Error
+ H5S_SEL_NONE = 0, #Nothing selected
+ H5S_SEL_POINTS = 1, #Sequence of points selected
+ H5S_SEL_HYPERSLABS = 2, #"New-style" hyperslab selection defined
+ H5S_SEL_ALL = 3, #Entire extent selected
+ H5S_SEL_N = 4 #/*THIS MUST BE LAST
# Basic operations
@@ -1145,10 +1136,38 @@ cdef extern from "hdf5.h":
H5Z_ENABLE_EDC = 1,
H5Z_NO_EDC = 2
- # --- Filter API ----------------------------------------------------------
htri_t H5Zfilter_avail(H5Z_filter_t id_) except *
herr_t H5Zget_filter_info(H5Z_filter_t filter_, unsigned int *filter_config_flags) except *
+# === H5A - Attributes API ====================================================
+
+cdef extern from "hdf5.h":
+
+ 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) except *
+ 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 *
+ 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) except -1
+ herr_t H5Aiterate(hid_t loc_id, unsigned * idx, H5A_operator_t op, op_data) except *
+
+ IF H5PY_18API:
+
+ ctypedef struct H5A_info_t:
+ hbool_t corder_valid # Indicate if creation order is valid
+ H5O_msg_crt_idx_t corder # Creation order
+ H5T_cset_t cset # Character set of attribute name
+ hsize_t data_size # Size of raw data
+
diff --git a/h5py/h5.pxd b/h5py/h5.pxd
index c88d587..8b8b350 100644
--- a/h5py/h5.pxd
+++ b/h5py/h5.pxd
@@ -25,7 +25,8 @@ cpdef PHIL get_phil()
cdef class H5PYConfig:
- cdef object _complex_names
+ cdef object _r_name
+ cdef object _i_name
cdef readonly object API_16
cdef readonly object API_18
cdef readonly object DEBUG
@@ -38,8 +39,7 @@ cdef class ObjectID:
cdef readonly int _locked
cdef object _hash
-cdef object standard_richcmp(object self, object other, int how)
-cdef object obj_hash(ObjectID obj)
+# Library init. Safe to call more than once.
cdef int init_hdf5() except -1
diff --git a/h5py/h5.pyx b/h5py/h5.pyx
index 5bcf12b..ea8b2fa 100644
--- a/h5py/h5.pyx
+++ b/h5py/h5.pyx
@@ -33,7 +33,7 @@
include "config.pxi"
-from python cimport PyErr_SetObject
+from python_exc cimport PyErr_SetString
import atexit
import threading
@@ -49,6 +49,41 @@ cdef class H5PYConfig:
self.API_18 = H5PY_18API
self.DEBUG = H5PY_DEBUG
self.THREADS = H5PY_THREADS
+ self._r_name = 'r'
+ self._i_name = 'i'
+
+ property complex_names:
+ """ Settable 2-tuple controlling how complex numbers are saved.
+ """
+
+ def __get__(self):
+ return (self._r_name, self._i_name)
+
+ def __set__(self, val):
+ try:
+ r = val[0]
+ i = val[1]
+ if not (isinstance(r, str) and isinstance(i, str)):
+ raise TypeError
+ except Exception:
+ raise TypeError("complex_names must be a 2-tuple (real, img)")
+ self._r_name = r
+ self._i_name = i
+
+ def __repr__(self):
+ rstr = \
+"""\
+Summary of h5py config
+======================
+1.6 API: %s
+1.8 API: %s
+Thread-aware: %s
+Diagnostic mode: %s
+Complex names: %s"""
+
+ rstr %= (bool(self.API_16), bool(self.API_18), bool(self.THREADS),
+ bool(self.DEBUG), self.complex_names)
+ return rstr
# === Bootstrap diagnostics and threading, before decorator is defined ===
@@ -118,6 +153,7 @@ cdef class PHIL:
return 0
cdef PHIL phil = PHIL()
+
cpdef PHIL get_phil():
""" Obtain a reference to the PHIL. """
return phil
@@ -128,50 +164,6 @@ include "sync.pxi"
# === Public C API for object identifiers =====================================
-cdef object standard_richcmp(object self, object other, int how):
- # HDF5 object identity is determined by comparing hash values. In the
- # absence of a logical comparision method (for example, TypeId.equal()),
- # this hash-based identity is used for comparison.
-
- # Subject to:
- # 1. Both must be of the same type
- # 2. Both must be hashable
- # 3. Only == and != comparisons are supported
- #
- # Otherwise NotImplemented is returned, for Python's fallback mechanics.
-
- if how != 2 and how != 3:
- return NotImplemented
-
- if not type(self) == type(other) and isinstance(self, ObjectID):
- return NotImplemented # Can't compare across types
-
- try:
- eq = (hash(self) == hash(other))
- except TypeError:
- return NotImplemented # Can't compare unhashable instances
-
- if how == 2:
- return eq
- return not eq
-
-cdef object obj_hash(ObjectID obj):
- # Try to compute the hash of the given file-resident object, raising
- # TypeError if it can't be done.
-
- # This is a counterpart to standard_richcmp.
-
- cdef H5G_stat_t stat
-
- phil.acquire()
- try:
- H5Gget_objinfo(obj.id, '.', 0, &stat)
- return hash((stat.fileno[0], stat.fileno[1], stat.objno[0], stat.objno[1]))
- except:
- raise TypeError("Objects of class %s cannot be hashed" % obj.__class__.__name__)
- finally:
- phil.release()
-
cdef class ObjectID:
"""
@@ -247,18 +239,46 @@ cdef class ObjectID:
phil.release()
def __richcmp__(self, object other, int how):
- """ Supports only == and != """
- return standard_richcmp(self, other, how)
+ """ Basic comparison for HDF5 objects. Implements only equality:
+
+ 1. Mismatched types always NOT EQUAL
+ 2. Try to compare object hashes
+ 3. If unhashable, compare identifiers
+ """
+ cdef bint truthval = 0
+
+ if how != 2 and how != 3:
+ return NotImplemented
+
+ if isinstance(other, ObjectID) and type(self) == type(other):
+ try:
+ truthval = hash(self) == hash(other)
+ except TypeError:
+ truthval = self.id == other.id
+
+ if how == 2:
+ return truthval
+ return not truthval
def __hash__(self):
- """ By default HDF5 objects are hashed based on their file and object
- numbers. Objects which are not file-resident cannot be hashed.
+ """ Default hash is computed from the object header, which requires
+ a file-resident object. TypeError if this can't be done.
"""
+ cdef H5G_stat_t stat
+
if self._hash is None:
- self._hash = obj_hash(self)
+ phil.acquire()
+ try:
+ H5Gget_objinfo(self.id, '.', 0, &stat)
+ self._hash = hash((stat.fileno[0], stat.fileno[1], stat.objno[0], stat.objno[1]))
+ except Exception:
+ raise TypeError("Objects of class %s cannot be hashed" % self.__class__.__name__)
+ finally:
+ phil.release()
+
return self._hash
- def __str__(self):
+ def __repr__(self):
phil.acquire()
try:
ref = str(H5Iget_ref(self.id)) if self._valid else "X"
@@ -267,8 +287,6 @@ cdef class ObjectID:
finally:
phil.release()
- def __repr__(self):
- return self.__str__()
# === HDF5 "H5" API ===========================================================
@@ -521,8 +539,7 @@ def error_stack():
H5Ewalk(H5E_WALK_DOWNWARD, walk_cb, <void*>stack)
return stack
- at nosync
-def error_string():
+cpdef object error_string():
""" () => STRING error_stack
Return a string representation of the current error condition.
@@ -587,24 +604,16 @@ cdef herr_t err_callback(void* client_data) with gil:
H5Ewalk(H5E_WALK_UPWARD, extract_cb, &err_struct)
mj = err_struct.maj_num
- exc = _exceptions.get(mj, H5Error)
+ try:
+ exc = _exceptions[mj]
+ except:
+ exc = H5Error
msg = error_string()
- PyErr_SetObject(exc, msg)
+ PyErr_SetString(exc, msg)
return 1
-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
-
-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
# === Library init ============================================================
@@ -632,20 +641,23 @@ def _exithack():
finally:
free(objs)
-cdef int _hdf5_inited = 0
+cdef int hdf5_inited = 0
cdef int init_hdf5() except -1:
# Initialize the library and set register Python callbacks for exception
# handling. Safe to call more than once.
+ global hdf5_inited
- if not _hdf5_inited:
+ if not hdf5_inited:
IF H5PY_DEBUG:
log_lib.info("* Initializing h5py library")
if H5open() < 0:
raise RuntimeError("Failed to initialize the HDF5 library.")
- _enable_exceptions()
+ if H5Eset_auto(err_callback, NULL) < 0:
+ raise RuntimeError("Failed to register HDF5 exception callback.")
atexit.register(_exithack)
- _hdf5_inited = 1
+ hdf5_inited = 1
+
return 0
init_hdf5()
diff --git a/h5py/h5a.pyx b/h5py/h5a.pyx
index 885eda8..319e259 100644
--- a/h5py/h5a.pyx
+++ b/h5py/h5a.pyx
@@ -19,18 +19,15 @@ include "sync.pxi"
# Compile-time imports
from h5 cimport init_hdf5
-from h5t cimport TypeID, typewrap
+from h5t cimport TypeID, typewrap, py_create
from h5s cimport SpaceID
from numpy cimport import_array, ndarray, PyArray_DATA
-from utils cimport check_numpy_read, check_numpy_write, \
- emalloc, efree
+from utils cimport check_numpy_read, check_numpy_write, emalloc, efree
# Initialization
init_hdf5()
import_array()
-# Runtime imports
-import h5t
# === General attribute operations ============================================
@@ -38,7 +35,7 @@ import h5t
def create(ObjectID loc not None, char* name, TypeID tid not None,
SpaceID space not None):
""" (ObjectID loc, STRING name, TypeID tid, SpaceID space)
- => INT attr_id
+ => AttrID
Create a new attribute attached to a parent object, specifiying an
HDF5 datatype and dataspace.
@@ -47,7 +44,7 @@ def create(ObjectID loc not None, char* name, TypeID tid not None,
@sync
def open_idx(ObjectID loc not None, int idx):
- """ (ObjectID loc_id, UINT idx) => INT attr_id
+ """ (ObjectID loc_id, UINT idx) => AttrID
Open an exisiting attribute on an object, by zero-based index.
"""
@@ -60,7 +57,7 @@ def open_idx(ObjectID loc not None, int idx):
@sync
def open_name(ObjectID loc not None, char* name):
- """ (ObjectID loc, STRING name) => INT attr_id
+ """ (ObjectID loc, STRING name) => AttrID
Open an existing attribute on an object, by name.
"""
@@ -178,6 +175,9 @@ cdef class AttrID(ObjectID):
name: The attribute's name
dtype: A Numpy dtype representing this attribute's type
shape: A Numpy-style shape tuple representing the dataspace
+
+ Hashable: No
+ Equality: Python default
"""
property name:
""" The attribute's name
@@ -232,7 +232,7 @@ cdef class AttrID(ObjectID):
space_id = H5Aget_space(self.id)
check_numpy_write(arr_obj, space_id)
- mtype = h5t.py_create(arr_obj.dtype)
+ mtype = py_create(arr_obj.dtype)
H5Aread(self.id, mtype.id, PyArray_DATA(arr_obj))
@@ -258,7 +258,7 @@ cdef class AttrID(ObjectID):
try:
space_id = H5Aget_space(self.id)
check_numpy_read(arr_obj, space_id)
- mtype = h5t.py_create(arr_obj.dtype)
+ mtype = py_create(arr_obj.dtype)
H5Awrite(self.id, mtype.id, PyArray_DATA(arr_obj))
diff --git a/h5py/h5d.pyx b/h5py/h5d.pyx
index 0129130..6c8c8e4 100644
--- a/h5py/h5d.pyx
+++ b/h5py/h5d.pyx
@@ -22,7 +22,7 @@ from h5 cimport init_hdf5
from numpy cimport ndarray, import_array, PyArray_DATA, NPY_WRITEABLE
from utils cimport check_numpy_read, check_numpy_write, \
require_tuple, convert_tuple, emalloc, efree
-from h5t cimport TypeID, typewrap
+from h5t cimport TypeID, typewrap, py_create
from h5s cimport SpaceID
from h5p cimport PropID, propwrap, pdefault
@@ -30,9 +30,6 @@ from h5p cimport PropID, propwrap, pdefault
init_hdf5()
import_array()
-# Runtime imports
-import h5t
-
# === Public constants and data structures ====================================
COMPACT = H5D_COMPACT
@@ -56,6 +53,7 @@ FILL_VALUE_UNDEFINED = H5D_FILL_VALUE_UNDEFINED
FILL_VALUE_DEFAULT = H5D_FILL_VALUE_DEFAULT
FILL_VALUE_USER_DEFINED = H5D_FILL_VALUE_USER_DEFINED
+
# === Basic dataset operations ================================================
@sync
@@ -119,6 +117,9 @@ cdef class DatasetID(ObjectID):
dtype: Numpy dtype representing the dataset type
shape: Numpy-style shape tuple representing the dataspace
rank: Integer giving dataset rank
+
+ Hashable: Yes, if not anonymous
+ Equality: HDF5 identity if not anonymous, otherwise Python default
"""
property dtype:
@@ -186,7 +187,7 @@ cdef class DatasetID(ObjectID):
cdef void* data
cdef int oldflags
- mtype = h5t.py_create(arr_obj.dtype)
+ mtype = py_create(arr_obj.dtype)
check_numpy_write(arr_obj, -1)
self_id = self.id
@@ -226,7 +227,7 @@ cdef class DatasetID(ObjectID):
cdef void* data
cdef int oldflags
- mtype = h5t.py_create(arr_obj.dtype)
+ mtype = py_create(arr_obj.dtype)
check_numpy_read(arr_obj, -1)
self_id = self.id
diff --git a/h5py/h5f.pyx b/h5py/h5f.pyx
index bff07c2..c4dfb10 100644
--- a/h5py/h5f.pyx
+++ b/h5py/h5f.pyx
@@ -243,6 +243,9 @@ cdef class FileID(ObjectID):
Properties:
name: File name on disk
+
+ Hashable: Yes, always
+ Equality: HDF5 object identity
"""
property name:
diff --git a/h5py/h5g.pyx b/h5py/h5g.pyx
index 7a0205d..d8ec0d3 100644
--- a/h5py/h5g.pyx
+++ b/h5py/h5g.pyx
@@ -18,7 +18,7 @@ include "config.pxi"
include "sync.pxi"
# Compile-time imports
-from h5 cimport init_hdf5, standard_richcmp
+from h5 cimport init_hdf5
from utils cimport emalloc, efree
from h5p cimport PropID, pdefault
IF H5PY_18API:
@@ -260,6 +260,8 @@ cdef class GroupID(ObjectID):
providing access to the H5L family of routines. See the docs
for h5py.h5l.LinkProxy for more information.
+ Hashable: Yes, unless anonymous
+ Equality: HDF5 object identity if not anonymous, or NotImplemented
"""
IF H5PY_18API:
diff --git a/h5py/h5l.pyx b/h5py/h5l.pyx
index 0d39abd..8932364 100644
--- a/h5py/h5l.pyx
+++ b/h5py/h5l.pyx
@@ -9,7 +9,6 @@
# $Date$
#
#-
-from utils cimport pybool
"""
API for the "H5L" family of link-related operations
@@ -36,6 +35,8 @@ cdef class LinkProxy(ObjectID):
>>> g.links.exists("FooBar")
False
+ Hashable: No
+ Equality: Undefined
"""
def __cinit__(self, hid_t id_):
@@ -46,13 +47,19 @@ cdef class LinkProxy(ObjectID):
# shared by both this object and the parent.
H5Iinc_ref(self.id)
+ def __richcmp__(self, object other, int how):
+ return NotImplemented
+
+ def __hash__(self):
+ raise TypeError("Link proxies are unhashable; use the parent group instead.")
+
@sync
def exists(self, char* name):
""" (STRING name) => BOOL
Check if a link of the specified name exists in this group.
"""
- return pybool(H5Lexists(self.id, name, H5P_DEFAULT))
+ return <bint>(H5Lexists(self.id, name, H5P_DEFAULT))
diff --git a/h5py/h5o.pyx b/h5py/h5o.pyx
index 8a03b1e..c97c894 100644
--- a/h5py/h5o.pyx
+++ b/h5py/h5o.pyx
@@ -17,7 +17,7 @@ include "sync.pxi"
# built with API compatibility level below 1.8.
# Pyrex compile-time imports
-from h5 cimport init_hdf5
+from h5 cimport init_hdf5, ObjectID
from h5f cimport wrap_identifier
# Initialization
@@ -47,6 +47,7 @@ cdef class ObjInfo:
newcopy.infostruct = self.infostruct
return newcopy
+ at sync
def get_info(ObjectID obj not None):
""" (ObjectID obj) => ObjInfo
"""
@@ -91,7 +92,7 @@ cdef herr_t visit_cb(hid_t obj, char* name, H5O_info_t *info, void* data):
return 0
-
+ at sync
def visit(ObjectID obj not None, object func, int idx_type=H5_INDEX_NAME,
int order=H5_ITER_NATIVE):
""" (ObjectID obj, CALLABLE func, INT idx_type=, INT order=)
diff --git a/h5py/h5p.pyx b/h5py/h5p.pyx
index 1bb31c4..41b22bf 100644
--- a/h5py/h5p.pyx
+++ b/h5py/h5p.pyx
@@ -19,33 +19,20 @@ include "config.pxi"
include "sync.pxi"
# Compile-time imports
-from h5 cimport init_hdf5, standard_richcmp
+from h5 cimport init_hdf5
from utils cimport require_tuple, convert_dims, convert_tuple, \
emalloc, efree, require_list, \
check_numpy_write, check_numpy_read
from numpy cimport ndarray, import_array
-from h5t cimport TypeID
+from h5t cimport TypeID, py_create
# Initialization
init_hdf5()
import_array()
-# Runtime imports
-import h5t
# === C API ===================================================================
-cdef class PropClassID(PropID):
-
- def __richcmp__(self, object other, int how):
- return standard_richcmp(self, other, how)
-
- def __hash__(self):
- """ Since classes are library-created and immutable, they are uniquely
- identified by their HDF5 identifiers.
- """
- return hash(self.id)
-
cdef hid_t pdefault(PropID pid):
if pid is None:
@@ -97,6 +84,7 @@ DEFAULT = None # In the HDF5 header files this is actually 0, which is an
# === Property list functional API ============================================
+ at sync
def create(PropClassID cls not None):
""" (PropClassID cls) => PropID
@@ -118,6 +106,7 @@ cdef class PropID(ObjectID):
Base class for all property lists and classes
"""
+ @sync
def equal(self, PropID plist not None):
""" (PropID plist) => BOOL
@@ -125,13 +114,49 @@ cdef class PropID(ObjectID):
"""
return <bint>(H5Pequal(self.id, plist.id))
+ def __richcmp__(self, object other, int how):
+ cdef bint truthval = 0
+ if how != 2 and how != 3:
+ return NotImplemented
+ if type(self) == type(other):
+ truthval = self.equal(other)
+
+ if how == 2:
+ return truthval
+ return not truthval
+
+ def __hash__(self):
+ raise TypeError("Property lists are unhashable")
+
+cdef class PropClassID(PropID):
+
+ """
+ An HDF5 property list class.
+
+ Hashable: Yes, by identifier
+ Equality: Logical H5P comparison
+ """
+
+ def __richcmp__(self, object other, int how):
+ return PropID.__richcmp__(self, other, how)
+
+ def __hash__(self):
+ """ Since classes are library-created and immutable, they are uniquely
+ identified by their HDF5 identifiers.
+ """
+ return hash(self.id)
+
cdef class PropInstanceID(PropID):
"""
Base class for property list instance objects. Provides methods which
are common across all HDF5 property list classes.
+
+ Hashable: No
+ Equality: Logical H5P comparison
"""
+ @sync
def copy(self):
""" () => PropList newid
@@ -139,6 +164,7 @@ cdef class PropInstanceID(PropID):
"""
return type(self)(H5Pcopy(self.id))
+ @sync
def _close(self):
""" ()
@@ -148,6 +174,7 @@ cdef class PropInstanceID(PropID):
"""
H5Pclose(self.id)
+ @sync
def get_class(self):
""" () => PropClassID
@@ -164,6 +191,7 @@ cdef class PropFCID(PropInstanceID):
File creation property list.
"""
+ @sync
def get_version(self):
""" () => TUPLE version_info
@@ -185,7 +213,7 @@ cdef class PropFCID(PropInstanceID):
return (super_, freelist, stab, shhdr)
-
+ @sync
def set_userblock(self, hsize_t size):
""" (INT/LONG size)
@@ -194,6 +222,7 @@ cdef class PropFCID(PropInstanceID):
"""
H5Pset_userblock(self.id, size)
+ @sync
def get_userblock(self):
""" () => LONG size
@@ -203,6 +232,7 @@ cdef class PropFCID(PropInstanceID):
H5Pget_userblock(self.id, &size)
return size
+ @sync
def set_sizes(self, size_t addr, size_t size):
""" (UINT addr, UINT size)
@@ -211,6 +241,7 @@ cdef class PropFCID(PropInstanceID):
"""
H5Pset_sizes(self.id, addr, size)
+ @sync
def get_sizes(self):
""" () => TUPLE sizes
@@ -225,6 +256,7 @@ cdef class PropFCID(PropInstanceID):
H5Pget_sizes(self.id, &addr, &size)
return (addr, size)
+ @sync
def set_sym_k(self, unsigned int ik, unsigned int lk):
""" (INT ik, INT lk)
@@ -232,6 +264,7 @@ cdef class PropFCID(PropInstanceID):
"""
H5Pset_sym_k(self.id, ik, lk)
+ @sync
def get_sym_k(self):
""" () => TUPLE settings
@@ -243,6 +276,7 @@ cdef class PropFCID(PropInstanceID):
H5Pget_sym_k(self.id, &ik, &lk)
return (ik, lk)
+ @sync
def set_istore_k(self, unsigned int ik):
""" (UINT ik)
@@ -250,6 +284,7 @@ cdef class PropFCID(PropInstanceID):
"""
H5Pset_istore_k(self.id, ik)
+ @sync
def get_istore_k(self):
""" () => UINT ik
@@ -267,6 +302,7 @@ cdef class PropDCID(PropInstanceID):
Dataset creation property list.
"""
+ @sync
def set_layout(self, int layout_code):
""" (INT layout_code)
@@ -277,6 +313,7 @@ cdef class PropDCID(PropInstanceID):
"""
H5Pset_layout(self.id, layout_code)
+ @sync
def get_layout(self):
""" () => INT layout_code
@@ -287,7 +324,7 @@ cdef class PropDCID(PropInstanceID):
"""
return <int>H5Pget_layout(self.id)
-
+ @sync
def set_chunk(self, object chunksize):
""" (TUPLE chunksize)
@@ -307,7 +344,8 @@ cdef class PropDCID(PropInstanceID):
H5Pset_chunk(self.id, rank, dims)
finally:
efree(dims)
-
+
+ @sync
def get_chunk(self):
""" () => TUPLE chunk_dimensions
@@ -327,6 +365,7 @@ cdef class PropDCID(PropInstanceID):
finally:
efree(dims)
+ @sync
def set_fill_value(self, ndarray value not None):
""" (NDARRAY value)
@@ -337,9 +376,10 @@ cdef class PropDCID(PropInstanceID):
cdef TypeID tid
check_numpy_read(value, -1)
- tid = h5t.py_create(value.dtype)
+ tid = py_create(value.dtype)
H5Pset_fill_value(self.id, tid.id, value.data)
+ @sync
def get_fill_value(self, ndarray value not None):
""" (NDARRAY value)
@@ -350,9 +390,10 @@ cdef class PropDCID(PropInstanceID):
cdef TypeID tid
check_numpy_write(value, -1)
- tid = h5t.py_create(value.dtype)
+ tid = py_create(value.dtype)
H5Pget_fill_value(self.id, tid.id, value.data)
+ @sync
def set_fill_time(self, int fill_time):
""" (INT fill_time)
@@ -366,6 +407,7 @@ cdef class PropDCID(PropInstanceID):
"""
H5Pset_fill_time(self.id, <H5D_fill_time_t>fill_time)
+ @sync
def get_fill_time(self):
""" () => INT
@@ -381,8 +423,10 @@ cdef class PropDCID(PropInstanceID):
H5Pget_fill_time(self.id, &fill_time)
return <int>fill_time
+
# === Filter functions ====================================================
+ @sync
def set_deflate(self, unsigned int level=5):
""" (UINT level=5)
@@ -390,7 +434,8 @@ cdef class PropDCID(PropInstanceID):
Valid levels are 0-9, default is 5.
"""
H5Pset_deflate(self.id, level)
-
+
+ @sync
def set_fletcher32(self):
""" ()
@@ -398,6 +443,7 @@ cdef class PropDCID(PropInstanceID):
"""
H5Pset_fletcher32(self.id)
+ @sync
def set_shuffle(self):
""" ()
@@ -406,6 +452,7 @@ cdef class PropDCID(PropInstanceID):
"""
H5Pset_shuffle(self.id)
+ @sync
def set_szip(self, unsigned int options, unsigned int pixels_per_block):
""" (UINT options, UINT pixels_per_block)
@@ -414,6 +461,7 @@ cdef class PropDCID(PropInstanceID):
"""
H5Pset_szip(self.id, options, pixels_per_block)
+ @sync
def get_nfilters(self):
""" () => INT
@@ -421,6 +469,7 @@ cdef class PropDCID(PropInstanceID):
"""
return H5Pget_nfilters(self.id)
+ @sync
def set_filter(self, int filter_code, unsigned int flags=0, object values=None):
""" (INT filter_code, UINT flags=0, TUPLE values=None)
@@ -458,6 +507,7 @@ cdef class PropDCID(PropInstanceID):
finally:
efree(cd_values)
+ @sync
def all_filters_avail(self):
""" () => BOOL
@@ -466,6 +516,7 @@ cdef class PropDCID(PropInstanceID):
"""
return <bint>(H5Pall_filters_avail(self.id))
+ @sync
def get_filter(self, int filter_idx):
""" (UINT filter_idx) => TUPLE filter_info
@@ -499,6 +550,7 @@ cdef class PropDCID(PropInstanceID):
return (filter_code, flags, tuple(vlist), name)
+ @sync
def _has_filter(self, int filter_code):
""" (INT filter_code)
@@ -513,6 +565,7 @@ cdef class PropDCID(PropInstanceID):
return True
return False
+ @sync
def get_filter_by_id(self, int filter_code):
""" (INT filter_code) => TUPLE filter_info or None
@@ -549,6 +602,7 @@ cdef class PropDCID(PropInstanceID):
return (flags, tuple(vlist), name)
+ @sync
def remove_filter(self, int filter_class):
""" (INT filter_class)
@@ -557,6 +611,7 @@ cdef class PropDCID(PropInstanceID):
"""
H5Premove_filter(self.id, <H5Z_filter_t>filter_class)
+ @sync
def fill_value_defined(self):
""" () => INT fill_status
@@ -578,6 +633,7 @@ cdef class PropFAID(PropInstanceID):
File access property list
"""
+ @sync
def set_fclose_degree(self, int close_degree):
""" (INT close_degree)
@@ -591,6 +647,7 @@ cdef class PropFAID(PropInstanceID):
"""
H5Pset_fclose_degree(self.id, <H5F_close_degree_t>close_degree)
+ @sync
def get_fclose_degree(self):
""" () => INT close_degree
@@ -606,6 +663,7 @@ cdef class PropFAID(PropInstanceID):
H5Pget_fclose_degree(self.id, °)
return deg
+ @sync
def set_fapl_core(self, size_t increment=1024*1024, hbool_t backing_store=0):
""" (UINT increment=1M, BOOL backing_store=False)
@@ -616,6 +674,7 @@ cdef class PropFAID(PropInstanceID):
"""
H5Pset_fapl_core(self.id, increment, backing_store)
+ @sync
def get_fapl_core(self):
""" () => TUPLE core_settings
@@ -630,6 +689,7 @@ cdef class PropFAID(PropInstanceID):
H5Pget_fapl_core(self.id, &increment, &backing_store)
return (increment, <bint>(backing_store))
+ @sync
def set_fapl_family(self, hsize_t memb_size, PropID memb_fapl=None):
""" (UINT memb_size, PropFAID memb_fapl=None)
@@ -641,6 +701,7 @@ cdef class PropFAID(PropInstanceID):
plist_id = pdefault(memb_fapl)
H5Pset_fapl_family(self.id, memb_size, plist_id)
+ @sync
def get_fapl_family(self):
""" () => TUPLE info
@@ -660,6 +721,7 @@ cdef class PropFAID(PropInstanceID):
return (msize, plist)
+ @sync
def set_fapl_log(self, char* logfile, unsigned int flags, size_t buf_size):
""" (STRING logfile, UINT flags, UINT buf_size)
@@ -668,6 +730,7 @@ cdef class PropFAID(PropInstanceID):
"""
H5Pset_fapl_log(self.id, logfile, flags, buf_size)
+ @sync
def set_fapl_sec2(self):
""" ()
@@ -675,6 +738,7 @@ cdef class PropFAID(PropInstanceID):
"""
H5Pset_fapl_sec2(self.id)
+ @sync
def set_fapl_stdio(self):
""" ()
@@ -682,6 +746,7 @@ cdef class PropFAID(PropInstanceID):
"""
H5Pset_fapl_stdio(self.id)
+ @sync
def get_driver(self):
""" () => INT driver code
@@ -699,6 +764,7 @@ cdef class PropFAID(PropInstanceID):
"""
return H5Pget_driver(self.id)
+ @sync
def set_cache(self, int mdc, int rdcc, size_t rdcc_nbytes, double rdcc_w0):
""" (INT mdc, INT rdcc, UINT rdcc_nbytes, DOUBLE rdcc_w0)
@@ -707,6 +773,7 @@ cdef class PropFAID(PropInstanceID):
"""
H5Pset_cache(self.id, mdc, rdcc, rdcc_nbytes, rdcc_w0)
+ @sync
def get_cache(self):
""" () => TUPLE cache info
diff --git a/h5py/h5r.pyx b/h5py/h5r.pyx
index 88c53df..c8077fe 100644
--- a/h5py/h5r.pyx
+++ b/h5py/h5r.pyx
@@ -36,6 +36,7 @@ DATASET_REGION = H5R_DATASET_REGION
# === Reference API ===========================================================
+ at sync
def create(ObjectID loc not None, char* name, int ref_type, SpaceID space=None):
""" (ObjectID loc, STRING name, INT ref_type, SpaceID space=None)
=> ReferenceObject ref
@@ -76,6 +77,7 @@ cdef class Reference:
or a dataset region (DATASET_REGION).
"""
+ @sync
def dereference(self, ObjectID id not None):
""" (ObjectID id) => ObjectID obj_id
@@ -87,6 +89,7 @@ cdef class Reference:
"""
return wrap_identifier(H5Rdereference(id.id, <H5R_type_t>self.typecode, &self.ref))
+ @sync
def get_region(self, ObjectID id not None):
""" (ObjectID id) => SpaceID dataspace_id
@@ -100,6 +103,7 @@ cdef class Reference:
"""
return SpaceID(H5Rget_region(id.id, <H5R_type_t>self.typecode, &self.ref))
+ @sync
def get_obj_type(self, ObjectID id not None):
""" (ObjectID id) => INT obj_code
@@ -116,6 +120,7 @@ cdef class Reference:
"""
return <int>H5Rget_obj_type(id.id, <H5R_type_t>self.typecode, &self.ref)
+ @nosync
def __str__(self):
if self.typecode == H5R_OBJECT:
return "HDF5 object reference"
diff --git a/h5py/h5s.pyx b/h5py/h5s.pyx
index b9b4086..920ec92 100644
--- a/h5py/h5s.pyx
+++ b/h5py/h5s.pyx
@@ -22,7 +22,7 @@ from h5 cimport init_hdf5
from utils cimport require_tuple, require_list, convert_dims, convert_tuple, \
emalloc, efree, create_numpy_hsize, create_hsize_array
from numpy cimport ndarray
-from python cimport PyString_FromStringAndSize
+from python_string cimport PyString_FromStringAndSize
# Initialization
init_hdf5()
@@ -65,6 +65,7 @@ SEL_ALL = H5S_SEL_ALL
# === Basic dataspace operations ==============================================
+ at sync
def create(int class_code):
""" (INT class_code) => SpaceID
@@ -109,6 +110,7 @@ def create_simple(object dims_tpl, object max_dims_tpl=None):
efree(max_dims)
IF H5PY_18API:
+ @sync
def decode(buf):
""" (STRING buf) => SpaceID
@@ -128,6 +130,9 @@ cdef class SpaceID(ObjectID):
Properties:
shape: Numpy-style shape tuple with dimensions.
+
+ Hashable: No
+ Equality: Unimplemented
"""
property shape:
@@ -136,6 +141,7 @@ cdef class SpaceID(ObjectID):
def __get__(self):
return self.get_simple_extent_dims()
+ @sync
def _close(self):
""" ()
@@ -145,6 +151,7 @@ cdef class SpaceID(ObjectID):
"""
H5Sclose(self.id)
+ @sync
def copy(self):
""" () => SpaceID
@@ -152,7 +159,8 @@ cdef class SpaceID(ObjectID):
"""
return SpaceID(H5Scopy(self.id))
- IF H5PY_18API:
+ IF H5PY_18API:
+ @sync
def encode(self):
""" () => STRING
@@ -177,9 +185,11 @@ cdef class SpaceID(ObjectID):
IF H5PY_18API:
# Enable pickling
+ @nosync
def __reduce__(self):
return (type(self), (-1,), self.encode())
+ @sync
def __setstate__(self, state):
cdef char* buf
buf = state
@@ -187,6 +197,7 @@ cdef class SpaceID(ObjectID):
# === Simple dataspaces ===================================================
+ @sync
def is_simple(self):
""" () => BOOL is_simple
@@ -195,6 +206,7 @@ cdef class SpaceID(ObjectID):
"""
return <bint>(H5Sis_simple(self.id))
+ @sync
def offset_simple(self, object offset=None):
""" (TUPLE offset=None)
@@ -229,6 +241,7 @@ cdef class SpaceID(ObjectID):
finally:
efree(dims)
+ @sync
def get_simple_extent_ndims(self):
""" () => INT rank
@@ -236,6 +249,7 @@ cdef class SpaceID(ObjectID):
"""
return H5Sget_simple_extent_ndims(self.id)
+ @sync
def get_simple_extent_dims(self, int maxdims=0):
""" (BOOL maxdims=False) => TUPLE shape
@@ -260,6 +274,7 @@ cdef class SpaceID(ObjectID):
finally:
efree(dims)
+ @sync
def get_simple_extent_npoints(self):
""" () => LONG npoints
@@ -267,6 +282,7 @@ cdef class SpaceID(ObjectID):
"""
return H5Sget_simple_extent_npoints(self.id)
+ @sync
def get_simple_extent_type(self):
""" () => INT class_code
@@ -276,6 +292,7 @@ cdef class SpaceID(ObjectID):
# === Extents =============================================================
+ @sync
def extent_copy(self, SpaceID source not None):
""" (SpaceID source)
@@ -284,6 +301,7 @@ cdef class SpaceID(ObjectID):
"""
H5Sextent_copy(self.id, source.id)
+ @sync
def set_extent_simple(self, object dims_tpl, object max_dims_tpl=None):
""" (TUPLE dims_tpl, TUPLE max_dims_tpl=None)
@@ -318,6 +336,7 @@ cdef class SpaceID(ObjectID):
efree(dims)
efree(max_dims)
+ @sync
def set_extent_none(self):
""" ()
@@ -327,6 +346,7 @@ cdef class SpaceID(ObjectID):
# === General selection operations ========================================
+ @sync
def get_select_type(self):
""" () => INT select_code
@@ -338,6 +358,7 @@ cdef class SpaceID(ObjectID):
"""
return <int>H5Sget_select_type(self.id)
+ @sync
def get_select_npoints(self):
""" () => LONG npoints
@@ -346,6 +367,7 @@ cdef class SpaceID(ObjectID):
"""
return H5Sget_select_npoints(self.id)
+ @sync
def get_select_bounds(self):
""" () => (TUPLE start, TUPLE end)
@@ -374,6 +396,7 @@ cdef class SpaceID(ObjectID):
efree(start)
efree(end)
+ @sync
def select_all(self):
""" ()
@@ -381,6 +404,7 @@ cdef class SpaceID(ObjectID):
"""
H5Sselect_all(self.id)
+ @sync
def select_none(self):
""" ()
@@ -388,6 +412,7 @@ cdef class SpaceID(ObjectID):
"""
H5Sselect_none(self.id)
+ @sync
def select_valid(self):
""" () => BOOL select_valid
@@ -398,6 +423,7 @@ cdef class SpaceID(ObjectID):
# === Point selection functions ===========================================
+ @sync
def get_select_elem_npoints(self):
""" () => LONG npoints
@@ -405,6 +431,7 @@ cdef class SpaceID(ObjectID):
"""
return H5Sget_select_elem_npoints(self.id)
+ @sync
def get_select_elem_pointlist(self):
""" () => NDARRAY elements_list
@@ -423,6 +450,7 @@ cdef class SpaceID(ObjectID):
return buf
+ @sync
def select_elements(self, object coords, int op=H5S_SELECT_SET):
""" (SEQUENCE coords, INT op=SELECT_SET)
@@ -459,6 +487,7 @@ cdef class SpaceID(ObjectID):
# === Hyperslab selection functions =======================================
+ @sync
def get_select_hyper_nblocks(self):
""" () => LONG nblocks
@@ -466,6 +495,7 @@ cdef class SpaceID(ObjectID):
"""
return H5Sget_select_hyper_nblocks(self.id)
+ @sync
def get_select_hyper_blocklist(self):
""" () => NDARRAY hyperslab_blocks
@@ -492,6 +522,7 @@ cdef class SpaceID(ObjectID):
return buf
+ @sync
def select_hyperslab(self, object start, object count, object stride=None,
object block=None, int op=H5S_SELECT_SET):
""" (TUPLE start, TUPLE count, TUPLE stride=None, TUPLE block=None,
diff --git a/h5py/h5t.pxd b/h5py/h5t.pxd
index 1b8076c..448cc87 100644
--- a/h5py/h5t.pxd
+++ b/h5py/h5t.pxd
@@ -66,7 +66,15 @@ cdef class TypeEnumID(TypeCompositeID):
cdef class TypeCompoundID(TypeCompositeID):
pass
+# === C API for other modules =================================================
+
cdef object typewrap(hid_t id_)
+cpdef object py_create(object dtype, object enum_vals=*)
+
+
+
+
+
diff --git a/h5py/h5t.pyx b/h5py/h5t.pyx
index 9b1b994..81c2279 100644
--- a/h5py/h5t.pyx
+++ b/h5py/h5t.pyx
@@ -35,8 +35,8 @@
fields. When a two-element compound type is encountered in a file with
compatible field names, it is treated as a complex type.
- The names for these fields are taken from a global, which can be set
- via the module function py_complex_names(realname, imgname).
+ The names for complex types are set as a property on the global
+ configuration object, available at h5.config.
3. Enumerated types
@@ -61,9 +61,9 @@ include "config.pxi"
include "sync.pxi"
# Pyrex compile-time imports
-from h5 cimport init_hdf5, PHIL, get_phil
+from h5 cimport init_hdf5, PHIL, get_phil, H5PYConfig
from numpy cimport dtype, ndarray
-from python cimport PyString_FromStringAndSize
+from python_string cimport PyString_FromStringAndSize
from utils cimport emalloc, efree, \
create_ieee_complex64, create_ieee_complex128, \
@@ -74,10 +74,12 @@ init_hdf5()
# Runtime imports
import sys
+import h5
+cdef H5PYConfig cfg = h5.config
# === Custom C API ============================================================
-
+
cdef object typewrap(hid_t id_):
cdef H5T_class_t cls
@@ -118,7 +120,6 @@ cdef object lockid(hid_t id_in):
# === Public constants and data structures ====================================
-_complex_names = ('r','i')
# Enumeration H5T_class_t
NO_CLASS = H5T_NO_CLASS
@@ -225,28 +226,14 @@ STD_REF_DSETREG = lockid(H5T_STD_REF_DSETREG)
C_S1 = lockid(H5T_C_S1)
FORTRAN_S1 = lockid(H5T_FORTRAN_S1)
-# Map array protocol strings to their HDF5 atomic equivalents
-# Not sure why LE/BE versions of I8/U8 exist; I'll include them anyway.
-_code_map = {
- "<i1": STD_I8LE, "<i2": STD_I16LE, "<i4": STD_I32LE, "<i8": STD_I64LE,
- ">i1": STD_I8BE, ">i2": STD_I16BE, ">i4": STD_I32BE, ">i8": STD_I64BE,
- "|i1": NATIVE_INT8, "|u1": NATIVE_UINT8,
- "<u1": STD_U8LE, "<u2": STD_U16LE, "<u4": STD_U32LE, "<u8": STD_U64LE,
- ">u1": STD_U8BE, ">u2": STD_U16BE, ">u4": STD_U32BE, ">u8": STD_U64BE,
- "<f4": IEEE_F32LE, "<f8": IEEE_F64LE, ">f4": IEEE_F32BE, ">f8": IEEE_F64BE
- }
-
-# Intermediate mapping which takes complex types to their components
-_complex_map = { "<c8": IEEE_F32LE, "<c16": IEEE_F64LE,
- ">c8": IEEE_F32BE, ">c16": IEEE_F64BE }
-
-_order_map = { H5T_ORDER_NONE: '|', H5T_ORDER_LE: '<', H5T_ORDER_BE: '>'}
-_sign_map = { H5T_SGN_NONE: 'u', H5T_SGN_2: 'i' }
-
+# Translation tables for HDF5 -> NumPy dtype conversion
+cdef dict _order_map = { H5T_ORDER_NONE: '|', H5T_ORDER_LE: '<', H5T_ORDER_BE: '>'}
+cdef dict _sign_map = { H5T_SGN_NONE: 'u', H5T_SGN_2: 'i' }
# === General datatype operations =============================================
+ at sync
def create(int classtype, size_t size):
""" (INT classtype, UINT size) => TypeID
@@ -260,6 +247,7 @@ def create(int classtype, size_t size):
return typewrap(H5Tcreate(<H5T_class_t>classtype, size))
+ at sync
def open(ObjectID group not None, char* name):
""" (ObjectID group, STRING name) => TypeID
@@ -267,6 +255,7 @@ def open(ObjectID group not None, char* name):
"""
return typewrap(H5Topen(group.id, name))
+ at sync
def array_create(TypeID base not None, object dims_tpl):
""" (TypeID base, TUPLE dimensions)
@@ -288,6 +277,7 @@ def array_create(TypeID base not None, object dims_tpl):
finally:
efree(dims)
+ at sync
def enum_create(TypeID base not None):
""" (TypeID base) => TypeID
@@ -295,6 +285,7 @@ def enum_create(TypeID base not None):
"""
return typewrap(H5Tenum_create(base.id))
+ at sync
def vlen_create(TypeID base not None):
""" (TypeID base) => TypeID
@@ -306,6 +297,7 @@ def vlen_create(TypeID base not None):
return typewrap(H5Tvlen_create(base.id))
IF H5PY_18API:
+ @sync
def decode(buf):
""" (STRING buf) => TypeID
@@ -322,13 +314,50 @@ cdef class TypeID(ObjectID):
"""
Base class for type identifiers (implements common operations)
+
+ Hashable: If locked and committed; in HDF5 1.8.X, also if only locked
+ Equality: Logical H5T comparison
"""
+ def __hash__(self):
+ try:
+ # Try to use object header first
+ return ObjectID.__hash__(self)
+ except TypeError:
+ # It's a transient type object
+ IF H5PY_18API:
+ if self._locked:
+ self._hash = hash(self.encode())
+ else:
+ raise TypeError("Only locked or committed types can be hashed")
+ ELSE:
+ raise TypeError("Only committed types can be hashed")
+
+ return self._hash
+
+ def __richcmp__(self, object other, int how):
+ cdef bint truthval = 0
+ if how != 2 and how != 3:
+ return NotImplemented
+ if isinstance(other, TypeID):
+ truthval = self.equal(other)
+
+ if how == 2:
+ return truthval
+ return not truthval
+
def __copy__(self):
cdef TypeID cpy
cpy = ObjectID.__copy__(self)
return cpy
+ def __repr__(self):
+ try:
+ dstr = " "+self.dtype.str
+ except Exception:
+ dstr = ""
+ return ObjectID.__repr__(self)+dstr
+
property dtype:
""" A Numpy-style dtype object representing this object.
"""
@@ -336,16 +365,9 @@ cdef class TypeID(ObjectID):
return self.py_dtype()
cdef object py_dtype(self):
- raise NotImplementedError("Don't know how to convert %s objects to Numpy" % self.__class__.__name__)
-
- def __repr__(self):
- try:
- dts = str(self.dtype)
- except:
- dts = "(Numpy type unknown)"
-
- return str(self)+" "+dts
+ raise TypeError("No NumPy equivalent for %s exists" % self.__class__.__name__)
+ @sync
def commit(self, ObjectID group not None, char* name):
""" (ObjectID group, STRING name)
@@ -353,6 +375,7 @@ cdef class TypeID(ObjectID):
"""
H5Tcommit(group.id, name, self.id)
+ @sync
def committed(self):
""" () => BOOL is_comitted
@@ -360,6 +383,7 @@ cdef class TypeID(ObjectID):
"""
return <bint>(H5Tcommitted(self.id))
+ @sync
def copy(self):
""" () => TypeID
@@ -367,14 +391,16 @@ cdef class TypeID(ObjectID):
"""
return typewrap(H5Tcopy(self.id))
+ @sync
def equal(self, TypeID typeid):
""" (TypeID typeid) => BOOL
- Test whether two identifiers refer to the same datatype. Seems
- to perform a logical comparison.
+ Logical comparison between datatypes. Also called by
+ Python's "==" operator.
"""
return <bint>(H5Tequal(self.id, typeid.id))
+ @sync
def lock(self):
""" ()
@@ -384,6 +410,7 @@ cdef class TypeID(ObjectID):
H5Tlock(self.id)
self._locked = 1
+ @sync
def get_class(self):
""" () => INT classcode
@@ -391,6 +418,7 @@ cdef class TypeID(ObjectID):
"""
return <int>H5Tget_class(self.id)
+ @sync
def set_size(self, size_t size):
""" (UINT size)
@@ -398,6 +426,7 @@ cdef class TypeID(ObjectID):
"""
H5Tset_size(self.id, size)
+ @sync
def get_size(self):
""" () => INT size
@@ -405,6 +434,7 @@ cdef class TypeID(ObjectID):
"""
return H5Tget_size(self.id)
+ @sync
def get_super(self):
""" () => TypeID
@@ -412,6 +442,7 @@ cdef class TypeID(ObjectID):
"""
return typewrap(H5Tget_super(self.id))
+ @sync
def detect_class(self, int classtype):
""" (INT classtype) => BOOL class_is_present
@@ -420,6 +451,7 @@ cdef class TypeID(ObjectID):
"""
return <bint>(H5Tdetect_class(self.id, <H5T_class_t>classtype))
+ @sync
def _close(self):
""" Close this datatype. If it's locked, nothing happens.
@@ -430,6 +462,7 @@ cdef class TypeID(ObjectID):
H5Tclose(self.id)
IF H5PY_18API:
+ @sync
def encode(self):
""" () => STRING
@@ -458,11 +491,13 @@ cdef class TypeID(ObjectID):
def __reduce__(self):
return (type(self), (-1,), self.encode())
+ @sync
def __setstate__(self, state):
cdef char* buf
buf = state
self.id = H5Tdecode(<unsigned char*>buf)
+
# === Top-level classes (inherit directly from TypeID) ========================
cdef class TypeArrayID(TypeID):
@@ -471,6 +506,7 @@ cdef class TypeArrayID(TypeID):
Represents an array datatype
"""
+ @sync
def get_array_ndims(self):
""" () => INT rank
@@ -478,6 +514,7 @@ cdef class TypeArrayID(TypeID):
"""
return H5Tget_array_ndims(self.id)
+ @sync
def get_array_dims(self):
""" () => TUPLE dimensions
@@ -513,6 +550,7 @@ cdef class TypeOpaqueID(TypeID):
Represents an opaque type
"""
+ @sync
def set_tag(self, char* tag):
""" (STRING tag)
@@ -521,6 +559,7 @@ cdef class TypeOpaqueID(TypeID):
"""
H5Tset_tag(self.id, tag)
+ @sync
def get_tag(self):
""" () => STRING tag
@@ -547,6 +586,7 @@ cdef class TypeStringID(TypeID):
String datatypes, both fixed and vlen.
"""
+ @sync
def is_variable_str(self):
""" () => BOOL is_variable
@@ -556,6 +596,7 @@ cdef class TypeStringID(TypeID):
"""
return <bint>(H5Tis_variable_str(self.id))
+ @sync
def get_cset(self):
""" () => INT character_set
@@ -564,6 +605,7 @@ cdef class TypeStringID(TypeID):
"""
return <int>H5Tget_cset(self.id)
+ @sync
def set_cset(self, int cset):
""" (INT character_set)
@@ -572,6 +614,7 @@ cdef class TypeStringID(TypeID):
"""
H5Tset_cset(self.id, <H5T_cset_t>cset)
+ @sync
def get_strpad(self):
""" () => INT padding_type
@@ -582,6 +625,7 @@ cdef class TypeStringID(TypeID):
"""
return <int>H5Tget_strpad(self.id)
+ @sync
def set_strpad(self, int pad):
""" (INT pad)
@@ -595,7 +639,7 @@ cdef class TypeStringID(TypeID):
cdef object py_dtype(self):
# Numpy translation function for string types
if self.is_variable_str():
- raise NotImplementedError("Variable-length strings are not supported.")
+ raise TypeError("Variable-length strings are not supported.")
return dtype("|S" + str(self.get_size()))
@@ -635,6 +679,7 @@ cdef class TypeAtomicID(TypeID):
Base class for atomic datatypes (float or integer)
"""
+ @sync
def get_order(self):
""" () => INT order
@@ -644,6 +689,7 @@ cdef class TypeAtomicID(TypeID):
"""
return <int>H5Tget_order(self.id)
+ @sync
def set_order(self, int order):
""" (INT order)
@@ -653,6 +699,7 @@ cdef class TypeAtomicID(TypeID):
"""
H5Tset_order(self.id, <H5T_order_t>order)
+ @sync
def get_precision(self):
""" () => UINT precision
@@ -660,6 +707,7 @@ cdef class TypeAtomicID(TypeID):
"""
return H5Tget_precision(self.id)
+ @sync
def set_precision(self, size_t precision):
""" (UINT precision)
@@ -667,6 +715,7 @@ cdef class TypeAtomicID(TypeID):
"""
H5Tset_precision(self.id, precision)
+ @sync
def get_offset(self):
""" () => INT offset
@@ -674,6 +723,7 @@ cdef class TypeAtomicID(TypeID):
"""
return H5Tget_offset(self.id)
+ @sync
def set_offset(self, size_t offset):
""" (UINT offset)
@@ -681,6 +731,7 @@ cdef class TypeAtomicID(TypeID):
"""
H5Tset_offset(self.id, offset)
+ @sync
def get_pad(self):
""" () => (INT lsb_pad_code, INT msb_pad_code)
@@ -694,6 +745,7 @@ cdef class TypeAtomicID(TypeID):
H5Tget_pad(self.id, &lsb, &msb)
return (<int>lsb, <int>msb)
+ @sync
def set_pad(self, int lsb, int msb):
""" (INT lsb_pad_code, INT msb_pad_code)
@@ -711,6 +763,7 @@ cdef class TypeIntegerID(TypeAtomicID):
Integer atomic datatypes
"""
+ @sync
def get_sign(self):
""" () => INT sign
@@ -720,6 +773,7 @@ cdef class TypeIntegerID(TypeAtomicID):
"""
return <int>H5Tget_sign(self.id)
+ @sync
def set_sign(self, int sign):
""" (INT sign)
@@ -740,6 +794,7 @@ cdef class TypeFloatID(TypeAtomicID):
Floating-point atomic datatypes
"""
+ @sync
def get_fields(self):
""" () => TUPLE field_info
@@ -755,6 +810,7 @@ cdef class TypeFloatID(TypeAtomicID):
H5Tget_fields(self.id, &spos, &epos, &esize, &mpos, &msize)
return (spos, epos, esize, mpos, msize)
+ @sync
def set_fields(self, size_t spos, size_t epos, size_t esize,
size_t mpos, size_t msize):
""" (UINT spos, UINT epos, UINT esize, UINT mpos, UINT msize)
@@ -764,6 +820,7 @@ cdef class TypeFloatID(TypeAtomicID):
"""
H5Tset_fields(self.id, spos, epos, esize, mpos, msize)
+ @sync
def get_ebias(self):
""" () => UINT ebias
@@ -771,6 +828,7 @@ cdef class TypeFloatID(TypeAtomicID):
"""
return H5Tget_ebias(self.id)
+ @sync
def set_ebias(self, size_t ebias):
""" (UINT ebias)
@@ -778,6 +836,7 @@ cdef class TypeFloatID(TypeAtomicID):
"""
H5Tset_ebias(self.id, ebias)
+ @sync
def get_norm(self):
""" () => INT normalization_code
@@ -788,6 +847,7 @@ cdef class TypeFloatID(TypeAtomicID):
"""
return <int>H5Tget_norm(self.id)
+ @sync
def set_norm(self, int norm):
""" (INT normalization_code)
@@ -798,6 +858,7 @@ cdef class TypeFloatID(TypeAtomicID):
"""
H5Tset_norm(self.id, <H5T_norm_t>norm)
+ @sync
def get_inpad(self):
""" () => INT pad_code
@@ -808,6 +869,7 @@ cdef class TypeFloatID(TypeAtomicID):
"""
return <int>H5Tget_inpad(self.id)
+ @sync
def set_inpad(self, int pad_code):
""" (INT pad_code)
@@ -832,6 +894,7 @@ cdef class TypeCompositeID(TypeID):
Base class for enumerated and compound types.
"""
+ @sync
def get_nmembers(self):
""" () => INT number_of_members
@@ -839,6 +902,7 @@ cdef class TypeCompositeID(TypeID):
"""
return H5Tget_nmembers(self.id)
+ @sync
def get_member_name(self, int member):
""" (INT member) => STRING name
@@ -860,6 +924,7 @@ cdef class TypeCompositeID(TypeID):
return pyname
+ @sync
def get_member_index(self, char* name):
""" (STRING name) => INT index
@@ -876,6 +941,7 @@ cdef class TypeCompoundID(TypeCompositeID):
"""
+ @sync
def get_member_class(self, int member):
""" (INT member) => INT class
@@ -887,6 +953,7 @@ cdef class TypeCompoundID(TypeCompositeID):
return H5Tget_member_class(self.id, member)
+ @sync
def get_member_offset(self, int member):
""" (INT member) => INT offset
@@ -897,6 +964,7 @@ cdef class TypeCompoundID(TypeCompositeID):
raise ValueError("Member index must be non-negative.")
return H5Tget_member_offset(self.id, member)
+ @sync
def get_member_type(self, int member):
""" (INT member) => TypeID
@@ -907,6 +975,7 @@ cdef class TypeCompoundID(TypeCompositeID):
raise ValueError("Member index must be non-negative.")
return typewrap(H5Tget_member_type(self.id, member))
+ @sync
def insert(self, char* name, size_t offset, TypeID field not None):
""" (STRING name, UINT offset, TypeID field)
@@ -916,6 +985,7 @@ cdef class TypeCompoundID(TypeCompositeID):
"""
H5Tinsert(self.id, name, offset, field.id)
+ @sync
def pack(self):
""" ()
@@ -943,9 +1013,9 @@ cdef class TypeCompoundID(TypeCompositeID):
# 1. Check if it should be converted to a complex number
- if len(field_names) == 2 and \
- tuple(field_names) == _complex_names and \
- field_types[0] == field_types[1] and \
+ if len(field_names) == 2 and \
+ tuple(field_names) == (cfg._r_name, cfg._i_name) and \
+ field_types[0] == field_types[1] and \
field_types[0].kind == 'f':
bstring = field_types[0].str
@@ -988,6 +1058,7 @@ cdef class TypeEnumID(TypeCompositeID):
finally:
H5Tclose(basetype)
+ @sync
def enum_insert(self, char* name, long long value):
""" (STRING name, INT/LONG value)
@@ -1002,6 +1073,7 @@ cdef class TypeEnumID(TypeCompositeID):
self.enum_convert(&buf, 0)
H5Tenum_insert(self.id, name, &buf)
+ @sync
def enum_nameof(self, long long value):
""" (LLONG value) => STRING name
@@ -1020,6 +1092,7 @@ cdef class TypeEnumID(TypeCompositeID):
retstring = name
return retstring
+ @sync
def enum_valueof(self, char* name):
""" (STRING name) => LONG value
@@ -1031,6 +1104,7 @@ cdef class TypeEnumID(TypeCompositeID):
self.enum_convert(&buf, 1)
return buf
+ @sync
def get_member_value(self, int idx):
""" (UINT index) => LONG value
@@ -1057,30 +1131,18 @@ cdef class TypeEnumID(TypeCompositeID):
# === Python extension functions ==============================================
-def py_complex_names(object realname=None, object imgname=None, reset=False):
- """ (STRING realname=None, STRING imgname=None, reset=False)
-
- Set the real and imaginary strings used to translate complex
- numbers to and from HDF5 compound types.
-
- Both realname and imgname must be supplied, or both can be omitted to
- disable conversion completely. Call with reset=True to reset to the
- default pair ('r','i').
- """
- global _complex_names
- if not ((realname is None and imgname is None) or \
- (isinstance(realname, str) and isinstance(imgname, str))):
- raise ValueError("Realname and imgname must both be specified, or both omitted.")
+# Map array protocol strings to their HDF5 atomic equivalents
+# This only works for integers (signed and unsigned) and floats
+cdef dict _code_map = {
+ "<i1": STD_I8LE, "<i2": STD_I16LE, "<i4": STD_I32LE, "<i8": STD_I64LE,
+ ">i1": STD_I8BE, ">i2": STD_I16BE, ">i4": STD_I32BE, ">i8": STD_I64BE,
+ "|i1": NATIVE_INT8, "|u1": NATIVE_UINT8,
+ "<u1": STD_U8LE, "<u2": STD_U16LE, "<u4": STD_U32LE, "<u8": STD_U64LE,
+ ">u1": STD_U8BE, ">u2": STD_U16BE, ">u4": STD_U32BE, ">u8": STD_U64BE,
+ "<f4": IEEE_F32LE, "<f8": IEEE_F64LE, ">f4": IEEE_F32BE, ">f8": IEEE_F64BE
+ }
- if reset:
- _complex_names = ('r','i')
- else:
- if realname is None:
- _complex_names = None
- else:
- _complex_names = (realname, imgname)
-
-def py_create(object dtype_in, enum=None):
+cpdef object py_create(object dtype_in, object enum_vals=None):
""" (OBJECT dtype_in, DICT enum=None) => TypeID
Given a Numpy dtype object, generate a byte-for-byte memory-compatible
@@ -1124,12 +1186,12 @@ def py_create(object dtype_in, enum=None):
otype.insert(name, offset, tmp)
# Enums may be created out of integer types
- elif (kind == c'u' or kind == c'i') and enum is not None:
+ elif (kind == c'u' or kind == c'i') and enum_vals is not None:
otype = enum_create(_code_map[dt.str])
- for key in sorted(enum):
- otype.enum_insert(key, enum[key])
+ for key in sorted(enum_vals):
+ otype.enum_insert(key, enum_vals[key])
# Integers and floats map directly to HDF5 atomic types
elif kind == c'u' or kind == c'i'or kind == c'f':
@@ -1139,13 +1201,10 @@ def py_create(object dtype_in, enum=None):
# Complex numbers are stored as HDF5 structs, with names defined at runtime
elif kind == c'c':
- if _complex_names is None:
- raise ValueError("Complex conversion is currently disabled. Use py_complex_names to re-enable.")
-
if length == 8:
- otype = typewrap(create_ieee_complex64(byteorder, _complex_names[0], _complex_names[1]))
+ otype = typewrap(create_ieee_complex64(byteorder, cfg._r_name, cfg._i_name))
elif length == 16:
- otype = typewrap(create_ieee_complex128(byteorder, _complex_names[0], _complex_names[1]))
+ otype = typewrap(create_ieee_complex128(byteorder, cfg._r_name, cfg._i_name))
else:
raise ValueError("Unsupported length %d for complex dtype: %s" % (length, repr(dt)))
@@ -1169,11 +1228,6 @@ def py_create(object dtype_in, enum=None):
else:
raise ValueError("No conversion path for dtype: %s" % repr(dt))
- IF H5PY_DEBUG:
- import logging
- logger = logging.getLogger('h5py')
- logger.info( "H5T create: %s\n"
- " => %s" % (str(dt), repr(otype)))
return otype
diff --git a/h5py/h5z.pyx b/h5py/h5z.pyx
index 1374264..f617249 100644
--- a/h5py/h5z.pyx
+++ b/h5py/h5z.pyx
@@ -58,8 +58,10 @@ DISABLE_EDC = H5Z_DISABLE_EDC
ENABLE_EDC = H5Z_ENABLE_EDC
NO_EDC = H5Z_NO_EDC
+
# === Filter API =============================================================
+ at sync
def filter_avail(int filter_code):
""" (INT filter_code) => BOOL available
@@ -73,6 +75,7 @@ def filter_avail(int filter_code):
"""
return <bint>H5Zfilter_avail(<H5Z_filter_t>filter_code)
+ at sync
def get_filter_info(int filter_code):
""" (INT filter_code) => INT filter_flags
diff --git a/h5py/sync.pxi b/h5py/sync.pxi
index c81e704..1584d75 100644
--- a/h5py/sync.pxi
+++ b/h5py/sync.pxi
@@ -10,20 +10,16 @@
#
#-
-# Header file which goes as the first line in all .pyx files. Currently its
-# main function is to help simplify the .pxi-based import fiasco.
+# Header file which defines decorators for thread safety and debug logging.
+# Intended to be included in the beginning of module .pyx files.
-# hdr_pxd already brought in hdf5 and stdlib defines. So we just need to
-# include the configs, and define things like synchronization decorators.
-
-include "config.pxi"
-
-# Defines the following decorators:
-#
# sync: Acquire PHIL for this function, and log function entry in
# debug mode.
# nosync: Don't acquire PHIL, but log function entry in debug mode.
-#
+
+
+include "config.pxi" # For H5PY_* defines
+
IF H5PY_DEBUG:
import logging
@@ -46,3 +42,5 @@ ELSE:
ELSE:
cdef inline object sync(object func):
return func
+
+
diff --git a/h5py/utils.pyx b/h5py/utils.pyx
index 0cd1fd1..243f410 100644
--- a/h5py/utils.pyx
+++ b/h5py/utils.pyx
@@ -15,7 +15,8 @@ include "sync.pxi"
# Compile-time imports
from h5 cimport init_hdf5
-from python cimport PyTuple_Check, PyList_Check, PyErr_SetString, Py_INCREF
+from python_exc cimport PyErr_SetString
+
from numpy cimport import_array, NPY_UINT16, NPY_UINT32, NPY_UINT64, \
npy_intp, PyArray_SimpleNew, PyArray_ContiguousFromAny, \
PyArray_FROM_OTF, NPY_CONTIGUOUS, NPY_NOTSWAPPED, \
@@ -106,7 +107,7 @@ cdef int require_tuple(object tpl, int none_allowed, int size, char* name) excep
# Otherwise raises ValueError
if (tpl is None and none_allowed) or \
- ( PyTuple_Check(tpl) and (size < 0 or len(tpl) == size)):
+ (isinstance(tpl, tuple) and (size < 0 or len(tpl) == size)):
return 1
nmsg = ""
@@ -124,7 +125,7 @@ cdef int require_list(object lst, int none_allowed, int size, char* name) except
# Counterpart of require_tuple, for lists
if (lst is None and none_allowed) or \
- (PyList_Check(lst) and (size < 0 or len(lst) == size)):
+ (isinstance(lst, list) and (size < 0 or len(lst) == size)):
return 1
nmsg = ""
--
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