summaryrefslogtreecommitdiff
path: root/numpy/core/_internal.py
diff options
context:
space:
mode:
authorEric Wieser <wieser.eric@gmail.com>2017-05-05 12:36:02 +0100
committerEric Wieser <wieser.eric@gmail.com>2017-05-05 12:38:54 +0100
commita4f435c68c15bc43a9b09869aaedb94d6c1bee2a (patch)
tree0282d4380390a0dfa5828060527ef58164a5ecbe /numpy/core/_internal.py
parent3c4545fd1be20ad2dc8168ef49c9c4f3486d1435 (diff)
downloadnumpy-a4f435c68c15bc43a9b09869aaedb94d6c1bee2a.tar.gz
BUG: Prevent autogenerated names clashing with given names
Diffstat (limited to 'numpy/core/_internal.py')
-rw-r--r--numpy/core/_internal.py47
1 files changed, 20 insertions, 27 deletions
diff --git a/numpy/core/_internal.py b/numpy/core/_internal.py
index d69b7be8d..40a3173a8 100644
--- a/numpy/core/_internal.py
+++ b/numpy/core/_internal.py
@@ -470,25 +470,9 @@ def __dtype_from_pep3118(stream, is_subdtype):
itemsize=0
)
offset = 0
- explicit_name = False
- this_explicit_name = False
common_alignment = 1
is_padding = False
- dummy_name_index = [0]
-
-
- def next_dummy_name():
- dummy_name_index[0] += 1
-
- def get_dummy_name():
- while True:
- name = 'f%d' % dummy_name_index[0]
- if name not in field_spec['names']:
- return name
- next_dummy_name()
-
-
# Parse spec
while stream:
value = None
@@ -583,25 +567,19 @@ def __dtype_from_pep3118(stream, is_subdtype):
value = dtype((value, shape))
# Field name
- this_explicit_name = False
if stream.consume(':'):
name = stream.consume_until(':')
- explicit_name = True
- this_explicit_name = True
else:
- name = get_dummy_name()
+ name = None
- if not is_padding or this_explicit_name:
- if name in field_spec['names']:
+ if not (is_padding and name is None):
+ if name is not None and name in field_spec['names']:
raise RuntimeError("Duplicate field name '%s' in PEP3118 format"
% name)
field_spec['names'].append(name)
field_spec['formats'].append(value)
field_spec['offsets'].append(offset)
- if not this_explicit_name:
- next_dummy_name()
-
offset += value.itemsize
offset += extra_offset
@@ -612,18 +590,33 @@ def __dtype_from_pep3118(stream, is_subdtype):
field_spec['itemsize'] += (-offset) % common_alignment
# Check if this was a simple 1-item type, and unwrap it
- if (len(field_spec['names']) == 1
+ if (field_spec['names'] == [None]
and field_spec['offsets'][0] == 0
and field_spec['itemsize'] == field_spec['formats'][0].itemsize
- and not explicit_name
and not is_subdtype):
ret = field_spec['formats'][0]
else:
+ _fix_names(field_spec)
ret = dtype(field_spec)
# Finished
return ret, common_alignment
+def _fix_names(field_spec):
+ """ Replace names which are None with the next unused f%d name """
+ names = field_spec['names']
+ for i, name in enumerate(names):
+ if name is not None:
+ continue
+
+ j = 0
+ while True:
+ name = 'f{}'.format(j)
+ if name not in names:
+ break
+ j = j + 1
+ names[i] = name
+
def _add_trailing_padding(value, padding):
"""Inject the specified number of padding bytes at the end of a dtype"""
if value.fields is None: