Author: mattip <[email protected]>
Branch: 
Changeset: r58511:d503178b639c
Date: 2012-10-27 19:28 +0200
http://bitbucket.org/pypy/pypy/changeset/d503178b639c/

Log:    merge branch into default

diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py
--- a/lib_pypy/numpypy/core/numeric.py
+++ b/lib_pypy/numpypy/core/numeric.py
@@ -1,5 +1,5 @@
 
-from _numpypy import array, ndarray, int_, float_, bool_ #, complex_# , 
longlong
+from _numpypy import array, ndarray, int_, float_, bool_, flexible #, 
complex_# , longlong
 from _numpypy import concatenate
 from .fromnumeric import any
 import math
@@ -200,7 +200,7 @@
             typename = "'%s'" % typename
 
         lf = ''
-        if 0: # or issubclass(arr.dtype.type, flexible):
+        if issubclass(arr.dtype.type, flexible):
             if arr.dtype.names:
                 typename = "%s" % str(arr.dtype)
             else:
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -38,6 +38,8 @@
 
 .. branch: numpypy-complex2
 Complex dtype support for numpy
+.. branch: numpypy-problems
+Improve dtypes intp, uintp, void, string and record
 .. branch: kill-someobject
 major cleanups including killing some object support
 
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
@@ -62,6 +62,7 @@
         'flexible': 'interp_boxes.W_FlexibleBox',
         'character': 'interp_boxes.W_CharacterBox',
         'str_': 'interp_boxes.W_StringBox',
+        'string_': 'interp_boxes.W_StringBox',
         'unicode_': 'interp_boxes.W_UnicodeBox',
         'void': 'interp_boxes.W_VoidBox',
         'complexfloating': 'interp_boxes.W_ComplexFloatingBox',
diff --git a/pypy/module/micronumpy/arrayimpl/voidbox.py 
b/pypy/module/micronumpy/arrayimpl/voidbox.py
--- a/pypy/module/micronumpy/arrayimpl/voidbox.py
+++ b/pypy/module/micronumpy/arrayimpl/voidbox.py
@@ -6,6 +6,7 @@
     def __init__(self, size, dtype):
         self.storage = alloc_raw_storage(size)
         self.dtype = dtype
+        self.size = size
 
     def __del__(self):
         free_raw_storage(self.storage)
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
@@ -246,7 +246,11 @@
         except KeyError:
             raise OperationError(space.w_IndexError,
                                  space.wrap("Field %s does not exist" % item))
-        return dtype.itemtype.read(self.arr, self.ofs, ofs, dtype)
+        read_val = dtype.itemtype.read(self.arr, self.ofs, ofs, dtype)
+        if isinstance (read_val, W_StringBox):
+            # StringType returns a str
+            return space.wrap(dtype.itemtype.to_str(read_val))
+        return read_val
 
     @unwrap_spec(item=str)
     def descr_setitem(self, space, item, w_value):
@@ -271,6 +275,13 @@
             arr.storage[i] = arg[i]
         return W_StringBox(arr, 0, arr.dtype)
 
+    # Running entire test suite needs this function to succeed,
+    # running single test_stringarray succeeds without it.
+    # With convert_to() test_ztranslation fails since 
+    # W_CharacterBox is not a W_GenericBox.
+    # Why is it needed for multiple tests?
+    #def convert_to(self, dtype):
+    #    xxx
 
 class W_UnicodeBox(W_CharacterBox):
     def descr__new__unicode_box(space, w_subtype, w_arg):
@@ -474,6 +485,7 @@
 
 W_VoidBox.typedef = TypeDef("void", W_FlexibleBox.typedef,
     __module__ = "numpypy",
+    __new__ = interp2app(W_VoidBox.descr__new__.im_func),
     __getitem__ = interp2app(W_VoidBox.descr_getitem),
     __setitem__ = interp2app(W_VoidBox.descr_setitem),
 )
diff --git a/pypy/module/micronumpy/interp_dtype.py 
b/pypy/module/micronumpy/interp_dtype.py
--- a/pypy/module/micronumpy/interp_dtype.py
+++ b/pypy/module/micronumpy/interp_dtype.py
@@ -8,6 +8,7 @@
 from pypy.module.micronumpy import types, interp_boxes
 from pypy.rlib.objectmodel import specialize
 from pypy.rlib.rarithmetic import LONG_BIT, r_longlong, r_ulonglong
+from pypy.rpython.lltypesystem import rffi
 
 
 UNSIGNEDLTR = "u"
@@ -17,6 +18,8 @@
 VOIDLTR = 'V'
 STRINGLTR = 'S'
 UNICODELTR = 'U'
