1. Pypy
  2. Untitled project
  3. pypy

Commits

Philip Jenvey  committed 2e294c8 Merge

merge default

  • Participants
  • Parent commits 5acd4d6, 1f1e196
  • Branches py3k

Comments (0)

Files changed (46)

File lib_pypy/numpypy/lib/utils.py

View file
         ...
 
     """
-    try:
-        import numpy
-    except:
-        # running from pypy source directory
-        head, tail = os.path.split(os.path.dirname(os.path.abspath(__file__)))
-        return os.path.join(head, '../include')
-    else:
-        # using installed numpy core headers
-        import numpy.core as core
-        d = os.path.join(os.path.dirname(core.__file__), 'include')
-    return d
+    return os.path.join(os.path.dirname(__file__), '../../../include')

File pypy/doc/faq.rst

View file
 You cannot use most existing standard library modules from RPython.  The
 exceptions are
 some functions in ``os``, ``math`` and ``time`` that have native support.
+We have our own "RPython standard library" in ``rpython.rlib.*``.
 
 To read more about the RPython limitations read the `RPython description`_.
 

File pypy/doc/whatsnew-head.rst

View file
 
 .. branch: incremental-gc
 Added the new incminimark GC which performs GC in incremental steps
+
+.. branch: fast_cffi_list_init
+fastpath for cffi.new("long[]")

File pypy/interpreter/baseobjspace.py

View file
         # _____ this code is here to support testing only _____
         return self
 
+    def unpackiterable_int(self, space):
+        lst = space.listview_int(self)
+        if lst:
+            return lst[:]
+        return None
+
+    def unpackiterable_float(self, space):
+        lst = space.listview_float(self)
+        if lst:
+            return lst[:]
+        return None
+
 
 class W_InterpIterable(W_Root):
     def __init__(self, space, w_iterable):
         return self._unpackiterable_known_length_jitlook(w_iterator,
                                                          expected_length)
 
+
+    def unpackiterable_int(self, w_obj):
+        """
+        Return a RPython list of unwrapped ints out of w_obj. The list is
+        guaranteed to be acopy of the actual data contained in w_obj, so you
+        can freely modify it. It might return None if not supported.
+        """
+        return w_obj.unpackiterable_int(self)
+
+    def unpackiterable_float(self, w_obj):
+        """
+        Same as unpackiterable_int, but for floats.
+        """
+        return w_obj.unpackiterable_float(self)
+
+
     def length_hint(self, w_obj, default):
         """Return the length of an object, consulting its __length_hint__
         method if necessary.
         """
         return None
 
+    def listview_int(self, w_list):
+        """ Return a list of unwrapped int out of a list of int. If the
+        argument is not a list or does not contain only int, return None.
+        May return None anyway.
+        """
+        return None
+
+    def listview_float(self, w_list):
+        """ Return a list of unwrapped float out of a list of float. If the
+        argument is not a list or does not contain only float, return None.
+        May return None anyway.
+        """
+        return None
+
     def view_as_kwargs(self, w_dict):
         """ if w_dict is a kwargs-dict, return two lists, one of unwrapped
         strings and one of wrapped values. otherwise return (None, None)

File pypy/interpreter/nestedscope.py

View file
         if len(cellvars) != ncellvars:
             raise OperationError(self.space.w_TypeError,
                                  self.space.wrap("bad cellvars"))
-        if self.cells is not None:
-            self.cells[:ncellvars] = cellvars
+        self.cells[:ncellvars] = cellvars
 
     @jit.dont_look_inside
     def fast2locals(self):
 
     @jit.unroll_safe
     def init_cells(self):
-        if self.cells is None:
-            return
         args_to_copy = self.pycode._args_as_cellvars
         for i in range(len(args_to_copy)):
             argnum = args_to_copy[i]

File pypy/module/_cffi_backend/cdataobj.py

View file
     def iter(self):
         return self.ctype.iter(self)
 
+    def unpackiterable_int(self, space):
+        from pypy.module._cffi_backend import ctypearray
+        ctype = self.ctype
+        if isinstance(ctype, ctypearray.W_CTypeArray):
+            return ctype.ctitem.unpack_list_of_int_items(self)
+        return None
+
+    def unpackiterable_float(self, space):
+        from pypy.module._cffi_backend import ctypearray
+        ctype = self.ctype
+        if isinstance(ctype, ctypearray.W_CTypeArray):
+            return ctype.ctitem.unpack_list_of_float_items(self)
+        return None
+
     @specialize.argtype(1)
     def write_raw_signed_data(self, source):
         misc.write_raw_signed_data(self._cdata, source, self.ctype.size)

File pypy/module/_cffi_backend/ctypearray.py

File contents unchanged.

File pypy/module/_cffi_backend/ctypeobj.py

View file
     def is_unichar_ptr_or_array(self):
         return False
 
+    def unpack_list_of_int_items(self, cdata):
+        return None
+
+    def unpack_list_of_float_items(self, cdata):
+        return None
+
+    def pack_list_of_items(self, cdata, w_ob):
+        return False
+
     def newp(self, w_init):
         space = self.space
         raise operationerrfmt(space.w_TypeError,
                               "cdata '%s' does not support iteration",
                               self.name)
 
+    def unpackiterable_int(self, cdata):
+        return None
+
     def get_vararg_type(self):
         return self
 

File pypy/module/_cffi_backend/ctypeprim.py

