[h5py] 71/455: H5T tests reinstated; docs updated. Release tomorrow.

Ghislain Vaillant ghisvail-guest at moszumanska.debian.org
Thu Jul 2 18:19:18 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 ad3a2f410dc0386585d8656d77c11091a3bf465b
Author: andrewcollette <andrew.collette at gmail.com>
Date:   Wed Jul 9 05:39:15 2008 +0000

    H5T tests reinstated; docs updated.  Release tomorrow.
---
 docs.cfg                     |   2 -
 h5py/h5.pyx                  |  24 ++++--
 h5py/h5a.pyx                 |   2 +-
 h5py/h5f.pxd                 |   3 +
 h5py/h5f.pyx                 |   8 ++
 h5py/h5g.pyx                 |  23 +++++-
 h5py/h5p.pyx                 |   4 +
 h5py/h5r.pyx                 |  19 +++--
 h5py/h5t.pyx                 |  62 ++++++++++++----
 h5py/highlevel.py            |  30 ++++++--
 h5py/proxy.py                | 170 -------------------------------------------
 h5py/tests/__init__.py       |   4 +-
 h5py/tests/test_highlevel.py |  12 +--
 13 files changed, 138 insertions(+), 225 deletions(-)

diff --git a/docs.cfg b/docs.cfg
index 6498abd..2f7e14d 100644
--- a/docs.cfg
+++ b/docs.cfg
@@ -3,8 +3,6 @@
 name: h5py HDF5 interface for Python
 url: http://h5py.alfven.org
 link: <a href="http://h5py.alfven.org">h5py Project Page at Alfven.org</a>
-
 docformat: plaintext
-
 private: no
 
diff --git a/h5py/h5.pyx b/h5py/h5.pyx
index 47dc821..ffbf759 100644
--- a/h5py/h5.pyx
+++ b/h5py/h5.pyx
@@ -19,13 +19,11 @@
     Useful things defined here:
     
       hdf5_version:         String with library version (e.g. "1.6.5")
-      hdf5_version_tuple:   Tuple form of the version (e.g. (1,6,5))
+      hdf5_version_tuple:   3-tuple form of the version (e.g. (1,6,5))
       api_version:          String form of the API used (e.g. "1.6")
-      api_version_tuple:    Tuple form of the version (e.g. (1,6))
+      api_version_tuple:    2-tuple form of the version (e.g. (1,6))
 
     All exception classes and error handling functions are also in this module.
-
-
 """
 
 include "conditions.pxi"
@@ -74,7 +72,23 @@ def _open():
 # === Identifier wrappers =====================================================
 
 cdef class ObjectID:
-        
+
+    """
+        Base class for all HDF5 identifiers.
+
+        This is an extremely thin object layer, which makes dealing with
+        HDF5 identifiers a less frustrating experience.  It synchronizes
+        Python object reference counts with their HDF5 counterparts, so that
+        HDF5 identifiers are automatically closed when they become unreachable.
+
+        The only (known) HDF5 property which can problematic is locked objects;
+        there is no way to determine whether or not an HDF5 object is locked
+        or not, without trying an operation and having it fail.  A "lock" flag
+        is maintained on the Python side, and is set by methods like
+        TypeID.lock(), but this is not tracked across copies.  Until HDF5
+        provides something like H5Tis_locked(), this will not be fixed.
+    """
+
     property _valid:
         """ Indicates whether or not this identifier points to an HDF5 object.
         """
diff --git a/h5py/h5a.pyx b/h5py/h5a.pyx
index 8860961..2d03d75 100644
--- a/h5py/h5a.pyx
+++ b/h5py/h5a.pyx
@@ -157,7 +157,7 @@ cdef class AttrID(ObjectID):
             return self.get_name()
 
     property shape:
-        """ A Numpy-style shape tuple representing the attribute dataspace.
+        """ A Numpy-style shape tuple representing the attribute's dataspace.
         """
         def __get__(self):
 
