[pypy-commit] pypy default: merge heads

arigo noreply at buildbot.pypy.org
Thu Nov 14 09:45:06 CET 2013


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r68025:315906031082
Date: 2013-11-14 09:44 +0100
http://bitbucket.org/pypy/pypy/changeset/315906031082/

Log:	merge heads

diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py
--- a/pypy/module/micronumpy/arrayimpl/concrete.py
+++ b/pypy/module/micronumpy/arrayimpl/concrete.py
@@ -52,7 +52,7 @@
         loop.setslice(space, shape, self, impl)
 
     def get_size(self):
-        return self.size // self.dtype.itemtype.get_element_size()
+        return self.size // self.dtype.get_size()
 
     def get_storage_size(self):
         return self.size
@@ -399,7 +399,7 @@
         self.storage = parent.storage
         self.order = parent.order
         self.dtype = dtype
-        self.size = support.product(shape) * self.dtype.itemtype.get_element_size()
+        self.size = support.product(shape) * self.dtype.get_size()
         self.start = start
         self.orig_arr = orig_arr
 
diff --git a/pypy/module/micronumpy/conversion_utils.py b/pypy/module/micronumpy/conversion_utils.py
--- a/pypy/module/micronumpy/conversion_utils.py
+++ b/pypy/module/micronumpy/conversion_utils.py
@@ -1,6 +1,27 @@
 from pypy.interpreter.error import OperationError
 from pypy.module.micronumpy.constants import *
 
+
+def byteorder_converter(space, new_order):
+    endian = new_order[0]
+    if endian not in (NPY_BIG, NPY_LITTLE, NPY_NATIVE, NPY_IGNORE, NPY_SWAP):
+        ch = endian
+        if ch in ('b', 'B'):
+            endian = NPY_BIG
+        elif ch in ('l', 'L'):
+            endian = NPY_LITTLE
+        elif ch in ('n', 'N'):
+            endian = NPY_NATIVE
+        elif ch in ('i', 'I'):
+            endian = NPY_IGNORE
+        elif ch in ('s', 'S'):
+            endian = NPY_SWAP
+        else:
+            raise OperationError(space.w_ValueError, space.wrap(
+                "%s is an unrecognized byteorder" % new_order))
+    return endian
+
+
 def clipmode_converter(space, w_mode):
     if space.is_none(w_mode):
         return NPY_RAISE
@@ -19,6 +40,7 @@
     raise OperationError(space.w_TypeError,
                          space.wrap("clipmode not understood"))
 
+
 def order_converter(space, w_order, default):
     if space.is_none(w_order):
         return default
@@ -41,6 +63,7 @@
             raise OperationError(space.w_TypeError, space.wrap(
                 "order not understood"))
 
+
 def multi_axis_converter(space, w_axis, ndim):
     if space.is_none(w_axis):
         return [True] * ndim
diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py
--- a/pypy/module/micronumpy/interp_dtype.py
+++ b/pypy/module/micronumpy/interp_dtype.py
@@ -9,6 +9,7 @@
 from rpython.rlib.rarithmetic import LONG_BIT, r_longlong, r_ulonglong
 from rpython.rtyper.lltypesystem import rffi
 from rpython.rlib import jit
+from pypy.module.micronumpy.conversion_utils import byteorder_converter
 from pypy.module.micronumpy.constants import *
 
 
@@ -34,10 +35,12 @@
     return out
 
 class W_Dtype(W_Root):
-    _immutable_fields_ = ["itemtype?", "num", "kind", "name?", "char", "w_box_type", "byteorder", "float_type"]
+    _immutable_fields_ = ["itemtype?", "num", "kind", "name?", "char",
+                          "w_box_type", "byteorder", "size?", "float_type",
+                          "fields?", "fieldnames?", "shape", "subdtype", "base"]
 
     def __init__(self, itemtype, num, kind, name, char, w_box_type, byteorder=NPY_NATIVE,
-                 alternate_constructors=[], aliases=[], float_type=None,
+                 size=1, alternate_constructors=[], aliases=[], float_type=None,
                  fields=None, fieldnames=None, shape=[], subdtype=None):
         self.itemtype = itemtype
         self.num = num