View file
 Primitives.
 """
 
+import sys
 from pypy.interpreter.error import operationerrfmt
 
 from rpython.rlib.rarithmetic import r_uint, r_ulonglong, intmask
             return self.space.wrapbytes(s)
         return W_CType.string(self, cdataobj, maxlen)
 
-
 class W_CTypePrimitiveCharOrUniChar(W_CTypePrimitive):
     _attrs_ = []
     is_primitive_integer = True
             sh = self.size * 8
             self.vmin = r_uint(-1) << (sh - 1)
             self.vrangemax = (r_uint(1) << sh) - 1
+        else:
+            self.vmin = r_uint(0)
+            self.vrangemax = r_uint(-1)
 
     def cast_to_int(self, cdata):
         return self.convert_to_object(cdata)
     def write_raw_integer_data(self, w_cdata, value):
         w_cdata.write_raw_signed_data(value)
 
+    def unpack_list_of_int_items(self, w_cdata):
+        if self.size == rffi.sizeof(rffi.LONG):
+            from rpython.rlib.rrawarray import populate_list_from_raw_array
+            res = []
+            buf = rffi.cast(rffi.LONGP, w_cdata._cdata)
+            length = w_cdata.get_array_length()
+            populate_list_from_raw_array(res, buf, length)
+            return res
+        elif self.value_fits_long:
+            res = [0] * w_cdata.get_array_length()
+            misc.unpack_list_from_raw_array(res, w_cdata._cdata, self.size)
+            return res
+        return None
+
+    def pack_list_of_items(self, cdata, w_ob):
+        int_list = self.space.listview_int(w_ob)
+        if int_list is not None:
+            if self.size == rffi.sizeof(rffi.LONG): # fastest path
+                from rpython.rlib.rrawarray import copy_list_to_raw_array
+                cdata = rffi.cast(rffi.LONGP, cdata)
+                copy_list_to_raw_array(int_list, cdata)
+            else:
+                overflowed = misc.pack_list_to_raw_array_bounds(
+                    int_list, cdata, self.size, self.vmin, self.vrangemax)
+                if overflowed != 0:
+                    self._overflow(self.space.wrap(overflowed))
+            return True
+        return W_CTypePrimitive.pack_list_of_items(self, cdata, w_ob)
+
 
 class W_CTypePrimitiveUnsigned(W_CTypePrimitive):
     _attrs_            = ['value_fits_long', 'value_fits_ulong', 'vrangemax']
         self.value_fits_ulong = self.size <= rffi.sizeof(lltype.Unsigned)
         if self.value_fits_long:
             self.vrangemax = self._compute_vrange_max()
+        else:
+            self.vrangemax = r_uint(sys.maxint)
 
     def _compute_vrange_max(self):
         sh = self.size * 8
     def write_raw_integer_data(self, w_cdata, value):
         w_cdata.write_raw_unsigned_data(value)
 
+    def unpack_list_of_int_items(self, w_cdata):
+        if self.value_fits_long:
+            res = [0] * w_cdata.get_array_length()
+            misc.unpack_unsigned_list_from_raw_array(res, w_cdata._cdata,
+                                                     self.size)
+            return res
+        return None
+
+    def pack_list_of_items(self, cdata, w_ob):
+        int_list = self.space.listview_int(w_ob)
+        if int_list is not None:
+            overflowed = misc.pack_list_to_raw_array_bounds(
+                int_list, cdata, self.size, r_uint(0), self.vrangemax)
+            if overflowed != 0:
+                self._overflow(self.space.wrap(overflowed))
+            return True
+        return W_CTypePrimitive.pack_list_of_items(self, cdata, w_ob)
+
 
 class W_CTypePrimitiveBool(W_CTypePrimitiveUnsigned):
     _attrs_ = []
         value = space.float_w(space.float(w_ob))
         misc.write_raw_float_data(cdata, value, self.size)
 
+    def unpack_list_of_float_items(self, w_cdata):
+        if self.size == rffi.sizeof(rffi.DOUBLE):
+            from rpython.rlib.rrawarray import populate_list_from_raw_array
+            res = []
+            buf = rffi.cast(rffi.DOUBLEP, w_cdata._cdata)
+            length = w_cdata.get_array_length()
+            populate_list_from_raw_array(res, buf, length)
+            return res
+        elif self.size == rffi.sizeof(rffi.FLOAT):
+            res = [0.0] * w_cdata.get_array_length()
+            misc.unpack_cfloat_list_from_raw_array(res, w_cdata._cdata)
+            return res
+        return None
+
+    def pack_list_of_items(self, cdata, w_ob):
+        float_list = self.space.listview_float(w_ob)
+        if float_list is not None:
+            if self.size == rffi.sizeof(rffi.DOUBLE):   # fastest path
+                from rpython.rlib.rrawarray import copy_list_to_raw_array
+                cdata = rffi.cast(rffi.DOUBLEP, cdata)
+                copy_list_to_raw_array(float_list, cdata)
+                return True
+            elif self.size == rffi.sizeof(rffi.FLOAT):
+                misc.pack_float_list_to_raw_array(float_list, cdata,
+                                                  rffi.FLOAT, rffi.FLOATP)
+                return True
+        return W_CTypePrimitive.pack_list_of_items(self, cdata, w_ob)
+
 
 class W_CTypePrimitiveLongDouble(W_CTypePrimitiveFloat):
     _attrs_ = []
         return misc.longdouble2str(lvalue)
 
     def cast(self, w_ob):
-        space = self.space
         if (isinstance(w_ob, cdataobj.W_CData) and
                 isinstance(w_ob.ctype, W_CTypePrimitiveLongDouble)):
             w_cdata = self.convert_to_object(w_ob._cdata)
         else:
             value = space.float_w(space.float(w_ob))
             self._to_longdouble_and_write(value, cdata)
+
+    # Cannot have unpack_list_of_float_items() here:
+    # 'list(array-of-longdouble)' returns a list of cdata objects,
+    # not a list of floats.
+
+    def pack_list_of_items(self, cdata, w_ob):
+        float_list = self.space.listview_float(w_ob)
+        if float_list is not None:
+            misc.pack_float_list_to_raw_array(float_list, cdata,
+                                             rffi.LONGDOUBLE, rffi.LONGDOUBLEP)
+            return True
+        return W_CTypePrimitive.pack_list_of_items(self, cdata, w_ob)

File pypy/module/_cffi_backend/ctypeptr.py

View file
             value = rffi.cast(rffi.CCHARP, value)
         return cdataobj.W_CData(space, value, self)
 
+    def _convert_array_from_listview(self, cdata, w_ob):
+        if self.ctitem.pack_list_of_items(cdata, w_ob):   # fast path
+            return
+        #
+        space = self.space
+        lst_w = space.listview(w_ob)
+        if self.length >= 0 and len(lst_w) > self.length:
+            raise operationerrfmt(space.w_IndexError,
+                "too many initializers for '%s' (got %d)",
+                                  self.name, len(lst_w))
+        ctitem = self.ctitem
+        for i in range(len(lst_w)):
+            ctitem.convert_from_object(cdata, lst_w[i])
+            cdata = rffi.ptradd(cdata, ctitem.size)
+
     def convert_array_from_object(self, cdata, w_ob):
         space = self.space
         if (space.isinstance_w(w_ob, space.w_list) or
             space.isinstance_w(w_ob, space.w_tuple)):
-            lst_w = space.listview(w_ob)
-            if self.length >= 0 and len(lst_w) > self.length:
-                raise operationerrfmt(space.w_IndexError,
-                    "too many initializers for '%s' (got %d)",
-                                      self.name, len(lst_w))
-            ctitem = self.ctitem
-            for i in range(len(lst_w)):
-                ctitem.convert_from_object(cdata, lst_w[i])
-                cdata = rffi.ptradd(cdata, ctitem.size)
+            self._convert_array_from_listview(cdata, w_ob)
         elif (self.can_cast_anything or
               (self.ctitem.is_primitive_integer and
                self.ctitem.size == rffi.sizeof(lltype.Char))):

File pypy/module/_cffi_backend/misc.py

View file
             _raw_memclear_tp(TP, TPP, dest)
             return
     raise NotImplementedError("bad clear size")
+
+# ____________________________________________________________
+
+def pack_list_to_raw_array_bounds(int_list, target, size, vmin, vrangemax):
+    for TP, TPP in _prim_signed_types:
+        if size == rffi.sizeof(TP):
+            ptr = rffi.cast(TPP, target)
+            for i in range(len(int_list)):
+                x = int_list[i]
+                if r_uint(x) - vmin > vrangemax:
+                    return x      # overflow
+                ptr[i] = rffi.cast(TP, x)
+            return 0
+    raise NotImplementedError("bad integer size")
+
+@specialize.arg(2)
+def pack_float_list_to_raw_array(float_list, target, TP, TPP):
+    target = rffi.cast(TPP, target)
+    for i in range(len(float_list)):
+        x = float_list[i]
+        target[i] = rffi.cast(TP, x)
+
+def unpack_list_from_raw_array(int_list, source, size):
+    for TP, TPP in _prim_signed_types:
+        if size == rffi.sizeof(TP):
+            ptr = rffi.cast(TPP, source)
+            for i in range(len(int_list)):
+                int_list[i] = rffi.cast(lltype.Signed, ptr[i])
+            return
+    raise NotImplementedError("bad integer size")
+
+def unpack_unsigned_list_from_raw_array(int_list, source, size):
+    for TP, TPP in _prim_unsigned_types:
+        if size == rffi.sizeof(TP):
+            ptr = rffi.cast(TPP, source)
+            for i in range(len(int_list)):
+                int_list[i] = rffi.cast(lltype.Signed, ptr[i])
+            return
+    raise NotImplementedError("bad integer size")
+
+def unpack_cfloat_list_from_raw_array(float_list, source):
+    ptr = rffi.cast(rffi.FLOATP, source)
+    for i in range(len(float_list)):
+        float_list[i] = rffi.cast(lltype.Float, ptr[i])

File pypy/module/_cffi_backend/newtype.py

View file
 
 SF_MSVC_BITFIELDS = 1
 SF_GCC_ARM_BITFIELDS = 2
+SF_GCC_BIG_ENDIAN = 4
 
 if sys.platform == 'win32':
     DEFAULT_SFLAGS = SF_MSVC_BITFIELDS
-elif rffi_platform.getdefined('__arm__', ''):
-    DEFAULT_SFLAGS = SF_GCC_ARM_BITFIELDS
 else:
-    DEFAULT_SFLAGS = 0
+    if rffi_platform.getdefined('__arm__', ''):
+        DEFAULT_SFLAGS = SF_GCC_ARM_BITFIELDS
+    else:
+        DEFAULT_SFLAGS = 0
+    if sys.byteorder == 'big':
+        DEFAULT_SFLAGS |= SF_GCC_BIG_ENDIAN
 
 @unwrap_spec(name=str)
 def new_struct_type(space, name):
                     prev_bitfield_free -= fbitsize
                     field_offset_bytes = boffset / 8 - ftype.size
 
+                if sflags & SF_GCC_BIG_ENDIAN:
+                    bitshift = 8 * ftype.size - fbitsize- bitshift
+
                 fld = ctypestruct.W_CField(ftype, field_offset_bytes,
                                            bitshift, fbitsize)
                 fields_list.append(fld)

File pypy/module/_cffi_backend/test/_backend_test_c.py

View file
     _test_bitfield_details(flag=2)
 
 def test_bitfield_as_big_endian():
-    if '__pypy__' in sys.builtin_module_names:
-        py.test.skip("no big endian machine supported on pypy for now")
     _test_bitfield_details(flag=4)
 
 

File pypy/module/_cffi_backend/test/test_fastpath.py

View file
+# side-effect: FORMAT_LONGDOUBLE must be built before the first test
+from pypy.module._cffi_backend import misc
+from pypy.module._cffi_backend.ctypeobj import W_CType
+
+
+class AppTest_fast_path_from_list(object):
+    spaceconfig = dict(usemodules=('_cffi_backend', 'cStringIO'))
+
+    def setup_method(self, meth):
+        def forbidden(*args):
+            assert False, 'The slow path is forbidden'
+        self._original = W_CType.pack_list_of_items.im_func
+        W_CType.pack_list_of_items = forbidden
+
+    def teardown_method(self, meth):
+        W_CType.pack_list_of_items = self._original
+
+    def test_fast_init_from_list(self):
+        import _cffi_backend
+        LONG = _cffi_backend.new_primitive_type('long')
+        P_LONG = _cffi_backend.new_pointer_type(LONG)
+        LONG_ARRAY = _cffi_backend.new_array_type(P_LONG, None)
+        buf = _cffi_backend.newp(LONG_ARRAY, [1, 2, 3])
+        assert buf[0] == 1
+        assert buf[1] == 2
+        assert buf[2] == 3
+
+    def test_fast_init_from_list_float(self):
+        import _cffi_backend
+        DOUBLE = _cffi_backend.new_primitive_type('double')
+        P_DOUBLE = _cffi_backend.new_pointer_type(DOUBLE)
+        DOUBLE_ARRAY = _cffi_backend.new_array_type(P_DOUBLE, None)
+        buf = _cffi_backend.newp(DOUBLE_ARRAY, [1.1, 2.2, 3.3])
+        assert buf[0] == 1.1
+        assert buf[1] == 2.2
+        assert buf[2] == 3.3
+
+    def test_fast_init_short_from_list(self):
+        import _cffi_backend
+        SHORT = _cffi_backend.new_primitive_type('short')
+        P_SHORT = _cffi_backend.new_pointer_type(SHORT)
+        SHORT_ARRAY = _cffi_backend.new_array_type(P_SHORT, None)
+        buf = _cffi_backend.newp(SHORT_ARRAY, [1, -2, 3])
+        assert buf[0] == 1
+        assert buf[1] == -2
+        assert buf[2] == 3
+        raises(OverflowError, _cffi_backend.newp, SHORT_ARRAY, [40000])
+        raises(OverflowError, _cffi_backend.newp, SHORT_ARRAY, [-40000])
+
+    def test_fast_init_longlong_from_list(self):
+        if type(2 ** 50) is long:
+            large_int = 2 ** 30
+        else:
+            large_int = 2 ** 50
+        import _cffi_backend
+        LONGLONG = _cffi_backend.new_primitive_type('long long')
+        P_LONGLONG = _cffi_backend.new_pointer_type(LONGLONG)
+        LONGLONG_ARRAY = _cffi_backend.new_array_type(P_LONGLONG, None)
+        buf = _cffi_backend.newp(LONGLONG_ARRAY, [1, -2, 3, large_int])
+        assert buf[0] == 1
+        assert buf[1] == -2
+        assert buf[2] == 3
+        assert buf[3] == large_int
+
+    def test_fast_init_ushort_from_list(self):
+        import _cffi_backend
+        USHORT = _cffi_backend.new_primitive_type('unsigned short')
+        P_USHORT = _cffi_backend.new_pointer_type(USHORT)
+        USHORT_ARRAY = _cffi_backend.new_array_type(P_USHORT, None)
+        buf = _cffi_backend.newp(USHORT_ARRAY, [1, 2, 40000])
+        assert buf[0] == 1
+        assert buf[1] == 2
+        assert buf[2] == 40000
+        raises(OverflowError, _cffi_backend.newp, USHORT_ARRAY, [70000])
+        raises(OverflowError, _cffi_backend.newp, USHORT_ARRAY, [-1])
+
+    def test_fast_init_ulong_from_list(self):
+        import sys
+        import _cffi_backend
+        ULONG = _cffi_backend.new_primitive_type('unsigned long')
+        P_ULONG = _cffi_backend.new_pointer_type(ULONG)
+        ULONG_ARRAY = _cffi_backend.new_array_type(P_ULONG, None)
+        buf = _cffi_backend.newp(ULONG_ARRAY, [1, 2, sys.maxint])
+        assert buf[0] == 1
+        assert buf[1] == 2
+        assert buf[2] == sys.maxint
+        raises(OverflowError, _cffi_backend.newp, ULONG_ARRAY, [-1])
+        raises(OverflowError, _cffi_backend.newp, ULONG_ARRAY, [-sys.maxint])
+
+    def test_fast_init_cfloat_from_list(self):
+        import _cffi_backend
+        FLOAT = _cffi_backend.new_primitive_type('float')
+        P_FLOAT = _cffi_backend.new_pointer_type(FLOAT)
+        FLOAT_ARRAY = _cffi_backend.new_array_type(P_FLOAT, None)
+        buf = _cffi_backend.newp(FLOAT_ARRAY, [1.25, -3.5])
+        assert buf[0] == 1.25
+        assert buf[1] == -3.5
+
+    def test_fast_init_clongdouble_from_list(self):
+        import _cffi_backend
+        LONGDOUBLE = _cffi_backend.new_primitive_type('long double')
+        P_LONGDOUBLE = _cffi_backend.new_pointer_type(LONGDOUBLE)
+        LONGDOUBLE_ARRAY = _cffi_backend.new_array_type(P_LONGDOUBLE, None)
+        buf = _cffi_backend.newp(LONGDOUBLE_ARRAY, [1.25, -3.5])
+        assert float(buf[0]) == 1.25
+        assert float(buf[1]) == -3.5
+
+    def test_fast_init_bool_from_list(self):
+        import _cffi_backend
+        BOOL = _cffi_backend.new_primitive_type('_Bool')
+        P_BOOL = _cffi_backend.new_pointer_type(BOOL)
+        BOOL_ARRAY = _cffi_backend.new_array_type(P_BOOL, None)
+        buf = _cffi_backend.newp(BOOL_ARRAY, [1, 0])
+        assert buf[0] == 1
+        assert buf[1] == 0
+        assert type(buf[1]) is int
+        raises(OverflowError, _cffi_backend.newp, BOOL_ARRAY, [2])
+        raises(OverflowError, _cffi_backend.newp, BOOL_ARRAY, [-1])
+
+
+class AppTest_fast_path_bug(object):
+    spaceconfig = dict(usemodules=('_cffi_backend', 'cStringIO'))
+
+    def test_bug_not_list_or_tuple(self):
+        import _cffi_backend
+        LONG = _cffi_backend.new_primitive_type('long')
+        P_LONG = _cffi_backend.new_pointer_type(LONG)
+        LONG_ARRAY_2 = _cffi_backend.new_array_type(P_LONG, 2)
+        P_LONG_ARRAY_2 = _cffi_backend.new_pointer_type(LONG_ARRAY_2)
+        LONG_ARRAY_ARRAY = _cffi_backend.new_array_type(P_LONG_ARRAY_2, None)
+        raises(TypeError, _cffi_backend.newp, LONG_ARRAY_ARRAY, [set([4, 5])])
+
+
+class AppTest_fast_path_to_list(object):
+    spaceconfig = dict(usemodules=('_cffi_backend', 'cStringIO'))
+
+    def setup_method(self, meth):
+        from pypy.interpreter import gateway
+        from rpython.rlib import rrawarray
+        #
+        self.count = 0
+        def get_count(*args):
+            return self.space.wrap(self.count)
+        self.w_get_count = self.space.wrap(gateway.interp2app(get_count))
+        #
+        original = rrawarray.populate_list_from_raw_array
+        def populate_list_from_raw_array(*args):
+            self.count += 1
+            return original(*args)
+        self._original = original
+        rrawarray.populate_list_from_raw_array = populate_list_from_raw_array
+        #
+        original2 = misc.unpack_list_from_raw_array
+        def unpack_list_from_raw_array(*args):
+            self.count += 1
+            return original2(*args)
+        self._original2 = original2
+        misc.unpack_list_from_raw_array = unpack_list_from_raw_array
+        #
+        original3 = misc.unpack_cfloat_list_from_raw_array
+        def unpack_cfloat_list_from_raw_array(*args):
+            self.count += 1
+            return original3(*args)
+        self._original3 = original3
+        misc.unpack_cfloat_list_from_raw_array = (
+            unpack_cfloat_list_from_raw_array)
+        #
+        original4 = misc.unpack_unsigned_list_from_raw_array
+        def unpack_unsigned_list_from_raw_array(*args):
+            self.count += 1
+            return original4(*args)
+        self._original4 = original4
+        misc.unpack_unsigned_list_from_raw_array = (
+            unpack_unsigned_list_from_raw_array)
+        #
+        self.w_runappdirect = self.space.wrap(self.runappdirect)
+
+
+    def teardown_method(self, meth):
+        from rpython.rlib import rrawarray
+        rrawarray.populate_list_from_raw_array = self._original
+        misc.unpack_list_from_raw_array = self._original2
+        misc.unpack_cfloat_list_from_raw_array = self._original3
+        misc.unpack_unsigned_list_from_raw_array = self._original4
+
+    def test_list_int(self):
+        import _cffi_backend
+        LONG = _cffi_backend.new_primitive_type('long')
+        P_LONG = _cffi_backend.new_pointer_type(LONG)
+        LONG_ARRAY = _cffi_backend.new_array_type(P_LONG, 3)
+        buf = _cffi_backend.newp(LONG_ARRAY)
+        buf[0] = 1
+        buf[1] = 2
+        buf[2] = 3
+        lst = list(buf)
+        assert lst == [1, 2, 3]
+        if not self.runappdirect:
+            assert self.get_count() == 1
+
+    def test_TypeError_if_no_length(self):
+        import _cffi_backend
+        LONG = _cffi_backend.new_primitive_type('long')
+        P_LONG = _cffi_backend.new_pointer_type(LONG)
+        LONG_ARRAY = _cffi_backend.new_array_type(P_LONG, 3)
+        buf = _cffi_backend.newp(LONG_ARRAY)
+        pbuf = _cffi_backend.cast(P_LONG, buf)
+        raises(TypeError, "list(pbuf)")
+
+    def test_bug(self):
+        import _cffi_backend
+        LONG = _cffi_backend.new_primitive_type('long')
+        five = _cffi_backend.cast(LONG, 5)
+        raises(TypeError, list, five)
+        DOUBLE = _cffi_backend.new_primitive_type('double')
+        five_and_a_half = _cffi_backend.cast(DOUBLE, 5.5)
+        raises(TypeError, list, five_and_a_half)
+
+    def test_list_float(self):
+        import _cffi_backend
+        DOUBLE = _cffi_backend.new_primitive_type('double')
+        P_DOUBLE = _cffi_backend.new_pointer_type(DOUBLE)
+        DOUBLE_ARRAY = _cffi_backend.new_array_type(P_DOUBLE, 3)
+        buf = _cffi_backend.newp(DOUBLE_ARRAY)
+        buf[0] = 1.1
+        buf[1] = 2.2
+        buf[2] = 3.3
+        lst = list(buf)
+        assert lst == [1.1, 2.2, 3.3]
+        if not self.runappdirect:
+            assert self.get_count() == 1
+
+    def test_list_short(self):
+        import _cffi_backend
+        SHORT = _cffi_backend.new_primitive_type('short')
+        P_SHORT = _cffi_backend.new_pointer_type(SHORT)
+        SHORT_ARRAY = _cffi_backend.new_array_type(P_SHORT, 3)
+        buf = _cffi_backend.newp(SHORT_ARRAY)
+        buf[0] = 1
+        buf[1] = 2
+        buf[2] = 3
+        lst = list(buf)
+        assert lst == [1, 2, 3]
+        if not self.runappdirect:
+            assert self.get_count() == 1
+
+    def test_list_ushort(self):
+        import _cffi_backend
+        USHORT = _cffi_backend.new_primitive_type('unsigned short')
+        P_USHORT = _cffi_backend.new_pointer_type(USHORT)
+        USHORT_ARRAY = _cffi_backend.new_array_type(P_USHORT, 3)
+        buf = _cffi_backend.newp(USHORT_ARRAY)
+        buf[0] = 1
+        buf[1] = 2
+        buf[2] = 50505
+        lst = list(buf)
+        assert lst == [1, 2, 50505]
+        if not self.runappdirect:
+            assert self.get_count() == 1
+
+    def test_list_cfloat(self):
+        import _cffi_backend
+        FLOAT = _cffi_backend.new_primitive_type('float')
+        P_FLOAT = _cffi_backend.new_pointer_type(FLOAT)
+        FLOAT_ARRAY = _cffi_backend.new_array_type(P_FLOAT, 3)
+        buf = _cffi_backend.newp(FLOAT_ARRAY)
+        buf[0] = 1.25
+        buf[1] = -2.5
+        buf[2] = 3.75
+        lst = list(buf)
+        assert lst == [1.25, -2.5, 3.75]
+        if not self.runappdirect:
+            assert self.get_count() == 1

File pypy/module/micronumpy/arrayimpl/sort.py

View file
 from rpython.rlib.rawstorage import raw_storage_getitem, raw_storage_setitem, \
         free_raw_storage, alloc_raw_storage
 from rpython.rlib.unroll import unrolling_iterable
-from rpython.rlib.rarithmetic import intmask
+from rpython.rlib.rarithmetic import widen
 from rpython.rlib.objectmodel import specialize
 from pypy.interpreter.error import OperationError
 from pypy.module.micronumpy.base import W_NDimArray
                                     + self.start + step * i)
                     v.append(_v)
             if comp_type == 'int':
-                v = intmask(v)
+                v = widen(v)
             elif comp_type == 'float':
                 v = float(v)
             elif comp_type == 'complex':
     if count < 2:
         def arg_lt(a, b):
             # Does numpy do <= ?
-            return a[0] < b[0]
+            return a[0] < b[0] or b[0] != b[0] and a[0] == a[0]
     else:
         def arg_lt(a, b):
             for i in range(count):
+                if b[0][i] != b[0][i] and a[0][i] == a[0][i]:
+                    return True
+                elif b[0][i] == b[0][i] and a[0][i] != a[0][i]:
+                    return False
+            for i in range(count):
                 if a[0][i] < b[0][i]:
                     return True
                 elif a[0][i] > b[0][i]:
                                     + self.start + step * i)
                     v.append(_v)
             if comp_type == 'int':
-                v = intmask(v)
+                v = widen(v)
             elif comp_type == 'float':
                 v = float(v)
             elif comp_type == 'complex':
 
 all_types = (types.all_float_types + types.all_complex_types +
              types.all_int_types)
-all_types = [i for i in all_types if not '_mixin_' in i[0].__dict__]
+all_types = [i for i in all_types if not '_mixin_' in i[0].__dict__ and
+                                     not issubclass(i[0], types.BaseFloat16)]
 all_types = unrolling_iterable(all_types)
 
 class ArgSortCache(object):

File pypy/module/micronumpy/interp_arrayops.py

View file
                 shape[i] += axis_size
         a_dt = arr.get_dtype()
         if dtype.is_record_type() and a_dt.is_record_type():
-            #Record types must match
+            # Record types must match
             for f in dtype.fields:
                 if f not in a_dt.fields or \
                              dtype.fields[f] != a_dt.fields[f]:
                     raise OperationError(space.w_TypeError,
-                               space.wrap("record type mismatch"))
+                               space.wrap("invalid type promotion"))
         elif dtype.is_record_type() or a_dt.is_record_type():
             raise OperationError(space.w_TypeError,
                         space.wrap("invalid type promotion"))

File pypy/module/micronumpy/interp_boxes.py

View file
 
 class PrimitiveBox(Box):
     _mixin_ = True
+    _immutable_fields_ = ['value']
 
     def __init__(self, value):
         self.value = value
         ret = builder.build()
 
         lltype.free(value, flavor="raw")
-
         return ret
 
 class ComplexBox(Box):
     _mixin_ = True
+    _immutable_fields_ = ['real', 'imag']
 
     def __init__(self, real, imag=0.):
         self.real = real
         ret = builder.build()
 
         lltype.free(value, flavor="raw")
-
         return ret
 
+
 class W_GenericBox(W_Root):
-    _attrs_ = ()
+    _attrs_ = []
 
     def descr__new__(space, w_subtype, __args__):
         raise operationerrfmt(space.w_TypeError,
     def get_dtype(self, space):
         return self._get_dtype(space)
 
+    def item(self, space):
+        return self.get_dtype(space).itemtype.to_builtin_type(space, self)
+
     def descr_str(self, space):
         return space.wrap(self.get_dtype(space).itemtype.str_format(self))
 
     def descr_format(self, space, w_spec):
         return space.format(self.item(space), w_spec)
 
+    def descr_hash(self, space):
+        return space.hash(self.item(space))
+
+    def descr_index(self, space):
+        return space.index(self.item(space))
+
     def descr_int(self, space):
         box = self.convert_to(W_LongBox._get_dtype(space))
         assert isinstance(box, W_LongBox)
         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)
-
     def descr_any(self, space):
         value = space.is_true(self)
         return self.get_dtype(space).box(value)
     descr__new__, _get_dtype, descr_reduce = new_dtype_getter("bool")
 
 class W_NumberBox(W_GenericBox):
-    _attrs_ = ()
+    pass
 
 class W_IntegerBox(W_NumberBox):
     def int_w(self, space):
     descr__new__, _get_dtype, descr_reduce = new_dtype_getter('ulonglong')
 
 class W_InexactBox(W_NumberBox):
-    _attrs_ = ()
+    pass
 
 class W_FloatingBox(W_InexactBox):
-    _attrs_ = ()
+    pass
 
 class W_Float16Box(W_FloatingBox, PrimitiveBox):
     descr__new__, _get_dtype, descr_reduce = new_dtype_getter("float16")
 class W_Float64Box(W_FloatingBox, PrimitiveBox):
     descr__new__, _get_dtype, descr_reduce = new_dtype_getter("float64")
 
+class W_ComplexFloatingBox(W_InexactBox):
+    def descr_get_real(self, space):
+        dtype = self._COMPONENTS_BOX._get_dtype(space)
+        box = self.convert_real_to(dtype)
+        assert isinstance(box, self._COMPONENTS_BOX)
+        return space.wrap(box)
+
+    def descr_get_imag(self, space):
+        dtype = self._COMPONENTS_BOX._get_dtype(space)
+        box = self.convert_imag_to(dtype)
+        assert isinstance(box, self._COMPONENTS_BOX)
+        return space.wrap(box)
+
+class W_Complex64Box(ComplexBox, W_ComplexFloatingBox):
+    descr__new__, _get_dtype, descr_reduce = new_dtype_getter("complex64")
+    _COMPONENTS_BOX = W_Float32Box
+
+class W_Complex128Box(ComplexBox, W_ComplexFloatingBox):
+    descr__new__, _get_dtype, descr_reduce = new_dtype_getter("complex128")
+    _COMPONENTS_BOX = W_Float64Box
+
+if long_double_size == 8:
+    W_FloatLongBox = W_Float64Box
+    W_ComplexLongBox = W_Complex128Box
+
+elif long_double_size in (12, 16):
+    class W_FloatLongBox(W_FloatingBox, PrimitiveBox):
+        descr__new__, _get_dtype, descr_reduce = new_dtype_getter("float%d" % (long_double_size * 8))
+
+    class W_ComplexLongBox(ComplexBox, W_ComplexFloatingBox):
+        descr__new__, _get_dtype, descr_reduce = new_dtype_getter("complex%d" % (long_double_size * 16))
+        _COMPONENTS_BOX = W_FloatLongBox
+
 class W_FlexibleBox(W_GenericBox):
-    _attrs_ = ['ofs', 'dtype', 'arr']
-    _immutable_fields_ = ['ofs']
+    _attrs_ = ['arr', 'ofs', 'dtype']
+    _immutable_fields_ = ['arr', 'ofs', 'dtype']
+
     def __init__(self, arr, ofs, dtype):
         self.arr = arr # we have to keep array alive
         self.ofs = ofs
     def get_dtype(self, space):
         return self.arr.dtype
 
-@unwrap_spec(self=W_GenericBox)
-def descr_index(space, self):
-    return space.index(self.item(space))
-
-
 class W_VoidBox(W_FlexibleBox):
     def descr_getitem(self, space, w_item):
         from pypy.module.micronumpy.types import VoidType
         # XXX assert dtype is str type
         return self
 
-
 class W_StringBox(W_CharacterBox):
     def descr__new__string_box(space, w_subtype, w_arg):
         from pypy.module.micronumpy.interp_dtype import new_string_dtype
             arr.storage[i] = arg[i]
         return W_StringBox(arr, 0, arr.dtype)
 
-
 class W_UnicodeBox(W_CharacterBox):
     def descr__new__unicode_box(space, w_subtype, w_arg):
         raise OperationError(space.w_NotImplementedError, space.wrap("Unicode is not supported yet"))
         #    arr.storage[i] = arg[i]
         return W_UnicodeBox(arr, 0, arr.dtype)
 
-
-class W_ComplexFloatingBox(W_InexactBox):
-    _attrs_ = ()
-    def descr_get_real(self, space):
-        dtype = self._COMPONENTS_BOX._get_dtype(space)
-        box = self.convert_real_to(dtype)
-        assert isinstance(box, self._COMPONENTS_BOX)
-        return space.wrap(box)
-
-    def descr_get_imag(self, space):
-        dtype = self._COMPONENTS_BOX._get_dtype(space)
-        box = self.convert_imag_to(dtype)
-        assert isinstance(box, self._COMPONENTS_BOX)
-        return space.wrap(box)
-
-
-class W_Complex64Box(ComplexBox, W_ComplexFloatingBox):
-    descr__new__, _get_dtype, descr_reduce = new_dtype_getter("complex64")
-    _COMPONENTS_BOX = W_Float32Box
-
-
-class W_Complex128Box(ComplexBox, W_ComplexFloatingBox):
-    descr__new__, _get_dtype, descr_reduce = new_dtype_getter("complex128")
-    _COMPONENTS_BOX = W_Float64Box
-
-
-if long_double_size == 8:
-    W_FloatLongBox = W_Float64Box
-    W_ComplexLongBox = W_Complex128Box
-
-elif long_double_size in (12, 16):
-    class W_FloatLongBox(W_FloatingBox, PrimitiveBox):
-        descr__new__, _get_dtype, descr_reduce = new_dtype_getter("float%d" % (long_double_size * 8))
-
-    class W_ComplexLongBox(ComplexBox, W_ComplexFloatingBox):
-        descr__new__, _get_dtype, descr_reduce = new_dtype_getter("complex%d" % (long_double_size * 16))
-        _COMPONENTS_BOX = W_FloatLongBox
-
-
 W_GenericBox.typedef = TypeDef("generic",
     __module__ = "numpypy",
 
 W_BoolBox.typedef = TypeDef("bool_", W_GenericBox.typedef,
     __module__ = "numpypy",
     __new__ = interp2app(W_BoolBox.descr__new__.im_func),
-    __index__ = interp2app(descr_index),
+    __index__ = interp2app(W_BoolBox.descr_index),
     __reduce__ = interp2app(W_BoolBox.descr_reduce),
 )
 
 W_Int8Box.typedef = TypeDef("int8", W_SignedIntegerBox.typedef,
     __module__ = "numpypy",
     __new__ = interp2app(W_Int8Box.descr__new__.im_func),
-    __index__ = interp2app(descr_index),
+    __index__ = interp2app(W_Int8Box.descr_index),
     __reduce__ = interp2app(W_Int8Box.descr_reduce),
 )
 
 W_UInt8Box.typedef = TypeDef("uint8", W_UnsignedIntegerBox.typedef,
     __module__ = "numpypy",
     __new__ = interp2app(W_UInt8Box.descr__new__.im_func),
-    __index__ = interp2app(descr_index),
+    __index__ = interp2app(W_UInt8Box.descr_index),
     __reduce__ = interp2app(W_UInt8Box.descr_reduce),
 )
 
 W_Int16Box.typedef = TypeDef("int16", W_SignedIntegerBox.typedef,
     __module__ = "numpypy",
     __new__ = interp2app(W_Int16Box.descr__new__.im_func),
-    __index__ = interp2app(descr_index),
+    __index__ = interp2app(W_Int16Box.descr_index),
     __reduce__ = interp2app(W_Int16Box.descr_reduce),
 )
 
 W_UInt16Box.typedef = TypeDef("uint16", W_UnsignedIntegerBox.typedef,
     __module__ = "numpypy",
     __new__ = interp2app(W_UInt16Box.descr__new__.im_func),
-    __index__ = interp2app(descr_index),
+    __index__ = interp2app(W_UInt16Box.descr_index),
     __reduce__ = interp2app(W_UInt16Box.descr_reduce),
 )
 
 W_Int32Box.typedef = TypeDef("int32", (W_SignedIntegerBox.typedef,) + MIXIN_32,
     __module__ = "numpypy",
     __new__ = interp2app(W_Int32Box.descr__new__.im_func),
-    __index__ = interp2app(descr_index),
+    __index__ = interp2app(W_Int32Box.descr_index),
     __reduce__ = interp2app(W_Int32Box.descr_reduce),
 )
 
 W_UInt32Box.typedef = TypeDef("uint32", W_UnsignedIntegerBox.typedef,
     __module__ = "numpypy",
     __new__ = interp2app(W_UInt32Box.descr__new__.im_func),
-    __index__ = interp2app(descr_index),
+    __index__ = interp2app(W_UInt32Box.descr_index),
     __reduce__ = interp2app(W_UInt32Box.descr_reduce),
 )
 
 W_Int64Box.typedef = TypeDef("int64", (W_SignedIntegerBox.typedef,) + MIXIN_64,
     __module__ = "numpypy",
     __new__ = interp2app(W_Int64Box.descr__new__.im_func),
-    __index__ = interp2app(descr_index),
+    __index__ = interp2app(W_Int64Box.descr_index),
     __reduce__ = interp2app(W_Int64Box.descr_reduce),
 )
 
 W_UInt64Box.typedef = TypeDef("uint64", W_UnsignedIntegerBox.typedef,
     __module__ = "numpypy",
     __new__ = interp2app(W_UInt64Box.descr__new__.im_func),
-    __index__ = interp2app(descr_index),
+    __index__ = interp2app(W_UInt64Box.descr_index),
     __reduce__ = interp2app(W_UInt64Box.descr_reduce),
 )
 

File pypy/module/micronumpy/interp_dtype.py

View file
-
 import sys
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter.error import OperationError, operationerrfmt
 from rpython.rtyper.lltypesystem import rffi
 from rpython.rlib import jit
 
+if sys.byteorder == 'little':
+    byteorder_prefix = '<'
+    nonnative_byteorder_prefix = '>'
+else:
+    byteorder_prefix = '>'
+    nonnative_byteorder_prefix = '<'
 
 UNSIGNEDLTR = "u"
 SIGNEDLTR = "i"
     out = base.W_NDimArray.from_shape(space, shape, dtype)
     return out
 
-
 class W_Dtype(W_Root):
     _immutable_fields_ = ["itemtype", "num", "kind", "shape"]
 
     def __init__(self, itemtype, num, kind, name, char, w_box_type,
-                 alternate_constructors=[], aliases=[],
+                 alternate_constructors=[], aliases=[], float_type=None,
                  fields=None, fieldnames=None, native=True, shape=[], subdtype=None):
         self.itemtype = itemtype
         self.num = num
         self.w_box_type = w_box_type
         self.alternate_constructors = alternate_constructors
         self.aliases = aliases
+        self.float_type = float_type
         self.fields = fields
         self.fieldnames = fieldnames
         self.native = native
-        self.float_type = None
         self.shape = list(shape)
         self.subdtype = subdtype
         if not subdtype:
 
     def build_and_convert(self, space, box):
         return self.itemtype.build_and_convert(space, self, box)
+
     def coerce(self, space, w_item):
         return self.itemtype.coerce(space, self, w_item)
 
 
     def eq(self, space, w_other):
         w_other = space.call_function(space.gettypefor(W_Dtype), w_other)
-        return space.is_w(self, w_other)
+        if space.is_w(self, w_other):
+            return True
+        if isinstance(w_other, W_Dtype):
+            return space.eq_w(self.descr_reduce(space), w_other.descr_reduce(space))
+        return False
 
     def descr_eq(self, space, w_other):
         return space.wrap(self.eq(space, w_other))
         return self.kind == SIGNEDLTR
 
     def is_complex_type(self):
-        return False
+        return self.kind == COMPLEXLTR
 
     def is_float_type(self):
         return (self.kind == FLOATINGLTR or self.float_type is not None)
         fields = space.getitem(w_data, space.wrap(4))
         self.set_fields(space, fields)
 
-class W_ComplexDtype(W_Dtype):
-    def __init__(self, itemtype, num, kind, name, char, w_box_type,
-                 alternate_constructors=[], aliases=[],
-                 fields=None, fieldnames=None, native=True, float_type=None):
-        W_Dtype.__init__(self, itemtype, num, kind, name, char, w_box_type,
-                 alternate_constructors=alternate_constructors, aliases=aliases,
-                 fields=fields, fieldnames=fieldnames, native=native)
-        self.float_type = float_type
-
-    def is_complex_type(self):
-        return True
-
 def dtype_from_list(space, w_lst):
     lst_w = space.listview(w_lst)
     fields = {}
     raise OperationError(space.w_NotImplementedError, space.wrap(
         "dtype from dict"))
 
-def variable_dtype(space, name):
-    if name[0] in '<>=':
-        name = name[1:]
-    char = name[0]
-    if len(name) == 1:
-        size = 0
-    else:
-        try:
-            size = int(name[1:])
-        except ValueError:
-            raise OperationError(space.w_TypeError, space.wrap("data type not understood"))
-    if char == 'S' or char == 'c':
-        itemtype = types.StringType(size)
-        basename = 'string'
-        num = 18
-        w_box_type = space.gettypefor(interp_boxes.W_StringBox)
-    elif char == 'V':
-        num = 20
-        basename = 'void'
-        itemtype = types.VoidType(size)
-        return W_Dtype(itemtype, 20, VOIDLTR, "void" + str(size),
-                    "V", space.gettypefor(interp_boxes.W_VoidBox))
-    else:
-        assert char == 'U'
-        basename = 'unicode'
-        itemtype = types.UnicodeType(size)
-        num = 19
-        w_box_type = space.gettypefor(interp_boxes.W_UnicodeBox)
-    return W_Dtype(itemtype, num, char,
-                   basename + str(8 * itemtype.get_element_size()),
-                   char, w_box_type)
-
 def dtype_from_spec(space, name):
         raise OperationError(space.w_NotImplementedError, space.wrap(
             "dtype from spec"))
 )
 W_Dtype.typedef.acceptable_as_base_class = False
 
-if sys.byteorder == 'little':
-    byteorder_prefix = '<'
-    nonnative_byteorder_prefix = '>'
-else:
-    byteorder_prefix = '>'
-    nonnative_byteorder_prefix = '<'
+
+def variable_dtype(space, name):
+    if name[0] in '<>=':
+        name = name[1:]
+    char = name[0]
+    if len(name) == 1:
+        size = 0
+    else:
+        try:
+            size = int(name[1:])
+        except ValueError:
+            raise OperationError(space.w_TypeError, space.wrap("data type not understood"))
+    if char == 'c':
+        char = 'S'
+        size = 1
+    if char == 'S':
+        itemtype = types.StringType(size)
+        basename = 'string'
+        num = 18
+        w_box_type = space.gettypefor(interp_boxes.W_StringBox)
+    elif char == 'V':
+        num = 20
+        basename = 'void'
+        itemtype = types.VoidType(size)
+        return W_Dtype(itemtype, 20, VOIDLTR, "void" + str(size),
+                    "V", space.gettypefor(interp_boxes.W_VoidBox))
+    else:
+        assert char == 'U'
+        basename = 'unicode'
+        itemtype = types.UnicodeType(size)
+        num = 19
+        w_box_type = space.gettypefor(interp_boxes.W_UnicodeBox)
+    return W_Dtype(itemtype, num, char,
+                   basename + str(8 * itemtype.get_element_size()),
+                   char, w_box_type)
 
 def new_string_dtype(space, size):
+    itemtype = types.StringType(size)
     return W_Dtype(
-        types.StringType(size),
+        itemtype,
         num=18,
         kind=STRINGLTR,
-        name='string',
-        char='S' + str(size),
+        name='string' + str(8 * itemtype.get_element_size()),
+        char='S',
         w_box_type = space.gettypefor(interp_boxes.W_StringBox),
     )
 
 def new_unicode_dtype(space, size):
+    itemtype = types.UnicodeType(size)
     return W_Dtype(
-        types.UnicodeType(size),
+        itemtype,
         num=19,
         kind=UNICODELTR,
-        name='unicode',
-        char='U' + str(size),
+        name='unicode' + str(8 * itemtype.get_element_size()),
+        char='U',
         w_box_type = space.gettypefor(interp_boxes.W_UnicodeBox),
     )
 
             w_box_type=space.gettypefor(interp_boxes.W_FloatLongBox),
             aliases=["longdouble", "longfloat"],
         )
-        self.w_complex64dtype = W_ComplexDtype(
+        self.w_complex64dtype = W_Dtype(
             types.Complex64(),
             num=14,
             kind=COMPLEXLTR,
             w_box_type = space.gettypefor(interp_boxes.W_Complex64Box),
             float_type = self.w_float32dtype,
         )
-        self.w_complex128dtype = W_ComplexDtype(
+        self.w_complex128dtype = W_Dtype(
             types.Complex128(),
             num=15,
             kind=COMPLEXLTR,
             aliases=["complex"],
             float_type = self.w_float64dtype,
         )
-        self.w_complexlongdtype = W_ComplexDtype(
+        self.w_complexlongdtype = W_Dtype(
             types.ComplexLong(),
             num=16,
             kind=COMPLEXLTR,

File pypy/module/micronumpy/interp_ufuncs.py

View file
 
 
 class W_Ufunc(W_Root):
-    _attrs_ = ["name", "promote_to_float", "promote_bools", "identity",
-               "allow_bool", "allow_complex", "complex_to_float"]
-    _immutable_fields_ = ["promote_to_float", "promote_bools", "name",
-            "allow_bool", "allow_complex", "complex_to_float"]
+    _immutable_fields_ = ["name", "promote_to_float", "promote_bools", "identity",
+            "int_only", "allow_bool", "allow_complex", "complex_to_float"]
 
     def __init__(self, name, promote_to_float, promote_bools, identity,
                  int_only, allow_bool, allow_complex, complex_to_float):
         return res
 
 class W_Ufunc1(W_Ufunc):
+    _immutable_fields_ = ["func", "bool_result"]
     argcount = 1
 
-    _immutable_fields_ = ["func", "name"]
-
     def __init__(self, func, name, promote_to_float=False, promote_bools=False,
-        identity=None, bool_result=False, int_only=False,
-        allow_bool=True, allow_complex=True, complex_to_float=False):
-
+            identity=None, bool_result=False, int_only=False,
+            allow_bool=True, allow_complex=True, complex_to_float=False):
         W_Ufunc.__init__(self, name, promote_to_float, promote_bools, identity,
                          int_only, allow_bool, allow_complex, complex_to_float)
         self.func = func
 
 
 class W_Ufunc2(W_Ufunc):
-    _immutable_fields_ = ["comparison_func", "func", "name", "int_only"]
+    _immutable_fields_ = ["func", "comparison_func", "done_func"]
     argcount = 2
 
     def __init__(self, func, name, promote_to_float=False, promote_bools=False,
-        identity=None, comparison_func=False, int_only=False,
-        allow_bool=True, allow_complex=True, complex_to_float=False):
-
+            identity=None, comparison_func=False, int_only=False,
+            allow_bool=True, allow_complex=True, complex_to_float=False):
         W_Ufunc.__init__(self, name, promote_to_float, promote_bools, identity,
                          int_only, allow_bool, allow_complex, complex_to_float)
         self.func = func

File pypy/module/micronumpy/test/test_complex.py

View file
 from rpython.rlib.rcomplex import c_pow
 
 
-def rAlmostEqual(a, b, rel_err=2e-15, abs_err=5e-323, msg='', isnumpy=False):
+def rAlmostEqual(a, b, rel_err=2e-15, abs_err=5e-323, msg=''):
     """Fail if the two floating-point numbers are not almost equal.
 
     Determine whether floating-point values a and b are equal to within
     # (in theory there are examples where it would be legitimate for a
     # and b to have opposite signs; in practice these hardly ever
     # occur).
