[pypy-commit] pypy default: change concrete.get_storage to a context manager API, issue #1994

mattip noreply at buildbot.pypy.org
Wed Mar 4 17:27:54 CET 2015


Author: mattip <matti.picus at gmail.com>
Branch: 
Changeset: r76243:5cfbc35539b9
Date: 2015-03-04 18:24 +0200
http://bitbucket.org/pypy/pypy/changeset/5cfbc35539b9/

Log:	change concrete.get_storage to a context manager API, issue #1994

diff --git a/pypy/module/micronumpy/concrete.py b/pypy/module/micronumpy/concrete.py
--- a/pypy/module/micronumpy/concrete.py
+++ b/pypy/module/micronumpy/concrete.py
@@ -12,6 +12,7 @@
 from pypy.module.micronumpy.strides import (Chunk, Chunks, NewAxisChunk,
     RecordChunk, calc_strides, calc_new_strides, shape_agreement,
     calculate_broadcast_strides, calc_backstrides)
+from rpython.rlib.objectmodel import keepalive_until_here
 
 
 class BaseConcreteArray(object):
@@ -312,12 +313,18 @@
         l_w = [w_res.descr_getitem(space, space.wrap(d)) for d in range(nd)]
         return space.newtuple(l_w)
 
-    def get_storage_as_int(self, space):
-        return rffi.cast(lltype.Signed, self.storage) + self.start
+    def get_storage_as_int(self):
+            return rffi.cast(lltype.Signed, self.storage) + self.start
 
-    def get_storage(self):
+    ##def get_storage(self):
+    ##    return self.storage
+    ## use a safer context manager
+    def __enter__(self):
         return self.storage
 
+    def __exit__(self, typ, value, traceback):
+        keepalive_until_here(self)
+        
     def get_buffer(self, space, readonly):
         return ArrayBuffer(self, readonly)
 
diff --git a/pypy/module/micronumpy/loop.py b/pypy/module/micronumpy/loop.py
--- a/pypy/module/micronumpy/loop.py
+++ b/pypy/module/micronumpy/loop.py
@@ -605,7 +605,7 @@
     w_res_str = W_NDimArray.from_shape(space, [1], arr.get_dtype(), order='C')
     itemsize = arr.get_dtype().elsize
     res_str_casted = rffi.cast(rffi.CArrayPtr(lltype.Char),
-                               w_res_str.implementation.get_storage_as_int(space))
+                               w_res_str.implementation.get_storage_as_int())
     while not iter.done(state):
         w_res_str.implementation.setitem(0, iter.getitem(state))
         for i in range(itemsize):
diff --git a/pypy/module/micronumpy/ndarray.py b/pypy/module/micronumpy/ndarray.py
--- a/pypy/module/micronumpy/ndarray.py
+++ b/pypy/module/micronumpy/ndarray.py
@@ -532,7 +532,7 @@
             self.get_dtype(), storage_bytes=sz, w_base=self)
 
     def descr_array_iface(self, space):