@@ -46,6 +49,7 @@
         self.char = char
         self.w_box_type = w_box_type
         self.byteorder = byteorder
+        self.size = size
         self.alternate_constructors = alternate_constructors
         self.aliases = aliases
         self.float_type = float_type
@@ -122,7 +126,7 @@
         return self.byteorder in (NPY_NATIVE, NPY_NATBYTE)
 
     def get_size(self):
-        return self.itemtype.get_element_size()
+        return self.size * self.itemtype.get_element_size()
 
     def get_name(self):
         if self.char == 'S':
@@ -136,7 +140,7 @@
         return space.wrap("dtype('%s')" % self.get_name())
 
     def descr_get_itemsize(self, space):
-        return space.wrap(self.itemtype.get_element_size())
+        return space.wrap(self.get_size())
 
     def descr_get_alignment(self, space):
         return space.wrap(self.itemtype.alignment)
@@ -196,7 +200,6 @@
             self.fields = None
         else:
             self.fields = {}
-            ofs_and_items = []
             size = 0
             for key in space.listview(w_fields):
                 value = space.getitem(w_fields, key)
@@ -207,11 +210,11 @@
                 offset = space.int_w(space.getitem(value, space.wrap(1)))
                 self.fields[space.str_w(key)] = offset, dtype
 
-                ofs_and_items.append((offset, dtype.itemtype))
-                size += dtype.itemtype.get_element_size()
+                size += dtype.get_size()
 
-            self.itemtype = types.RecordType(ofs_and_items, size)
-            self.name = "void" + str(8 * self.itemtype.get_element_size())
+            self.itemtype = types.RecordType()
+            self.size = size
+            self.name = "void" + str(8 * self.get_size())
 
     def descr_get_names(self, space):
         if self.fieldnames is None:
@@ -263,7 +266,7 @@
         w_class = space.type(self)
 
         kind = self.kind
-        elemsize = self.itemtype.get_element_size()
+        elemsize = self.get_size()
         builder_args = space.newtuple([space.wrap("%s%d" % (kind, elemsize)), space.wrap(0), space.wrap(1)])
 
         version = space.wrap(3)
@@ -308,11 +311,23 @@
         fields = space.getitem(w_data, space.wrap(4))
         self.set_fields(space, fields)
 
+    @unwrap_spec(new_order=str)
+    def descr_newbyteorder(self, space, new_order=NPY_SWAP):
+        newendian = byteorder_converter(space, new_order)
+        endian = self.byteorder
+        if endian != NPY_IGNORE:
+            if newendian == NPY_SWAP:
+                endian = NPY_OPPBYTE if self.is_native() else NPY_NATBYTE
+            elif newendian != NPY_IGNORE:
+                endian = newendian
+        itemtype = self.itemtype.__class__(endian in (NPY_NATIVE, NPY_NATBYTE))
+        return W_Dtype(itemtype, self.num, self.kind, self.name, self.char,
+                       self.w_box_type, endian, size=self.size)
+
 def dtype_from_list(space, w_lst):
     lst_w = space.listview(w_lst)
     fields = {}
     offset = 0
-    ofs_and_items = []
     fieldnames = []
     for w_elem in lst_w:
         size = 1
@@ -329,13 +344,13 @@
             raise OperationError(space.w_ValueError, space.wrap("two fields with the same name"))
         assert isinstance(subdtype, W_Dtype)
         fields[fldname] = (offset, subdtype)
-        ofs_and_items.append((offset, subdtype.itemtype))
-        offset += subdtype.itemtype.get_element_size() * size
+        offset += subdtype.get_size() * size
         fieldnames.append(fldname)