+INTPLTR = 'p'
+UINTPLTR = 'P'
 
 def decode_w_dtype(space, w_dtype):
     if space.is_none(w_dtype):
@@ -66,11 +69,16 @@
     def fill(self, storage, box, start, stop):
         self.itemtype.fill(storage, self.get_size(), box, start, stop, 0)
 
+    def get_name(self):
+        if self.char == 'S':
+            return '|S' + str(self.get_size())
+        return self.name
+
     def descr_str(self, space):
-        return space.wrap(self.name)
+        return space.wrap(self.get_name())
 
     def descr_repr(self, space):
-        return space.wrap("dtype('%s')" % self.name)
+        return space.wrap("dtype('%s')" % self.get_name())
 
     def descr_get_itemsize(self, space):
         return space.wrap(self.itemtype.get_element_size())
@@ -135,6 +143,9 @@
     def is_record_type(self):
         return self.fields is not None
 
+    def is_flexible_type(self):
+        return (self.num == 18 or self.num == 19 or self.num == 20)
+
     def __repr__(self):
         if self.fields is not None:
             return '<DType %r>' % self.fields
@@ -454,6 +465,35 @@
             #alternate_constructors=[space.w_buffer],
             # XXX no buffer in space
         )
+        ptr_size = rffi.sizeof(rffi.CCHARP)
+        if ptr_size == 4:
+            intp_box = interp_boxes.W_Int32Box
+            intp_type = types.Int32()
+            uintp_box = interp_boxes.W_UInt32Box
+            uintp_type = types.UInt32()
+        elif ptr_size == 8:
+            intp_box = interp_boxes.W_Int64Box
+            intp_type = types.Int64()
+            uintp_box = interp_boxes.W_UInt64Box
+            uintp_type = types.UInt64()
+        else:
+            raise ValueError('unknown point size %d' % ptr_size)
+        self.w_intpdtype = W_Dtype(
+            intp_type,
+            num=5,
+            kind=INTPLTR,
+            name='intp',
+            char=INTPLTR,
+            w_box_type = space.gettypefor(intp_box),
+        )    
+        self.w_uintpdtype = W_Dtype(
+            uintp_type,
+            num=6,
+            kind=UINTPLTR,
+            name='uintp',
+            char=UINTPLTR,
+            w_box_type = space.gettypefor(uintp_box),
+        )    
         self.builtin_dtypes = [
             self.w_booldtype, self.w_int8dtype, self.w_uint8dtype,
             self.w_int16dtype, self.w_uint16dtype, self.w_int32dtype,
@@ -462,7 +502,7 @@
             self.w_float32dtype, self.w_float64dtype, self.w_complex64dtype,
             self.w_complex128dtype,
             self.w_stringdtype, self.w_unicodedtype,
-            self.w_voiddtype,
+            self.w_voiddtype, self.w_intpdtype, self.w_uintpdtype,
         ]
         self.float_dtypes_by_num_bytes = sorted(
             (dtype.itemtype.get_element_size(), dtype)
@@ -504,7 +544,8 @@
             #'CDOUBLE',
             #'DATETIME',
             'UINT': self.w_uint32dtype,
-            'INTP': self.w_longdtype,
+            'INTP': self.w_intpdtype,
+            'UINTP': self.w_uintpdtype,
             #'HALF',
             'BYTE': self.w_int8dtype,
             #'CFLOAT': ,
diff --git a/pypy/module/micronumpy/interp_ufuncs.py 
b/pypy/module/micronumpy/interp_ufuncs.py
--- a/pypy/module/micronumpy/interp_ufuncs.py
+++ b/pypy/module/micronumpy/interp_ufuncs.py
@@ -150,6 +150,9 @@
                 "supported for binary functions"))
         assert isinstance(self, W_Ufunc2)
         obj = convert_to_array(space, w_obj)
+        if obj.get_dtype().is_flexible_type():
+            raise OperationError(space.w_TypeError, 
+                      space.wrap('cannot perform reduce for flexible type'))
         obj_shape = obj.get_shape()
         if obj.is_scalar():
             return obj.get_scalar_value()
@@ -235,6 +238,9 @@
             if space.is_w(out, space.w_None):
                 out = None
         w_obj = convert_to_array(space, w_obj)