-        addr = self.implementation.get_storage_as_int(space)
+        addr = self.implementation.get_storage_as_int()
         # will explode if it can't
         w_d = space.newdict()
         space.setitem_str(w_d, 'data',
@@ -1165,7 +1165,8 @@
                 builder.append(box.raw_str())
                 state = iter.next(state)
         else:
-            builder.append_charpsize(self.implementation.get_storage(),
+            with self.implementation as storage:
+                builder.append_charpsize(storage,
                                      self.implementation.get_storage_size())
 
         state = space.newtuple([
diff --git a/pypy/module/micronumpy/selection.py b/pypy/module/micronumpy/selection.py
--- a/pypy/module/micronumpy/selection.py
+++ b/pypy/module/micronumpy/selection.py
@@ -33,14 +33,14 @@
             self.values = values
             self.indexes = indexes
 
-        def getitem(self, item):
+        def getitem(self, idx):
             if count < 2:
-                v = raw_storage_getitem(TP, self.values, item * self.stride_size
+                v = raw_storage_getitem(TP, self.values, idx * self.stride_size
                                     + self.start)
             else:
                 v = []
                 for i in range(count):
-                    _v = raw_storage_getitem(TP, self.values, item * self.stride_size
+                    _v = raw_storage_getitem(TP, self.values, idx * self.stride_size
                                     + self.start + step * i)
                     v.append(_v)
             if comp_type == 'int':
@@ -52,7 +52,7 @@
             else:
                 raise NotImplementedError('cannot reach')
             return (v, raw_storage_getitem(lltype.Signed, self.indexes,
-                                           item * self.index_stride_size +
+                                           idx * self.index_stride_size +
                                            self.index_start))
 
         def setitem(self, idx, item):
@@ -134,37 +134,37 @@
         # create array of indexes
         dtype = descriptor.get_dtype_cache(space).w_longdtype
         index_arr = W_NDimArray.from_shape(space, arr.get_shape(), dtype)
-        storage = index_arr.implementation.get_storage()
-        if len(arr.get_shape()) == 1:
-            for i in range(arr.get_size()):
-                raw_storage_setitem(storage, i * INT_SIZE, i)
-            r = Repr(INT_SIZE, itemsize, arr.get_size(), arr.get_storage(),
-                     storage, 0, arr.start)
-            ArgSort(r).sort()
-        else:
-            shape = arr.get_shape()
-            if axis < 0:
-                axis = len(shape) + axis
-            if axis < 0 or axis >= len(shape):
-                raise oefmt(space.w_IndexError, "Wrong axis %d", axis)
-            arr_iter = AllButAxisIter(arr, axis)
-            arr_state = arr_iter.reset()
-            index_impl = index_arr.implementation
-            index_iter = AllButAxisIter(index_impl, axis)
-            index_state = index_iter.reset()
-            stride_size = arr.strides[axis]
-            index_stride_size = index_impl.strides[axis]
-            axis_size = arr.shape[axis]
-            while not arr_iter.done(arr_state):
-                for i in range(axis_size):
-                    raw_storage_setitem(storage, i * index_stride_size +
-                                        index_state.offset, i)
-                r = Repr(index_stride_size, stride_size, axis_size,
-                         arr.get_storage(), storage, index_state.offset, arr_state.offset)
+        with index_arr.implementation as storage, arr as arr_storage:
+            if len(arr.get_shape()) == 1:
+                for i in range(arr.get_size()):
+                    raw_storage_setitem(storage, i * INT_SIZE, i)
+                r = Repr(INT_SIZE, itemsize, arr.get_size(), arr_storage,
+                         storage, 0, arr.start)
                 ArgSort(r).sort()
-                arr_state = arr_iter.next(arr_state)
-                index_state = index_iter.next(index_state)
-        return index_arr
+            else:
+                shape = arr.get_shape()
+                if axis < 0:
+                    axis = len(shape) + axis
+                if axis < 0 or axis >= len(shape):
+                    raise oefmt(space.w_IndexError, "Wrong axis %d", axis)
+                arr_iter = AllButAxisIter(arr, axis)
+                arr_state = arr_iter.reset()
+                index_impl = index_arr.implementation
+                index_iter = AllButAxisIter(index_impl, axis)
+                index_state = index_iter.reset()
+                stride_size = arr.strides[axis]
+                index_stride_size = index_impl.strides[axis]
+                axis_size = arr.shape[axis]
+                while not arr_iter.done(arr_state):
+                    for i in range(axis_size):
+                        raw_storage_setitem(storage, i * index_stride_size +
+                                            index_state.offset, i)
+                    r = Repr(index_stride_size, stride_size, axis_size,
+                         arr_storage, storage, index_state.offset, arr_state.offset)
+                    ArgSort(r).sort()
+                    arr_state = arr_iter.next(arr_state)
+                    index_state = index_iter.next(index_state)
+            return index_arr
 
     return argsort
 
@@ -282,25 +282,25 @@
             axis = -1
         else:
             axis = space.int_w(w_axis)
-        # create array of indexes
-        if len(arr.get_shape()) == 1:
-            r = Repr(itemsize, arr.get_size(), arr.get_storage(),
-                     arr.start)
-            ArgSort(r).sort()
-        else:
-            shape = arr.get_shape()
-            if axis < 0:
-                axis = len(shape) + axis
-            if axis < 0 or axis >= len(shape):
-                raise oefmt(space.w_IndexError, "Wrong axis %d", axis)
-            arr_iter = AllButAxisIter(arr, axis)
-            arr_state = arr_iter.reset()
-            stride_size = arr.strides[axis]
-            axis_size = arr.shape[axis]
-            while not arr_iter.done(arr_state):
-                r = Repr(stride_size, axis_size, arr.get_storage(), arr_state.offset)
+        with arr as storage:
+            if len(arr.get_shape()) == 1:
+                r = Repr(itemsize, arr.get_size(), storage,
+                         arr.start)
                 ArgSort(r).sort()
-                arr_state = arr_iter.next(arr_state)
+            else:
+                shape = arr.get_shape()
+                if axis < 0:
+                    axis = len(shape) + axis
+                if axis < 0 or axis >= len(shape):
+                    raise oefmt(space.w_IndexError, "Wrong axis %d", axis)
+                arr_iter = AllButAxisIter(arr, axis)
+                arr_state = arr_iter.reset()
+                stride_size = arr.strides[axis]
+                axis_size = arr.shape[axis]
+                while not arr_iter.done(arr_state):
+                    r = Repr(stride_size, axis_size, storage, arr_state.offset)
+                    ArgSort(r).sort()
+                    arr_state = arr_iter.next(arr_state)
 
     return sort
 
diff --git a/pypy/module/micronumpy/ufuncs.py b/pypy/module/micronumpy/ufuncs.py
--- a/pypy/module/micronumpy/ufuncs.py
+++ b/pypy/module/micronumpy/ufuncs.py
@@ -1407,7 +1407,7 @@
                          space.wrap("cannot mix ndarray and %r (arg %d) in call to ufunc" % (
                                     arg_i, i)))
                 raw_storage_setitem(dataps, CCHARP_SIZE * i,
-                        rffi.cast(rffi.CCHARP, arg_i.implementation.get_storage_as_int(space)))
+                        rffi.cast(rffi.CCHARP, arg_i.implementation.get_storage_as_int()))
                 #This assumes we iterate over the whole array (it should be a view...)
                 raw_storage_setitem(self.dims, LONG_SIZE * i, rffi.cast(rffi.LONG, arg_i.get_size()))
                 raw_storage_setitem(self.steps, LONG_SIZE * i, rffi.cast(rffi.LONG, arg_i.get_dtype().elsize))
@@ -1416,7 +1416,7 @@
                 arg_i = args_w[i]
                 assert isinstance(arg_i, W_NDimArray)
                 raw_storage_setitem(dataps, CCHARP_SIZE * i,
-                        rffi.cast(rffi.CCHARP, arg_i.implementation.get_storage_as_int(space)))
+                        rffi.cast(rffi.CCHARP, arg_i.implementation.get_storage_as_int()))
         try:
             arg1 = rffi.cast(rffi.CArrayPtr(rffi.CCHARP), dataps)
             arg2 = rffi.cast(npy_intpp, self.dims)


More information about the pypy-commit mailing list