[pypy-commit] pypy dtypes-compatability: fine tune alignment and __str__(), all tests pass
mattip
noreply at buildbot.pypy.org
Fri Jul 10 09:10:18 CEST 2015
Author: mattip <matti.picus at gmail.com>
Branch: dtypes-compatability
Changeset: r78522:10bff82523d3
Date: 2015-07-10 10:03 +0300
http://bitbucket.org/pypy/pypy/changeset/10bff82523d3/
Log: fine tune alignment and __str__(), all tests pass
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
@@ -220,12 +220,13 @@
for name, title in self.names:
offset, subdtype = self.fields[name]
if subdtype.is_record():
- substr = space.str_w(subdtype.descr_get_descr(space, style))
+ substr = space.str_w(space.str(subdtype.descr_get_descr(
+ space, style='substr'))) + ","
elif subdtype.subdtype is not None:
- substr = subdtype.subdtype.get_str(ignore='')
+ substr = "'" + subdtype.subdtype.get_str(ignore='') + "',"
else:
- substr = subdtype.get_str(ignore='')
- formats += "'" + substr + "',"
+ substr = "'" + subdtype.get_str(ignore='') + "',"
+ formats += substr
offsets += str(offset) + ','
names += "'" + name + "',"
titles += "'" + str(title) + "',"
@@ -237,6 +238,8 @@
titles = titles[:-1] + ']'
if style == 'str':
suffix = ", 'aligned':True}"
+ elif style == 'substr':
+ suffix = '}'
else:
suffix = "}, align=True"
if use_titles:
@@ -617,7 +620,7 @@
fields = {}
if offsets is None:
offsets = [0] * len(lst_w)
- maxalign = 0
+ maxalign = alignment
fldnames = [''] * len(lst_w)
subdtypes = [None] * len(lst_w)
titles = [None] * len(lst_w)
@@ -625,7 +628,7 @@
w_elem = lst_w[i]
if simple:
subdtype = make_new_dtype(space, space.gettypefor(W_Dtype), w_elem,
- alignment)
+ maxalign)
fldnames[i] = 'f%d' % i
else:
w_shape = space.newtuple([])
@@ -636,7 +639,7 @@
else:
w_fldname, w_flddesc = space.fixedview(w_elem, 2)
subdtype = make_new_dtype(space, space.gettypefor(W_Dtype),
- w_flddesc, alignment, w_shape=w_shape)
+ w_flddesc, maxalign, w_shape=w_shape)
if space.isinstance_w(w_fldname, space.w_tuple):
fldlist = space.listview(w_fldname)
fldnames[i] = space.str_w(fldlist[0])
@@ -654,22 +657,24 @@
maxalign = max(subdtype.alignment, maxalign)
if not subdtype.is_record():
maxalign = max(subdtype.elsize, maxalign)
- if i + 1 < len(offsets) and offsets[i + 1] == 0:
- if alignment >= 0:
- 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]
+ 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:
+ else:
+ if i + 1 < len(offsets) and offsets[i + 1] == 0:
offsets[i+1] = offsets[i] + subdtype.elsize
subdtypes[i] = subdtype
names = []
for i in range(len(subdtypes)):
subdtype = subdtypes[i]
assert isinstance(subdtype, W_Dtype)
+ if alignment >=0 and subdtype.is_record():
+ subdtype.alignment = maxalign
if fldnames[i] in fields:
raise oefmt(space.w_ValueError, "two fields with the same name")
fields[fldnames[i]] = offsets[i], subdtype
@@ -711,7 +716,11 @@
for fname in w_dict.iterkeys().iterator:
obj = _get_list_or_none(space, w_dict, fname)
num = space.int_w(obj[1])
- format = dtype_from_spec(space, obj[0], alignment=-1)
+ if align:
+ alignment = 0
+ else:
+ alignment = -1
+ format = dtype_from_spec(space, obj[0], alignment=alignment)
if len(obj) > 2:
title = obj[2]
else:
@@ -821,7 +830,7 @@
sqbracket -= 1
return False
-def _set_metadata_and_copy(dtype, space, w_metadata, copy=False):
+def _set_metadata_and_copy(space, w_metadata, dtype, copy=False):
cache = get_dtype_cache(space)
assert isinstance(dtype, W_Dtype)
if copy or (dtype in cache.builtin_dtypes and w_metadata is not None):
@@ -874,10 +883,9 @@
if size >= 2 ** 31:
raise oefmt(space.w_ValueError, "invalid shape in fixed-type tuple: "
"dtype size in bytes must fit into a C int.")
- return _set_metadata_and_copy(W_Dtype(types.VoidType(space),
- space.gettypefor(boxes.W_VoidBox),
- shape=shape, subdtype=subdtype, elsize=size),
- space, w_metadata)
+ return _set_metadata_and_copy(space, w_metadata,
+ W_Dtype(types.VoidType(space), space.gettypefor(boxes.W_VoidBox),
+ shape=shape, subdtype=subdtype, elsize=size))
if space.is_none(w_dtype):
return cache.w_float64dtype
@@ -888,7 +896,8 @@
if space.isinstance_w(w_dtype, space.w_str):
name = space.str_w(w_dtype)
if _check_for_commastring(name):
- return _set_metadata_and_copy(dtype_from_spec(space, w_dtype, alignment), space, w_metadata)
+ return _set_metadata_and_copy(space, w_metadata,
+ dtype_from_spec(space, w_dtype, alignment))
cname = name[1:] if name[0] == NPY.OPPBYTE else name
try:
dtype = cache.dtypes_by_name[cname]
@@ -902,8 +911,8 @@
return variable_dtype(space, name)
raise oefmt(space.w_TypeError, 'data type "%s" not understood', name)
elif space.isinstance_w(w_dtype, space.w_list):
- return _set_metadata_and_copy(dtype_from_list(space, w_dtype, False, alignment),
- space, w_metadata, copy)
+ return _set_metadata_and_copy( space, w_metadata,
+ dtype_from_list(space, w_dtype, False, alignment), copy)
elif space.isinstance_w(w_dtype, space.w_tuple):
w_dtype0 = space.getitem(w_dtype, space.wrap(0))
w_dtype1 = space.getitem(w_dtype, space.wrap(1))
@@ -914,22 +923,22 @@
retval = make_new_dtype(space, w_subtype, space.wrap(name), alignment, copy)
else:
retval = make_new_dtype(space, w_subtype, w_dtype0, alignment, copy, w_shape=w_dtype1)
- return _set_metadata_and_copy(retval, space, w_metadata, copy)
+ return _set_metadata_and_copy(space, w_metadata, retval, copy)
elif space.isinstance_w(w_dtype, space.w_dict):
- return _set_metadata_and_copy(dtype_from_dict(space, w_dtype, alignment),
- space, w_metadata, copy)
+ return _set_metadata_and_copy(space, w_metadata,
+ dtype_from_dict(space, w_dtype, alignment), copy)
for dtype in cache.builtin_dtypes:
if dtype.num in cache.alternate_constructors and \
w_dtype in cache.alternate_constructors[dtype.num]:
- return _set_metadata_and_copy(dtype, space, w_metadata, copy)
+ return _set_metadata_and_copy(space, w_metadata, dtype, copy)
if w_dtype is dtype.w_box_type:
- return _set_metadata_and_copy(dtype, space, w_metadata, copy)
+ return _set_metadata_and_copy(space, w_metadata, dtype, copy)
if space.isinstance_w(w_dtype, space.w_type) and \
space.is_true(space.issubtype(w_dtype, dtype.w_box_type)):
- return _set_metadata_and_copy(W_Dtype(dtype.itemtype, w_dtype, elsize=0),
- space, w_metadata, copy)
+ return _set_metadata_and_copy( space, w_metadata,
+ W_Dtype(dtype.itemtype, w_dtype, elsize=0), copy)
if space.isinstance_w(w_dtype, space.w_type):
- return _set_metadata_and_copy(cache.w_objectdtype, space, w_metadata, copy)
+ return _set_metadata_and_copy(space, w_metadata, cache.w_objectdtype, copy)
raise oefmt(space.w_TypeError, "data type not understood")
diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py
--- a/pypy/module/micronumpy/test/test_dtypes.py
+++ b/pypy/module/micronumpy/test/test_dtypes.py
@@ -1321,7 +1321,7 @@
'formats':['i4', 'u1'],
'offsets':[0, 4]}, align=True)
assert dt.itemsize == 8
- dt = np.dtype({'f0': ('i4', 0), 'f1':('u1', 4)}, align=True)
+ dt = np.dtype([('f0', 'i4'), ('f1', 'u1')], align=True)
assert dt.itemsize == 8
assert dt.alignment == 4
assert str(dt) == "{'names':['f0','f1'], 'formats':['<i4','u1'], 'offsets':[0,4], 'itemsize':8, 'aligned':True}"
@@ -1345,13 +1345,13 @@
'f2': ('i1', 16)}, align=True)
assert dt3.itemsize == 20
assert dt1 == dt2
- assert str(dt3) == "{'names':['f0','f1','f2'], " + \
- "'formats':['<i4',{'names':['f1','f2','f3'], " + \
- "'formats':['i1','<i4','i1'], " + \
- "'offsets':[0,4,8], 'itemsize':12}," + \
- "'i1'], " + \
- "'offsets':[0,4,16], 'itemsize':20, 'aligned':True}"
- print '+++++++++++++++++'
+ answer = "{'names':['f0','f1','f2'], " + \
+ "'formats':['<i4',{'names':['f1','f2','f3'], " + \
+ "'formats':['i1','<i4','i1'], " + \
+ "'offsets':[0,4,8], 'itemsize':12}," + \
+ "'i1'], " + \
+ "'offsets':[0,4,16], 'itemsize':20, 'aligned':True}"
+ assert str(dt3) == answer
assert dt2 == dt3
# Nesting should preserve packing
dt1 = np.dtype([('f0', 'i4'),
More information about the pypy-commit
mailing list