-    if not a and not b and not isnumpy:
+    if not a and not b:
         # only check it if we are running on top of CPython >= 2.6
         if sys.version_info >= (2, 6) and copysign(1., a) != copysign(1., b):
             raise AssertionError( msg + \
                     (k, space.unwrap(v))
                     for k, v in kwargs.iteritems()
                 ])
-                if '__pypy__' not in sys.builtin_module_names:
-                    kwargs['isnumpy'] = True
                 return space.wrap(rAlmostEqual(*args, **kwargs))
             cls.w_rAlmostEqual = cls.space.wrap(interp2app(cls_rAlmostEqual))
             def cls_c_pow(space, args_w):
         import numpypy as np
         rAlmostEqual = self.rAlmostEqual
 
-        for complex_, abs_err, testcases in (\
-                 (np.complex128, 5e-323, self.testcases128),
-                 # (np.complex64,  5e-32,  self.testcases64),
+        for complex_, testcases in (
+                 (np.complex128, self.testcases128),
+                 #(np.complex64, self.testcases64),
                 ):
             for id, fn, ar, ai, er, ei, flags in testcases:
                 arg = complex_(complex(ar, ai))
                 if fn in ('log', 'log10'):
                     real_abs_err = 2e-15
                 else:
-                    real_abs_err = abs_err
+                    real_abs_err = 5e-323
 
                 error_message = (
                     '%s: %s(%r(%r, %r))\n'
                 # since rAlmostEqual is a wrapped function,
                 # convert arguments to avoid boxed values
                 rAlmostEqual(float(expected[0]), float(actual[0]),
-                               abs_err=real_abs_err, msg=error_message)
+                             abs_err=real_abs_err, msg=error_message)
                 rAlmostEqual(float(expected[1]), float(actual[1]),
-                                   msg=error_message)
+                             msg=error_message)
                 sys.stderr.write('.')
             sys.stderr.write('\n')
 

