[pypy-commit] pypy can_cast: Create pypy.module.micronumpy.casting

rlamy noreply at buildbot.pypy.org
Fri May 1 20:05:19 CEST 2015


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: can_cast
Changeset: r76971:c9fbdb4fd4eb
Date: 2015-05-01 19:05 +0100
http://bitbucket.org/pypy/pypy/changeset/c9fbdb4fd4eb/

Log:	Create pypy.module.micronumpy.casting

diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py
--- a/pypy/module/micronumpy/__init__.py
+++ b/pypy/module/micronumpy/__init__.py
@@ -20,9 +20,9 @@
         'concatenate': 'arrayops.concatenate',
         'count_nonzero': 'arrayops.count_nonzero',
         'dot': 'arrayops.dot',
-        'result_type': 'arrayops.result_type',
-        'can_cast': 'arrayops.can_cast',
         'where': 'arrayops.where',
+        'result_type': 'casting.result_type',
+        'can_cast': 'casting.can_cast',
 
         'set_string_function': 'appbridge.set_string_function',
         'typeinfo': 'descriptor.get_dtype_cache(space).w_typeinfo',
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
@@ -1,4 +1,3 @@
-from rpython.rlib import jit
 from pypy.interpreter.error import OperationError, oefmt
 from pypy.interpreter.gateway import unwrap_spec
 from pypy.module.micronumpy import loop, descriptor, ufuncs, support, \
@@ -7,10 +6,6 @@
 from pypy.module.micronumpy.converters import clipmode_converter
 from pypy.module.micronumpy.strides import (
     Chunk, Chunks, shape_agreement, shape_agreement_multiple)
-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):
@@ -288,105 +283,3 @@
     else:
         loop.diagonal_array(space, arr, out, offset, axis1, axis2, shape)
     return out
-
-
- at jit.unroll_safe
-def result_type(space, __args__):
-    args_w, kw_w = __args__.unpack()
-    if kw_w:
-        raise oefmt(space.w_TypeError, "result_type() takes no keyword arguments")
-    if not args_w:
-        raise oefmt(space.w_ValueError, "at least one array or dtype is required")
-    result = None
-    for w_arg in args_w:
-        dtype = as_dtype(space, w_arg)
-        result = ufuncs.find_binop_result_dtype(space, result, dtype)
-    return result
-
- at unwrap_spec(casting=str)
-def can_cast(space, w_from, w_totype, casting='safe'):
-    try:
-        target = as_dtype(space, w_totype, allow_None=False)
-    except TypeError:
-        raise oefmt(space.w_TypeError,
-            "did not understand one of the types; 'None' not accepted")
-    if isinstance(w_from, W_NDimArray):
-        return space.wrap(can_cast_array(space, w_from, target, casting))
-    elif is_scalar_w(space, w_from):
-        w_scalar = as_scalar(space, w_from)
-        w_arr = W_NDimArray.from_scalar(space, w_scalar)
-        return space.wrap(can_cast_array(space, w_arr, target, casting))
-
-    try:
-        origin = as_dtype(space, w_from, allow_None=False)
-    except TypeError:
-        raise oefmt(space.w_TypeError,
-            "did not understand one of the types; 'None' not accepted")
-    return space.wrap(can_cast_type(space, origin, target, casting))
-
-kind_ordering = {
-    Bool.kind: 0, ULong.kind: 1, Long.kind: 2,
-    Float64.kind: 4, Complex64.kind: 5,
-    NPY.STRINGLTR: 6, NPY.STRINGLTR2: 6,
-    UnicodeType.kind: 7, VoidType.kind: 8, ObjectType.kind: 9}
-
-def can_cast_type(space, origin, target, casting):
-    if casting == 'no':
-        return origin.eq(space, target)
-    elif casting == 'equiv':
-        return origin.num == target.num and origin.elsize == target.elsize
-    elif casting == 'unsafe':
-        return True
-    elif casting == 'same_kind':
-        if origin.can_cast_to(target):
-            return True
-        if origin.kind in kind_ordering and target.kind in kind_ordering:
-            return kind_ordering[origin.kind] <= kind_ordering[target.kind]
-        return False
-    else:
-        return origin.can_cast_to(target)
-
-def can_cast_array(space, w_from, target, casting):
-    origin = w_from.get_dtype()
-    if w_from.is_scalar():
-        return can_cast_scalar(
-            space, origin, w_from.get_scalar_value(), target, casting)
-    else:
-        return can_cast_type(space, origin, target, casting)
-
-def can_cast_scalar(space, from_type, value, target, casting):
-    if from_type == target or casting == 'unsafe':
-        return True
-    if not from_type.is_number() or casting in ('no', 'equiv'):
-        return can_cast_type(space, from_type, target, casting)
-    if not from_type.is_native():
-        value = value.descr_byteswap(space)
-    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
-            space.isinstance_w(w_arg, space.w_int) or
-            space.isinstance_w(w_arg, space.w_float) or
-            space.isinstance_w(w_arg, space.w_complex) or
-            space.isinstance_w(w_arg, space.w_long) or
-            space.isinstance_w(w_arg, space.w_bool))
-
-def as_dtype(space, w_arg, allow_None=True):
-    # roughly equivalent to CNumPy's PyArray_DescrConverter2
-    if not allow_None and space.is_none(w_arg):
-        raise TypeError("Cannot create dtype from None here")
-    if isinstance(w_arg, W_NDimArray):
-        return w_arg.get_dtype()
-    elif is_scalar_w(space, w_arg):
-        return ufuncs.find_dtype_for_scalar(space, w_arg)
-    else:
-        return space.interp_w(descriptor.W_Dtype,
-            space.call_function(space.gettypefor(descriptor.W_Dtype), w_arg))
-
-def as_scalar(space, w_obj):
-    dtype = ufuncs.find_dtype_for_scalar(space, w_obj)
-    return dtype.coerce(space, w_obj)
diff --git a/pypy/module/micronumpy/casting.py b/pypy/module/micronumpy/casting.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/micronumpy/casting.py
@@ -0,0 +1,117 @@
+"""Functions and helpers for converting between dtypes"""
+
+from rpython.rlib import jit
+from pypy.interpreter.gateway import unwrap_spec
+from pypy.interpreter.error import oefmt
+
+from pypy.module.micronumpy.base import W_NDimArray
+from pypy.module.micronumpy import constants as NPY
+from pypy.module.micronumpy.ufuncs import (
+    find_binop_result_dtype, find_dtype_for_scalar)
+from .boxes import W_GenericBox
+from .types import (
+    Bool, ULong, Long, Float64, Complex64, UnicodeType, VoidType, ObjectType)
+from .descriptor import get_dtype_cache, W_Dtype
+
+ at jit.unroll_safe
+def result_type(space, __args__):
+    args_w, kw_w = __args__.unpack()
+    if kw_w:
+        raise oefmt(space.w_TypeError,
+            "result_type() takes no keyword arguments")
+    if not args_w:
+        raise oefmt(space.w_ValueError,
+            "at least one array or dtype is required")
+    result = None
+    for w_arg in args_w:
+        dtype = as_dtype(space, w_arg)
+        result = find_binop_result_dtype(space, result, dtype)
+    return result
+
+ at unwrap_spec(casting=str)
+def can_cast(space, w_from, w_totype, casting='safe'):
+    try:
+        target = as_dtype(space, w_totype, allow_None=False)
+    except TypeError:
+        raise oefmt(space.w_TypeError,
+            "did not understand one of the types; 'None' not accepted")
+    if isinstance(w_from, W_NDimArray):
+        return space.wrap(can_cast_array(space, w_from, target, casting))
+    elif is_scalar_w(space, w_from):
+        w_scalar = as_scalar(space, w_from)
+        w_arr = W_NDimArray.from_scalar(space, w_scalar)
+        return space.wrap(can_cast_array(space, w_arr, target, casting))
+
+    try:
+        origin = as_dtype(space, w_from, allow_None=False)
+    except TypeError:
+        raise oefmt(space.w_TypeError,
+            "did not understand one of the types; 'None' not accepted")
+    return space.wrap(can_cast_type(space, origin, target, casting))
+
+kind_ordering = {
+    Bool.kind: 0, ULong.kind: 1, Long.kind: 2,
+    Float64.kind: 4, Complex64.kind: 5,
+    NPY.STRINGLTR: 6, NPY.STRINGLTR2: 6,
+    UnicodeType.kind: 7, VoidType.kind: 8, ObjectType.kind: 9}
+
+def can_cast_type(space, origin, target, casting):
+    if casting == 'no':
+        return origin.eq(space, target)
+    elif casting == 'equiv':
+        return origin.num == target.num and origin.elsize == target.elsize
+    elif casting == 'unsafe':
+        return True
+    elif casting == 'same_kind':
+        if origin.can_cast_to(target):
+            return True
+        if origin.kind in kind_ordering and target.kind in kind_ordering:
+            return kind_ordering[origin.kind] <= kind_ordering[target.kind]
+        return False
+    else:
+        return origin.can_cast_to(target)
+
+def can_cast_array(space, w_from, target, casting):
+    origin = w_from.get_dtype()
+    if w_from.is_scalar():
+        return can_cast_scalar(
+            space, origin, w_from.get_scalar_value(), target, casting)
+    else:
+        return can_cast_type(space, origin, target, casting)
+
+def can_cast_scalar(space, from_type, value, target, casting):
+    if from_type == target or casting == 'unsafe':
+        return True
+    if not from_type.is_number() or casting in ('no', 'equiv'):
+        return can_cast_type(space, from_type, target, casting)
+    if not from_type.is_native():
+        value = value.descr_byteswap(space)
+    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
+            space.isinstance_w(w_arg, space.w_int) or
+            space.isinstance_w(w_arg, space.w_float) or
+            space.isinstance_w(w_arg, space.w_complex) or
+            space.isinstance_w(w_arg, space.w_long) or
+            space.isinstance_w(w_arg, space.w_bool))
+
+def as_dtype(space, w_arg, allow_None=True):
+    # roughly equivalent to CNumPy's PyArray_DescrConverter2
+    if not allow_None and space.is_none(w_arg):
+        raise TypeError("Cannot create dtype from None here")
+    if isinstance(w_arg, W_NDimArray):
+        return w_arg.get_dtype()
+    elif is_scalar_w(space, w_arg):
+        return find_dtype_for_scalar(space, w_arg)
+    else:
+        return space.interp_w(W_Dtype,
+            space.call_function(space.gettypefor(W_Dtype), w_arg))
+
+def as_scalar(space, w_obj):
+    dtype = find_dtype_for_scalar(space, w_obj)
+    return dtype.coerce(space, w_obj)
diff --git a/pypy/module/micronumpy/test/test_arrayops.py b/pypy/module/micronumpy/test/test_arrayops.py
--- a/pypy/module/micronumpy/test/test_arrayops.py
+++ b/pypy/module/micronumpy/test/test_arrayops.py
@@ -199,19 +199,3 @@
         a.put(23, -1, mode=1)  # wrap
         assert (a == array([0, 1, -10, -1, -15])).all()
         raises(TypeError, "arange(5).put(22, -5, mode='zzzz')")  # unrecognized mode
-
-    def test_result_type(self):
-        import numpy as np
-        exc = raises(ValueError, np.result_type)
-        assert str(exc.value) == "at least one array or dtype is required"
-        exc = raises(TypeError, np.result_type, a=2)
-        assert str(exc.value) == "result_type() takes no keyword arguments"
-        assert np.result_type(True) is np.dtype('bool')
-        assert np.result_type(1) is np.dtype('int')
-        assert np.result_type(1.) is np.dtype('float64')
-        assert np.result_type(1+2j) is np.dtype('complex128')
-        assert np.result_type(1, 1.) is np.dtype('float64')
-        assert np.result_type(np.array([1, 2])) is np.dtype('int')
-        assert np.result_type(np.array([1, 2]), 1, 1+2j) is np.dtype('complex128')
-        assert np.result_type(np.array([1, 2]), 1, 'float64') is np.dtype('float64')
-        assert np.result_type(np.array([1, 2]), 1, None) is np.dtype('float64')
diff --git a/pypy/module/micronumpy/test/test_casting.py b/pypy/module/micronumpy/test/test_casting.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/micronumpy/test/test_casting.py
@@ -0,0 +1,114 @@
+from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest
+
+
+class AppTestNumSupport(BaseNumpyAppTest):
+    def test_result_type(self):
+        import numpy as np
+        exc = raises(ValueError, np.result_type)
+        assert str(exc.value) == "at least one array or dtype is required"
+        exc = raises(TypeError, np.result_type, a=2)
+        assert str(exc.value) == "result_type() takes no keyword arguments"
+        assert np.result_type(True) is np.dtype('bool')
+        assert np.result_type(1) is np.dtype('int')
+        assert np.result_type(1.) is np.dtype('float64')
+        assert np.result_type(1+2j) is np.dtype('complex128')
+        assert np.result_type(1, 1.) is np.dtype('float64')
+        assert np.result_type(np.array([1, 2])) is np.dtype('int')
+        assert np.result_type(np.array([1, 2]), 1, 1+2j) is np.dtype('complex128')
+        assert np.result_type(np.array([1, 2]), 1, 'float64') is np.dtype('float64')
+        assert np.result_type(np.array([1, 2]), 1, None) is np.dtype('float64')
+
+    def test_can_cast(self):
+        import numpy as np
+
+        assert np.can_cast(np.int32, np.int64)
+        assert np.can_cast(np.float64, complex)
+        assert not np.can_cast(np.complex64, float)
+
+        assert np.can_cast('i8', 'f8')
+        assert not np.can_cast('i8', 'f4')
+        assert np.can_cast('i4', 'S11')
+
+        assert np.can_cast('i8', 'i8', 'no')
+        assert not np.can_cast('<i8', '>i8', 'no')
+
+        assert np.can_cast('<i8', '>i8', 'equiv')
+        assert not np.can_cast('<i4', '>i8', 'equiv')
+
+        assert np.can_cast('<i4', '>i8', 'safe')
+        assert not np.can_cast('<i8', '>i4', 'safe')
+
+        assert np.can_cast('<i8', '>i4', 'same_kind')
+        assert not np.can_cast('<i8', '>u4', 'same_kind')
+
+        assert np.can_cast('<i8', '>u4', 'unsafe')
+
+        assert np.can_cast('bool', 'S5')
+        assert not np.can_cast('bool', 'S4')
+
+        assert np.can_cast('b', 'S4')
+        assert not np.can_cast('b', 'S3')
+
+        assert np.can_cast('u1', 'S3')
+        assert not np.can_cast('u1', 'S2')
+        assert np.can_cast('u2', 'S5')
+        assert not np.can_cast('u2', 'S4')
+        assert np.can_cast('u4', 'S10')
+        assert not np.can_cast('u4', 'S9')
+        assert np.can_cast('u8', 'S20')
+        assert not np.can_cast('u8', 'S19')
+
+        assert np.can_cast('i1', 'S4')
+        assert not np.can_cast('i1', 'S3')
+        assert np.can_cast('i2', 'S6')
+        assert not np.can_cast('i2', 'S5')
+        assert np.can_cast('i4', 'S11')
+        assert not np.can_cast('i4', 'S10')
+        assert np.can_cast('i8', 'S21')
+        assert not np.can_cast('i8', 'S20')
+
+        assert np.can_cast('bool', 'S5')
+        assert not np.can_cast('bool', 'S4')
+
+        assert np.can_cast('b', 'U4')
+        assert not np.can_cast('b', 'U3')
+
+        assert np.can_cast('u1', 'U3')
+        assert not np.can_cast('u1', 'U2')
+        assert np.can_cast('u2', 'U5')
+        assert not np.can_cast('u2', 'U4')
+        assert np.can_cast('u4', 'U10')
+        assert not np.can_cast('u4', 'U9')
+        assert np.can_cast('u8', 'U20')
+        assert not np.can_cast('u8', 'U19')
+
+        assert np.can_cast('i1', 'U4')
+        assert not np.can_cast('i1', 'U3')
+        assert np.can_cast('i2', 'U6')
+        assert not np.can_cast('i2', 'U5')
+        assert np.can_cast('i4', 'U11')
+        assert not np.can_cast('i4', 'U10')
+        assert np.can_cast('i8', 'U21')
+        assert not np.can_cast('i8', 'U20')
+
+        raises(TypeError, np.can_cast, 'i4', None)
+        raises(TypeError, np.can_cast, None, 'i4')
+
+    def test_can_cast_scalar(self):
+        import numpy as np
+        assert np.can_cast(True, np.bool_)
+        assert np.can_cast(True, np.int8)
+        assert not np.can_cast(0, np.bool_)
+        assert np.can_cast(127, np.int8)
+        assert not np.can_cast(128, np.int8)
+        assert np.can_cast(128, np.int16)
+
+        assert np.can_cast(np.float32('inf'), np.float32)
+        assert np.can_cast(float('inf'), np.float32)  # XXX: False in CNumPy?!
+        assert np.can_cast(3.3e38, np.float32)
+        assert not np.can_cast(3.4e38, np.float32)
+
+        assert np.can_cast(1 + 2j, np.complex64)
+        assert not np.can_cast(1 + 1e50j, np.complex64)
+        assert np.can_cast(1., np.complex64)
+        assert not np.can_cast(1e50, np.complex64)
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
@@ -3971,98 +3971,3 @@
         a = ndarray._from_shape_and_storage((2,), addr, int, sz,
                                            strides=[2 * base.strides[0]])
         assert a[1] == 3