diff --git a/h5py/h5f.pxd b/h5py/h5f.pxd
index 29bb49c..d60b831 100644
--- a/h5py/h5f.pxd
+++ b/h5py/h5f.pxd
@@ -20,6 +20,9 @@ from h5 cimport class ObjectID
 cdef class FileID(ObjectID):
     pass
 
+# Internal h5py function to wrap file-resident identifiers
+cdef object wrap_identifier(hid_t ident)
+
 cdef extern from "hdf5.h":
 
   # File constants
diff --git a/h5py/h5f.pyx b/h5py/h5f.pyx
index 4ede49f..95c0142 100644
--- a/h5py/h5f.pyx
+++ b/h5py/h5f.pyx
@@ -234,7 +234,15 @@ cdef class FileID(ObjectID):
 
     """ 
         Represents an HDF5 file identifier.
+
+        These objects wrap a small portion of the H5F interface; all the
+        H5F functions which can take arbitrary objects in addition to
+        file identifiers are provided as functions in the h5f module.
+
+        Properties:
+        name:   File name on disk
     """
+
     property name:
         """ File name on disk (according to h5f.get_name()) """
         def __get__(self):
diff --git a/h5py/h5g.pyx b/h5py/h5g.pyx
index f41d47c..9852815 100644
--- a/h5py/h5g.pyx
+++ b/h5py/h5g.pyx
@@ -76,7 +76,8 @@ cdef class GroupIter:
 
     def __next__(self):
         if self.idx == self.nobjs:
-            self.grp = None
+            if self.grp is not None:
+                self.grp = None
             raise StopIteration
         
         retval = self.grp.get_objname_by_idx(self.idx)
@@ -149,6 +150,10 @@ cdef class GroupID(ObjectID):
 
     """
         Represents an HDF5 group identifier
+
+        Python extensions:
+        py_exists(name, [typecode]):    Determine if a group member exists
+        py_iter():      Return an iterator over member names
     """
 
     def _close(self):
@@ -334,13 +339,23 @@ cdef class GroupID(ObjectID):
         finally:
             efree(cmnt)
 
-    def py_exists(self, char* name):
+    def py_exists(self, char* name, int typecode=-1):
+        """ (STRING name, INT typecode=-1)
 
+            Determine if a group member of the given name and (optional)
+            type is present.  Typecode may be one of 
+                - LINK
+                - GROUP
+                - DATASET
+                - DATATYPE
+        """
         try:
-            self.get_objinfo(name)
+            info = self.get_objinfo(name)
+            if (typecode == -1) or (info.type == typecode):
+                return True
+            return False
         except H5Error:
             return False    
-        return True
 
     def py_iter(self):
         """ () => ITERATOR
diff --git a/h5py/h5p.pyx b/h5py/h5p.pyx
index 813f82b..d88ab70 100644
--- a/h5py/h5p.pyx
+++ b/h5py/h5p.pyx
@@ -96,6 +96,10 @@ def create(PropClassID cls not None):
 
 cdef class PropID(ObjectID):
 
+    """
+        Base class for all property lists and classes
+    """
+
     def equal(self, PropID plist not None):
         """ (PropID plist) => BOOL
 
diff --git a/h5py/h5r.pyx b/h5py/h5r.pyx
index 1d66968..3fa490a 100644
--- a/h5py/h5r.pyx
+++ b/h5py/h5r.pyx
@@ -12,10 +12,14 @@
 
 """
     H5R API for object and region references.
+
+    Functions in this module are not well tested.
 """
 
 # Pyrex compile-time imports
 from h5g cimport H5G_obj_t
+from h5f cimport wrap_identifier
+from h5s cimport SpaceID
 
 # Runtime imports
 import h5
@@ -58,13 +62,14 @@ def create(ObjectID loc not None, char* name, int ref_type, SpaceID space=None):
         Create a new reference. The value of ref_type detemines the kind
         of reference created:
 
-        - OBJECT    Reference to an object in an HDF5 file.  Parameters loc_id
-                    and name identify the object; space_id is unused.
+        - OBJECT
+            Reference to an object in an HDF5 file.  Parameters loc
+            and name identify the object; space is unused.
 
         - DATASET_REGION    
-                    Reference to a dataset region.  Parameters loc_id and
-                    name identify the dataset; the selection on space_id
-                    identifies the region.
+            Reference to a dataset region.  Parameters loc and
+            name identify the dataset; the selection on space
+            identifies the region.
     """
     cdef hid_t space_id
     cdef Reference ref
@@ -87,7 +92,7 @@ def dereference(ObjectID fid not None, Reference ref):
         a file identifier or an identifier for any object which lives
         in the file.
     """
-    return H5Rdereference(fid.id, <H5R_type_t>ref.typecode, &ref.ref)
+    return wrap_identifier(H5Rdereference(fid.id, <H5R_type_t>ref.typecode, &ref.ref))
 
 def get_region(ObjectID dataset not None, Reference ref):
     """ (ObjectID dataset, Reference ref) => INT dataspace_id
@@ -98,7 +103,7 @@ def get_region(ObjectID dataset not None, Reference ref):
 
         The given reference object must be of type DATASET_REGION.
     """
-    return H5Rget_region(dataset.id, <H5R_type_t>ref.typecode, &ref.ref)
+    return SpaceID(H5Rget_region(dataset.id, <H5R_type_t>ref.typecode, &ref.ref))
 
 def get_obj_type(ObjectID ds not None, Reference ref):
     """ (ObjectID ds, Reference ref) => INT obj_code
diff --git a/h5py/h5t.pyx b/h5py/h5t.pyx
index 9bbf867..6bfcde3 100644
--- a/h5py/h5t.pyx
+++ b/h5py/h5t.pyx
@@ -12,6 +12,42 @@
 
 """
     HDF5 "H5T" data-type API
+
+    This module contains the datatype identifier class TypeID, and its
+    subclasses which represent things like integer/float/compound identifiers.
+    The majority of the H5T API is presented as methods on these identifiers.
+
+    1. Translating between Numpy dtypes and HDF5 type objects
+
+        All identifier classes have a property "dtype", returning a Numpy
+        dtype which as closely as possible matches the HDF5 type.
+
+        The module function py_create is the complement to this property, and
+        is the standard way to translate Numpy dtypes to HDF5 type identifiers.
+        Unlike the dtype property, HDF5 datatypes returned by this function are
+        guaranteed to be binary-compatible with their Numpy dtype counterparts
+
+    2. Complex numbers
+
+        Complex number support has been refactored in this version of h5py.
+        HDF5 has no native concept of a complex number.  Numpy complex types
+        are translated to two-element compound types with two floating-point
+        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).
+
+    3. Enumerated types
+
+        Native support for "dtype-encoded" enums has been dropped, as it proved
+        to be too unwieldy.  Enumerated types are read from HDF5 files as
+        Numpy integers (kind i or u).
+
+        You can get at the fields of an enum through the standard HDF5 API
+        calls, which are presented as methods of class TypeEnumID.
+        Additionally, the py_create function allows you to create HDF5
+        enumerated types by passing in a dictionary along with a Numpy dtype.
 """
 
 include "conditions.pxi"
@@ -264,8 +300,7 @@ def vlen_create(TypeID base not None):
 cdef class TypeID(ObjectID):
 
     """
-        Represents an HDF5 datatype identifier, and encapsulates common
-        operations.
+        Base class for type identifiers (implements common operations)
     """
 
     def __copy__(self):
@@ -374,7 +409,6 @@ cdef class TypeID(ObjectID):
         if not self._locked:
             H5Tclose(self.id)
 
-
 # === Top-level classes (inherit directly from TypeID) ========================
 
 cdef class TypeArrayID(TypeID):
@@ -537,7 +571,7 @@ cdef class TypeBitfieldID(TypeID):
 cdef class TypeAtomicID(TypeID):
 
     """