File pypy/module/micronumpy/test/test_dtypes.py

View file
         from numpypy import dtype
         nnp = self.non_native_prefix
         byteorder = self.native_prefix
-        assert dtype('i8') == dtype(byteorder + 'i8') == dtype('=i8') # XXX should be equal == dtype(long)
+        assert dtype('i8') == dtype(byteorder + 'i8') == dtype('=i8') == dtype(long)
         assert dtype(nnp + 'i8') != dtype('i8')
         assert dtype(nnp + 'i8').byteorder == nnp
         assert dtype('=i8').byteorder == '='
         assert d.type is str_
         assert d.name == "string64"
         assert d.num == 18
+        for i in [1, 2, 3]:
+            d = dtype('c%d' % i)
+            assert d.itemsize == 1
+            assert d.kind == 'S'
+            assert d.type is str_
+            assert d.name == 'string8'
+            assert d.num == 18
+            assert d.str == '|S1'
 
     def test_unicode_dtype(self):
         from numpypy import dtype, unicode_

File pypy/module/micronumpy/test/test_numarray.py

View file
         assert a.max() == 5.7
         b = array([])
         raises(ValueError, "b.max()")
-
-        if 0: # XXX too pedantic
-            assert list(zeros((0, 2)).max(axis=1)) == []
+        assert list(zeros((0, 2)).max(axis=1)) == []
 
     def test_max_add(self):
         from numpypy import array
         assert a.min() == -3.0
         b = array([])
         raises(ValueError, "b.min()")