-    itemtype = types.RecordType(ofs_and_items, offset)
-    return W_Dtype(itemtype, NPY_VOID, NPY_VOIDLTR, "void" + str(8 * itemtype.get_element_size()),
-                   NPY_VOIDLTR, space.gettypefor(interp_boxes.W_VoidBox), fields=fields,
-                   fieldnames=fieldnames)
+    itemtype = types.RecordType()
+    return W_Dtype(itemtype, NPY_VOID, NPY_VOIDLTR,
+                   "void" + str(8 * offset * itemtype.get_element_size()),
+                   NPY_VOIDLTR, space.gettypefor(interp_boxes.W_VoidBox),
+                   fields=fields, fieldnames=fieldnames, size=offset)
 
 def dtype_from_dict(space, w_dict):
     raise OperationError(space.w_NotImplementedError, space.wrap(
@@ -349,7 +364,8 @@
     # w_align and w_copy are necessary for pickling
     cache = get_dtype_cache(space)
 
-    if w_shape is not None and (space.isinstance_w(w_shape, space.w_int) or space.len_w(w_shape) > 0):
+    if w_shape is not None and (space.isinstance_w(w_shape, space.w_int) or
+                                space.len_w(w_shape) > 0):
         subdtype = descr__new__(space, w_subtype, w_dtype, w_align, w_copy)
         assert isinstance(subdtype, W_Dtype)
         size = 1
@@ -360,8 +376,11 @@
             dim = space.int_w(w_dim)
             shape.append(dim)
             size *= dim
-        return W_Dtype(types.VoidType(subdtype.itemtype.get_element_size() * size), NPY_VOID, NPY_VOIDLTR, "void" + str(8 * subdtype.itemtype.get_element_size() * size),
-                    NPY_VOIDLTR, space.gettypefor(interp_boxes.W_VoidBox), shape=shape, subdtype=subdtype)
+        return W_Dtype(types.VoidType(), NPY_VOID, NPY_VOIDLTR,
+                       "void" + str(8 * subdtype.get_size() * size),
+                       NPY_VOIDLTR, space.gettypefor(interp_boxes.W_VoidBox),
+                       shape=shape, subdtype=subdtype,
+                       size=subdtype.get_size() * size)
 
     if space.is_none(w_dtype):
         return cache.w_float64dtype
@@ -413,6 +432,7 @@
 
     __reduce__ = interp2app(W_Dtype.descr_reduce),
     __setstate__ = interp2app(W_Dtype.descr_setstate),
+    newbyteorder = interp2app(W_Dtype.descr_newbyteorder),
 
     type = interp_attrproperty_w("w_box_type", cls=W_Dtype),
     kind = interp_attrproperty("kind", cls=W_Dtype),
@@ -450,17 +470,17 @@
         size = 1
 
     if char == NPY_STRINGLTR:
-        itemtype = types.StringType(size)
+        itemtype = types.StringType()
         basename = 'string'
         num = NPY_STRING
         w_box_type = space.gettypefor(interp_boxes.W_StringBox)
     elif char == NPY_VOIDLTR:
-        itemtype = types.VoidType(size)
+        itemtype = types.VoidType()
         basename = 'void'
         num = NPY_VOID
         w_box_type = space.gettypefor(interp_boxes.W_VoidBox)
     elif char == NPY_UNICODELTR:
-        itemtype = types.UnicodeType(size)
+        itemtype = types.UnicodeType()
         basename = 'unicode'
         num = NPY_UNICODE
         w_box_type = space.gettypefor(interp_boxes.W_UnicodeBox)
@@ -468,27 +488,29 @@
         assert False
 
     return W_Dtype(itemtype, num, char,
-                   basename + str(8 * itemtype.get_element_size()),
-                   char, w_box_type)
+                   basename + str(8 * size * itemtype.get_element_size()),
+                   char, w_box_type, size=size)
 
 def new_string_dtype(space, size):
-    itemtype = types.StringType(size)
+    itemtype = types.StringType()
     return W_Dtype(
         itemtype,
+        size=size,
         num=NPY_STRING,
         kind=NPY_STRINGLTR,
-        name='string' + str(8 * itemtype.get_element_size()),
+        name='string' + str(8 * size * itemtype.get_element_size()),
         char=NPY_STRINGLTR,
         w_box_type = space.gettypefor(interp_boxes.W_StringBox),
     )
 
 def new_unicode_dtype(space, size):
-    itemtype = types.UnicodeType(size)
+    itemtype = types.UnicodeType()
     return W_Dtype(
         itemtype,
+        size=size,
         num=NPY_UNICODE,
         kind=NPY_UNICODELTR,
-        name='unicode' + str(8 * itemtype.get_element_size()),
+        name='unicode' + str(8 * size * itemtype.get_element_size()),
         char=NPY_UNICODELTR,
         w_box_type = space.gettypefor(interp_boxes.W_UnicodeBox),
     )
@@ -663,7 +685,8 @@
             float_type = self.w_floatlongdtype,
         )
         self.w_stringdtype = W_Dtype(
-            types.StringType(0),
+            types.StringType(),
+            size=0,
             num=NPY_STRING,
             kind=NPY_STRINGLTR,
             name='string',
@@ -673,7 +696,8 @@
             aliases=["str"],
         )
         self.w_unicodedtype = W_Dtype(
-            types.UnicodeType(0),
+            types.UnicodeType(),
+            size=0,
             num=NPY_UNICODE,
             kind=NPY_UNICODELTR,
             name='unicode',
@@ -682,7 +706,8 @@
             alternate_constructors=[space.w_unicode],
         )
         self.w_voiddtype = W_Dtype(
-            types.VoidType(0),
+            types.VoidType(),
+            size=0,
             num=NPY_VOID,
             kind=NPY_VOIDLTR,
             name='void',
@@ -750,7 +775,7 @@
             self.w_intpdtype, self.w_uintpdtype,
         ]
         self.float_dtypes_by_num_bytes = sorted(
-            (dtype.itemtype.get_element_size(), dtype)
+            (dtype.get_size(), dtype)
             for dtype in float_dtypes
         )
         self.dtypes_by_num = {}
