[h5py] 116/455: Initial h5l and h5o modules for 1.8; h5o.visit function
Ghislain Vaillant
ghisvail-guest at moszumanska.debian.org
Thu Jul 2 18:19:23 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 6faabb1f50019ce6b65e08419d1060ff7a750086
Author: andrewcollette <andrew.collette at gmail.com>
Date: Sat Sep 6 01:43:55 2008 +0000
Initial h5l and h5o modules for 1.8; h5o.visit function
---
autotest.py | 2 +-
h5py/__init__.py | 7 ++-
h5py/h5i.pyx | 2 +
h5py/h5l.pxd | 11 +++++
h5py/h5l.pyx | 11 +++++
h5py/h5o.pxd | 91 ++++++++++++++++++++++++++++++++++++
h5py/h5o.pyx | 119 +++++++++++++++++++++++++++++++++++++++++++++++
h5py/h5p.pyx | 38 +++++++++++----
h5py/h5r.pxd | 12 +++++
h5py/h5r.pyx | 122 +++++++++++++++++++++++++------------------------
h5py/highlevel.py | 9 +++-
h5py/tests/__init__.py | 4 +-
h5py/tests/test_h5r.py | 59 ++++++++++++++++++++++++
setup.py | 3 ++
14 files changed, 416 insertions(+), 74 deletions(-)
diff --git a/autotest.py b/autotest.py
index 7029205..2c2a4f4 100644
--- a/autotest.py
+++ b/autotest.py
@@ -8,7 +8,7 @@ lib_base = op.abspath(op.join(op.curdir, '..'))
libs = [''] + [' --hdf5='+op.join(lib_base, x) for x in libnames]
# Experimental non-blocking I/O
-nonblock = ['',' --io-nonblock']
+nonblock = ['']
# API versions
api = [' --api=16', ' --api=18']
diff --git a/h5py/__init__.py b/h5py/__init__.py
index 4dd6890..92a691a 100644
--- a/h5py/__init__.py
+++ b/h5py/__init__.py
@@ -30,6 +30,11 @@ from highlevel import File, Group, Dataset, Datatype, AttributeManager, CoordsLi
__doc__ = __doc__ % (h5.version, h5.hdf5_version, h5.api_version)
-__all__ = ['h5', 'h5f', 'h5g', 'h5s', 'h5t', 'h5d', 'h5a', 'h5p',
+__all__ = ['h5', 'h5f', 'h5g', 'h5s', 'h5t', 'h5d', 'h5a', 'h5p', 'h5r',
'h5z', 'h5i', 'File', 'Group', 'Dataset',
'Datatype', 'AttributeManager', 'CoordsList']
+
+if h5.api_version_tuple >= (1,8):
+ import h5o, h5l
+ __all__ += ['h5l', 'h5o']
+
diff --git a/h5py/h5i.pyx b/h5py/h5i.pyx
index c42e427..575e07c 100644
--- a/h5py/h5i.pyx
+++ b/h5py/h5i.pyx
@@ -54,6 +54,8 @@ def get_name(ObjectID obj not None):
If the identifier is invalid or is not associated with a name
(in the case of transient datatypes, dataspaces, etc), returns None.
+
+ For some reason, this does not work on dereferenced objects.
"""
cdef int namelen
cdef char* name
diff --git a/h5py/h5l.pxd b/h5py/h5l.pxd
new file mode 100644
index 0000000..0321a47
--- /dev/null
+++ b/h5py/h5l.pxd
@@ -0,0 +1,11 @@
+#+
+#
+# This file is part of h5py, a low-level Python interface to the HDF5 library.
+#
+# Copyright (C) 2008 Andrew Collette
+# http://h5py.alfven.org
+# License: BSD (See LICENSE.txt for full license)
+#
+# $Date$
+#
+#-
diff --git a/h5py/h5l.pyx b/h5py/h5l.pyx
new file mode 100644
index 0000000..0321a47
--- /dev/null
+++ b/h5py/h5l.pyx
@@ -0,0 +1,11 @@
+#+
+#
+# This file is part of h5py, a low-level Python interface to the HDF5 library.
+#
+# Copyright (C) 2008 Andrew Collette
+# http://h5py.alfven.org
+# License: BSD (See LICENSE.txt for full license)
+#
+# $Date$
+#
+#-
diff --git a/h5py/h5o.pxd b/h5py/h5o.pxd
new file mode 100644
index 0000000..375fcba
--- /dev/null
+++ b/h5py/h5o.pxd
@@ -0,0 +1,91 @@
+#+
+#
+# This file is part of h5py, a low-level Python interface to the HDF5 library.
+#
+# Copyright (C) 2008 Andrew Collette
+# http://h5py.alfven.org
+# License: BSD (See LICENSE.txt for full license)
+#
+# $Date$
+#
+#-
+
+include "std_defs.pxi"
+
+from h5 cimport ObjectID
+from h5g cimport GroupID
+
+cdef extern from "hdf5.h":
+
+ 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_NTYPES # Number of different object types (must be last!)
+
+ # --- Components for the H5O_info_t struct ----------------------------------
+
+ cdef struct space:
+ hsize_t total # Total space for storing object header in file
+ hsize_t meta # Space within header for object header metadata information
+ hsize_t mesg # Space within header for actual message information
+ hsize_t free # Free space within object header
+
+ cdef struct mesg:
+ unsigned long present # Flags to indicate presence of message type in header
+ unsigned long shared # Flags to indicate message type is shared in header
+
+ cdef struct hdr:
+ unsigned version # Version number of header format in file
+ unsigned nmesgs # Number of object header messages
+ unsigned nchunks # Number of object header chunks
+ unsigned flags # Object header status flags
+ space space
+ mesg mesg
+
+ ctypedef struct H5_ih_info_t:
+ 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 */
+
+ ctypedef struct H5O_info_t:
+ unsigned long fileno # File number that object is located in
+ haddr_t addr # Object address in file
+ H5O_type_t type # Basic object type (group, dataset, etc.)
+ unsigned rc # Reference count of object
+ time_t atime # Access time
+ time_t mtime # Modification time
+ time_t ctime # Change time
+ time_t btime # Birth time
+ hsize_t num_attrs # # of attributes attached to object
+ 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)
+
+ herr_t H5Ovisit(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order,
+ H5O_iterate_t op, void *op_data) except *
+
+ herr_t H5Oget_info(hid_t loc_id, H5O_info_t *oinfo)
+
+
+
+
+
+
+
+
diff --git a/h5py/h5o.pyx b/h5py/h5o.pyx
new file mode 100644
index 0000000..32d954c
--- /dev/null
+++ b/h5py/h5o.pyx
@@ -0,0 +1,119 @@
+#+
+#
+# This file is part of h5py, a low-level Python interface to the HDF5 library.
+#
+# Copyright (C) 2008 Andrew Collette
+# http://h5py.alfven.org
+# License: BSD (See LICENSE.txt for full license)
+#
+# $Date$
+#
+#-
+
+# Module for the new "H5O" functions introduced in HDF5 1.8.0. Not even
+# built with API compatibility level below 1.8.
+
+# Pyrex compile-time imports
+from h5f cimport wrap_identifier
+
+# Runtime imports
+import h5
+
+cdef class ObjInfo:
+
+ property fileno:
+ def __get__(self):
+ return self.infostruct.fileno
+ property addr:
+ def __get__(self):
+ return self.infostruct.addr
+ property type:
+ def __get__(self):
+ return <int>self.infostruct.type
+ property rc:
+ def __get__(self):
+ return self.infostruct.rc
+
+ cdef H5O_info_t infostruct
+
+ def __copy__(self):
+ cdef ObjInfo newcopy
+ newcopy = ObjInfo()
+ newcopy.infostruct = self.infostruct
+ return newcopy
+
+def get_info(ObjectID obj not None):
+ """ (ObjectID obj) => ObjInfo
+ """
+
+ cdef ObjInfo info
+ info = ObjInfo()
+
+ H5Oget_info(obj.id, &info.infostruct)
+ return info
+
+cdef class _Triplet:
+
+ cdef object func
+ cdef object exc
+ cdef ObjInfo objinfo
+
+ def __init__(self, func):
+ self.func = func
+ self.exc = None
+ self.objinfo = ObjInfo()
+
+cdef herr_t iter_cb(hid_t obj, char* name, H5O_info_t *info, void* data):
+
+ cdef _Triplet triplet
+ triplet = <_Triplet>data
+
+ triplet.objinfo.infostruct = info[0]
+
+ try:
+ retval = triplet.func(name, triplet.objinfo)
+ except BaseException, e: # The exception MUST be propagated
+ triplet.exc = e
+ return 1
+
+ if retval is not None:
+ return 1
+
+ return 0
+
+
+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=)
+
+ Recursively iterate a function or callable object over this group's
+ contents. Your callable should match the signature:
+
+ func(name, info)
+
+ where "name" is (a) name relative to the starting group, and "info" is
+ an ObjInfo instance describing each object. Please note the same
+ ObjInfo instance is provided call to call, with its values mutated.
+ Don't store references to it; use the copy module instead:
+
+ mylist.append(info) # WRONG
+ mylist.append(copy.copy(info)) # RIGHT
+ """
+ cdef _Triplet triplet
+ triplet = _Triplet(func)
+
+ H5Ovisit(obj.id, <H5_index_t>idx_type, <H5_iter_order_t>order, iter_cb, <void*>triplet)
+
+ if triplet.exc is not None:
+ raise triplet.exc
+
+
+
+
+
+
+
+
+
+
+
diff --git a/h5py/h5p.pyx b/h5py/h5p.pyx
index 7eb6a3b..489ee72 100644
--- a/h5py/h5p.pyx
+++ b/h5py/h5p.pyx
@@ -339,6 +339,34 @@ cdef class PropDCID(PropInstanceID):
tid = h5t.py_create(value.dtype)
H5Pget_fill_value(self.id, tid.id, value.data)
+ def set_fill_time(self, int fill_time):
+ """ (INT fill_time)
+
+ Define when fill values are written to the dataset. Legal
+ values (defined in module h5d) are:
+
+ h5d.FILL_TIME_ALLOC Write fill values at storage allocation time
+ h5d.FILL_TIME_NEVER Never write fill values
+ h5d.FILL_TIME_IFSET Write fill values at allocation time only
+ if a user-defined value is being used.
+ """
+ H5Pset_fill_time(self.id, <H5D_fill_time_t>fill_time)
+
+ def get_fill_time(self):
+ """ () => INT
+
+ Determine when fill values are written to the dataset. Legal
+ values (defined in module h5d) are:
+
+ h5d.FILL_TIME_ALLOC Write fill values at storage allocation time
+ h5d.FILL_TIME_NEVER Never write fill values
+ h5d.FILL_TIME_IFSET Write fill values at allocation time only
+ if a user-defined value is being used.
+ """
+ cdef H5D_fill_time_t fill_time
+ H5Pget_fill_time(self.id, &fill_time)
+ return <int>fill_time
+
# === Filter functions ====================================================
def set_deflate(self, unsigned int level=5):
@@ -515,16 +543,6 @@ cdef class PropDCID(PropInstanceID):
"""
H5Premove_filter(self.id, <H5Z_filter_t>filter_class)
- def set_fill_time(self, int fill_code):
- """ (INT fill_code)
-
- Set the fill time. Legal values are:
- h5d.FILL_TIME_ALLOC
- h5d.FILL_TIME_NEVER
- h5d.FILL_TIME_IFSET
- """
- H5Pset_fill_time(self.id, fill_time)
-
def fill_value_defined(self):
""" () => INT fill_status
diff --git a/h5py/h5r.pxd b/h5py/h5r.pxd
index 79cd722..0c00357 100644
--- a/h5py/h5r.pxd
+++ b/h5py/h5r.pxd
@@ -36,4 +36,16 @@ cdef extern from "hdf5.h":
hid_t H5Rget_region(hid_t dataset, H5R_type_t ref_type, void *ref) except *
H5G_obj_t H5Rget_obj_type(hid_t id, H5R_type_t ref_type, void *ref) except *
+cdef union ref_u:
+ hobj_ref_t obj_ref
+ hdset_reg_ref_t reg_ref
+
+cdef class Reference:
+
+ cdef ref_u ref
+ cdef readonly int typecode
+
+
+
+
diff --git a/h5py/h5r.pyx b/h5py/h5r.pyx
index 3fa490a..e40cdd7 100644
--- a/h5py/h5r.pyx
+++ b/h5py/h5r.pyx
@@ -29,29 +29,6 @@ import h5
OBJECT = H5R_OBJECT
DATASET_REGION = H5R_DATASET_REGION
-cdef union ref_u:
- hobj_ref_t obj_ref
- hdset_reg_ref_t reg_ref
-
-cdef class Reference:
-
- """
- Represents an HDF5 reference.
-
- Objects of this class are created exclusively by the library and
- cannot be modified. The read-only attribute "typecode" determines
- whether the reference is to an object in an HDF5 file (OBJECT)
- or a dataset region (DATASET_REGION).
- """
-
- cdef ref_u ref
- cdef readonly int typecode
-
- def __str__(self):
- return "HDF5 reference (type %s)" % PY_TYPE[self.typecode]
-
- def __repr__(self):
- return self.__str__()
# === Reference API ===========================================================
@@ -63,12 +40,12 @@ def create(ObjectID loc not None, char* name, int ref_type, SpaceID space=None):
of reference created:
- OBJECT
- Reference to an object in an HDF5 file. Parameters loc
- and name identify the object; space is unused.
+ 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 and
- name identify the dataset; the selection on space
+ Reference to a dataset region. Parameters "loc" and
+ "name" identify the dataset; the selection on "space"
identifies the region.
"""
cdef hid_t space_id
@@ -84,43 +61,70 @@ def create(ObjectID loc not None, char* name, int ref_type, SpaceID space=None):
return ref
-def dereference(ObjectID fid not None, Reference ref):
- """ (ObjectID fid, ReferenceObject ref) => INT obj_id
+cdef class Reference:
+
+ """
+ Represents an HDF5 reference.
- Open the object pointed to by "ref" and return its identifier.
- The containing file must be provided via fid, which can be
- a file identifier or an identifier for any object which lives
- in the file.
+ Objects of this class are created exclusively by the library and
+ cannot be modified. The read-only attribute "typecode" determines
+ whether the reference is to an object in an HDF5 file (OBJECT)
+ or a dataset region (DATASET_REGION).
"""
- 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
+ def dereference(self, ObjectID id not None):
+ """ (ObjectID id) => ObjectID obj_id
+
+ Open the object pointed to by this reference and return its
+ identifier. The file identifier (or the identifier for any object
+ in the file) must also be provided.
+
+ The reference type may be either OBJECT or DATASET_REGION.
+ """
+ return wrap_identifier(H5Rdereference(id.id, <H5R_type_t>self.typecode, &self.ref))
+
+ def get_region(self, ObjectID id not None):
+ """ (ObjectID id) => SpaceID dataspace_id
+
+ Retrieve the dataspace selection pointed to by this reference.
+ Returns a copy of the dataset's dataspace, with the appropriate
+ elements selected. The file identifier or the identifier of any
+ object in the file (including the dataset itself) must also be
+ provided.
+
+ The reference object must be of type DATASET_REGION.
+ """
+ return SpaceID(H5Rget_region(id.id, <H5R_type_t>self.typecode, &self.ref))
+
+ def get_obj_type(self, ObjectID id not None):
+ """ (ObjectID id) => INT obj_code
+
+ Determine what type of object this eference points to. The
+ reference may be either type OBJECT or DATASET_REGION. The file
+ identifier or the identifier of any object in the file must also
+ be provided.
+
+ The return value is one of:
+ h5g.LINK Symbolic link
+ h5g.GROUP Group
+ h5g.DATASET Dataset
+ h5g.TYPE Named datatype
+ """
+ return <int>H5Rget_obj_type(id.id, <H5R_type_t>self.typecode, &self.ref)
+
+ def __str__(self):
+ if self.typecode == H5R_OBJECT:
+ return "HDF5 object reference"
+ elif self.typecode == H5R_DATASET_REGION:
+ return "HDF5 dataset region reference"
+
+ return "Unknown HDF5 reference"
+
+ def __repr__(self):
+ return self.__str__()
+
- Retrieve the dataspace selection pointed to by a reference.
- Returns a copy of the dataset's dataspace, with the appropriate
- elements selected.
- The given reference object must be of type DATASET_REGION.
- """
- 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
-
- Determine what type of object an object reference points to. The
- reference may be either type OBJECT or DATASET_REGION. For
- DATASET_REGION, the parameter ds must be either the dataset
- identifier, or the identifier for the object within which the
- dataset is contained.
-
- The return value is one of:
- h5g.LINK Symbolic link
- h5g.GROUP Group
- h5g.DATASET Dataset
- h5g.TYPE Named datatype
- """
- return <int>H5Rget_obj_type(ds.id, <H5R_type_t>ref.typecode, &ref.ref)
diff --git a/h5py/highlevel.py b/h5py/highlevel.py
index 346d596..52b7a6f 100644
--- a/h5py/highlevel.py
+++ b/h5py/highlevel.py
@@ -50,6 +50,7 @@ import os
import numpy
import inspect
import threading
+import sys
from h5py import h5, h5f, h5g, h5s, h5t, h5d, h5a, h5p, h5z, h5i, config
from h5py.h5 import H5Error
@@ -477,7 +478,7 @@ class Dataset(HLObject):
Creation keywords (* is default):
- chunks: Tuple of chunk dimensions or None*
+ chunks: Tuple of chunk dimensions, True, or None*
compression: DEFLATE (gzip) compression level, int or None*
shuffle: Use the shuffle filter? (requires compression) T/F*
fletcher32: Enable Fletcher32 error detection? T/F*
@@ -508,7 +509,8 @@ class Dataset(HLObject):
dtype = numpy.dtype(dtype)
- if any((compression, shuffle, fletcher32, maxshape)) and chunks is None:
+ if chunks is True or \
+ (any((compression, shuffle, fletcher32, maxshape)) and chunks is None):
chunks = guess_chunk(shape, dtype.itemsize)
if chunks is not None and shape == ():
@@ -554,6 +556,9 @@ class Dataset(HLObject):
shape = self.shape
if len(shape) == 0:
raise TypeError("Attempt to take len() of scalar dataset")
+ size = shape[0]
+ if size > sys.maxint:
+ raise OverflowError("Dataset length is larger than Python's len() function can handle")
return shape[0]
def __iter__(self):
diff --git a/h5py/tests/__init__.py b/h5py/tests/__init__.py
index df9edfa..62a7746 100644
--- a/h5py/tests/__init__.py
+++ b/h5py/tests/__init__.py
@@ -15,6 +15,7 @@ import sys
import test_h5a, test_h5d, test_h5f, \
test_h5g, test_h5i, test_h5p, \
test_h5s, test_h5t, test_h5, \
+ test_h5r, \
test_highlevel, test_threads
from h5py import *
@@ -25,13 +26,14 @@ sections = {'h5a': test_h5a.TestH5A, 'h5d': test_h5d.TestH5D,
'h5p.fcid': test_h5p.TestFCID, 'h5p.faid': test_h5p.TestFAID,
'h5p.dcid': test_h5p.TestDCID, 'h5p.dxid': test_h5p.TestDXID,
'h5s': test_h5s.TestH5S, 'h5t': test_h5t.TestH5T,
+ 'h5r': test_h5r.TestH5R,
'h5': test_h5.TestH5,
'File': test_highlevel.TestFile,
'Group': test_highlevel.TestGroup,
'Dataset': test_highlevel.TestDataset,
'threads': test_threads.TestThreads }
-order = ('h5a', 'h5d', 'h5f', 'h5g', 'h5i', 'h5p', 'h5p.fcid', 'h5p.faid',
+order = ('h5a', 'h5d', 'h5f', 'h5g', 'h5i', 'h5r', 'h5p', 'h5p.fcid', 'h5p.faid',
'h5p.dcid', 'h5p.dxid', 'h5s', 'h5', 'File', 'Group', 'Dataset',
'threads')
diff --git a/h5py/tests/test_h5r.py b/h5py/tests/test_h5r.py
new file mode 100644
index 0000000..0ec1470
--- /dev/null
+++ b/h5py/tests/test_h5r.py
@@ -0,0 +1,59 @@
+#+
+#
+# This file is part of h5py, a low-level Python interface to the HDF5 library.
+#
+# Copyright (C) 2008 Andrew Collette
+# http://h5py.alfven.org
+# License: BSD (See LICENSE.txt for full license)
+#
+# $Date$
+#
+#-
+
+import unittest
+import tempfile
+import os
+import numpy
+
+from h5py import *
+from h5py.h5 import H5Error
+
+
+class TestH5R(unittest.TestCase):
+
+ def setUp(self):
+ self.fname = tempfile.mktemp('.hdf5')
+ self.f = File(self.fname, 'w')
+ self.dset = self.f.create_dataset("ds", (100,))
+ self.grp = self.f.create_group("grp")
+
+ def tearDown(self):
+ self.f.close()
+ os.unlink(self.fname)
+
+ def test_objref(self):
+ ref = h5r.create(self.f.id, "grp", h5r.OBJECT)
+ deref = ref.dereference(self.f.id)
+ self.assertEqual(deref, self.grp.id)
+ #self.assertEqual(h5i.get_name(deref), h5i.get_name(self.grp.id))
+ self.assertEqual(ref.get_obj_type(self.f.id), h5g.GROUP)
+
+ def test_regref(self):
+ space = self.dset.id.get_space()
+ space.select_hyperslab((13,), (42,))
+ ref = h5r.create(self.f.id, "ds", h5r.DATASET_REGION, space)
+
+ #deref = ref.dereference(self.f.id)
+ #self.assertEqual(deref, self.grp.id)
+ #self.assertEqual(h5i.get_name(deref), h5i.get_name(self.grp.id))
+
+ deref_space = ref.get_region(self.f.id)
+ self.assertEqual(space.shape, deref_space.shape)
+ self.assert_(space.get_select_bounds(), deref_space.get_select_bounds())
+
+ self.assertEqual(ref.get_obj_type(self.f.id), h5g.DATASET)
+
+
+
+
+
diff --git a/setup.py b/setup.py
index 1f0abed..cc2e7c6 100644
--- a/setup.py
+++ b/setup.py
@@ -150,6 +150,9 @@ except ImportError:
modules = ['h5' , 'h5f', 'h5g', 'h5s', 'h5t', 'h5d',
'h5a', 'h5p', 'h5z', 'h5i', 'h5r', 'h5fd', 'utils']
+if (opts.API_MAJ, opts.API_MIN) >= (1,8):
+ modules += ['h5o','h5l']
+
# C source files required for Pyrex code (with extension)
extra_src = ['utils_low.c']
--
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