at 18.03-beta 4.2 kB view raw
1From 5009e062a6f7d4e074cab0fcb42a780ac2b1d7d4 Mon Sep 17 00:00:00 2001 2From: James Tocknell <aragilar@gmail.com> 3Date: Thu, 28 Dec 2017 20:55:55 +1100 4Subject: [PATCH] FIX: Don't reorder compound types, breaks on numpy 1.14 5 6--- 7 h5py/h5t.pyx | 25 +++++++------------------ 8 setup.py | 2 +- 9 tox.ini | 4 ++-- 10 3 files changed, 10 insertions(+), 21 deletions(-) 11 12diff --git a/h5py/h5t.pyx b/h5py/h5t.pyx 13index cc2344e1..7445e9eb 100644 14--- a/h5py/h5t.pyx 15+++ b/h5py/h5t.pyx 16@@ -1136,12 +1136,6 @@ cdef class TypeCompoundID(TypeCompositeID): 17 else: 18 if sys.version[0] == '3': 19 field_names = [x.decode('utf8') for x in field_names] 20- if len(field_names) > 0: 21- collated_fields = zip(field_names, field_types, field_offsets) 22- ordered_fields = sorted( 23- collated_fields, key=operator.itemgetter(2)) 24- field_names, field_types, field_offsets = \ 25- map(list, zip(*ordered_fields)) 26 typeobj = dtype({ 27 'names': field_names, 28 'formats': field_types, 29@@ -1458,8 +1452,7 @@ cdef TypeCompoundID _c_compound(dtype dt, int logical, int aligned): 30 cdef dtype member_dt 31 cdef size_t member_offset = 0 32 33- cdef dict offsets = {} 34- cdef list fields = [] 35+ cdef dict fields = {} 36 37 # The challenge with correctly converting a numpy/h5py dtype to a HDF5 type 38 # which is composed of subtypes has three aspects we must consider 39@@ -1468,19 +1461,14 @@ cdef TypeCompoundID _c_compound(dtype dt, int logical, int aligned): 40 # 2. For correct round-tripping of aligned dtypes, we need to consider how 41 # much padding we need by looking at the field offsets 42 # 3. There is no requirement that the offsets be monotonically increasing 43- # (so we start by sorting the names as a function of increasing offset) 44 # 45 # The code below tries to cover these aspects 46 47- # Get offsets for each compound member 48- for name, field in dt.fields.items(): 49- offsets[name] = field[1] 50- 51 # Build list of names, offsets, and types, sorted by increasing offset 52 # (i.e. the position of the member in the struct) 53- for name in sorted(dt.names, key=offsets.__getitem__): 54+ for name in sorted(dt.names, key=(lambda n: dt.fields[n][1])): 55 field = dt.fields[name] 56- name = name.encode('utf8') if isinstance(name, unicode) else name 57+ h5_name = name.encode('utf8') if isinstance(name, unicode) else name 58 59 # Get HDF5 data types and set the offset for each member 60 member_dt = field[0] 61@@ -1489,7 +1477,7 @@ cdef TypeCompoundID _c_compound(dtype dt, int logical, int aligned): 62 if aligned and (member_offset > field[1] 63 or member_dt.itemsize != member_type.get_size()): 64 raise TypeError("Enforced alignment not compatible with HDF5 type") 65- fields.append((name, member_offset, member_type)) 66+ fields[name] = (h5_name, member_offset, member_type) 67 68 # Update member offset based on the HDF5 type size 69 member_offset += member_type.get_size() 70@@ -1500,8 +1488,9 @@ cdef TypeCompoundID _c_compound(dtype dt, int logical, int aligned): 71 72 # Create compound with the necessary size, and insert its members 73 tid = H5Tcreate(H5T_COMPOUND, member_offset) 74- for (name, member_offset, member_type) in fields: 75- H5Tinsert(tid, name, member_offset, member_type.id) 76+ for name in dt.names: 77+ h5_name, member_offset, member_type = fields[name] 78+ H5Tinsert(tid, h5_name, member_offset, member_type.id) 79 80 return TypeCompoundID(tid) 81 82diff --git a/setup.py b/setup.py 83index ec2a78a7..bbb086f6 100755 84--- a/setup.py 85+++ b/setup.py 86@@ -32,7 +32,7 @@ 87 # these are required to build h5py 88 # RUN_REQUIRES is included as setup.py test needs RUN_REQUIRES for testing 89 # RUN_REQUIRES can be removed when setup.py test is removed 90-SETUP_REQUIRES = RUN_REQUIRES + [NUMPY_DEP, 'Cython>=0.19', 'pkgconfig'] 91+SETUP_REQUIRES = RUN_REQUIRES + [NUMPY_DEP, 'Cython>=0.23', 'pkgconfig'] 92 93 # Needed to avoid trying to install numpy/cython on pythons which the latest 94 # versions don't support