+        if w_obj.get_dtype().is_flexible_type():
+            raise OperationError(space.w_TypeError, 
+                      space.wrap('Not implemented for this type'))
         calc_dtype = find_unaryop_result_dtype(space,
                                   w_obj.get_dtype(),
                                   promote_to_float=self.promote_to_float,
@@ -301,6 +307,10 @@
             w_out = None
         w_lhs = convert_to_array(space, w_lhs)
         w_rhs = convert_to_array(space, w_rhs)
+        if w_lhs.get_dtype().is_flexible_type() or \
+           w_rhs.get_dtype().is_flexible_type():
+            raise OperationError(space.w_TypeError, 
+                      space.wrap('unsupported operand types'))
         calc_dtype = find_binop_result_dtype(space,
             w_lhs.get_dtype(), w_rhs.get_dtype(),
             int_only=self.int_only,
@@ -447,6 +457,7 @@
     int64_dtype = interp_dtype.get_dtype_cache(space).w_int64dtype
     complex_type = interp_dtype.get_dtype_cache(space).w_complex128dtype
     float_type = interp_dtype.get_dtype_cache(space).w_float64dtype
+    str_dtype = interp_dtype.get_dtype_cache(space).w_stringdtype
     if isinstance(w_obj, interp_boxes.W_GenericBox):
         dtype = w_obj.get_dtype(space)
         if current_guess is None:
@@ -473,6 +484,15 @@
             current_guess is complex_type or current_guess is float_type):
             return complex_type
         return current_guess
+    elif space.isinstance_w(w_obj, space.w_str):
+        if (current_guess is None):
+            return interp_dtype.variable_dtype(space, 
+                                               'S%d' % space.len_w(w_obj))
+        elif current_guess.num ==18:
+            if  current_guess.itemtype.get_size() < space.len_w(w_obj):
+                return interp_dtype.variable_dtype(space, 
+                                                   'S%d' % space.len_w(w_obj))
+        return current_guess
     if current_guess is complex_type:
         return complex_type
     return interp_dtype.get_dtype_cache(space).w_float64dtype
diff --git a/pypy/module/micronumpy/stdobjspace.py 
b/pypy/module/micronumpy/stdobjspace.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/micronumpy/stdobjspace.py
@@ -0,0 +1,11 @@
+
+from pypy.objspace.std import stringobject
+from pypy.module.micronumpy import interp_boxes
+
+def delegate_stringbox2stringobj(space, w_box):
+    return space.wrap(w_box.dtype.itemtype.to_str(w_box))
+
+def register_delegates(typeorder):
+    typeorder[interp_boxes.W_StringBox] = [
+        (stringobject.W_StringObject, delegate_stringbox2stringobj),
+    ]
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
@@ -31,6 +31,8 @@
         from _numpypy import dtype
 
         assert dtype(bool).num == 0
+        assert dtype('intp').num == 5
+        assert dtype('uintp').num == 6
         assert dtype(int).num == 7
         assert dtype(long).num == 9
         assert dtype(float).num == 12
@@ -176,10 +178,15 @@
 
     def test_cant_subclass(self):
         from _numpypy import dtype
-
         # You can't subclass dtype
         raises(TypeError, type, "Foo", (dtype,), {})
 
+    def test_can_subclass(self):
+        import _numpypy
+        class xyz(_numpypy.void):
+            pass
+        assert True
+
     def test_aliases(self):
         from _numpypy import dtype
 
@@ -228,6 +235,17 @@
 
 
 class AppTestTypes(BaseNumpyAppTest):
+    def setup_class(cls):
+        BaseNumpyAppTest.setup_class.im_func(cls)
+        if option.runappdirect:
+            import platform
+            bits, linkage = platform.architecture()
+            ptr_size = int(bits[:-3]) // 8
+        else:
+            from pypy.rpython.lltypesystem import rffi
+            ptr_size = rffi.sizeof(rffi.CCHARP)
+        cls.w_ptr_size = cls.space.wrap(ptr_size)
+
     def test_abstract_types(self):
         import _numpypy as numpy
         raises(TypeError, numpy.generic, 0)
@@ -269,7 +287,9 @@
     def test_int8(self):
         import _numpypy as numpy
 
-        assert numpy.int8.mro() == [numpy.int8, numpy.signedinteger, 
numpy.integer, numpy.number, numpy.generic, object]
+        assert numpy.int8.mro() == [numpy.int8, numpy.signedinteger,
+                                    numpy.integer, numpy.number, 
+                                    numpy.generic, object]
 
         a = numpy.array([1, 2, 3], numpy.int8)
         assert type(a[1]) is numpy.int8
@@ -291,7 +311,9 @@
     def test_uint8(self):
         import _numpypy as numpy
 
-        assert numpy.uint8.mro() == [numpy.uint8, numpy.unsignedinteger, 
numpy.integer, numpy.number, numpy.generic, object]
+        assert numpy.uint8.mro() == [numpy.uint8, numpy.unsignedinteger, 
+                                     numpy.integer, numpy.number, 
+                                     numpy.generic, object]
 
         a = numpy.array([1, 2, 3], numpy.uint8)
         assert type(a[1]) is numpy.uint8
@@ -361,16 +383,22 @@
         import _numpypy as numpy
 
         assert numpy.int_ is numpy.dtype(int).type
-        assert numpy.int_.mro() == [numpy.int_, numpy.signedinteger, 
numpy.integer, numpy.number, numpy.generic, int, object]
+        assert numpy.int_.mro() == [numpy.int_, numpy.signedinteger, 
+                                    numpy.integer, numpy.number, 
+                                    numpy.generic, int, object]
 
     def test_int64(self):
         import sys
         import _numpypy as numpy
 
         if sys.maxint == 2 ** 63 -1:
-            assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, 
numpy.integer, numpy.number, numpy.generic, int, object]
+            assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, 
+                                         numpy.integer, numpy.number, 
+                                         numpy.generic, int, object]
         else:
-            assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, 
numpy.integer, numpy.number, numpy.generic, object]
+            assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, 
+                                         numpy.integer, numpy.number, 
+                                         numpy.generic, object]
 
         assert numpy.dtype(numpy.int64).type is numpy.int64
         assert numpy.int64(3) == 3
@@ -385,7 +413,9 @@
         import sys
         import _numpypy as numpy
 
-        assert numpy.uint64.mro() == [numpy.uint64, numpy.unsignedinteger, 
numpy.integer, numpy.number, numpy.generic, object]
+        assert numpy.uint64.mro() == [numpy.uint64, numpy.unsignedinteger, 
+                                      numpy.integer, numpy.number, 
+                                      numpy.generic, object]
 
         assert numpy.dtype(numpy.uint64).type is numpy.uint64
         skip("see comment")
@@ -400,7 +430,9 @@
     def test_float32(self):
         import _numpypy as numpy
 
-        assert numpy.float32.mro() == [numpy.float32, numpy.floating, 
numpy.inexact, numpy.number, numpy.generic, object]
+        assert numpy.float32.mro() == [numpy.float32, numpy.floating, 
+                                       numpy.inexact, numpy.number, 
+                                       numpy.generic, object]
 
         assert numpy.float32(12) == numpy.float64(12)
         assert numpy.float32('23.4') == numpy.float32(23.4)
@@ -409,7 +441,9 @@
     def test_float64(self):
         import _numpypy as numpy
 
-        assert numpy.float64.mro() == [numpy.float64, numpy.floating, 
numpy.inexact, numpy.number, numpy.generic, float, object]
+        assert numpy.float64.mro() == [numpy.float64, numpy.floating, 
+                                       numpy.inexact, numpy.number, 
+                                       numpy.generic, float, object]
 
         a = numpy.array([1, 2, 3], numpy.float64)
         assert type(a[1]) is numpy.float64
@@ -508,15 +542,16 @@
 
     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
-        if sys.maxint == (1 << 63) - 1:
-            assert '%r' % numpy.intp == '%r' % numpy.int64
-        else:
-            assert '%r' % numpy.intp == '%r' % numpy.int32
+        if self.ptr_size == 4:
+            assert numpy.intp is numpy.int32
+            assert numpy.uintp is numpy.uint32
+        elif self.ptr_size == 8:
+            assert numpy.intp is numpy.int64
+            assert numpy.uintp is numpy.uint64
 
     def test_mro(self):
         import _numpypy as numpy
@@ -562,6 +597,11 @@
         assert dtype('=i8').byteorder == '='
         assert dtype(byteorder + 'i8').byteorder == '='
 
+    def test_intp(self):
+        from _numpypy import dtype
+        assert dtype('p') == dtype('intp')
+        assert dtype('P') == dtype('uintp')
+
     def test_alignment(self):
         from _numpypy import dtype
         assert dtype('i4').alignment == 4
diff --git a/pypy/module/micronumpy/test/test_numarray.py 
b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -2238,7 +2238,49 @@
         assert arr[1]['y']['y'] == 3.5
         assert arr[1]['y']['x'] == 0.0
         assert arr[1]['x'] == 15