-        Represents an atomic datatype (float or integer).
+        Base class for atomic datatypes (float or integer)
     """
 
     def get_order(self):
@@ -613,7 +647,7 @@ cdef class TypeAtomicID(TypeID):
 cdef class TypeIntegerID(TypeAtomicID):
 
     """
-        Integer atomic types
+        Integer atomic datatypes
     """
 
     def get_sign(self):
@@ -642,7 +676,7 @@ cdef class TypeIntegerID(TypeAtomicID):
 cdef class TypeFloatID(TypeAtomicID):
 
     """
-        Floating-point datatypes
+        Floating-point atomic datatypes
     """
 
     def get_fields(self):
@@ -734,7 +768,7 @@ cdef class TypeFloatID(TypeAtomicID):
 cdef class TypeCompositeID(TypeID):
 
     """
-        Encapsulates operations common to both enumerated and compound types.
+        Base class for enumerated and compound types.
     """
 
     def get_nmembers(self):
@@ -958,14 +992,10 @@ cdef class TypeEnumID(TypeCompositeID):
 
         cdef TypeID tmp_type
         tmp_type = self.get_super()
-        typeobj = tmp_type.py_dtype()
-
-        return typeobj
+        return tmp_type.py_dtype()
 
 # === Python extension functions ==============================================
 
-
-
 def py_complex_names(object realname=None, object imgname=None, reset=False):
     """ (STRING realname=None, STRING imgname=None, reset=False)
 
@@ -990,12 +1020,14 @@ def py_complex_names(object realname=None, object imgname=None, reset=False):
             _complex_names = (realname, imgname)
     
 def py_create(object dtype_in, enum=None):
-    """ ( OBJECT dt, DICT enum=None) => TypeID
+    """ (OBJECT dtype_in, DICT enum=None) => TypeID
 
         Given a Numpy dtype object, generate a byte-for-byte memory-compatible
         HDF5 datatype object.  The result is guaranteed to be transient and
-        unlocked. Argument dtype_in may be a dtype object, or anything which
-        can be converted to a dtype.
+        unlocked.
+
+        Argument dtype_in may be a dtype object, or anything which can be
+        converted to a dtype, including strings like '<i4'.
 
         enum:
             A optional dictionary mapping names to integer values.  If the
diff --git a/h5py/highlevel.py b/h5py/highlevel.py
index d4b9597..f4e9da8 100644
--- a/h5py/highlevel.py
+++ b/h5py/highlevel.py
@@ -23,7 +23,7 @@
     A strong emphasis has been placed on reasonable automatic conversion from
     Python types to their HDF5 equivalents.  Setting and retrieving HDF5 data
     is almost always handled by a simple assignment.  For example, you can
-    create an initialize and HDF5 dataset simply by assigning a Numpy array
+    create an initialize an HDF5 dataset simply by assigning a Numpy array
     to a group:
 
         group["name"] = numpy.ones((10,50), dtype='<i2')
@@ -48,7 +48,8 @@ from h5py.h5 import H5Error
 from utils_hl import slicer, hbasename, strhdr, strlist
 from browse import _H5Browser
 
-__all__ = ["File", "Group", "Dataset", "Datatype"]
+__all__ = ["HLObject", "File", "Group", "Dataset",
+           "Datatype", "AttributeManager"]
 
 try:
     # For interactive File.browse() capability
@@ -372,7 +373,10 @@ class Dataset(HLObject):
     def __init__(self, group, name,
                     data=None, dtype=None, shape=None, 
                     chunks=None, compression=None, shuffle=False, fletcher32=False):
-        """ Create a new Dataset object.  There are two modes of operation:
+        """ Create a Dataset object.  You might find it easier to use the
+            Group methods: Group["name"] or Group.create_dataset().
+
+            There are two modes of operation for this constructor:
 
             1.  Open an existing dataset
                 If you only supply the required parameters "group" and "name",