-
-        if 0: # XXX too pedantic
-            assert list(zeros((0, 2)).min(axis=1)) == []
+        assert list(zeros((0, 2)).min(axis=1)) == []
 
     def test_argmax(self):
         from numpypy import array
         exc = raises(TypeError, concatenate,
                             (zeros((2,), dtype=[('x', int), ('y', float)]),
                             (zeros((2,), dtype=[('x', float), ('y', float)]))))
-        assert str(exc.value).startswith('record type mismatch')
+        assert str(exc.value).startswith('invalid type promotion')
         exc = raises(TypeError, concatenate, ([1], zeros((2,),
                                             dtype=[('x', int), ('y', float)])))
         assert str(exc.value).startswith('invalid type promotion')

File pypy/module/micronumpy/test/test_sorting.py

View file
 from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest
 
-class AppTestSupport(BaseNumpyAppTest):
-    def setup_class(cls):
-        import struct
-        BaseNumpyAppTest.setup_class.im_func(cls)
-        cls.w_data = cls.space.wrap(struct.pack('dddd', 1, 2, 3, 4))
-        cls.w_fdata = cls.space.wrap(struct.pack('f', 2.3))
-        cls.w_float16val = cls.space.wrap('\x00E') # 5.0 in float16
-        cls.w_float32val = cls.space.wrap(struct.pack('f', 5.2))
-        cls.w_float64val = cls.space.wrap(struct.pack('d', 300.4))
-        cls.w_ulongval = cls.space.wrap(struct.pack('L', 12))
-
+class AppTestSorting(BaseNumpyAppTest):
     def test_argsort_dtypes(self):
         from numpypy import array, arange
         assert array(2.0).argsort() == 0
         nnp = self.non_native_prefix
         for dtype in ['int', 'float', 'int16', 'float32', 'uint64',
-                        nnp + 'i2', complex]:
+                      nnp + 'i2', complex]:
             a = array([6, 4, -1, 3, 8, 3, 256+20, 100, 101], dtype=dtype)
+            exp = list(a)
+            exp = sorted(range(len(exp)), key=exp.__getitem__)
             c = a.copy()
             res = a.argsort()
-            assert (res == [2, 3, 5, 1, 0, 4, 7, 8, 6]).all(), \
+            assert (res == exp).all(), \
                 'a,res,dtype %r,%r,%r' % (a,res,dtype)
             assert (a == c).all() # not modified
-            a = arange(100)
+
+            a = arange(100, dtype=dtype)
             assert (a.argsort() == a).all()
         raises(NotImplementedError, 'arange(10,dtype="float16").argsort()')
 
-    def test_argsort_nd(self):
+    def test_argsort_ndim(self):
         from numpypy import array
         a = array([[4, 2], [1, 3]])
         assert (a.argsort() == [[1, 0], [0, 1]]).all()
     def test_sort_dtypes(self):
         from numpypy import array, arange
         for dtype in ['int', 'float', 'int16', 'float32', 'uint64',
-                        'i2', complex]:
+                      'i2', complex]:
             a = array([6, 4, -1, 3, 8, 3, 256+20, 100, 101], dtype=dtype)
-            b = array([-1, 3, 3, 4, 6, 8, 100, 101, 256+20], dtype=dtype)
+            b = sorted(list(a))
             c = a.copy()
             a.sort()
             assert (a == b).all(), \
                 'a,orig,dtype %r,%r,%r' % (a,c,dtype)
-        a = arange(100)
-        c = a.copy()
-        a.sort()
-        assert (a == c).all()
 
-    def test_sort_dtypesi_nonnative(self):
+            a = arange(100, dtype=dtype)
+            c = a.copy()
+            a.sort()
+            assert (a == c).all()
+
+    def test_sort_nonnative(self):
         from numpypy import array
         nnp = self.non_native_prefix
         for dtype in [ nnp + 'i2']:
         assert [isnan(bb) for bb in b] == [isnan(aa) for aa in a[::-1]]
         assert (b[:2] == a[::-1][:2]).all()
 
+        b = a.argsort()
+        assert (b == [2, 1, 0]).all()
+
         # check complex
         a = zeros(9, dtype=complex128)
         a.real += [nan, nan, nan, 1, 0, 1, 1, 0, 0]
         assert [isnan(bb) for bb in b] == [isnan(aa) for aa in a[::-1]]
         assert (b[:4] == a[::-1][:4]).all()
 
+        b = a.argsort()
+        assert (b == [8, 7, 6, 5, 4, 3, 2, 1, 0]).all()
+
         # all c scalar sorts use the same code with different types
         # so it suffices to run a quick check with one type. The number
         # of sorted items must be greater than ~50 to check the actual

File pypy/module/micronumpy/test/test_ufuncs.py

View file
         for i in range(4):
             assert b[i] == reference[i]
 
-        for dtype in ['int8', 'int16', 'int32', 'int64',
-                      'uint8', 'uint16', 'uint32', 'uint64']:
+        for dtype in 'bBhHiIlLqQ':
+            a = array([-2, -1, 0, 1, 2], dtype)
             reference = [0, -1, 0, 1, 0]
+            dtype = a.dtype.name
             if dtype[0] == 'u':
                 reference[1] = 0
             elif dtype == 'int32':
                     reference[2] = -2147483648
             elif dtype == 'int64':
                     reference[2] = -9223372036854775808