@@ -760,7 +785,7 @@
         for dtype in reversed(self.builtin_dtypes):
             self.dtypes_by_num[dtype.num] = dtype
             self.dtypes_by_name[dtype.name] = dtype
-            can_name = dtype.kind + str(dtype.itemtype.get_element_size())
+            can_name = dtype.kind + str(dtype.get_size())
             self.dtypes_by_name[can_name] = dtype
             self.dtypes_by_name[NPY_NATBYTE + can_name] = dtype
             self.dtypes_by_name[NPY_NATIVE + can_name] = dtype
@@ -830,7 +855,7 @@
         for k, v in typeinfo_partial.iteritems():
             space.setitem(w_typeinfo, space.wrap(k), space.gettypefor(v))
         for k, dtype in typeinfo_full.iteritems():
-            itemsize = dtype.itemtype.get_element_size()
+            itemsize = dtype.get_size()
             items_w = [space.wrap(dtype.char),
                        space.wrap(dtype.num),
                        space.wrap(itemsize * 8), # in case of changing
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
@@ -85,10 +85,10 @@
         return space.wrap(len(self.get_shape()))
 
     def descr_get_itemsize(self, space):
-        return space.wrap(self.get_dtype().itemtype.get_element_size())
+        return space.wrap(self.get_dtype().get_size())
 
     def descr_get_nbytes(self, space):
-        return space.wrap(self.get_size() * self.get_dtype().itemtype.get_element_size())
+        return space.wrap(self.get_size() * self.get_dtype().get_size())
 
     def descr_fill(self, space, w_value):
         self.fill(self.get_dtype().coerce(space, w_value))
@@ -625,10 +625,10 @@
         raise OperationError(space.w_NotImplementedError, space.wrap(
             "itemset not implemented yet"))
 
-    @unwrap_spec(neworder=str)
-    def descr_newbyteorder(self, space, neworder):
-        raise OperationError(space.w_NotImplementedError, space.wrap(
-            "newbyteorder not implemented yet"))
+    @unwrap_spec(new_order=str)
+    def descr_newbyteorder(self, space, new_order=NPY_SWAP):
+        return self.descr_view(space,
+            self.get_dtype().descr_newbyteorder(space, new_order))
 
     @unwrap_spec(w_axis=WrappedDefault(None),
                  w_out=WrappedDefault(None))
@@ -1268,6 +1268,7 @@
     diagonal = interp2app(W_NDimArray.descr_diagonal),
     trace = interp2app(W_NDimArray.descr_trace),
     view = interp2app(W_NDimArray.descr_view),
+    newbyteorder = interp2app(W_NDimArray.descr_newbyteorder),
 
     ctypes = GetSetProperty(W_NDimArray.descr_get_ctypes), # XXX unimplemented
     __array_interface__ = GetSetProperty(W_NDimArray.descr_array_iface),
@@ -1340,7 +1341,7 @@
     # not an array or incorrect dtype
     shape, elems_w = find_shape_and_elems(space, w_object, dtype)
     if dtype is None or (
-                 dtype.is_str_or_unicode() and dtype.itemtype.get_size() < 1):
+                 dtype.is_str_or_unicode() and dtype.get_size() < 1):
         for w_elem in elems_w:
             dtype = interp_ufuncs.find_dtype_for_scalar(space, w_elem,
                                                         dtype)