@@ -523,7 +527,7 @@ class AttributeManager(object):
 
     """ Allows dictionary-style access to an HDF5 object's attributes.
 
-        These come attached to HDF5 objects as Obj.attrs.  You should never
+        These come attached to HDF5 objects as <obj>.attrs.  There's no need to
         create one yourself.
 
         Like the members of groups, attributes are accessed using dict-style
@@ -539,7 +543,8 @@ class AttributeManager(object):
     """
 
     def __init__(self, parent):
-
+        """ Private constructor; you should not create these.
+        """
         self.id = parent.id
 
     def __getitem__(self, name):
@@ -602,14 +607,23 @@ class Datatype(HLObject):
         Represents an HDF5 named datatype.
 
         These intentionally only represent named types, and exist mainly so
-        that you can access their attributes.
+        that you can access their attributes.  The property Datatype.dtype
+        provides a Numpy dtype equivalent.
+
+        They're produced only by indexing into a Group object; you can't create
+        one manually.  To create a named datatype in a file:
 
-        The property Datatype.dtype provides a Numpy dtype equivalent.
+            group["name"] = <Numpy dtype object> | <Datatype object>*
+
+            * will create hard link to an existing type
     """
 
-    dtype = property(lambda self: self.id.dtype)
+    dtype = property(lambda self: self.id.dtype,
+        doc = "Numpy dtype equivalent for this datatype")
 
     def __init__(grp, name):
+        """ Private constructor; you should not create these.
+        """
         self.id = h5t.open(grp.id, name)
 
     def __str__(self):
diff --git a/h5py/proxy.py b/h5py/proxy.py
deleted file mode 100644
index 3019d91..0000000
--- a/h5py/proxy.py
+++ /dev/null
@@ -1,170 +0,0 @@
-import tempfile
-import os
-import numpy
-
-import h5d, h5s, h5t, h5f, h5p, h5z
-
-class ProxyError(StandardError):
-    pass
-
-class DatasetProxy(object):
-
-    """
-        Thin class which acts as an interface to an HDF5 dataset object.
-
-    """
-    def begin_proxy(self):
-
-
-        if self.proxy_active():
-            raise ProxyError("Already proxying.")
-
-        fid = 0
-        space_id = 0
-        plist_id = 0
-        type_id = 0
-        proxy_id = 0
-        fname = tempfile.mktemp('.hdf5')
-
-        try:
-            space_id = h5d.get_space(self.id)
-            type_id = h5g.get_type(self.id)
-            plist_id = h5g.get_create_plist(self.id)
-
-            h5p.remove_filter(plist_id, h5z.FILTER_ALL)
-            h5p.set_alloc_time(plist_id, h5p.ALLOC_TIME_INCR)
-
-            fid = h5f.create(fname, h5f.ACC_RDWR)
-            proxy_id = h5d.create(fid, "PROXY", type_id, space_id, plist_id)
-        except:
-            if fid != 0:
-                h5f.close(fid)
-            if space_id != 0:
-                h5s.close(space_id)
-            raise
-        finally:
-            if plist_id != 0:
-                h5p.close(plist_id)
-            if type_id != 0:
-                h5t.close(type_id)
-
-        self._proxy_fid = fid
-        self._proxy_fname = fname
-        self._proxy_space = space_id
-        self._proxy_id = proxy_id
-
-    def proxy_active(self):
-        if hasattr(self, '_proxy_id') and self._proxy_id is not None:
-            return True
-        return False
-
-    def end_proxy(self):
-
-        if not self.proxy_active():
-            raise ProxyError("Not proxying.")
-
-        h5s.close(self._proxy_space)
-        h5d.close(self._proxy_id)
-        h5f.close(self._proxy_fid)
-        self._proxy_id = None
-        os.unlink(self._proxy_fname)
-
-    def _read(self, start, count, stride=None, **kwds):
-        """ Dataset read access.  In direct mode, simply reads data from 
-            self.id.  In proxy mode, reads unmodified data from self.id and
-            modified sections from self._proxy_id.
-
-            Don't call this directly.
-        """
-        if not self.proxy_active():
-            return h5d.py_read_slab(self.id, start, count, stride, **kwds)
-
-        else:
-            mem_space = 0
-            backing_space = 0
-            patch_space = 0
-            
-            try:
-                mem_space = h5s.create_simple(count)    
-
-                # Create Numpy array
-                dtype = h5t.py_dtype(self._proxy_id)
-                arr = numpy.ndarray(count, dtype=dtype)
-
-                patch_space = h5s.copy(self._proxy_space)
-                backing_space = h5s.copy(self._proxy_space)
-
-                # What needs to be read from the original dataset.
-                # This is all elements of the new selection which are not
-                # already selected in self._proxy_space
-                h5s.select_hyperslab(backing_space, start, count, stride, op=h5s.SELECT_NOTA)
-
-                # What needs to be read from the proxy dataset.
-                # This is the intersection of the modified selection and the
-                # requested selection.
-                h5s.select_hyperslab(patch_space, start, count, stride, op=h5s.SELECT_AND)
-
-                # Read from the original dataset.
-                if h5s.get_select_npoints(backing_space) > 0:
-                    h5d.read(self.id, mem_space, backing_space, arr)
-
-                # Read the rest from the proxy dataset.
-                if h5s.get_select_npoints(patch_space) > 0:
-                    h5d.read(self._proxy_id, mem_space, patch_space, arr)
-
-            finally:
-                if mem_space != 0:
-                    h5s.close(mem_space)
-                if backing_space != 0:
-                    h5s.close(backing_space)
-                if patch_space != 0:
-                    h5s.close(patch_space)
-
-            return arr
-
-    def _write(self, arr, start, stride=None):
-        
-        if not self.proxy_active():
-            h5d.py_write_slab(self.id, arr, start, stride)
-        
-        else:
-            # We get free argument validation courtesy of this function.
-            h5d.py_write_slab(self._proxy_id, arr, start, stride)
-
-            # Record this section of the dataspace as changed.
-            count = arr.shape
-            h5s.select_hyperslab(self._proxy_space, start, count, stride, op=h5s.SELECT_OR)
-
-    def commit(self):
-
-        if self.proxy_active():
-            h5d.py_patch(self._proxy_id, self.id, self._proxy_space)
-            h5s.select_none(self._proxy_space)
-
-    def rollback(self):
-
-        if self.proxy_active():
-            # Proxy file doesn't shrink, but space will be re-used.
-            # Worst case == proxy file is size of the original dataset, sans
-            # compression
-            h5s.select_none(self._proxy_space)
-            
-        
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-            
diff --git a/h5py/tests/__init__.py b/h5py/tests/__init__.py
index e9760b2..ccbd25a 100644
--- a/h5py/tests/__init__.py
+++ b/h5py/tests/__init__.py
@@ -14,13 +14,13 @@ import unittest
 import sys
 import test_h5a, test_h5d, test_h5f, \
        test_h5g, test_h5i, test_h5p, \
-       test_h5s, test_h5
+       test_h5s, test_h5t, test_h5
 
 from h5py import *
 
 TEST_CASES = (test_h5a.TestH5A, test_h5d.TestH5D, test_h5f.TestH5F, 
               test_h5g.TestH5G, test_h5i.TestH5I, test_h5p.TestH5P,
-              test_h5s.TestH5S, test_h5.TestH5)
+              test_h5s.TestH5S, test_h5t.TestH5T, test_h5.TestH5)
 
 def buildsuite(cases):
 
diff --git a/h5py/tests/test_highlevel.py b/h5py/tests/test_highlevel.py
index aed6e80..3f672ee 100644
--- a/h5py/tests/test_highlevel.py
+++ b/h5py/tests/test_highlevel.py
@@ -10,14 +10,4 @@
 # 
 #-
 
-import unittest
-import os
-import tempfile
-from numpy import all
-
-import h5py
-from h5py.highlevel import *
-
-
-class TestHighlevel(unittest.TestCase):
-    pass
+# empty for now

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