Author: mattip <[email protected]>
Branch: dtypes-compatability
Changeset: r78535:1f2bc798e9d3
Date: 2015-07-11 20:38 +0300
http://bitbucket.org/pypy/pypy/changeset/1f2bc798e9d3/
Log: add arg checking logic, allow specifying itemsize
diff --git a/pypy/module/micronumpy/descriptor.py
b/pypy/module/micronumpy/descriptor.py
--- a/pypy/module/micronumpy/descriptor.py
+++ b/pypy/module/micronumpy/descriptor.py
@@ -615,10 +615,12 @@
@specialize.arg(2)
-def dtype_from_list(space, w_lst, simple, alignment, offsets=None):
+def dtype_from_list(space, w_lst, simple, alignment, offsets=None, itemsize=0):
lst_w = space.listview(w_lst)
fields = {}
+ use_supplied_offsets = True
if offsets is None:
+ use_supplied_offsets = False
offsets = [0] * len(lst_w)
maxalign = alignment
fldnames = [''] * len(lst_w)
@@ -663,12 +665,13 @@
delta = subdtype.alignment
# Set offset to the next power-of-two above delta
delta = (delta + maxalign -1) & (-maxalign)
- if delta > offsets[i]:
- for j in range(i):
- offsets[j+1] = delta + offsets[j]
- if i + 1 < len(offsets) and offsets[i + 1] == 0:
- offsets[i + 1] = offsets[i] + max(delta, subdtype.elsize)
- else:
+ if not use_supplied_offsets:
+ if delta > offsets[i]:
+ for j in range(i):
+ offsets[j+1] = delta + offsets[j]
+ if i + 1 < len(offsets) and offsets[i + 1] == 0:
+ offsets[i + 1] = offsets[i] + max(delta, subdtype.elsize)
+ elif not use_supplied_offsets:
if i + 1 < len(offsets) and offsets[i + 1] == 0:
offsets[i+1] = offsets[i] + subdtype.elsize
subdtypes[i] = subdtype
@@ -680,6 +683,10 @@
subdtype.alignment = maxalign
if fldnames[i] in fields:
raise oefmt(space.w_ValueError, "two fields with the same name")
+ if maxalign > 1 and offsets[i] % maxalign:
+ raise oefmt(space.w_ValueError, "offset %d for NumPy dtype with "
+ "fields is not divisible by the field alignment %d "
+ "with align=True", offsets[i], maxalign)
fields[fldnames[i]] = offsets[i], subdtype
if titles[i] is not None:
if titles[i] in fields:
@@ -687,6 +694,17 @@
fields[titles[i]] = offsets[i], subdtype
names.append((fldnames[i], titles[i]))
total = offsets[-1] + max(maxalign, fields[names[-1][0]][1].elsize)
+ if itemsize > 1:
+ if total > itemsize:
+ raise oefmt(space.w_ValueError,
+ "NumPy dtype descriptor requires %d bytes, cannot"
+ " override to smaller itemsize of %d", total, itemsize)
+ if alignment >= 0 and itemsize % maxalign:
+ raise oefmt(space.w_ValueError,
+ "NumPy dtype descriptor requires alignment of %d bytes, "
+ "which is not divisible into the specified itemsize %d",
+ maxalign, itemsize)
+ total = itemsize
retval = W_Dtype(types.RecordType(space),
space.gettypefor(boxes.W_VoidBox),
names=names, fields=fields, elsize=total)
if alignment >=0:
@@ -751,6 +769,7 @@
titles_w = _get_list_or_none(space, w_dict, 'titles')
metadata_w = _get_val_or_none(space, w_dict, 'metadata')
aligned_w = _get_val_or_none(space, w_dict, 'align')
+ itemsize_w = _get_val_or_none(space, w_dict, 'itemsize')
if names_w is None or formats_w is None:
if we_are_translated():
return get_appbridge_cache(space).call_method(space,
@@ -782,9 +801,14 @@
_names_w.append(space.newtuple([names_w[i], titles_w[i]]))
names_w = _names_w
aslist = []
+ if itemsize_w is None:
+ itemsize = 0
+ else:
+ itemsize = space.int_w(itemsize_w)
for i in range(min(len(names_w), len(formats_w))):
aslist.append(space.newtuple([names_w[i], formats_w[i]]))
- retval = dtype_from_list(space, space.newlist(aslist), False, alignment,
offsets=offsets)
+ retval = dtype_from_list(space, space.newlist(aslist), False, alignment,
+ offsets=offsets, itemsize=itemsize)
if metadata_w is not None:
retval.descr_set_metadata(space, metadata_w)
retval.flags |= NPY.NEEDS_PYAPI
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit