Author: Ronan Lamy <[email protected]>
Branch: can_cast
Changeset: r76930:2c0b8658d9ed
Date: 2015-04-25 03:33 +0100
http://bitbucket.org/pypy/pypy/changeset/2c0b8658d9ed/
Log: create casting_table and use it in can_cast()
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
@@ -94,7 +94,7 @@
return self.itemtype.box_complex(real, imag)
def can_cast_to(self, other):
- return True
+ return self.itemtype.can_cast_to(other.itemtype)
def coerce(self, space, w_item):
return self.itemtype.coerce(space, self, w_item)
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
@@ -129,6 +129,13 @@
else:
return alloc_raw_storage(size, track_allocation=False, zero=False)
+ @classmethod
+ def basesize(cls):
+ return rffi.sizeof(cls.T)
+
+ def can_cast_to(self, other):
+ return casting_table[self.num][other.num]
+
class Primitive(object):
_mixin_ = True
@@ -412,6 +419,7 @@
class Integer(Primitive):
_mixin_ = True
+ signed = True
def _base_coerce(self, space, w_item):
if w_item is None:
@@ -568,6 +576,7 @@
char = NPY.UBYTELTR
BoxType = boxes.W_UInt8Box
format_code = "B"
+ signed = False
class Int16(BaseType, Integer):
T = rffi.SHORT
@@ -584,6 +593,7 @@
char = NPY.USHORTLTR
BoxType = boxes.W_UInt16Box
format_code = "H"
+ signed = False
class Int32(BaseType, Integer):
T = rffi.INT
@@ -600,6 +610,7 @@
char = NPY.UINTLTR
BoxType = boxes.W_UInt32Box
format_code = "I"
+ signed = False
def _int64_coerce(self, space, w_item):
try:
@@ -645,6 +656,7 @@
char = NPY.ULONGLONGLTR
BoxType = boxes.W_UInt64Box
format_code = "Q"
+ signed = False
_coerce = func_with_new_name(_uint64_coerce, '_coerce')
@@ -676,6 +688,7 @@
char = NPY.ULONGLTR
BoxType = boxes.W_ULongBox
format_code = "L"
+ signed = False
_coerce = func_with_new_name(_ulong_coerce, '_coerce')
@@ -2392,8 +2405,11 @@
del tp
all_float_types = []
+float_types = []
all_int_types = []
+int_types = []
all_complex_types = []
+complex_types = []
def _setup():
# compute alignment
@@ -2402,9 +2418,57 @@
tp.alignment =
widen(clibffi.cast_type_to_ffitype(tp.T).c_alignment)
if issubclass(tp, Float):
all_float_types.append((tp, 'float'))
+ float_types.append(tp)
if issubclass(tp, Integer):
all_int_types.append((tp, 'int'))
+ int_types.append(tp)
if issubclass(tp, ComplexFloating):
all_complex_types.append((tp, 'complex'))
+ complex_types.append(tp)
_setup()
del _setup
+
+casting_table = [[False] * NPY.NTYPES for _ in range(NPY.NTYPES)]
+number_types = int_types + float_types + complex_types
+all_types = number_types + [ObjectType, StringType, UnicodeType, VoidType]
+
+def enable_cast(type1, type2):
+ casting_table[type1.num][type2.num] = True
+
+for tp in all_types:
+ enable_cast(tp, tp)
+ if tp.num != NPY.DATETIME:
+ enable_cast(Bool, tp)
+ enable_cast(tp, ObjectType)
+ enable_cast(tp, VoidType)
+enable_cast(StringType, UnicodeType)
+#enable_cast(Bool, TimeDelta)
+
+for tp in number_types:
+ enable_cast(tp, StringType)
+ enable_cast(tp, UnicodeType)
+
+for tp1 in int_types:
+ for tp2 in int_types:
+ if tp1.signed:
+ if tp2.signed and tp1.basesize() <= tp2.basesize():
+ enable_cast(tp1, tp2)
+ else:
+ if tp2.signed and tp1.basesize() < tp2.basesize():
+ enable_cast(tp1, tp2)
+ elif not tp2.signed and tp1.basesize() <= tp2.basesize():
+ enable_cast(tp1, tp2)
+for tp1 in int_types:
+ for tp2 in float_types + complex_types:
+ size1 = tp1.basesize()
+ size2 = tp2.basesize()
+ if (size1 < 8 and size2 > size1) or (size1 >= 8 and size2 >= size1):
+ enable_cast(tp1, tp2)
+for tp1 in float_types:
+ for tp2 in float_types + complex_types:
+ if tp1.basesize() <= tp2.basesize():
+ enable_cast(tp1, tp2)
+for tp1 in complex_types:
+ for tp2 in complex_types:
+ if tp1.basesize() <= tp2.basesize():
+ enable_cast(tp1, tp2)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit