[pypy-commit] pypy can_cast: Add missing comparison operations on dtype

rlamy noreply at buildbot.pypy.org
Wed May 6 18:09:21 CEST 2015


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: can_cast
Changeset: r77163:39a612244a74
Date: 2015-05-06 17:09 +0100
http://bitbucket.org/pypy/pypy/changeset/39a612244a74/

Log:	Add missing comparison operations on dtype

diff --git a/pypy/module/micronumpy/casting.py b/pypy/module/micronumpy/casting.py
--- a/pypy/module/micronumpy/casting.py
+++ b/pypy/module/micronumpy/casting.py
@@ -11,7 +11,7 @@
 from .boxes import W_GenericBox
 from .types import (
     Bool, ULong, Long, Float64, Complex64, UnicodeType, VoidType, ObjectType)
-from .descriptor import get_dtype_cache, W_Dtype
+from .descriptor import get_dtype_cache, as_dtype, is_scalar_w
 
 @jit.unroll_safe
 def result_type(space, __args__):
@@ -95,26 +95,6 @@
     dtype = get_dtype_cache(space).dtypes_by_num[dtypenum]
     return can_cast_type(space, dtype, target, casting)
 
-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/descriptor.py b/pypy/module/micronumpy/descriptor.py
--- a/pypy/module/micronumpy/descriptor.py
+++ b/pypy/module/micronumpy/descriptor.py
@@ -8,7 +8,9 @@
 from rpython.rlib import jit
 from rpython.rlib.objectmodel import specialize, compute_hash, we_are_translated
 from rpython.rlib.rarithmetic import r_longlong, r_ulonglong
-from pypy.module.micronumpy import types, boxes, base, support, constants as NPY
+from rpython.rlib.signature import finishsigs, signature, types as ann
+from pypy.module.micronumpy import types, boxes, support, constants as NPY
+from .base import W_NDimArray
 from pypy.module.micronumpy.appbridge import get_appbridge_cache
 from pypy.module.micronumpy.converters import byteorder_converter
 
@@ -36,12 +38,13 @@
         if not space.is_none(w_arr):
             dtype = find_binop_result_dtype(space, dtype, w_arr.get_dtype())
     assert dtype is not None
-    out = base.W_NDimArray.from_shape(space, shape, dtype)
+    out = W_NDimArray.from_shape(space, shape, dtype)
     return out
 
 
 _REQ_STRLEN = [0, 3, 5, 10, 10, 20, 20, 20, 20]  # data for can_cast_to()
 
+ at finishsigs
 class W_Dtype(W_Root):
     _immutable_fields_ = [
         "itemtype?", "w_box_type", "byteorder?", "names?", "fields?",
@@ -95,6 +98,7 @@
     def box_complex(self, real, imag):
         return self.itemtype.box_complex(real, imag)
 
+    @signature(ann.self(), ann.self(), returns=ann.bool())
     def can_cast_to(self, other):
         # equivalent to PyArray_CanCastTo
         result = self.itemtype.can_cast_to(other.itemtype)
@@ -304,6 +308,22 @@
     def descr_ne(self, space, w_other):
         return space.wrap(not self.eq(space, w_other))
 
+    def descr_le(self, space, w_other):
+        w_other = as_dtype(space, w_other)
+        return space.wrap(self.can_cast_to(w_other))
+
+    def descr_ge(self, space, w_other):
+        w_other = as_dtype(space, w_other)
+        return space.wrap(w_other.can_cast_to(self))
+
+    def descr_lt(self, space, w_other):
+        w_other = as_dtype(space, w_other)
+        return space.wrap(self.can_cast_to(w_other) and not self.eq(space, w_other))
+
+    def descr_gt(self, space, w_other):
+        w_other = as_dtype(space, w_other)
+        return space.wrap(w_other.can_cast_to(self) and not self.eq(space, w_other))
+
     def _compute_hash(self, space, x):
         from rpython.rlib.rarithmetic import intmask
         if not self.fields and self.subdtype is None:
@@ -674,6 +694,10 @@
 
     __eq__ = interp2app(W_Dtype.descr_eq),
     __ne__ = interp2app(W_Dtype.descr_ne),
+    __lt__ = interp2app(W_Dtype.descr_lt),
+    __le__ = interp2app(W_Dtype.descr_le),
+    __gt__ = interp2app(W_Dtype.descr_gt),
+    __ge__ = interp2app(W_Dtype.descr_ge),
     __hash__ = interp2app(W_Dtype.descr_hash),
     __str__= interp2app(W_Dtype.descr_str),
     __repr__ = interp2app(W_Dtype.descr_repr),
@@ -981,3 +1005,26 @@
 
 def get_dtype_cache(space):
     return space.fromcache(DtypeCache)
+
+def as_dtype(space, w_arg, allow_None=True):
+    from pypy.module.micronumpy.ufuncs import find_dtype_for_scalar
+    # 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):
+        result = find_dtype_for_scalar(space, w_arg)
+        assert result is not None  # XXX: not guaranteed
+        return result
+    else:
+        return space.interp_w(W_Dtype,
+            space.call_function(space.gettypefor(W_Dtype), w_arg))
+
+def is_scalar_w(space, w_arg):
+    return (isinstance(w_arg, boxes.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))
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
@@ -112,6 +112,11 @@
         raises(TypeError, lambda: dtype("int8") == 3)
         assert dtype(bool) == bool
 
+    def test_dtype_cmp(self):
+        from numpy import dtype
+        assert dtype('int8') <= dtype('int8')
+        assert not (dtype('int8') < dtype('int8'))
+
     def test_dtype_aliases(self):
         from numpy import dtype
         assert dtype('bool8') is dtype('bool')
@@ -1287,7 +1292,7 @@
         from cPickle import loads, dumps
 
         d = dtype([("x", "int32"), ("y", "int32"), ("z", "int32"), ("value", float)])
-        assert d.__reduce__() == (dtype, ('V20', 0, 1), (3, '|', None, 
+        assert d.__reduce__() == (dtype, ('V20', 0, 1), (3, '|', None,
                      ('x', 'y', 'z', 'value'),
                      {'y': (dtype('int32'), 4), 'x': (dtype('int32'), 0),
                       'z': (dtype('int32'), 8), 'value': (dtype('float64'), 12),


More information about the pypy-commit mailing list