@@ -1349,7 +1350,7 @@
 
         if dtype is None:
             dtype = interp_dtype.get_dtype_cache(space).w_float64dtype
-    if dtype.is_str_or_unicode() and dtype.itemtype.get_size() < 1:
+    if dtype.is_str_or_unicode() and dtype.get_size() < 1:
         # promote S0 -> S1, U0 -> U1
         dtype = interp_dtype.variable_dtype(space, dtype.char + '1')
     if ndmin > len(shape):
diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py
--- a/pypy/module/micronumpy/interp_ufuncs.py
+++ b/pypy/module/micronumpy/interp_ufuncs.py
@@ -475,8 +475,7 @@
         if dt2.is_record_type():
             return dt2
         if dt1.is_str_or_unicode():
-            if dt2.itemtype.get_element_size() >= \
-                    dt1.itemtype.get_element_size():
+            if dt2.get_size() >= dt1.get_size():
                 return dt2
             return dt1
         return dt2
@@ -556,7 +555,7 @@
             return interp_dtype.variable_dtype(space,
                                                'S%d' % space.len_w(w_obj))
         elif current_guess.num == NPY_STRING:
-            if current_guess.itemtype.get_size() < space.len_w(w_obj):
+            if current_guess.get_size() < space.len_w(w_obj):
                 return interp_dtype.variable_dtype(space,
                                                    'S%d' % space.len_w(w_obj))
         return current_guess
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
@@ -164,7 +164,7 @@
         self.array = array
         self.offset = 0
         self.dtype = array.dtype
-        self.skip = self.dtype.itemtype.get_element_size()
+        self.skip = self.dtype.get_size()
         self.size = array.size
 
     def setitem(self, elem):
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
@@ -288,6 +288,49 @@
             assert a.dtype.__reduce__() == (dtype, ('i4', 0, 1), (3, '<', None, None, None, -1, -1, 0))
         assert loads(dumps(a.dtype)) == a.dtype
 
+    def test_newbyteorder(self):
+        import numpypy as np
+        import sys
+        sys_is_le = sys.byteorder == 'little'
+        native_code = sys_is_le and '<' or '>'
+        swapped_code = sys_is_le and '>' or '<'
+        native_dt = np.dtype(native_code+'i2')
+        swapped_dt = np.dtype(swapped_code+'i2')
+        assert native_dt.newbyteorder('S') == swapped_dt
+        assert native_dt.newbyteorder() == swapped_dt
+        assert native_dt == swapped_dt.newbyteorder('S')
+        assert native_dt == swapped_dt.newbyteorder('=')
+        assert native_dt == swapped_dt.newbyteorder('N')
+        assert native_dt == native_dt.newbyteorder('|')
+        assert np.dtype('<i2') == native_dt.newbyteorder('<')
+        assert np.dtype('<i2') == native_dt.newbyteorder('L')
+        assert np.dtype('>i2') == native_dt.newbyteorder('>')
+        assert np.dtype('>i2') == native_dt.newbyteorder('B')
+
+        for t in [np.int_, np.float_]:
+            dt = np.dtype(t)
+            dt1 = dt.newbyteorder().newbyteorder()
+            dt2 = dt.newbyteorder("<")
+            dt3 = dt.newbyteorder(">")
+            assert dt.byteorder != dt1.byteorder
+            #assert hash(dt) == hash(dt1)
+            if dt == dt2:
+                assert dt.byteorder != dt2.byteorder
+                #assert hash(dt) == hash(dt2)
+            else:
+                assert dt.byteorder != dt3.byteorder
+                #assert hash(dt) == hash(dt3)
+
+            exc = raises(ValueError, dt.newbyteorder, 'XX')
+            assert exc.value[0] == 'XX is an unrecognized byteorder'
+
+        for t in [np.int_, np.float_]:
+            dt1 = np.dtype(t)
+            dt2 = dt1.newbyteorder()
+            s1 = np.array(123, dtype=dt1).tostring()
+            s2 = np.array(123, dtype=dt2).byteswap().tostring()
+            assert s1 == s2
+
 class AppTestTypes(BaseAppTestDtypes):
     def test_abstract_types(self):
         import numpypy as numpy
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
@@ -2928,6 +2928,15 @@
         assert str(a.dtype) == '|S1'
         assert a == 'x'
 
+    def test_newbyteorder(self):
+        import numpy as np
+        a = np.array([1, 2], dtype=np.int16)
+        b = a.newbyteorder()
+        assert (b == [256, 512]).all()
+        c = b.byteswap()
+        assert (c == [1, 2]).all()
+        assert (a == [1, 2]).all()
+
     def test_pickle(self):
         from numpypy import dtype, array
         from cPickle import loads, dumps
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
@@ -1591,17 +1591,8 @@
         ComponentBoxType = interp_boxes.W_FloatLongBox
 
 class BaseStringType(BaseType):
-    _immutable_fields = ['size']
-
-    def __init__(self, size=0):
-        BaseType.__init__(self)
-        self.size = size
-
     def get_element_size(self):
-        return self.size * rffi.sizeof(self.T)
-
-    def get_size(self):
-        return self.size
+        return rffi.sizeof(self.T)
 
 def str_unary_op(func):
     specialize.argtype(1)(func)
@@ -1636,13 +1627,13 @@
 
     def store(self, arr, i, offset, box):
         assert isinstance(box, interp_boxes.W_StringBox)
-        return self._store(arr.storage, i, offset, box)
+        size = min(arr.dtype.size, box.arr.size - box.ofs)
+        return self._store(arr.storage, i, offset, box, size)
 
     @jit.unroll_safe
-    def _store(self, storage, i, offset, box):
+    def _store(self, storage, i, offset, box, size):
         assert isinstance(box, interp_boxes.W_StringBox)
-        # XXX simplify to range(box.dtype.get_size()) ?
-        for k in range(min(self.size, box.arr.size-box.ofs)):
+        for k in range(size):
             storage[k + offset + i] = box.arr.storage[k + box.ofs]
 
     def read(self, arr, i, offset, dtype=None):
@@ -1725,17 +1716,17 @@
         else:
             w_arg = box.descr_str(space)
             arg = space.str_w(space.str(w_arg))
