[pypy-commit] pypy default: Implmenet proper hash functions for the numpy types.

alex_gaynor noreply at buildbot.pypy.org
Sun Jun 3 16:55:58 CEST 2012


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: 
Changeset: r55290:0a3cae6d204d
Date: 2012-06-03 09:55 -0500
http://bitbucket.org/pypy/pypy/changeset/0a3cae6d204d/

Log:	Implmenet proper hash functions for the numpy types.

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
@@ -12,15 +12,18 @@
 MIXIN_32 = (int_typedef,) if LONG_BIT == 32 else ()
 MIXIN_64 = (int_typedef,) if LONG_BIT == 64 else ()
 
+
 def new_dtype_getter(name):
     def _get_dtype(space):
         from pypy.module.micronumpy.interp_dtype import get_dtype_cache
         return getattr(get_dtype_cache(space), "w_%sdtype" % name)
+
     def new(space, w_subtype, w_value):
         dtype = _get_dtype(space)
         return dtype.itemtype.coerce_subtype(space, w_subtype, w_value)
     return func_with_new_name(new, name + "_box_new"), staticmethod(_get_dtype)
 
+
 class PrimitiveBox(object):
     _mixin_ = True
 
@@ -30,6 +33,7 @@
     def convert_to(self, dtype):
         return dtype.box(self.value)
 
+
 class W_GenericBox(Wrappable):
     _attrs_ = ()
 
@@ -71,7 +75,7 @@
     def _binop_right_impl(ufunc_name):
         def impl(self, space, w_other, w_out=None):
             from pypy.module.micronumpy import interp_ufuncs
-            return getattr(interp_ufuncs.get(space), ufunc_name).call(space, 
+            return getattr(interp_ufuncs.get(space), ufunc_name).call(space,
                                                             [w_other, self, w_out])
         return func_with_new_name(impl, "binop_right_%s_impl" % ufunc_name)
 
@@ -132,6 +136,9 @@
         w_remainder = self.descr_rmod(space, w_other)
         return space.newtuple([w_quotient, w_remainder])
 
+    def descr_hash(self, space):
+        return space.hash(self.item(space))
+
     def item(self, space):
         return self.get_dtype(space).itemtype.to_builtin_type(space, self)
 
@@ -315,6 +322,8 @@
     __abs__ = interp2app(W_GenericBox.descr_abs),
     __invert__ = interp2app(W_GenericBox.descr_invert),
 
+    __hash__ = interp2app(W_GenericBox.descr_hash),
+
     tolist = interp2app(W_GenericBox.item),
 )
 
@@ -440,4 +449,4 @@
     __module__ = "numpypy",
     __new__ = interp2app(W_UnicodeBox.descr__new__unicode_box.im_func),
 )
-                                          
+
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
@@ -211,33 +211,23 @@
 
         a = array(range(10), dtype=int64)
         b = array([0] * 10, dtype=int64)
-        for idx in b: a[idx] += 1
+        for idx in b:
+            a[idx] += 1
 
-    def test_hash_int8(self):
-        from _numpypy import int8
+    def test_hash(self):
+        import _numpypy as numpy
+        for tp, value in [
+            (numpy.int8, 4),
+            (numpy.int16, 5),
+            (numpy.uint32, 7),
+            (numpy.int64, 3),
+            (numpy.float32, 2.0),
+            (numpy.float64, 4.32),
+        ]:
+            assert hash(tp(value)) == hash(value)
 
-        hash(int8(0))
-        d = {int8(5):99}
 
-    def test_hash_int16(self):
-        from _numpypy import int16
-
-        hash(int16(0))
-        d = {int16(99):42}
-
-    def test_hash_int32(self):
-        from _numpypy import int32
-
-        hash(int32(0))
-        d = {int32(5):99}
-
-    def test_hash_int64(self):
-        from _numpypy import int64
-
-        hash(int64(0))
-        d = {int64(99):42}
-
-class AppTestTypes(BaseNumpyAppTest):    
+class AppTestTypes(BaseNumpyAppTest):
     def test_abstract_types(self):
         import _numpypy as numpy
         raises(TypeError, numpy.generic, 0)