-
-    def test_can_cast(self):
-        import numpy as np
-
-        assert np.can_cast(np.int32, np.int64)
-        assert np.can_cast(np.float64, complex)
-        assert not np.can_cast(np.complex64, float)
-
-        assert np.can_cast('i8', 'f8')
-        assert not np.can_cast('i8', 'f4')
-        assert np.can_cast('i4', 'S11')
-
-        assert np.can_cast('i8', 'i8', 'no')
-        assert not np.can_cast('<i8', '>i8', 'no')
-
-        assert np.can_cast('<i8', '>i8', 'equiv')
-        assert not np.can_cast('<i4', '>i8', 'equiv')
-
-        assert np.can_cast('<i4', '>i8', 'safe')
-        assert not np.can_cast('<i8', '>i4', 'safe')
-
-        assert np.can_cast('<i8', '>i4', 'same_kind')
-        assert not np.can_cast('<i8', '>u4', 'same_kind')
-
-        assert np.can_cast('<i8', '>u4', 'unsafe')
-
-        assert np.can_cast('bool', 'S5')
-        assert not np.can_cast('bool', 'S4')
-
-        assert np.can_cast('b', 'S4')
-        assert not np.can_cast('b', 'S3')
-
-        assert np.can_cast('u1', 'S3')
-        assert not np.can_cast('u1', 'S2')
-        assert np.can_cast('u2', 'S5')
-        assert not np.can_cast('u2', 'S4')
-        assert np.can_cast('u4', 'S10')
-        assert not np.can_cast('u4', 'S9')
-        assert np.can_cast('u8', 'S20')
-        assert not np.can_cast('u8', 'S19')
-
-        assert np.can_cast('i1', 'S4')
-        assert not np.can_cast('i1', 'S3')
-        assert np.can_cast('i2', 'S6')
-        assert not np.can_cast('i2', 'S5')
-        assert np.can_cast('i4', 'S11')
-        assert not np.can_cast('i4', 'S10')
-        assert np.can_cast('i8', 'S21')
-        assert not np.can_cast('i8', 'S20')
-
-        assert np.can_cast('bool', 'S5')
-        assert not np.can_cast('bool', 'S4')
-
-        assert np.can_cast('b', 'U4')
-        assert not np.can_cast('b', 'U3')
-
-        assert np.can_cast('u1', 'U3')
-        assert not np.can_cast('u1', 'U2')
-        assert np.can_cast('u2', 'U5')
-        assert not np.can_cast('u2', 'U4')
-        assert np.can_cast('u4', 'U10')
-        assert not np.can_cast('u4', 'U9')
-        assert np.can_cast('u8', 'U20')
-        assert not np.can_cast('u8', 'U19')
-
-        assert np.can_cast('i1', 'U4')
-        assert not np.can_cast('i1', 'U3')
-        assert np.can_cast('i2', 'U6')
-        assert not np.can_cast('i2', 'U5')
-        assert np.can_cast('i4', 'U11')
-        assert not np.can_cast('i4', 'U10')
-        assert np.can_cast('i8', 'U21')
-        assert not np.can_cast('i8', 'U20')
-
-        raises(TypeError, np.can_cast, 'i4', None)
-        raises(TypeError, np.can_cast, None, 'i4')
-
-    def test_can_cast_scalar(self):
-        import numpy as np
-        assert np.can_cast(True, np.bool_)
-        assert np.can_cast(True, np.int8)
-        assert not np.can_cast(0, np.bool_)
-        assert np.can_cast(127, np.int8)
-        assert not np.can_cast(128, np.int8)
-        assert np.can_cast(128, np.int16)
-
-        assert np.can_cast(np.float32('inf'), np.float32)
-        assert np.can_cast(float('inf'), np.float32)  # XXX: False in CNumPy?!
-        assert np.can_cast(3.3e38, np.float32)
-        assert not np.can_cast(3.4e38, np.float32)
-
-        assert np.can_cast(1 + 2j, np.complex64)
-        assert not np.can_cast(1 + 1e50j, np.complex64)
-        assert np.can_cast(1., np.complex64)
-        assert not np.can_cast(1e50, np.complex64)


More information about the pypy-commit mailing list