-        arr = VoidBoxStorage(self.size, mydtype)
+        arr = VoidBoxStorage(mydtype.size, mydtype)
         i = 0
-        for i in range(min(len(arg), self.size)):
+        for i in range(min(len(arg), mydtype.size)):
             arr.storage[i] = arg[i]
-        for j in range(i + 1, self.size):
+        for j in range(i + 1, mydtype.size):
             arr.storage[j] = '\x00'
-        return interp_boxes.W_StringBox(arr,  0, arr.dtype)
+        return interp_boxes.W_StringBox(arr, 0, arr.dtype)
 
     def fill(self, storage, width, box, start, stop, offset):
         for i in xrange(start, stop, width):
-            self._store(storage, i, offset, box)
+            self._store(storage, i, offset, box, width)
 
 class UnicodeType(BaseStringType):
     T = lltype.UniChar
@@ -1772,14 +1763,14 @@
                 ofs += size
 
     def coerce(self, space, dtype, w_items):
-        arr = VoidBoxStorage(self.size, dtype)
+        arr = VoidBoxStorage(dtype.get_size(), dtype)
         self._coerce(space, arr, 0, dtype, w_items, dtype.shape)
         return interp_boxes.W_VoidBox(arr, 0, dtype)
 
     @jit.unroll_safe
     def store(self, arr, i, ofs, box):
         assert isinstance(box, interp_boxes.W_VoidBox)
-        for k in range(self.get_element_size()):
+        for k in range(box.arr.dtype.get_size()):
             arr.storage[k + ofs] = box.arr.storage[k + box.ofs]
 
     def readarray(self, arr, i, offset, dtype=None):
@@ -1793,15 +1784,9 @@
 
 class RecordType(BaseType):
     T = lltype.Char
-    _immutable_fields_ = ['offsets_and_fields', 'size']
-
-    def __init__(self, offsets_and_fields, size):
-        BaseType.__init__(self)
-        self.offsets_and_fields = offsets_and_fields
-        self.size = size
 
     def get_element_size(self):
-        return self.size
+        return rffi.sizeof(self.T)
 
     def read(self, arr, i, offset, dtype=None):
         if dtype is None:
@@ -1817,14 +1802,14 @@
         if not space.issequence_w(w_item):
             raise OperationError(space.w_TypeError, space.wrap(
                 "expected sequence"))
-        if len(self.offsets_and_fields) != space.len_w(w_item):
+        if len(dtype.fields) != space.len_w(w_item):
             raise OperationError(space.w_ValueError, space.wrap(
                 "wrong length"))
         items_w = space.fixedview(w_item)
-        arr = VoidBoxStorage(self.size, dtype)
+        arr = VoidBoxStorage(dtype.get_size(), dtype)
         for i in range(len(items_w)):
-            subdtype = dtype.fields[dtype.fieldnames[i]][1]
-            ofs, itemtype = self.offsets_and_fields[i]
+            ofs, subdtype = dtype.fields[dtype.fieldnames[i]]
+            itemtype = subdtype.itemtype
             w_item = items_w[i]
             w_box = itemtype.coerce(space, subdtype, w_item)
             itemtype.store(arr, 0, ofs, w_box)
@@ -1833,7 +1818,7 @@
     @jit.unroll_safe
     def store(self, arr, i, ofs, box):
         assert isinstance(box, interp_boxes.W_VoidBox)
-        for k in range(self.get_element_size()):
+        for k in range(box.arr.dtype.get_size()):
             arr.storage[k + i] = box.arr.storage[k + box.ofs]
 
     @jit.unroll_safe
@@ -1841,7 +1826,9 @@
         assert isinstance(box, interp_boxes.W_VoidBox)
         pieces = ["("]
         first = True
-        for ofs, tp in self.offsets_and_fields:
+        for name in box.dtype.fieldnames:
+            ofs, subdtype = box.dtype.fields[name]
+            tp = subdtype.itemtype
             if first:
                 first = False
             else:


More information about the pypy-commit mailing list