[pypy-commit] pypy numpy-record-dtypes: implement void read

fijal noreply at buildbot.pypy.org
Mon Feb 13 10:41:45 CET 2012


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: numpy-record-dtypes
Changeset: r52407:bb07db6244fc
Date: 2012-02-13 11:41 +0200
http://bitbucket.org/pypy/pypy/changeset/bb07db6244fc/

Log:	implement void read

diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py
--- a/pypy/module/micronumpy/interp_boxes.py
+++ b/pypy/module/micronumpy/interp_boxes.py
@@ -1,6 +1,6 @@
 from pypy.interpreter.baseobjspace import Wrappable
-from pypy.interpreter.error import operationerrfmt
-from pypy.interpreter.gateway import interp2app
+from pypy.interpreter.error import operationerrfmt, OperationError
+from pypy.interpreter.gateway import interp2app, unwrap_spec
 from pypy.interpreter.typedef import TypeDef
 from pypy.objspace.std.floattype import float_typedef
 from pypy.objspace.std.stringtype import str_typedef
@@ -8,6 +8,7 @@
 from pypy.objspace.std.inttype import int_typedef
 from pypy.rlib.rarithmetic import LONG_BIT
 from pypy.tool.sourcetools import func_with_new_name
+from pypy.rpython.lltypesystem import lltype
 
 MIXIN_32 = (int_typedef,) if LONG_BIT == 32 else ()
 MIXIN_64 = (int_typedef,) if LONG_BIT == 64 else ()
@@ -169,7 +170,24 @@
     pass
 
 class W_VoidBox(W_FlexibleBox):
-    pass
+    def __init__(self, dtype, arr):
+        self.arr = arr
+        self.dtype = dtype
+
+    def get_dtype(self, space):
+        return self.dtype
+
+    @unwrap_spec(item=str)
+    def descr_getitem(self, space, item):
+        try:
+            ofs, dtype = self.dtype.fields[item]
+        except KeyError:
+            raise OperationError(space.w_KeyError, space.wrap("Field %s does not exist" % item))
+        return dtype.itemtype.read(dtype, self.arr,
+                                   dtype.itemtype.get_element_size(), 0, ofs)         
+
+    def __del__(self):
+        lltype.free(self.arr, flavor='raw', track_allocation=False)
 
 class W_CharacterBox(W_FlexibleBox):
     pass
@@ -309,6 +327,7 @@
 
 W_VoidBox.typedef = TypeDef("void", W_FlexibleBox.typedef,
     __module__ = "numpypy",
+    __getitem__ = interp2app(W_VoidBox.descr_getitem),
 )
 
 W_CharacterBox.typedef = TypeDef("character", W_FlexibleBox.typedef,
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
@@ -39,10 +39,10 @@
 
     def malloc(self, length):
         # XXX find out why test_zjit explodes with tracking of allocations
-        return lltype.malloc(VOID_STORAGE, self.itemtype.get_element_size() * length,
-            zero=True, flavor="raw",
-            track_allocation=False, add_memory_pressure=True
-        )
+        return lltype.malloc(VOID_STORAGE,
+                             self.itemtype.get_element_size() * length,
+                             zero=True, flavor="raw",
+                             track_allocation=False, add_memory_pressure=True)
 
     @specialize.argtype(1)
     def box(self, value):
@@ -52,7 +52,7 @@
         return self.itemtype.coerce(space, w_item)
 
     def getitem(self, storage, i):
-        return self.itemtype.read(storage, self.itemtype.get_element_size(), i, 0)
+        return self.itemtype.read(self, storage, self.itemtype.get_element_size(), i, 0)
 
     def getitem_bool(self, storage, i):
         isize = self.itemtype.get_element_size()
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
@@ -515,6 +515,7 @@
         raises(KeyError, 'd.fields["xyz"]')
 
     def test_create_from_dict(self):
+        skip("not yet")
         from _numpypy import dtype
         d = dtype({'names': ['a', 'b', 'c'],
                    })
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
@@ -1791,3 +1791,11 @@
         cache = get_appbridge_cache(cls.space)
         cache.w_array_repr = cls.old_array_repr
         cache.w_array_str = cls.old_array_str
+
+class AppTestRecordDtype(BaseNumpyAppTest):
+    def test_zeros(self):
+        from _numpypy import zeros
+        a = zeros(2, dtype=[('x', int), ('y', float)])
+        raises(KeyError, 'a[0]["xyz"]')
+        assert a[0]['x'] == 0
+        assert a[0]['y'] == 0
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
@@ -104,7 +104,7 @@
         return libffi.array_getitem(clibffi.cast_type_to_ffitype(self.T),
                                     width, storage, i, offset)
 
-    def read(self, storage, width, i, offset):
+    def read(self, dtype, storage, width, i, offset):
         return self.box(self._read(storage, width, i, offset))
 
     def read_bool(self, storage, width, i, offset):
@@ -624,7 +624,11 @@
 NonNativeUnicodeType = UnicodeType
 
 class RecordType(CompositeType):
-    pass
+    def read(self, dtype, storage, width, i, offset):
+        arr = dtype.malloc(1)
+        for j in range(width):
+            arr[j] = storage[i + j]
+        return interp_boxes.W_VoidBox(dtype, arr)
 
 for tp in [Int32, Int64]:
     if tp.T == lltype.Signed:


More information about the pypy-commit mailing list