Author: Matti Picus <[email protected]>
Branch: ndarray-subtype
Changeset: r65187:31b9c2717719
Date: 2013-07-05 01:03 +0300
http://bitbucket.org/pypy/pypy/changeset/31b9c2717719/
Log: first pass at differentiating types from instances and handling
__array_finalize__
diff --git a/pypy/module/micronumpy/base.py b/pypy/module/micronumpy/base.py
--- a/pypy/module/micronumpy/base.py
+++ b/pypy/module/micronumpy/base.py
@@ -11,12 +11,17 @@
isinstance(w_obj, W_NDimArray))
def wrap_impl(space, cls, impl):
- if space.is_w(space.type(cls), space.gettypefor(W_NDimArray)):
+ if cls is None or space.is_w(space.type(cls),
space.gettypefor(W_NDimArray)):
ret = W_NDimArray(impl)
else:
- ret = space.allocate_instance(W_NDimArray, space.type(cls))
- print 'created',space.type(ret)
+ if space.isinstance_w(cls, space.w_type):
+ #got type, either from __new__ or from view casting
+ ret = space.allocate_instance(W_NDimArray, cls)
+ else:
+ ret = space.allocate_instance(W_NDimArray, space.type(cls))
W_NDimArray.__init__(ret, impl)
+ space.call_function(space.getattr(ret,
space.wrap('__array_finalize__')),
+ cls)
return ret
class ArrayArgumentException(Exception):
@@ -31,7 +36,7 @@
self.implementation = implementation
@staticmethod
- def from_shape(space, shape, dtype, order='C', subtype=None):
+ def from_shape(space, shape, dtype, order='C', subtype=None, is_new=False):
from pypy.module.micronumpy.arrayimpl import concrete, scalar
if not shape:
@@ -42,12 +47,25 @@
backstrides)
if subtype:
if space.isinstance_w(subtype, space.w_type):
- #got type, probably from descr_XXX
+ #got type, either from __new__ or from view casting
ret = space.allocate_instance(W_NDimArray, subtype)
+ W_NDimArray.__init__(ret, impl)
+ if is_new:
+ space.call_function(space.getattr(ret,
+ space.wrap('__array_finalize__')),
+ space.w_None)
+ else:
+ # view casting, call finalize
+ space.call_function(space.getattr(ret,
+ space.wrap('__array_finalize__')),
+ subtype)
else:
#got instance
ret = space.allocate_instance(W_NDimArray, space.type(subtype))
- W_NDimArray.__init__(ret, impl)
+ W_NDimArray.__init__(ret, impl)
+ space.call_function(space.getattr(ret,
+ space.wrap('__array_finalize__')),
+ subtype)
else:
ret = W_NDimArray(impl)
return ret
@@ -68,10 +86,17 @@
if space.isinstance_w(subtype, space.w_type):
#got type, probably from descr_XXX
ret = space.allocate_instance(W_NDimArray, subtype)
+ W_NDimArray.__init__(ret, impl)
+ space.call_function(space.getattr(ret,
+ space.wrap('__array_finalize__')),
+ space.w_None)
else:
#got instance
ret = space.allocate_instance(W_NDimArray, space.type(subtype))
- W_NDimArray.__init__(ret, impl)
+ W_NDimArray.__init__(ret, impl)
+ space.call_function(space.getattr(ret,
+ space.wrap('__array_finalize__')),
+ subtype)
return ret
return W_NDimArray(impl)
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
@@ -664,12 +664,7 @@
"new type not compatible with array."))
new_shape[-1] = new_shape[-1] * old_itemsize / new_itemsize
v = impl.get_view(self, dtype, new_shape)
- if w_type is not None:
- ret = space.allocate_instance(W_NDimArray, w_type)
- W_NDimArray.__init__(ret, v)
- return ret
- return W_NDimArray(v)
-
+ return wrap_impl(space, w_type, v)
# --------------------- operations ----------------------------
@@ -906,6 +901,8 @@
rffi.str2charp(space.str_w(storage), track_allocation=False),
dtype, owning=True).implementation
+ def descr___array_finalize__(self, space, w_obj):
+ pass
@unwrap_spec(offset=int, order=str)
def descr_new_array(space, w_subtype, w_shape, w_dtype=None, w_buffer=None,
@@ -921,7 +918,8 @@
return W_NDimArray.new_scalar(space, dtype)
if space.is_w(w_subtype, space.gettypefor(W_NDimArray)):
return W_NDimArray.from_shape(space, shape, dtype, order)
- return W_NDimArray.from_shape(space, shape, dtype, order, w_subtype)
+ ret = W_NDimArray.from_shape(space, shape, dtype, order, w_subtype,
is_new=True)
+ return ret
@unwrap_spec(addr=int)
def descr__from_shape_and_storage(space, w_cls, w_shape, addr, w_dtype,
w_subclass=None):
@@ -1068,6 +1066,7 @@
W_NDimArray.fdel___pypy_data__),
__reduce__ = interp2app(W_NDimArray.descr_reduce),
__setstate__ = interp2app(W_NDimArray.descr_setstate),
+ __array_finalize__ = interp2app(W_NDimArray.descr___array_finalize__),
)
@unwrap_spec(ndmin=int, copy=bool, subok=bool)
diff --git a/pypy/module/micronumpy/test/test_subtype.py
b/pypy/module/micronumpy/test/test_subtype.py
--- a/pypy/module/micronumpy/test/test_subtype.py
+++ b/pypy/module/micronumpy/test/test_subtype.py
@@ -4,8 +4,9 @@
class AppTestSupport(BaseNumpyAppTest):
def setup_class(cls):
+ BaseNumpyAppTest.setup_class.im_func(cls)
+ '''
from numpypy import ndarray
- BaseNumpyAppTest.setup_class.im_func(cls)
class NoNew(ndarray):
def __new__(cls):
raise ValueError('should not call __new__')
@@ -17,8 +18,42 @@
return cls
def __array_finalize(self, obj):
self.called_finalize = True
- cls.w_NoNew = cls.space.wrap(NoNew)
- cls.w_SubType = cls.space.wrap(SubType)
+ cls.w_NoNew = cls.space.wrap(NoNew)
+ cls.w_SubType = cls.space.wrap(SubType)
+ '''
+
+ def test_finalize(self):
+ #taken from
http://docs.scipy.org/doc/numpy/user/basics.subclassing.html#simple-example-adding-an-extra-attribute-to-ndarray
+ import numpypy as np
+ class InfoArray(np.ndarray):
+ def __new__(subtype, shape, dtype=float, buffer=None, offset=0,
+ strides=None, order='C', info=None):
+ obj = np.ndarray.__new__(subtype, shape, dtype, buffer,
+ offset, strides, order)
+ obj.info = info
+ return obj
+
+ def __array_finalize__(self, obj):
+ if obj is None:
+ print 'finazlize with None'
+ return
+ print 'finalize with something'
+ self.info = getattr(obj, 'info', None)
+ obj = InfoArray(shape=(3,))
+ assert isinstance(obj, InfoArray)
+ assert obj.info is None
+ obj = InfoArray(shape=(3,), info='information')
+ assert obj.info == 'information'
+ v = obj[1:]
+ assert isinstance(v, InfoArray)
+ assert v.base is obj
+ assert v.info == 'information'
+ arr = np.arange(10)
+ print '1'
+ cast_arr = arr.view(InfoArray)
+ assert isinstance(cast_arr, InfoArray)
+ assert cast_arr.base is arr
+ assert cast_arr.info is None
def test_sub_where(self):
from numpypy import where, ones, zeros, array
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit