[pypy-commit] pypy default: merge voidtype_strformat, which improves str formatting for record ndarrays
mattip
noreply at buildbot.pypy.org
Sat Nov 23 20:34:26 CET 2013
Author: Matti Picus <matti.picus at gmail.com>
Branch:
Changeset: r68295:f8f583791850
Date: 2013-11-23 21:33 +0200
http://bitbucket.org/pypy/pypy/changeset/f8f583791850/
Log: merge voidtype_strformat, which improves str formatting for record
ndarrays
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -15,3 +15,6 @@
.. branch: armhf-singlefloat
JIT support for singlefloats on ARM using the hardfloat ABI
+
+.. branch: voidtype_strformat
+Better support for record numpy arrays
diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -249,12 +249,13 @@
return space.wrap(self.dump_data())
return space.call_function(cache.w_array_str, self)
- def dump_data(self):
+ def dump_data(self, prefix='array(', suffix=')'):
i = self.create_iter()
first = True
dtype = self.get_dtype()
s = StringBuilder()
- s.append('array([')
+ s.append(prefix)
+ s.append('[')
while not i.done():
if first:
first = False
@@ -262,7 +263,8 @@
s.append(', ')
s.append(dtype.itemtype.str_format(i.getitem()))
i.next()
- s.append('])')
+ s.append(']')
+ s.append(suffix)
return s.build()
def create_iter(self, shape=None, backward_broadcast=False, require_index=False):
diff --git a/pypy/module/micronumpy/iter.py b/pypy/module/micronumpy/iter.py
--- a/pypy/module/micronumpy/iter.py
+++ b/pypy/module/micronumpy/iter.py
@@ -61,10 +61,22 @@
def apply(self, space, orig_arr):
arr = orig_arr.implementation
ofs, subdtype = arr.dtype.fields[self.name]
- # strides backstrides are identical, ofs only changes start
- return W_NDimArray.new_slice(space, arr.start + ofs, arr.get_strides(),
- arr.get_backstrides(),
- arr.shape, arr, orig_arr, subdtype)
+ # ofs only changes start
+ # create a view of the original array by extending
+ # the shape, strides, backstrides of the array
+ from pypy.module.micronumpy.support import calc_strides
+ strides, backstrides = calc_strides(subdtype.shape,
+ subdtype.subdtype, arr.order)
+ final_shape = arr.shape + subdtype.shape
+ final_strides = arr.get_strides() + strides
+ final_backstrides = arr.get_backstrides() + backstrides
+ final_dtype = subdtype
+ print self.name,'strides',arr.get_strides(),strides
+ if subdtype.subdtype:
+ final_dtype = subdtype.subdtype
+ return W_NDimArray.new_slice(space, arr.start + ofs, final_strides,
+ final_backstrides,
+ final_shape, arr, orig_arr, final_dtype)
class Chunks(BaseChunk):
def __init__(self, l):
diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -3096,7 +3096,9 @@
]
h = np.array(buf, dtype=descr)
assert len(h) == 2
- skip('broken') # XXX
+ assert h['x'].shape == (2, 2)
+ assert h['y'].strides == (41, 16, 8)
+ assert h['z'].shape == (2,)
for v in (h, h[0], h['x']):
repr(v) # check for crash in repr
assert (h['x'] == np.array([buf[0][0],
@@ -3127,6 +3129,22 @@
assert len(list(a[0])) == 2
+ def test_3d_record(self):
+ from numpypy import dtype, array
+ dt = dtype([('name', 'S4'), ('x', float), ('y', float),
+ ('block', int, (2, 2, 3))])
+ a = array([('aaaa', 1.0, 8.0, [[[1, 2, 3], [4, 5, 6]],
+ [[7, 8, 9], [10, 11, 12]]])],
+ dtype=dt)
+ s = str(a)
+ i = a.item()
+ assert isinstance(i, tuple)
+ assert len(i) == 4
+ skip('incorrect formatting via dump_data')
+ assert s.endswith("[('aaaa', 1.0, 8.0, [[[1, 2, 3], [4, 5, 6]], "
+ "[[7, 8, 9], [10, 11, 12]]])]")
+
+
def test_issue_1589(self):
import numpypy as numpy
c = numpy.array([[(1, 2, 'a'), (3, 4, 'b')], [(5, 6, 'c'), (7, 8, 'd')]],
diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py
--- a/pypy/module/micronumpy/types.py
+++ b/pypy/module/micronumpy/types.py
@@ -1789,6 +1789,40 @@
dtype.subdtype)
return W_NDimArray(implementation)
+ def read(self, arr, i, offset, dtype=None):
+ if dtype is None:
+ dtype = arr.dtype
+ return interp_boxes.W_VoidBox(arr, i + offset, dtype)
+
+ @jit.unroll_safe
+ def str_format(self, box):
+ assert isinstance(box, interp_boxes.W_VoidBox)
+ arr = self.readarray(box.arr, box.ofs, 0, box.dtype)
+ return arr.dump_data(prefix='', suffix='')
+
+ def to_builtin_type(self, space, item):
+ ''' From the documentation of ndarray.item():
+ "Void arrays return a buffer object for item(),
+ unless fields are defined, in which case a tuple is returned."
+ '''
+ assert isinstance(item, interp_boxes.W_VoidBox)
+ dt = item.arr.dtype
+ ret_unwrapped = []
+ for name in dt.fieldnames:
+ ofs, dtype = dt.fields[name]
+ if isinstance(dtype.itemtype, VoidType):
+ read_val = dtype.itemtype.readarray(item.arr, ofs, 0, dtype)
+ else:
+ read_val = dtype.itemtype.read(item.arr, ofs, 0, dtype)
+ if isinstance (read_val, interp_boxes.W_StringBox):
+ # StringType returns a str
+ read_val = space.wrap(dtype.itemtype.to_str(read_val))
+ ret_unwrapped = ret_unwrapped + [read_val,]
+ if len(ret_unwrapped) == 0:
+ raise OperationError(space.w_NotImplementedError, space.wrap(
+ "item() for Void aray with no fields not implemented"))
+ return space.newtuple(ret_unwrapped)
+
class RecordType(FlexibleType):
T = lltype.Char
@@ -1848,7 +1882,8 @@
first = False
else:
pieces.append(", ")
- pieces.append(tp.str_format(tp.read(box.arr, box.ofs, ofs)))
+ val = tp.read(box.arr, box.ofs, ofs, subdtype)
+ pieces.append(tp.str_format(val))
pieces.append(")")
return "".join(pieces)
More information about the pypy-commit
mailing list