-            a = array([-2, -1, 0, 1, 2], dtype)
             b = reciprocal(a)
             assert (b == reference).all()
 

File pypy/module/micronumpy/types.py

View file
         )
     return dispatcher
 
-
 def raw_unary_op(func):
     specialize.argtype(1)(func)
     @functools.wraps(func)
     return dispatcher
 
 class BaseType(object):
-    _attrs_ = ()
-
     SortRepr = None # placeholders for sorting classes, overloaded in sort.py
     Sort = None
 
         raw_storage_setitem(storage, i + offset, value)
 
 class Bool(BaseType, Primitive):
-    _attrs_ = ()
-
     T = lltype.Bool
     BoxType = interp_boxes.W_BoolBox
     format_code = "?"
         ans = 0
         if raw == 0:
             # XXX good place to warn
-            if self.T is rffi.INT or self.T is rffi.LONG:
+            if self.T is rffi.INT or self.T is rffi.LONG or self.T is rffi.LONGLONG:
                 ans = most_neg_value_of(self.T)
         elif abs(raw) == 1:
             ans = raw
     _mixin_ = True
 
 class Int8(BaseType, Integer):
-    _attrs_ = ()
-
     T = rffi.SIGNEDCHAR
     BoxType = interp_boxes.W_Int8Box
     format_code = "b"
+
 NonNativeInt8 = Int8
 
 class UInt8(BaseType, Integer):
-    _attrs_ = ()
-
     T = rffi.UCHAR
     BoxType = interp_boxes.W_UInt8Box
     format_code = "B"
+
 NonNativeUInt8 = UInt8
 
 class Int16(BaseType, Integer):
-    _attrs_ = ()
-
     T = rffi.SHORT
     BoxType = interp_boxes.W_Int16Box
     format_code = "h"
 
 class NonNativeInt16(BaseType, NonNativeInteger):
-    _attrs_ = ()
-
     T = rffi.SHORT
     BoxType = interp_boxes.W_Int16Box
     format_code = "h"
 
 class UInt16(BaseType, Integer):
-    _attrs_ = ()
-
     T = rffi.USHORT
     BoxType = interp_boxes.W_UInt16Box
     format_code = "H"
 
 class NonNativeUInt16(BaseType, NonNativeInteger):
-    _attrs_ = ()
-
     T = rffi.USHORT
     BoxType = interp_boxes.W_UInt16Box
     format_code = "H"
 
 class Int32(BaseType, Integer):
-    _attrs_ = ()
-
     T = rffi.INT
     BoxType = interp_boxes.W_Int32Box
     format_code = "i"
 
 class NonNativeInt32(BaseType, NonNativeInteger):
-    _attrs_ = ()
-
     T = rffi.INT
     BoxType = interp_boxes.W_Int32Box
     format_code = "i"
 
 class UInt32(BaseType, Integer):
-    _attrs_ = ()
-
     T = rffi.UINT
     BoxType = interp_boxes.W_UInt32Box
     format_code = "I"
 
 class NonNativeUInt32(BaseType, NonNativeInteger):
-    _attrs_ = ()
-
     T = rffi.UINT
     BoxType = interp_boxes.W_UInt32Box
     format_code = "I"
 
 class Long(BaseType, Integer):
-    _attrs_ = ()
-
     T = rffi.LONG
     BoxType = interp_boxes.W_LongBox
     format_code = "l"
 
 class NonNativeLong(BaseType, NonNativeInteger):
-    _attrs_ = ()
-
     T = rffi.LONG
     BoxType = interp_boxes.W_LongBox
     format_code = "l"
 
 class ULong(BaseType, Integer):
-    _attrs_ = ()
-
     T = rffi.ULONG
     BoxType = interp_boxes.W_ULongBox
     format_code = "L"
 
 class NonNativeULong(BaseType, NonNativeInteger):
-    _attrs_ = ()
-
     T = rffi.ULONG
     BoxType = interp_boxes.W_ULongBox
     format_code = "L"
     return self.box(value)
 
 class Int64(BaseType, Integer):
-    _attrs_ = ()
-
     T = rffi.LONGLONG
     BoxType = interp_boxes.W_Int64Box
     format_code = "q"
     _coerce = func_with_new_name(_int64_coerce, '_coerce')
 
 class NonNativeInt64(BaseType, NonNativeInteger):
-    _attrs_ = ()
-
     T = rffi.LONGLONG
     BoxType = interp_boxes.W_Int64Box
     format_code = "q"
     return self.box(value)
 
 class UInt64(BaseType, Integer):
-    _attrs_ = ()
-
     T = rffi.ULONGLONG
     BoxType = interp_boxes.W_UInt64Box
     format_code = "Q"
     _coerce = func_with_new_name(_uint64_coerce, '_coerce')
 
 class NonNativeUInt64(BaseType, NonNativeInteger):
-    _attrs_ = ()
-
     T = rffi.ULONGLONG
     BoxType = interp_boxes.W_UInt64Box
     format_code = "Q"
         swapped_value = byteswap(rffi.cast(self.T, value))
         raw_storage_setitem(storage, i + offset, swapped_value)
 
+class BaseFloat16(Float):
+    _mixin_ = True
+
+    _STORAGE_T = rffi.USHORT
+    T = rffi.SHORT
+    BoxType = interp_boxes.W_Float16Box
+
+    @specialize.argtype(1)
+    def box(self, value):
+        return self.BoxType(rffi.cast(rffi.DOUBLE, value))
+
+    def runpack_str(self, s):
+        assert len(s) == 2
+        fval = unpack_float(s, native_is_bigendian)
+        return self.box(fval)
+
+    def default_fromstring(self, space):
+        return self.box(-1.0)
+
+    def byteswap(self, w_v):
+        value = self.unbox(w_v)
+        hbits = float_pack(value,2)
+        swapped = byteswap(rffi.cast(self._STORAGE_T, hbits))
+        return self.box(float_unpack(r_ulonglong(swapped), 2))
+
+class Float16(BaseType, BaseFloat16):
+    def _read(self, storage, i, offset):
+        hbits = raw_storage_getitem(self._STORAGE_T, storage, i + offset)
+        return float_unpack(r_ulonglong(hbits), 2)
+
+    def _write(self, storage, i, offset, value):
+        hbits = float_pack(value,2)
+        raw_storage_setitem(storage, i + offset,
+                rffi.cast(self._STORAGE_T, hbits))
+
+class NonNativeFloat16(BaseType, BaseFloat16):
+    def _read(self, storage, i, offset):
+        hbits = raw_storage_getitem(self._STORAGE_T, storage, i + offset)
+        return float_unpack(r_ulonglong(byteswap(hbits)), 2)
+
+    def _write(self, storage, i, offset, value):
+        hbits = float_pack(value,2)
+        raw_storage_setitem(storage, i + offset,
+                byteswap(rffi.cast(self._STORAGE_T, hbits)))
+
 class Float32(BaseType, Float):
-    _attrs_ = ()
-
     T = rffi.FLOAT
     BoxType = interp_boxes.W_Float32Box
     format_code = "f"
 
 class NonNativeFloat32(BaseType, NonNativeFloat):
-    _attrs_ = ()
-
     T = rffi.FLOAT
     BoxType = interp_boxes.W_Float32Box
     format_code = "f"
         return bool(v)
 
 class Float64(BaseType, Float):
-    _attrs_ = ()
-
     T = rffi.DOUBLE
     BoxType = interp_boxes.W_Float64Box
     format_code = "d"
 
 class NonNativeFloat64(BaseType, NonNativeFloat):
-    _attrs_ = ()
-
     T = rffi.DOUBLE
     BoxType = interp_boxes.W_Float64Box
     format_code = "d"
 
 class ComplexFloating(object):
     _mixin_ = True
-    _attrs_ = ()
 
     def _coerce(self, space, w_item):
         w_item = space.call_function(space.w_complex, w_item)
         real, imag = box.real, box.imag
         return real, imag
 
-    def store(self, arr, i, offset, box):
-        real, imag = self.unbox(box)
-        raw_storage_setitem(arr.storage, i+offset, real)
-        raw_storage_setitem(arr.storage,
-                i+offset+rffi.sizeof(self.T), imag)
-
     def _read(self, storage, i, offset):
         real = raw_storage_getitem(self.T, storage, i + offset)
-        imag = raw_storage_getitem(self.T, storage,
-                              i + offset + rffi.sizeof(self.T))
+        imag = raw_storage_getitem(self.T, storage, i + offset + rffi.sizeof(self.T))
         return real, imag
 
     def read(self, arr, i, offset, dtype=None):
         real, imag = self._read(arr.storage, i, offset)
         return self.box_complex(real, imag)
 
+    def _write(self, storage, i, offset, value):
+        raw_storage_setitem(storage, i + offset, value[0])
+        raw_storage_setitem(storage, i + offset + rffi.sizeof(self.T), value[1])
+
+    def store(self, arr, i, offset, box):
+        self._write(arr.storage, i, offset, self.unbox(box))
+