[h5py] 65/455: Implemented conditional compilation, debug support, HL fixes, browser.
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 38f755d0392558364182435418198777c1555184
Author: andrewcollette <andrew.collette at gmail.com>
Date: Fri Jul 4 02:07:16 2008 +0000
Implemented conditional compilation, debug support, HL fixes, browser.
---
h5py/browse.py | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++
h5py/defs_c.pxd | 1 -
h5py/h5.pxd | 1 +
h5py/h5.pyx | 43 ++++++++++----
h5py/h5d.pyx | 2 +-
h5py/h5t.pyx | 12 +++-
h5py/highlevel.py | 122 ++++++++++++++++++++++++++--------------
h5py/tests/test_h5.py | 8 +--
h5py/utils_hl.py | 9 +++
setup.py | 75 +++++++++++++++++++++----
10 files changed, 354 insertions(+), 71 deletions(-)
diff --git a/h5py/browse.py b/h5py/browse.py
new file mode 100644
index 0000000..61a5f29
--- /dev/null
+++ b/h5py/browse.py
@@ -0,0 +1,152 @@
+#+
+#
+# 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 cmd
+import os
+import posixpath
+from utils_hl import hbasename
+
+from h5py.highlevel import File, Group, Dataset, Datatype
+from h5py import h5g
+
+class _H5Browser(cmd.Cmd):
+
+ """
+ HDF5 file browser class which holds state between sessions.
+ """
+
+ def __init__(self):
+ """ Create a new browser instance.
+ """
+ cmd.Cmd.__init__(self)
+ self.path = '/'
+ self.known_paths = {}
+ self.file = None #: Holds a File instance while executing, the file name otherwise.
+
+ def __call__(self, what=None, mode='r', importdict=None):
+ """ Browse the file, putting any imported names into importdict. """
+
+ if what is None:
+ if self.file is None:
+ raise ValueError("Either a file name or File object must be supplied.")
+ else:
+ self.file = File(self.file, mode=mode)
+
+ elif isinstance(what, File):
+ self.file = what
+
+ elif isinstance(what, str):
+ self.file = File(what, mode=mode)
+
+ else:
+ raise ValueError("Only a string file name or an File object may be supplied.")
+
+ # Now self.file is a File object, no matter what
+
+ try:
+ self.path = self.known_paths[os.path.abspath(self.file.name)]
+ except KeyError:
+ self.path = '/'
+
+ self.importdict = importdict
+ self.cmdloop('Browsing "%s". Type "help" for commands, "exit" to exit.' % os.path.basename(self.file.name))
+ self.importdict = None # don't hold a reference to this between browse sessions
+
+ self.known_paths[os.path.abspath(self.file.name)] = self.path
+ self.file = self.file.name
+
+ def _error(self, msg):
+ print "Error: "+str(msg)
+
+ def abspath(self, path):
+ """ Correctly interpret the given path fragment, relative to the
+ current path.
+ """
+ apath = posixpath.join(self.path, path)
+ apath = posixpath.normpath(apath)
+ return apath
+
+ def get_candidates(path, criterion=lambda grp, name: True):
+ """ Get a list of candidates, in the group pointed to by
+ "path", which satisfy a particular criterion.
+ """
+ pass
+
+ def do_exit(self, line):
+ return True
+
+ def do_EOF(self, line):
+ return True
+
+ def do_pwd(self, line):
+ print self.path
+
+ def do_cd(self, line):
+ path = line.strip()
+ if path == '': path = '/'
+ path = self.abspath(path)
+ dname = posixpath.dirname(path)
+ bname = posixpath.basename(path)
+ print dname, bname
+ try:
+ pgrp = self.file[dname]
+ if bname != '' and not pgrp.id.get_objinfo(bname).type == h5g.GROUP:
+ self._error('"%s" is not an HDF5 group' % bname)
+ else:
+ self.path = path
+ except:
+ self._error('Can\'t open group "%s"' % path)
+
+ def complete_cd(self, text, line, begidx, endidx):
+ text = text.strip()
+ grpname = posixpath.join(self.path,posixpath.dirname(text))
+ targetname = posixpath.basename(text)
+
+ try:
+ grp = self.file[grpname]
+ return [posixpath.join(grpname,x) for x in grp \
+ if x.find(targetname) == 0 and \
+ grp.id.get_objinfo(x).type == h5g.GROUP]
+ except:
+ return []
+
+ def do_ls(self, line):
+ """ List contents of the specified group, or this one """
+
+ line = line.strip()
+ if line == '':
+ grpname = self.path
+ else:
+ grpname = posixpath.join(self.path, line)
+
+ try:
+ grp = self.file[grpname]
+ for name in grp:
+ print name
+ except:
+ self._error('Can\'t list contents of group "%s"' % hbasename(grpname))
+
+ def complete_ls(self, *args):
+ return self.complete_cd(*args)
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/h5py/defs_c.pxd b/h5py/defs_c.pxd
index 69a7793..6ae13c2 100644
--- a/h5py/defs_c.pxd
+++ b/h5py/defs_c.pxd
@@ -36,4 +36,3 @@ cdef extern from "unistd.h":
ctypedef long ssize_t
-
diff --git a/h5py/h5.pxd b/h5py/h5.pxd
index 95f8f4c..4e90b59 100644
--- a/h5py/h5.pxd
+++ b/h5py/h5.pxd
@@ -14,6 +14,7 @@
# license is available at licenses/pytables.txt, in the distribution root
# directory.
+include "conditions.pxi"
from defs_c cimport size_t, ssize_t
# Common structs and types from HDF5
diff --git a/h5py/h5.pyx b/h5py/h5.pyx
index 359bfe3..76b8231 100644
--- a/h5py/h5.pyx
+++ b/h5py/h5.pyx
@@ -9,8 +9,6 @@
# $Date$
#
#-
-
-
"""
Common module for the HDF5 low-level interface library.
@@ -19,9 +17,21 @@
- API_VERS, API_VERS_TPL: API version (1.6 or 1.8) used to compile h5py.
All exception classes and error handling functions are also in this module.
+
+ This module is designed to be imported before any other h5py module is
+ executed. It opens the library and enables debug logging, if required.
"""
+
+include "conditions.pxi"
from python cimport PyErr_SetObject
+# Logging is only enabled when compiled with H5PY_DEBUG nonzero
+IF H5PY_DEBUG:
+ import logging
+ logger = logging.getLogger('h5py')
+ logger.setLevel(H5PY_DEBUG)
+ logger.addHandler(logging.StreamHandler())
+
# === API =====================================================================
def get_libversion():
@@ -38,10 +48,10 @@ def get_libversion():
return (major, minor, release)
-HDF5_VERS_TPL = get_libversion()
-HDF5_VERS = "%d.%d.%d" % HDF5_VERS_TPL
-API_VERS = '1.6'
-API_VERS_TPL = (1,6)
+hdf5_version_tuple = get_libversion()
+hdf5_version = "%d.%d.%d" % hdf5_version_tuple
+api_version_tuple = (H5PY_API_MAJ, H5PY_API_MIN)
+api_version = H5PY_API
class DDict(dict):
@@ -54,14 +64,24 @@ class DDict(dict):
cdef class ObjectID:
+ property _valid:
+ """ Indicates whether or not this identifier points to an HDF5 object.
+ """
+ def __get__(self):
+ return H5Iget_type(self.id) != H5I_BADID
+
def __cinit__(self, hid_t id_):
""" Object init; simply records the given ID. """
self._locked = 0
self.id = id_
+ IF H5PY_DEBUG:
+ logger.debug("+ %s" % str(self))
def __dealloc__(self):
""" Automatically decrefs the ID, if it's valid. """
- if (not self._locked) and (H5Iget_type(self.id) != H5I_BADID):
+ IF H5PY_DEBUG:
+ logger.debug("- %s" % str(self))
+ if (not self._locked) and self._valid:
H5Idec_ref(self.id)
def __copy__(self):
@@ -73,9 +93,11 @@ cdef class ObjectID:
cdef ObjectID copy
copy = type(self)(self.id)
assert typecheck(copy, ObjectID), "ObjectID copy encountered invalid type"
- if H5Iget_type(self.id) != H5I_BADID and not self._locked:
+ if self._valid and not self._locked:
H5Iinc_ref(self.id)
copy._locked = self._locked
+ IF H5PY_DEBUG:
+ logger.debug("c %s" % str(self))
return copy
def __richcmp__(self, object other, int how):
@@ -94,10 +116,11 @@ cdef class ObjectID:
raise TypeError("Only equality comparisons are supported.")
def __str__(self):
- if H5Iget_type(self.id) != H5I_BADID:
+ if self._valid:
ref = str(H5Iget_ref(self.id))
else:
ref = "INVALID"
+
if self._locked:
lstr = "locked"
else:
@@ -108,8 +131,6 @@ cdef class ObjectID:
def __repr__(self):
return self.__str__()
-# === Automatic error handling ================================================
-
# === Public exception hierarchy ==============================================
diff --git a/h5py/h5d.pyx b/h5py/h5d.pyx
index 02b2528..29dc9a3 100644
--- a/h5py/h5d.pyx
+++ b/h5py/h5d.pyx
@@ -183,7 +183,7 @@ cdef class DatasetID(ObjectID):
H5Dwrite(self.id, mtype.id, mspace.id, fspace.id, plist_id, PyArray_DATA(arr_obj))
finally:
- if mtype_id is not None:
+ if mtype is not None:
mtype.close()
def extend(self, object shape):
diff --git a/h5py/h5t.pyx b/h5py/h5t.pyx
index e406474..ee9211e 100644
--- a/h5py/h5t.pyx
+++ b/h5py/h5t.pyx
@@ -14,6 +14,8 @@
HDF5 "H5T" data-type API
"""
+include "conditions.pxi"
+
# Pyrex compile-time imports
from defs_c cimport free
from h5p cimport H5P_DEFAULT
@@ -298,6 +300,9 @@ cdef class TypeID(ObjectID):
cdef object py_dtype(self):
raise NotImplementedError("Don't know how to convert %s objects to Numpy" % self.__class__.__name__)
+ def __repr__(self):
+ return str(self)+" "+str(self.dtype)
+
def commit(self, ObjectID group not None, char* name):
""" (ObjectID group, STRING name)
@@ -624,7 +629,6 @@ cdef class TypeIntegerID(TypeAtomicID):
return dtype( _order_map[self.get_order()] +
_sign_map[self.get_sign()] + str(self.get_size()) )
-
cdef class TypeFloatID(TypeAtomicID):
"""
@@ -1053,6 +1057,12 @@ def py_create(dtype dt not None, object complex_names=None, enum=None):
if complex_names is not None:
otype.complex_names = complex_names
+
+ 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/highlevel.py b/h5py/highlevel.py
index 17ee7ad..c363cbf 100644
--- a/h5py/highlevel.py
+++ b/h5py/highlevel.py
@@ -13,10 +13,18 @@
import numpy
from h5py import h5, h5f, h5g, h5s, h5t, h5d, h5a, h5p, h5z, h5i
-from utils_hl import slicer
+from h5py.h5 import H5Error
+from utils_hl import slicer, hbasename
+class HLObject(object):
-class Group(object):
+ name = property(lambda self: h5i.get_name(self.id),
+ doc = "Name of this object in the HDF5 file. Not necessarily unique.")
+
+ def __repr__(self):
+ return str(self)
+
+class Group(HLObject):
""" Represents an HDF5 group.
@@ -41,35 +49,36 @@ class Group(object):
self._attrs = AttributeManager(self)
def __setitem__(self, name, obj):
- """ Add the given object to the group. Here are the rules:
+ """ Add the given object to the group. The action taken depends on
+ the type of object assigned:
- 1. If "obj" is a Dataset or Group object, a hard link is created
- in this group which points to the given object.
+ 1. Named HDF5 object (Dataset, Group, Datatype):
+ A hard link is created in this group which points to the
+ given object.
- 2. If "obj" is a Numpy ndarray, it is converted to a dataset
- object, with default settings (contiguous storage, etc.).
+ 2. Numpy ndarray:
+ The array is converted to a dataset object, with default
+ settings (contiguous storage, etc.).
- 3. If "obj is a Numpy dtype object or Datatype instance, commit
- a copy of the datatype as a named datatype in the file.
+ 3. Numpy dtype:
+ Commit a copy of the datatype as a named datatype in the file.
- 3. If "obj" is anything else, attempt to convert it to an ndarray
- and store it. Scalar values are stored as scalar datasets.
- Raise ValueError if we can't understand the resulting array
- dtype.
+ 4. Anything else:
+ Attempt to convert it to an ndarray and store it. Scalar
+ values are stored as scalar datasets. Raise ValueError if we
+ can't understand the resulting array dtype.
"""
- if isinstance(obj, Group) or isinstance(obj, Dataset):
+ if isinstance(obj, Group) or isinstance(obj, Dataset) or isinstance(obj, Datatype):
self.id.link(name, h5i.get_name(obj.id), link_type=h5g.LINK_HARD)
+
elif isinstance(obj, numpy.dtype):
htype = h5t.py_create(obj)
htype.commit(self.id, name)
- elif isinstance(obj, Datatype):
- htype = obj.id.copy()
- htype.commit(self.id, name)
+
else:
if not isinstance(obj, numpy.ndarray):
obj = numpy.array(obj)
- dset = Dataset(self, name, data=obj)
- dset.close()
+ Dataset(self, name, data=obj)
def __getitem__(self, name):
""" Open an object attached to this group.
@@ -80,8 +89,6 @@ class Group(object):
if info.type == h5g.DATASET:
dset = Dataset(self, name)
- if dset.shape == ():
- return dset[...]
return dset
elif info.type == h5g.GROUP:
@@ -103,21 +110,21 @@ class Group(object):
return self.id.py_iter()
def __str__(self):
- return 'Group (%d members): ' % len(self) + ', '.join(['"%s"' % name for name in self])
-
- def __repr__(self):
- return str(self)
+ if self.id._valid:
+ return 'Group "%s" (%d members): %s' % (hbasename(self.name),
+ len(self), ', '.join(['"%s"' % name for name in self]))
+ return "Closed group"
def iteritems(self):
for name in self:
- return (name, self[name])
+ yield (name, self[name])
class File(Group):
""" Represents an HDF5 file on disk.
Created with standard Python syntax File(name, mode).
- Legal modes: r, r+, w, w+, a.
+ Legal modes: r, r+, w, w+, a (default 'r')
File objects inherit from Group objects; Group-like methods all
operate on the HDF5 root group ('/'). Like Python file objects, you
@@ -133,7 +140,7 @@ class File(Group):
# --- Public interface (File) ---------------------------------------------
- def __init__(self, name, mode, noclobber=False):
+ def __init__(self, name, mode='r', noclobber=False):
""" Create a new file object.
Valid modes (like Python's file() modes) are:
@@ -178,12 +185,11 @@ class File(Group):
h5f.flush(self.fid)
def __str__(self):
- return 'File "%s", root members: %s' % (self.name, ', '.join(['"%s"' % name for name in self]))
+ if self.id._valid:
+ return 'File "%s", root members: %s' % (self.name, ', '.join(['"%s"' % name for name in self]))
+ return "Closed file (%s)" % self.name
- def __repr_(self):
- return str(self)
-
-class Dataset(object):
+class Dataset(HLObject):
""" High-level interface to an HDF5 dataset
"""
@@ -197,6 +203,15 @@ class Dataset(object):
attrs = property(lambda self: self._attrs,
doc = "Provides access to HDF5 attributes. See AttributeManager.")
+ def _getval(self):
+ arr = self[...]
+ if arr.shape == ():
+ return numpy.asscalar(arr)
+ return arr
+
+ value = property(_getval,
+ doc = "The entire dataset, as an array or scalar depending on the shape.")
+
def __init__(self, group, name,
data=None, dtype=None, shape=None,
chunks=None, compression=None, shuffle=False, fletcher32=False):
@@ -304,7 +319,10 @@ class Dataset(object):
mtype = htype
fspace = self.id.get_space()
- fspace.select_hyperslab(start, count, stride)
+ if fspace.get_simple_extent_type() == h5s.SCALAR:
+ fspace.select_all()
+ else:
+ fspace.select_hyperslab(start, count, stride)
mspace = h5s.create_simple(count)
arr = numpy.ndarray(count, mtype.dtype)
@@ -339,12 +357,12 @@ class Dataset(object):
self.id.write(mspace, fspace, array(val))
def __str__(self):
- return 'Dataset: '+str(self.shape)+' '+repr(self.dtype)
+ if self.id._valid:
+ return 'Dataset "%s": %s %s' % (hbasename(self.name),
+ str(self.shape), repr(self.dtype))
+ return "Closed dataset"
- def __repr__(self):
- return str(self)
-
-class AttributeManager(object):
+class AttributeManager(HLObject):
""" Allows dictionary-style access to an HDF5 object's attributes.
@@ -390,7 +408,7 @@ class AttributeManager(object):
h5a.delete(self.id, name)
except H5Error:
pass
- attr = h5a.py_create(self.id, name, htype, space)
+ attr = h5a.create(self.id, name, htype, space)
attr.write(value)
def __delitem__(self, name):
@@ -408,9 +426,21 @@ class AttributeManager(object):
yield (name, self[name])
def __str__(self):
- return "Attributes: "+', '.join(['"%s"' % x for x in self])
+ if self.id._valid:
+ rstr = 'Attributes of "%s": ' % hbasename(self.name)
+ if len(self) == 0:
+ rstr += '(none)'
+ else:
+ rstr += ', '.join(['"%s"' % x for x in self])
+ else:
+ rstr = "Attributes of closed object."
+
+ return rstr
-class Datatype(object):
+ def __repr__(self):
+ return str(self)
+
+class Datatype(HLObject):
"""
Represents an HDF5 datatype.
@@ -423,7 +453,15 @@ class Datatype(object):
def __init__(grp, name):
self.id = h5t.open(grp.id, name)
+ def __str__(self):
+ if self.id._valid:
+ return "Named datatype object (%s)" % str(self.dtype)
+ return "Closed datatype object"
+
+# Browser component. This is here to prevent issues with circular imports
+from browse import _H5Browser
+browse = _H5Browser()
diff --git a/h5py/tests/test_h5.py b/h5py/tests/test_h5.py
index 9908bea..44ca28f 100644
--- a/h5py/tests/test_h5.py
+++ b/h5py/tests/test_h5.py
@@ -19,7 +19,7 @@ class TestH5(unittest.TestCase):
# For 1.6 API
tpl = h5.get_libversion()
- self.assertEqual(tpl, h5.HDF5_VERS_TPL)
- self.assertEqual("%d.%d.%d" % tpl, h5.HDF5_VERS)
- h5.API_VERS
- h5.API_VERS_TPL
+ self.assertEqual(tpl, h5.hdf5_version_tuple)
+ self.assertEqual("%d.%d.%d" % tpl, h5.hdf5_version)
+ h5.api_version
+ h5.api_version_tuple
diff --git a/h5py/utils_hl.py b/h5py/utils_hl.py
index 3ae00b9..657f73c 100644
--- a/h5py/utils_hl.py
+++ b/h5py/utils_hl.py
@@ -2,6 +2,15 @@
"""
Utility functions for high-level modules.
"""
+from posixpath import basename, normpath
+
+def hbasename(name):
+ """ Basename function with more readable handling of trailing slashes"""
+ bname = normpath(name)
+ bname = basename(bname)
+ if bname == '':
+ bname = '/'
+ return bname
def slicer(shape, args):
""" Parse a tuple containing Numpy-style extended slices.
diff --git a/setup.py b/setup.py
index 7de4235..58d07fe 100644
--- a/setup.py
+++ b/setup.py
@@ -17,7 +17,8 @@
All commands take the usual distutils options, like --home, etc. Pyrex is
not required for installation, but will be invoked if the .c files are
- missing or the option --pyrex (or --pyrex-only) is used.
+ missing, one of the --pyrex options is used, or if a non-default API
+ version or debug level is requested.
To build:
python setup.py build
@@ -28,16 +29,20 @@
To run the test suite locally (won't install anything):
python setup.py test
+ Additional options (for all modes):
+ --pyrex Have Pyrex recompile changed *.pyx files.
+ --pyrex-only Have Pyrex recompile changed *.pyx files, and stop.
+ --pyrex-force Recompile all *.pyx files, regardless of timestamps.
+
+ --api=<n> Specifies API version. Only "16" is currently allowed.
+ --debug=<n> If nonzero, compile in debug mode. The number is
+ interpreted as a logging-module level number.
+
Advanced developer options:
python setup.py dev [--doc] [--clean] [--readme=<name.html>]
--doc: Rebuild HTML documentation (requires epydoc)
--clean: Wipe out build/ and Pyrex-created .c, .dep files
--readme: Compile the RST readme file into an HTML fragment
-
- Universal options:
- --pyrex Have Pyrex recompile changed *.pyx files
- --pyrex-only Have Pyrex recompile changed *.pyx files, and stop.
- --pyrex-force Recompile all *.pyx files, regardless of timestamps
"""
# === Global constants ========================================================
@@ -51,6 +56,8 @@ MIN_NUMPY = '1.0.3'
custom_include_dirs = [] # = ["/some/other/path", "/an/other/path"]
custom_library_dirs = []
+AUTO_HDR = "# This file is automatically generated. Do not edit."
+
# === Initial imports and utilities ===========================================
from distutils.cmd import Command
@@ -77,19 +84,33 @@ def warn(instring):
ENABLE_PYREX = False
PYREX_ONLY = False
PYREX_FORCE = False
+
+API_VERS = (1,6)
+DEBUG_LEVEL = 0
DEV_MODE = False
+
for arg in sys.argv[:]:
if arg == '--pyrex':
ENABLE_PYREX = True
sys.argv.remove(arg)
- if arg == '--pyrex-only':
+ elif arg == '--pyrex-only':
ENABLE_PYREX = True
PYREX_ONLY = True
sys.argv.remove(arg)
- if arg == '--pyrex-force':
+ elif arg == '--pyrex-force':
ENABLE_PYREX=True
PYREX_FORCE = True
sys.argv.remove(arg)
+ elif arg.find('--api=') == 0:
+ api = arg[6:]
+ if api == '16':
+ API_VERS = (1,6)
+ else:
+ fatal('Unrecognized API version "%s" (only "16" currently allowed)' % api)
+ sys.argv.remove(arg)
+ elif arg.find('--debug=') == 0:
+ DEBUG_LEVEL = int(arg[8:])
+ sys.argv.remove(arg)
if "dev" in sys.argv:
DEV_MODE = True
@@ -123,7 +144,7 @@ vers_in = open('VERSION.txt', 'r')
VERSION = vers_in.read().strip()
vers_out = open(os.path.join(NAME,'version.py'),'w')
rdfile = open('README.txt','r')
-vers_out.write('# This file is automatically generated; do not edit.\n')
+vers_out.write(AUTO_HDR+'\n')
vers_out.write('"""\nPackage "h5py" extended information\n\n%s"""\nversion = "%s"\n\n' % (rdfile.read(), VERSION))
rdfile.close()
vers_out.close()
@@ -155,14 +176,44 @@ extra_compile_args = pyx_extra_args
# Pyrex source files (without extension)
pyrex_sources = [os.path.join(pyx_src_path, x) for x in pyx_modules]
-# Enable Pyrex if requested or needed
-if ENABLE_PYREX or not all([os.path.exists(x+'.c') for x in pyrex_sources]):
+# Check if the conditions.pxi file is up-to-date
+cond_path = os.path.join(pyx_src_path, 'conditions.pxi')
+cond = \
+"""
+%s
+
+DEF H5PY_API_MAJ = %d
+DEF H5PY_API_MIN = %d
+DEF H5PY_DEBUG = %d
+DEF H5PY_API = "%d.%d"
+""" % (AUTO_HDR, API_VERS[0], API_VERS[1], DEBUG_LEVEL,API_VERS[0], API_VERS[1])
+
+cond_file = open(cond_path,'r')
+cond_present = cond_file.read()
+cond_file.close()
+if cond_present != cond:
+ ENABLE_PYREX = True
+
+# If for some reason the .c files are missing, Pyrex is required.
+if not all([os.path.exists(x+'.c') for x in pyrex_sources]):
+ ENABLE_PYREX = True
+
+if ENABLE_PYREX:
+ print "Running Pyrex..."
try:
from Pyrex.Compiler.Main import Version
if Version.version >= MIN_PYREX:
from Pyrex.Compiler.Main import compile_multiple, CompilationOptions
+ # If we regenerate the file every time, Pyrex's timestamp checking
+ # is useless. So only replace it if it's out of date.
+ if cond_present != cond:
+ print "Replacing conditions file..."
+ cond_file = open(cond_path,'w')
+ cond_file.write(cond)
+ cond_file.close()
+
opts = CompilationOptions(verbose=True, timestamps=(not PYREX_FORCE))
results = compile_multiple( [x+'.pyx' for x in pyrex_sources], opts)
@@ -178,6 +229,8 @@ if ENABLE_PYREX or not all([os.path.exists(x+'.c') for x in pyrex_sources]):
except ImportError:
fatal("Pyrex recompilation required, but Pyrex not installed.")
+else:
+ print "Pyrex not required, skipping."
# Create extensions
pyx_extensions = []
--
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