[pypy-commit] pypy default: merge numpy-newbyteorder
bdkearns
noreply at buildbot.pypy.org
Thu Nov 14 09:33:59 CET 2013
Author: Brian Kearns <bdkearns at gmail.com>
Branch:
Changeset: r68021:a80ac0e94c7e
Date: 2013-11-14 03:30 -0500
http://bitbucket.org/pypy/pypy/changeset/a80ac0e94c7e/
Log: merge numpy-newbyteorder
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