[pypy-commit] pypy can_cast: Implement enough of can_cast(<value>, dtype) to pass the test
rlamy
noreply at buildbot.pypy.org
Mon Apr 27 06:44:46 CEST 2015
Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: can_cast
Changeset: r76945:d45abfb9685d
Date: 2015-04-27 05:44 +0100
http://bitbucket.org/pypy/pypy/changeset/d45abfb9685d/
Log: Implement enough of can_cast(<value>, dtype) to pass the test
diff --git a/pypy/module/micronumpy/arrayops.py b/pypy/module/micronumpy/arrayops.py
--- a/pypy/module/micronumpy/arrayops.py
+++ b/pypy/module/micronumpy/arrayops.py
@@ -10,6 +10,7 @@
from .boxes import W_GenericBox
from .types import (
Bool, ULong, Long, Float64, Complex64, UnicodeType, VoidType, ObjectType)
+from .descriptor import get_dtype_cache
def where(space, w_arr, w_x=None, w_y=None):
@@ -360,7 +361,11 @@
return can_cast_type(space, from_type, target, casting)
if not from_type.is_native():
value = value.descr_byteswap(space)
- return can_cast_type(space, from_type, target, casting) # XXX: stub impl
+ dtypenum, altnum = value.min_dtype()
+ if target.is_unsigned():
+ dtypenum = altnum
+ dtype = get_dtype_cache(space).dtypes_by_num[dtypenum]
+ return can_cast_type(space, dtype, target, casting) # XXX: stub impl
def is_scalar_w(space, w_arg):
return (isinstance(w_arg, W_GenericBox) or
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
@@ -874,4 +874,3 @@
__new__ = interp2app(W_ObjectBox.descr__new__.im_func),
__getattr__ = interp2app(W_ObjectBox.descr__getattr__),
)
-
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
@@ -1,5 +1,6 @@
import functools
import math
+from rpython.rlib.unroll import unrolling_iterable
from pypy.interpreter.error import OperationError, oefmt
from pypy.objspace.std.floatobject import float2string
from pypy.objspace.std.complexobject import str_format
@@ -2472,3 +2473,56 @@
for tp2 in complex_types:
if tp1.basesize() <= tp2.basesize():
enable_cast(tp1, tp2)
+
+_int_types = [(Int8, UInt8), (Int16, UInt16), (Int32, UInt32),
+ (Int64, UInt64), (Long, ULong)]
+for Int_t, UInt_t in _int_types:
+ Int_t.Unsigned = UInt_t
+ UInt_t.Signed = Int_t
+ size = rffi.sizeof(Int_t.T)
+ Int_t.min_value = rffi.cast(Int_t.T, -1) << (8*size - 1)
+ Int_t.max_value = ~Int_t.min_value
+ UInt_t.max_value = ~rffi.cast(UInt_t.T, 0)
+
+
+signed_types = [Int8, Int16, Int32, Int64, Long]
+
+for Int_t in signed_types:
+ UInt_t = Int_t.Unsigned
+ smaller_types = [tp for tp in signed_types
+ if rffi.sizeof(tp.T) < rffi.sizeof(Int_t.T)]
+ smaller_types = unrolling_iterable(
+ [(tp, tp.Unsigned) for tp in smaller_types])
+ def min_dtype(self):
+ for Small, USmall in smaller_types:
+ signed_max = rffi.cast(UInt_t.T, Small.max_value)
+ unsigned_max = rffi.cast(UInt_t.T, USmall.max_value)
+ if self.value <= unsigned_max:
+ if self.value <= signed_max:
+ return Small.num, USmall.num
+ else:
+ return USmall.num, USmall.num
+ if self.value <= rffi.cast(UInt_t.T, Int_t.max_value):
+ return Int_t.num, UInt_t.num
+ else:
+ return UInt_t.num, UInt_t.num
+ UInt_t.BoxType.min_dtype = min_dtype
+
+ def min_dtype(self):
+ if self.value >= 0:
+ for Small, USmall in smaller_types:
+ signed_max = rffi.cast(UInt_t.T, Small.max_value)
+ unsigned_max = rffi.cast(UInt_t.T, USmall.max_value)
+ if self.value <= unsigned_max:
+ if self.value <= signed_max:
+ return Small.num, USmall.num
+ else:
+ return USmall.num, USmall.num
+ return Int_t.num, UInt_t.num
+ else:
+ for Small, USmall in smaller_types:
+ signed_min = rffi.cast(UInt_t.T, Small.min_value)
+ if self.value >= signed_max:
+ return Small.num, Small.num
+ return Int_t.num, Int_t.num
+ Int_t.BoxType.min_dtype = min_dtype
More information about the pypy-commit
mailing list