summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormattip <matti.picus@gmail.com>2018-11-13 11:15:14 -0800
committermattip <matti.picus@gmail.com>2018-11-13 11:15:14 -0800
commit62e47c34b39aebb9a7a6aa41e9af3b2e119a2d74 (patch)
tree506e36530c9b3bfccf5c1990975ec10bc6ffffab
parent1956ada852f950468e028cf108766e089f4575cc (diff)
downloadnumpy-62e47c34b39aebb9a7a6aa41e9af3b2e119a2d74.tar.gz
BUG: fix for titles, cleanup, fixes from review
-rw-r--r--numpy/lib/format.py27
-rw-r--r--numpy/lib/tests/test_format.py6
2 files changed, 25 insertions, 8 deletions
diff --git a/numpy/lib/format.py b/numpy/lib/format.py
index ad26cf46a..e58ffa017 100644
--- a/numpy/lib/format.py
+++ b/numpy/lib/format.py
@@ -260,8 +260,15 @@ def dtype_to_descr(dtype):
return dtype.str
def descr_to_dtype(descr):
- if isinstance(descr, str):
- # descr was produced by dtype.str, so this always works
+ '''
+ descr may be stored as dtype.descr, which is a list of
+ (name, format, [shape]) tuples. Offsets are not explicitly saved, rather
+ empty fields with name,format == '', '|Vn' are added as padding.
+
+ This function reverses the process, eliminating the empty padding fields.
+ '''
+ if isinstance(descr, (str, dict)):
+ # No padding removal needed
return numpy.dtype(descr)
fields = []
@@ -274,8 +281,8 @@ def descr_to_dtype(descr):
name, descr_str, shape = field
dt = numpy.dtype((descr_to_dtype(descr_str), shape))
- # ignore padding bytes, which will be void bytes with '' as name
- # (once blank fieldnames are deprecated, only "if name == ''" needed)
+ # Ignore padding bytes, which will be void bytes with '' as name
+ # Once support for blank names is removed, only "if name == ''" needed)
is_pad = (name == '' and dt.type is numpy.void and dt.names is None)
if not is_pad:
fields.append((name, dt, offset))
@@ -283,7 +290,14 @@ def descr_to_dtype(descr):
offset += dt.itemsize
names, formats, offsets = zip(*fields)
- return numpy.dtype({'names': names, 'formats': formats,
+ # names may be (title, names) tuples
+ names = list(names)
+ titles = [None] * len(names)
+ for i, n in enumerate(names):
+ if isinstance(n, tuple):
+ titles[i] = n[0]
+ names[i] = n[1]
+ return numpy.dtype({'names': names, 'formats': formats, 'titles': titles,
'offsets': offsets, 'itemsize': offset})
def header_data_from_array_1_0(array):
@@ -550,8 +564,7 @@ def _read_array_header(fp, version):
msg = "fortran_order is not a valid bool: %r"
raise ValueError(msg % (d['fortran_order'],))
try:
- descr = descr_to_dtype(d['descr'])
- dtype = numpy.dtype(descr)
+ dtype = descr_to_dtype(d['descr'])
except TypeError as e:
msg = "descr is not a valid dtype descriptor: %r"
raise ValueError(msg % (d['descr'],))
diff --git a/numpy/lib/tests/test_format.py b/numpy/lib/tests/test_format.py
index 13a12197c..0d7c7f7e0 100644
--- a/numpy/lib/tests/test_format.py
+++ b/numpy/lib/tests/test_format.py
@@ -533,7 +533,11 @@ dt2 = np.dtype({'names': ['a', 'b'], 'formats': ['i4', 'i4'],
dt3 = np.dtype({'names': ['c', 'd'], 'formats': ['i4', dt2]})
# field with '' name
dt4 = np.dtype({'names': ['a', '', 'b'], 'formats': ['i4']*3})
-@pytest.mark.parametrize("dt", [dt1, dt2, dt3, dt4])
+# titles
+dt5 = np.dtype({'names': ['a', 'b'], 'formats': ['i4', 'i4'],
+ 'offsets': [1, 6], 'titles': ['aa', 'bb']})
+
+@pytest.mark.parametrize("dt", [dt1, dt2, dt3, dt4, dt5])
def test_load_padded_dtype(dt):
arr = np.zeros(3, dt)
for i in range(3):