@@ -461,7 +451,7 @@
     def test_various_types(self):
         import _numpypy as numpy
         import sys
-        
+
         assert numpy.int16 is numpy.short
         assert numpy.int8 is numpy.byte
         assert numpy.bool_ is numpy.bool8
@@ -472,7 +462,7 @@
 
     def test_mro(self):
         import _numpypy as numpy
-        
+
         assert numpy.int16.__mro__ == (numpy.int16, numpy.signedinteger,
                                        numpy.integer, numpy.number,
                                        numpy.generic, object)
@@ -528,7 +518,7 @@
 class AppTestStrUnicodeDtypes(BaseNumpyAppTest):
     def test_str_unicode(self):
         from _numpypy import str_, unicode_, character, flexible, generic
-        
+
         assert str_.mro() == [str_, str, basestring, character, flexible, generic, object]
         assert unicode_.mro() == [unicode_, unicode, basestring, character, flexible, generic, object]
 
@@ -588,7 +578,7 @@
         from _numpypy import dtype
         d = dtype({'names': ['a', 'b', 'c'],
                    })
-        
+
 class AppTestNotDirect(BaseNumpyAppTest):
     def setup_class(cls):
         BaseNumpyAppTest.setup_class.im_func(cls)
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
@@ -13,11 +13,13 @@
 from pypy.tool.sourcetools import func_with_new_name
 from pypy.rlib import jit
 
+
 VOID_STORAGE = lltype.Array(lltype.Char, hints={'nolength': True,
                                                 'render_as_void': True})
 degToRad = math.pi / 180.0
 log2 = math.log(2)
-log2e = 1./log2
+log2e = 1. / log2
+
 
 def simple_unary_op(func):
     specialize.argtype(1)(func)
@@ -66,7 +68,7 @@
 
 class BaseType(object):
     _attrs_ = ()
-    
+
     def _unimplemented_ufunc(self, *args):
         raise NotImplementedError
 
@@ -133,7 +135,7 @@
                                  width, storage, i, offset, value)
         else:
             libffi.array_setitem_T(self.T, width, storage, i, offset, value)
-        
+
 
     def store(self, arr, width, i, offset, box):
         self._write(arr.storage, width, i, offset, self.unbox(box))
@@ -242,7 +244,7 @@
 
 class NonNativePrimitive(Primitive):
     _mixin_ = True
-    
+
     def _read(self, storage, width, i, offset):
         if we_are_translated():
             res = libffi.array_getitem(clibffi.cast_type_to_ffitype(self.T),
@@ -528,7 +530,7 @@
 
     T = rffi.LONGLONG
     BoxType = interp_boxes.W_Int64Box
-    format_code = "q"    
+    format_code = "q"
 
     _coerce = func_with_new_name(_int64_coerce, '_coerce')
 
@@ -900,7 +902,7 @@
 
     T = rffi.FLOAT
     BoxType = interp_boxes.W_Float32Box
-    format_code = "f"    
+    format_code = "f"
 
 class Float64(BaseType, Float):
     _attrs_ = ()
@@ -918,7 +920,7 @@
 
 class BaseStringType(object):
     _mixin_ = True
-    
+
     def __init__(self, size=0):
         self.size = size
 
@@ -949,14 +951,14 @@
 
     def get_element_size(self):
         return self.size
-    
+
     def read(self, arr, width, i, offset, dtype=None):
         if dtype is None:
             dtype = arr.dtype
         return interp_boxes.W_VoidBox(arr, i + offset, dtype)
 
     @jit.unroll_safe
-    def coerce(self, space, dtype, w_item): 
+    def coerce(self, space, dtype, w_item):
         from pypy.module.micronumpy.interp_numarray import W_NDimArray
 
         if isinstance(w_item, interp_boxes.W_VoidBox):


More information about the pypy-commit mailing list