[pypy-commit] pypy object-dtype2: start again, reuse the basic ideas from object-dtype
mattip
noreply at buildbot.pypy.org
Sat Feb 28 23:26:43 CET 2015
Author: mattip <matti.picus at gmail.com>
Branch: object-dtype2
Changeset: r76206:a41e39f68799
Date: 2015-02-27 17:00 +0200
http://bitbucket.org/pypy/pypy/changeset/a41e39f68799/
Log: start again, reuse the basic ideas from object-dtype
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
@@ -34,11 +34,13 @@
@staticmethod
def from_shape(space, shape, dtype, order='C', w_instance=None, zero=True):
- from pypy.module.micronumpy import concrete
+ from pypy.module.micronumpy import concrete, descriptor, boxes
from pypy.module.micronumpy.strides import calc_strides
strides, backstrides = calc_strides(shape, dtype.base, order)
impl = concrete.ConcreteArray(shape, dtype.base, order, strides,
backstrides, zero=zero)
+ if dtype == descriptor.get_dtype_cache(space).w_objectdtype:
+ impl.fill(space, boxes.W_ObjectBox(space.w_None))
if w_instance:
return wrap_impl(space, space.type(w_instance), w_instance, impl)
return W_NDimArray(impl)
diff --git a/pypy/module/micronumpy/boxes.py b/pypy/module/micronumpy/boxes.py
--- a/pypy/module/micronumpy/boxes.py
+++ b/pypy/module/micronumpy/boxes.py
@@ -607,6 +607,15 @@
# arr.storage[i] = arg[i]
return W_UnicodeBox(arr, 0, arr.dtype)
+class W_ObjectBox(W_GenericBox):
+ descr__new__, _get_dtype, descr_reduce = new_dtype_getter(NPY.OBJECT)
+
+ def __init__(self, w_obj):
+ self.w_obj = w_obj
+
+ def convert_to(self, space, dtype):
+ return self # XXX
+
W_GenericBox.typedef = TypeDef("numpy.generic",
__new__ = interp2app(W_GenericBox.descr__new__.im_func),
diff --git a/pypy/module/micronumpy/compile.py b/pypy/module/micronumpy/compile.py
--- a/pypy/module/micronumpy/compile.py
+++ b/pypy/module/micronumpy/compile.py
@@ -67,6 +67,7 @@
w_unicode = W_TypeObject("unicode")
w_complex = W_TypeObject("complex")
w_dict = W_TypeObject("dict")
+ w_object = W_TypeObject("object")
def __init__(self):
"""NOT_RPYTHON"""
diff --git a/pypy/module/micronumpy/descriptor.py b/pypy/module/micronumpy/descriptor.py
--- a/pypy/module/micronumpy/descriptor.py
+++ b/pypy/module/micronumpy/descriptor.py
@@ -56,7 +56,7 @@
self.char = char
self.w_box_type = w_box_type
if byteorder is None:
- if itemtype.get_element_size() == 1:
+ if itemtype.get_element_size() == 1 or isinstance(itemtype, types.ObjectType):
byteorder = NPY.IGNORE
else:
byteorder = NPY.NATIVE
@@ -112,6 +112,9 @@
def is_str(self):
return self.num == NPY.STRING
+ def is_object(self):
+ return self.num == NPY.OBJECT
+
def is_str_or_unicode(self):
return self.num == NPY.STRING or self.num == NPY.UNICODE
@@ -585,8 +588,7 @@
if w_dtype is dtype.w_box_type:
return dtype
if space.isinstance_w(w_dtype, space.w_type):
- raise oefmt(space.w_NotImplementedError,
- "cannot create dtype with type '%N'", w_dtype)
+ return cache.w_objectdtype
raise oefmt(space.w_TypeError, "data type not understood")
@@ -851,6 +853,13 @@
char=NPY.UINTPLTR,
w_box_type=space.gettypefor(boxes.W_ULongBox),
)
+ self.w_objectdtype = W_Dtype(
+ types.ObjectType(),
+ num=NPY.OBJECT,
+ kind=NPY.OBJECTLTR,
+ char=NPY.OBJECTLTR,
+ w_box_type=space.gettypefor(boxes.W_ObjectBox),
+ )
aliases = {
NPY.BOOL: ['bool_', 'bool8'],
NPY.BYTE: ['byte'],
@@ -869,6 +878,7 @@
NPY.CLONGDOUBLE: ['clongdouble', 'clongfloat'],
NPY.STRING: ['string_', 'str'],
NPY.UNICODE: ['unicode_'],
+ NPY.OBJECT: ['object_'],
}
self.alternate_constructors = {
NPY.BOOL: [space.w_bool],
@@ -887,6 +897,8 @@
NPY.UNICODE: [space.w_unicode],
NPY.VOID: [space.gettypefor(boxes.W_GenericBox)],
#space.w_buffer, # XXX no buffer in space
+ NPY.OBJECT: [space.gettypefor(boxes.W_ObjectBox),
+ space.w_object],
}
float_dtypes = [self.w_float16dtype, self.w_float32dtype,
self.w_float64dtype, self.w_floatlongdtype]
@@ -906,7 +918,7 @@
self.w_int64dtype, self.w_uint64dtype,
] + float_dtypes + complex_dtypes + [
self.w_stringdtype, self.w_unicodedtype, self.w_voiddtype,
- self.w_intpdtype, self.w_uintpdtype,
+ self.w_intpdtype, self.w_uintpdtype, self.w_objectdtype,
]
self.float_dtypes_by_num_bytes = sorted(
(dtype.elsize, dtype)
@@ -958,6 +970,7 @@
'USHORT': self.w_uint16dtype,
'FLOAT': self.w_float32dtype,
'BOOL': self.w_booldtype,
+ 'OBJECT': self.w_objectdtype,
}
typeinfo_partial = {
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
@@ -472,11 +472,8 @@
class O(object):
pass
for o in [object, O]:
- if '__pypy__' not in sys.builtin_module_names:
- assert np.dtype(o).str == '|O8'
- else:
- exc = raises(NotImplementedError, "np.dtype(o)")
- assert exc.value[0] == "cannot create dtype with type '%s'" % o.__name__
+ print np.dtype(o).byteorder
+ assert np.dtype(o).str == '|O8'
class AppTestTypes(BaseAppTestDtypes):
def test_abstract_types(self):
@@ -1354,9 +1351,21 @@
import sys
class Polynomial(object):
pass
- if '__pypy__' in sys.builtin_module_names:
- exc = raises(NotImplementedError, array, Polynomial())
- assert exc.value.message.find('unable to create dtype from objects') >= 0
- else:
- a = array(Polynomial())
- assert a.shape == ()
+ a = array(Polynomial())
+ assert a.shape == ()
+
+ def test_uninitialized_object_array_is_filled_by_None(self):
+ import numpy as np
+
+ a = np.ndarray([5], dtype="O")
+
+ assert a[0] == None
+
+ def test_object_arrays_add(self):
+ import numpy as np
+
+ a = np.array(["foo"], dtype=object)
+ b = np.array(["bar"], dtype=object)
+
+ res = a + b
+ assert res[0] == "foobar"
diff --git a/pypy/module/micronumpy/test/test_ndarray.py b/pypy/module/micronumpy/test/test_ndarray.py
--- a/pypy/module/micronumpy/test/test_ndarray.py
+++ b/pypy/module/micronumpy/test/test_ndarray.py
@@ -3150,11 +3150,7 @@
assert b[35] == 200
b[[slice(25, 30)]] = range(5)
assert all(a[:5] == range(5))
- import sys
- if '__pypy__' not in sys.builtin_module_names:
- raises(TypeError, 'b[[[slice(25, 125)]]]')
- else:
- raises(NotImplementedError, 'b[[[slice(25, 125)]]]')
+ raises(IndexError, 'b[[[slice(25, 125)]]]')
def test_cumsum(self):
from numpy import arange
diff --git a/pypy/module/micronumpy/test/test_selection.py b/pypy/module/micronumpy/test/test_selection.py
--- a/pypy/module/micronumpy/test/test_selection.py
+++ b/pypy/module/micronumpy/test/test_selection.py
@@ -12,14 +12,11 @@
exp = sorted(range(len(exp)), key=exp.__getitem__)
c = a.copy()
res = a.argsort()
- assert (res == exp).all(), '%r\n%r\n%r' % (a,res,exp)
+ assert (res == exp).all(), 'Failed sortng %r\na=%r\nres=%r\nexp=%r' % (dtype,a,res,exp)
assert (a == c).all() # not modified
a = arange(100, dtype=dtype)
assert (a.argsort() == a).all()
- import sys
- if '__pypy__' in sys.builtin_module_names:
- raises(NotImplementedError, 'arange(10,dtype="float16").argsort()')
def test_argsort_ndim(self):
from numpy import array
@@ -63,14 +60,13 @@
'i2', complex]:
a = array([6, 4, -1, 3, 8, 3, 256+20, 100, 101], dtype=dtype)
exp = sorted(list(a))
- res = a.copy()
- res.sort()
- assert (res == exp).all(), '%r\n%r\n%r' % (a,res,exp)
+ a.sort()
+ assert (a == exp).all(), 'Failed sorting %r\n%r\n%r' % (dtype, a, exp)
a = arange(100, dtype=dtype)
c = a.copy()
a.sort()
- assert (a == c).all()
+ assert (a == c).all(), 'Failed sortng %r\na=%r\nc=%r' % (dtype,a,c)
def test_sort_nonnative(self):
from numpy import array
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
@@ -3,8 +3,9 @@
from pypy.interpreter.error import OperationError, oefmt
from pypy.objspace.std.floatobject import float2string
from pypy.objspace.std.complexobject import str_format
+from pypy.interpreter.baseobjspace import W_Root
from rpython.rlib import clibffi, jit, rfloat, rcomplex
-from rpython.rlib.objectmodel import specialize
+from rpython.rlib.objectmodel import specialize, we_are_translated
from rpython.rlib.rarithmetic import widen, byteswap, r_ulonglong, \
most_neg_value_of, LONG_BIT
from rpython.rlib.rawstorage import (alloc_raw_storage,
@@ -14,7 +15,9 @@
pack_float80, unpack_float80)
from rpython.rlib.rstruct.nativefmttable import native_is_bigendian
from rpython.rlib.rstruct.runpack import runpack
-from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.rtyper.annlowlevel import cast_instance_to_gcref,\
+ cast_gcref_to_instance
+from rpython.rtyper.lltypesystem import lltype, rffi, llmemory
from rpython.tool.sourcetools import func_with_new_name
from pypy.module.micronumpy import boxes
from pypy.module.micronumpy.concrete import SliceArray, VoidBoxStorage
@@ -112,6 +115,7 @@
_immutable_fields_ = ['native']
def __init__(self, native=True):
+ assert native is True or native is False
self.native = native
def __repr__(self):
@@ -1623,6 +1627,80 @@
BoxType = boxes.W_ComplexLongBox
ComponentBoxType = boxes.W_FloatLongBox
+_all_objs_for_tests = [] # for tests
+
+class ObjectType(BaseType):
+ T = lltype.Signed
+ BoxType = boxes.W_ObjectBox
+
+ def get_element_size(self):
+ return rffi.sizeof(lltype.Signed)
+
+ def coerce(self, space, dtype, w_item):
+ if isinstance(w_item, boxes.W_ObjectBox):
+ return w_item
+ return boxes.W_ObjectBox(w_item)
+
+ def store(self, arr, i, offset, box):
+ self._write(arr.storage, i, offset, self.unbox(box))
+
+ def read(self, arr, i, offset, dtype=None):
+ return self.box(self._read(arr.storage, i, offset))
+
+ def _write(self, storage, i, offset, w_obj):
+ if we_are_translated():
+ value = rffi.cast(lltype.Signed, cast_instance_to_gcref(w_obj))
+ else:
+ value = len(_all_objs_for_tests)
+ _all_objs_for_tests.append(w_obj)
+ raw_storage_setitem_unaligned(storage, i + offset, value)
+
+ def _read(self, storage, i, offset):
+ res = raw_storage_getitem_unaligned(self.T, storage, i + offset)
+ if we_are_translated():
+ gcref = rffi.cast(llmemory.GCREF, res)
+ w_obj = cast_gcref_to_instance(W_Root, gcref)
+ else:
+ w_obj = _all_objs_for_tests[res]
+ return w_obj
+
+ def fill(self, storage, width, box, start, stop, offset):
+ value = self.unbox(box)
+ for i in xrange(start, stop, width):
+ self._write(storage, i, offset, value)
+
+ def unbox(self, box):
+ assert isinstance(box, self.BoxType)
+ return box.w_obj
+
+ @specialize.argtype(1)
+ def box(self, w_obj):
+ assert isinstance(w_obj, W_Root)
+ return self.BoxType(w_obj)
+
+ def str_format(self, box):
+ return 'Object as string'
+ #return space.str_w(space.repr(self.unbox(box)))
+
+ def to_builtin_type(self, space, box):
+ assert isinstance(box, self.BoxType)
+ return box.w_obj
+
+ @staticmethod
+ def for_computation(v):
+ return v
+
+ @simple_binary_op
+ def add(self, v1, v2):
+ return v1
+ #return self.space.add(v1, v2)
+
+ @raw_binary_op
+ def eq(self, v1, v2):
+ return True
+ #return self.space.eq_w(v1, v2)
+
+
class FlexibleType(BaseType):
def get_element_size(self):
return rffi.sizeof(self.T)
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
@@ -431,7 +431,9 @@
w_rhs = numpify(space, w_rhs)
w_ldtype = _get_dtype(space, w_lhs)
w_rdtype = _get_dtype(space, w_rhs)
- if w_ldtype.is_str() and w_rdtype.is_str() and \
+ if w_ldtype.is_object() or w_rdtype.is_object():
+ pass
+ elif w_ldtype.is_str() and w_rdtype.is_str() and \
self.comparison_func:
pass
elif (w_ldtype.is_str() or w_rdtype.is_str()) and \
@@ -945,6 +947,10 @@
return dt1
if dt1 is None:
return dt2
+
+ if dt1.num == NPY.OBJECT or dt2.num == NPY.OBJECT:
+ return get_dtype_cache(space).w_objectdtype
+
# dt1.num should be <= dt2.num
if dt1.num > dt2.num:
dt1, dt2 = dt2, dt1
@@ -1059,6 +1065,7 @@
uint64_dtype = get_dtype_cache(space).w_uint64dtype
complex_dtype = get_dtype_cache(space).w_complex128dtype
float_dtype = get_dtype_cache(space).w_float64dtype
+ object_dtype = get_dtype_cache(space).w_objectdtype
if isinstance(w_obj, boxes.W_GenericBox):
dtype = w_obj.get_dtype(space)
return find_binop_result_dtype(space, dtype, current_guess)
@@ -1092,9 +1099,10 @@
return variable_dtype(space,
'S%d' % space.len_w(w_obj))
return current_guess
- raise oefmt(space.w_NotImplementedError,
- 'unable to create dtype from objects, "%T" instance not '
- 'supported', w_obj)
+ return object_dtype
+ #raise oefmt(space.w_NotImplementedError,
+ # 'unable to create dtype from objects, "%T" instance not '
+ # 'supported', w_obj)
def ufunc_dtype_caller(space, ufunc_name, op_name, nin, comparison_func,
More information about the pypy-commit
mailing list