-        
+
+    def test_string_record(self):
+        from _numpypy import dtype, array
+        d = dtype([('x', str), ('y', 'int32')])
+        assert d.fields['x'] == (dtype(str), 0)
+        assert d.fields['y'] == (dtype('int32'), 1)
+        d = dtype([('x', 'S1'), ('y', 'int32')])
+        assert d.fields['x'] == (dtype(str), 0)
+        assert d.fields['y'] == (dtype('int32'), 1)
+        a = array([('a', 2), ('c', 1)], dtype=d)
+        assert a[1]['y'] == 1
+        assert a[0]['x'] == 'a'
+
+    def test_stringarray(self):
+        from _numpypy import array, flexible
+        a = array(['abc'],'S3')
+        assert str(a.dtype) == '|S3'
+        a = array(['abc'])
+        assert str(a.dtype) == '|S3'
+        a = array(['abc','defg','ab'])
+        assert str(a.dtype) == '|S4'
+        assert a[0] == 'abc'
+        assert a[1] == 'defg'
+        assert a[2] == 'ab'
+        raises(TypeError, a, 'sum')
+        raises(TypeError, 'a+a')
+
+    def test_flexible_repr(self):
+        # import overrides str(), repr() for array
+        from numpypy.core import arrayprint
+        from _numpypy import array
+        a = array(['abc'],'S3')
+        s = repr(a)
+        # simplify test for \n in repr
+        assert s.replace('\n', '') == "array(['abc'],       dtype='|S3')"
+        # but make sure it exists
+        assert s.find('\n') == 15
+        a = array(['abc','defg','ab'])
+        s = repr(a)
+        assert s.replace('\n', '') == \
+                      "array(['abc', 'defg', 'ab'],       dtype='|S4')"
+         
+       
 class AppTestPyPy(BaseNumpyAppTest):
     def setup_class(cls):
         if option.runappdirect and '__pypy__' not in sys.builtin_module_names:
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
@@ -16,6 +16,7 @@
 from pypy.rlib.rstruct.runpack import runpack
 from pypy.tool.sourcetools import func_with_new_name
 from pypy.rlib import jit
+from pypy.rlib.rstring import StringBuilder
 
 
 degToRad = math.pi / 180.0
@@ -1464,9 +1465,53 @@
     def get_element_size(self):
         return self.size * rffi.sizeof(self.T)
 
+    def get_size(self):
+        return self.size
+
 class StringType(BaseType, BaseStringType):
     T = lltype.Char
 
+    @jit.unroll_safe
+    def coerce(self, space, dtype, w_item):
+        from pypy.module.micronumpy.interp_dtype import new_string_dtype
+        arg = space.str_w(space.str(w_item))
+        arr = interp_boxes.VoidBoxStorage(len(arg), new_string_dtype(space, 
len(arg)))
+        for i in range(len(arg)):
+            arr.storage[i] = arg[i]
+        return interp_boxes.W_StringBox(arr,  0, None)
+
+    @jit.unroll_safe
+    def store(self, arr, i, offset, box):
+        assert isinstance(box, interp_boxes.W_StringBox)
+        for k in range(min(self.size, box.arr.size-offset)):
+            arr.storage[k + i] = box.arr.storage[k + offset]
+
+    def read(self, arr, i, offset, dtype=None):
+        if dtype is None:
+            dtype = arr.dtype
+        return interp_boxes.W_StringBox(arr, i + offset, dtype)
+
+    @jit.unroll_safe
+    def to_str(self, item):
+        builder = StringBuilder()
+        assert isinstance(item, interp_boxes.W_StringBox)
+        i = item.ofs
+        end = i+self.size
+        while i < end:
+            assert isinstance(item.arr.storage[i], str)
+            if item.arr.storage[i] == '\x00':
+                break
+            builder.append(item.arr.storage[i])
+            i += 1
+        return builder.build()
+
+    def str_format(self, item):
+        builder = StringBuilder()
+        builder.append("'")
+        builder.append(self.to_str(item))
+        builder.append("'")
+        return builder.build()
+
 class VoidType(BaseType, BaseStringType):
     T = lltype.Char
 
diff --git a/pypy/objspace/std/model.py b/pypy/objspace/std/model.py
--- a/pypy/objspace/std/model.py
+++ b/pypy/objspace/std/model.py
@@ -182,6 +182,10 @@
                 (complexobject.W_ComplexObject, 
smallintobject.delegate_SmallInt2Complex),
                 ]
 
+        if config.objspace.usemodules.micronumpy:
+            from pypy.module.micronumpy.stdobjspace import register_delegates
+            register_delegates(self.typeorder)
+
         self.typeorder[boolobject.W_BoolObject] += [
             (intobject.W_IntObject,     boolobject.delegate_Bool2IntObject),
             (floatobject.W_FloatObject, floatobject.delegate_Bool2Float),
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to