Author: mattip <[email protected]>
Branch: str-dtype-improvement
Changeset: r62350:88b9b898cd98
Date: 2013-03-14 16:05 -0700
http://bitbucket.org/pypy/pypy/changeset/88b9b898cd98/
Log: test more, partial fix
diff --git a/pypy/module/micronumpy/interp_arrayops.py
b/pypy/module/micronumpy/interp_arrayops.py
--- a/pypy/module/micronumpy/interp_arrayops.py
+++ b/pypy/module/micronumpy/interp_arrayops.py
@@ -122,6 +122,9 @@
raise operationerrfmt(space.w_IndexError, "axis %d out of bounds
[0, %d)", axis, len(shape))
if _axis < 0 or len(shape) <= _axis:
raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0,
%d)", axis, len(shape))
+ if dtype is None:
+ raise OperationError(space.w_TypeError, space.wrap(
+ 'invalid type promotion'))
res = W_NDimArray.from_shape(shape, dtype, 'C')
chunks = [Chunk(0, i, 1, i) for i in shape]
axis_start = 0
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
@@ -277,6 +277,10 @@
dtype.itemtype.store(self.arr, self.ofs, ofs,
dtype.coerce(space, w_value))
+ def convert_to(self, dtype):
+ assert dtype.fields == self.dtype.fields
+ return self
+
class W_CharacterBox(W_FlexibleBox):
pass
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
@@ -414,7 +414,7 @@
if promote_to_float:
return find_unaryop_result_dtype(space, dt2, promote_to_float=True)
# If they're the same kind, choose the greater one.
- if dt1.kind == dt2.kind:
+ if dt1.kind == dt2.kind and dt1.fields == dt2.fields:
return dt2
# Everything promotes to float, and bool promotes to everything.
@@ -434,7 +434,24 @@
elif dt2.num == 10 or (LONG_BIT == 64 and dt2.num == 8):
# UInt64 + signed = Float64
dtypenum = 12
- else:
+ elif dt2.is_flexible_type():
+ # For those operations that get here (concatenate, stack),
+ # flexible types take precedence over numeric type
+ if dt2.is_record_type():
+ if dt1.fields == dt2.fields:
+ #record types require an exact match
+ return dt2
+ return None
+ if dt1.is_str_or_unicode():
+ if dt2.num == 18:
+ size = max(dt2.itemtype.get_element_size(),
+ dt1.itemtype.get_element_size())
+ return interp_dtype.new_string_type(size)
+ size = max(dt2.itemtype.get_element_size(),
+ dt1.itemtype.get_element_size())
+ return interp_dtype.new_unitype_type(size)
+ return dt2
+ else:
# increase to the next signed type
dtypenum = dt2.num + 1
newdtype = interp_dtype.get_dtype_cache(space).dtypes_by_num[dtypenum]
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
@@ -1484,6 +1484,22 @@
assert a.dtype == 'S3'
a = concatenate((array([]), array(['abc'])))
assert a[0] == 'abc'
+
+ def test_record_concatenate(self):
+ # only an exact match can succeed
+ from numpypy import zeros, concatenate
+ a = concatenate((zeros((2,),dtype=[('x', int), ('y', float)]),
+ zeros((2,),dtype=[('x', int), ('y', float)])))
+ assert a.shape == (4,)
+ raises(TypeError, concatenate,
+ (zeros((2,), dtype=[('x', int), ('y', float)]),
+ (zeros((2,), dtype=[('x', float), ('y', float)]))))
+ raises(TypeError, concatenate, ([1], zeros((2,),
+ dtype=[('x', int), ('y', float)])))
+ raises(TypeError, concatenate, (['abc'], zeros((2,),
+ dtype=[('x', int), ('y', float)])))
+
+
def test_std(self):
from numpypy import array
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit