summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/core/_internal.py17
-rw-r--r--numpy/core/tests/test_multiarray.py10
2 files changed, 20 insertions, 7 deletions
diff --git a/numpy/core/_internal.py b/numpy/core/_internal.py
index 49216c646..9463b5099 100644
--- a/numpy/core/_internal.py
+++ b/numpy/core/_internal.py
@@ -436,8 +436,10 @@ def _dtype_from_pep3118(spec, byteorder='@', is_subdtype=False):
spec = spec[j+1:]
# Byte order
- if spec[0] in ('@', '=', '<', '>', '^'):
+ if spec[0] in ('@', '=', '<', '>', '^', '!'):
byteorder = spec[0]
+ if byteorder == '!':
+ byteorder = '>'
spec = spec[1:]
# Byte order characters also control native vs. standard type sizes
@@ -462,10 +464,10 @@ def _dtype_from_pep3118(spec, byteorder='@', is_subdtype=False):
is_padding = False
if spec[:2] == 'T{':
- value, spec, align = _dtype_from_pep3118(spec[2:],
- byteorder=byteorder,
- is_subdtype=True)
+ value, spec, align, next_byteorder = _dtype_from_pep3118(
+ spec[2:], byteorder=byteorder, is_subdtype=True)
elif spec[0] in type_map_chars:
+ next_byteorder = byteorder
if spec[0] == 'Z':
j = 2
else:
@@ -533,6 +535,8 @@ def _dtype_from_pep3118(spec, byteorder='@', is_subdtype=False):
next_dummy_name()
last_offset = offset
+ byteorder = next_byteorder
+
offset += value.itemsize
offset += extra_offset
@@ -541,13 +545,14 @@ def _dtype_from_pep3118(spec, byteorder='@', is_subdtype=False):
name = get_dummy_name()
fields[name] = ('V%d' % (offset - last_offset), last_offset)
- if len(fields.keys()) == 1 and not explicit_name and fields['f0'][1] == 0:
+ if len(fields.keys()) == 1 and not explicit_name and fields['f0'][1] == 0 \
+ and not is_subdtype:
ret = fields['f0'][0]
else:
ret = dtype(fields)
if is_subdtype:
- return ret, spec, common_alignment
+ return ret, spec, common_alignment, byteorder
else:
return ret
diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py
index 542cdd30b..f2974a82d 100644
--- a/numpy/core/tests/test_multiarray.py
+++ b/numpy/core/tests/test_multiarray.py
@@ -1476,12 +1476,20 @@ if sys.version_info >= (2, 6):
'f1': ('i', 1+j)})
def test_native_padding_2(self):
+ # Native padding should work also for structs and sub-arrays
self._check('x3T{xi}', {'f0': (({'f0': ('i', 4)}, (3,)), 4)})
- self._check('=x3T{xi}', {'f0': (({'f0': ('i', 1)}, (3,)), 1)})
+ self._check('^x3T{xi}', {'f0': (({'f0': ('i', 1)}, (3,)), 1)})
def test_trailing_padding(self):
+ # Trailing padding should be included
self._check('ix', [('f0', 'i'), ('f1', 'V1')])
+ def test_byteorder_inside_struct(self):
+ # The byte order after @T{=i} should be '=', not '@'.
+ # Check this by noting the absence of native alignment.
+ self._check('@T{^i}xi', {'f0': ({'f0': (np.int32, 0)}, 0),
+ 'f1': (np.int32, 5)})
+
class TestNewBufferProtocol(object):
def _check_roundtrip(self, obj):
obj = np.asarray(obj)