[pypy-commit] pypy unicode-strategies: hg merge default

antocuni noreply at buildbot.pypy.org
Wed Oct 31 16:53:06 CET 2012


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: unicode-strategies
Changeset: r58643:8e1d2da10583
Date: 2012-10-31 16:52 +0100
http://bitbucket.org/pypy/pypy/changeset/8e1d2da10583/

Log:	hg merge default

diff too long, truncating to 2000 out of 2638 lines

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/lib_pypy/pyrepl/readline.py b/lib_pypy/pyrepl/readline.py
--- a/lib_pypy/pyrepl/readline.py
+++ b/lib_pypy/pyrepl/readline.py
@@ -233,7 +233,7 @@
         try:
             return unicode(line, ENCODING)
         except UnicodeDecodeError:   # bah, silently fall back...
-            return unicode(line, 'utf-8')
+            return unicode(line, 'utf-8', 'replace')
 
     def get_history_length(self):
         return self.saved_history_length
diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py
--- a/lib_pypy/pyrepl/unix_console.py
+++ b/lib_pypy/pyrepl/unix_console.py
@@ -496,7 +496,7 @@
             if iscode:
                 self.__tputs(text)
             else:
-                os.write(self.output_fd, text.encode(self.encoding))
+                os.write(self.output_fd, text.encode(self.encoding, 'replace'))
         del self.__buffer[:]
 
     def __tputs(self, fmt, prog=delayprog):
diff --git a/py/_code/source.py b/py/_code/source.py
--- a/py/_code/source.py
+++ b/py/_code/source.py
@@ -118,7 +118,7 @@
         # 1. find the start of the statement
         from codeop import compile_command
         end = None
-        for start in range(lineno, -1, max(-1, lineno - 10)):
+        for start in range(lineno, -1, -1):
             if assertion:
                 line = self.lines[start]
                 # the following lines are not fully tested, change with care
@@ -135,9 +135,9 @@
                 compile_command(trysource)
             except (SyntaxError, OverflowError, ValueError):
                 continue
- 
+
             # 2. find the end of the statement
-            for end in range(lineno+1, min(len(self)+1, lineno + 10)):
+            for end in range(lineno+1, len(self)+1):
                 trysource = self[start:end]
                 if trysource.isparseable():
                     return start, end
diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py
--- a/pypy/annotation/annrpython.py
+++ b/pypy/annotation/annrpython.py
@@ -548,7 +548,7 @@
                         if cell.is_constant():
                             newcell.const = cell.const
                         cell = newcell
-                        cell.knowntypedata = renamed_knowntypedata
+                        cell.set_knowntypedata(renamed_knowntypedata)
 
                     cells.append(cell)
 
diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py
--- a/pypy/annotation/binaryop.py
+++ b/pypy/annotation/binaryop.py
@@ -144,7 +144,7 @@
         # XXX HACK HACK HACK
         bk = getbookkeeper()
         if bk is not None: # for testing
-            knowntypedata = r.knowntypedata = {}
+            knowntypedata = {}
             fn, block, i = bk.position_key
 
             annotator = bk.annotator
@@ -168,6 +168,7 @@
 
             bind(obj2, obj1, 0)
             bind(obj1, obj2, 1)
+            r.set_knowntypedata(knowntypedata)
 
         return r
 
@@ -337,8 +338,7 @@
             case = opname in ('gt', 'ge', 'eq')
             add_knowntypedata(knowntypedata, case, [op.args[0]],
                               SomeInteger(nonneg=True, knowntype=tointtype(int1)))
-        if knowntypedata:
-            r.knowntypedata = knowntypedata
+        r.set_knowntypedata(knowntypedata)
         # a special case for 'x < 0' or 'x >= 0',
         # where 0 is a flow graph Constant
         # (in this case we are sure that it cannot become a r_uint later)
@@ -369,8 +369,7 @@
         if hasattr(boo1, 'knowntypedata') and \
            hasattr(boo2, 'knowntypedata'):
             ktd = merge_knowntypedata(boo1.knowntypedata, boo2.knowntypedata)
-            if ktd:
-                s.knowntypedata = ktd
+            s.set_knowntypedata(ktd)
         return s 
 
     def and_((boo1, boo2)):
diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py
--- a/pypy/annotation/builtin.py
+++ b/pypy/annotation/builtin.py
@@ -188,10 +188,10 @@
             variables = [op.args[1]]
         for variable in variables:
             assert bk.annotator.binding(variable) == s_obj
-        r.knowntypedata = {}
-        
+        knowntypedata = {}
         if not hasattr(typ, '_freeze_') and isinstance(s_type, SomePBC):
-            add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ))
+            add_knowntypedata(knowntypedata, True, variables, bk.valueoftype(typ))
+        r.set_knowntypedata(knowntypedata)
     return r
 
 # note that this one either needs to be constant, or we will create SomeObject
diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py
--- a/pypy/annotation/model.py
+++ b/pypy/annotation/model.py
@@ -195,6 +195,10 @@
     unsigned = False
     def __init__(self):
         pass
+    def set_knowntypedata(self, knowntypedata):
+        assert not hasattr(self, 'knowntypedata')
+        if knowntypedata:
+            self.knowntypedata = knowntypedata
 
 class SomeStringOrUnicode(SomeObject):
     immutable = True
diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py
--- a/pypy/annotation/unaryop.py
+++ b/pypy/annotation/unaryop.py
@@ -76,7 +76,7 @@
         s_obj.is_true_behavior(r)
 
         bk = getbookkeeper()
-        knowntypedata = r.knowntypedata = {}
+        knowntypedata = {}
         fn, block, i = bk.position_key
         op = block.operations[i]
         assert op.opname == "is_true" or op.opname == "nonzero"
@@ -86,8 +86,8 @@
         if s_obj.can_be_none():
             s_nonnone_obj = s_obj.nonnoneify()
         add_knowntypedata(knowntypedata, True, [arg], s_nonnone_obj)
+        r.set_knowntypedata(knowntypedata)
         return r
-        
 
     def nonzero(obj):
         return obj.is_true()
diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py
--- a/pypy/config/translationoption.py
+++ b/pypy/config/translationoption.py
@@ -118,7 +118,7 @@
                          ("translation.gcrootfinder", DEFL_ROOTFINDER_WITHJIT),
                          ("translation.list_comprehension_operations", True)]),
     ChoiceOption("jit_backend", "choose the backend for the JIT",
-                 ["auto", "x86", "x86-without-sse2", "llvm", 'arm'],
+                 ["auto", "x86", "x86-without-sse2", 'arm'],
                  default="auto", cmdline="--jit-backend"),
     ChoiceOption("jit_profiler", "integrate profiler support into the JIT",
                  ["off", "oprofile"],
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/interpreter/buffer.py b/pypy/interpreter/buffer.py
--- a/pypy/interpreter/buffer.py
+++ b/pypy/interpreter/buffer.py
@@ -74,8 +74,11 @@
         elif step == 1:
             length = stop - start
             if length != len(newstring):
-                msg = "buffer slice assignment is wrong size"
-                raise OperationError(space.w_ValueError, space.wrap(msg))
+                if length < 0 and len(newstring) == 0:
+                    pass     # ok anyway
+                else:
+                    msg = "right operand length must match slice length"
+                    raise OperationError(space.w_ValueError, space.wrap(msg))
             self.setslice(start, newstring)
         else:
             raise OperationError(space.w_ValueError,
diff --git a/pypy/jit/backend/detect_cpu.py b/pypy/jit/backend/detect_cpu.py
--- a/pypy/jit/backend/detect_cpu.py
+++ b/pypy/jit/backend/detect_cpu.py
@@ -77,8 +77,6 @@
         return "pypy.jit.backend.x86.runner", "CPU_X86_64"
     elif backend_name == 'cli':
         return "pypy.jit.backend.cli.runner", "CliCPU"
-    elif backend_name == 'llvm':
-        return "pypy.jit.backend.llvm.runner", "LLVMCPU"
     elif backend_name == 'arm':
         return "pypy.jit.backend.arm.runner", "CPU_ARM"
     elif backend_name == 'armhf':
diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py
--- a/pypy/jit/metainterp/optimizeopt/optimizer.py
+++ b/pypy/jit/metainterp/optimizeopt/optimizer.py
@@ -1,17 +1,17 @@
 from pypy.jit.metainterp import jitprof, resume, compile
 from pypy.jit.metainterp.executor import execute_nonspec
-from pypy.jit.metainterp.history import BoxInt, BoxFloat, Const, ConstInt, REF, INT
+from pypy.jit.metainterp.history import BoxInt, BoxFloat, Const, ConstInt, REF
 from pypy.jit.metainterp.optimizeopt.intutils import IntBound, IntUnbounded, \
                                                      ImmutableIntUnbounded, \
                                                      IntLowerBound, MININT, MAXINT
-from pypy.jit.metainterp.optimizeopt.util import (make_dispatcher_method,
-    args_dict)
+from pypy.jit.metainterp.optimizeopt.util import make_dispatcher_method
 from pypy.jit.metainterp.resoperation import rop, ResOperation, AbstractResOp
 from pypy.jit.metainterp.typesystem import llhelper, oohelper
 from pypy.tool.pairtype import extendabletype
-from pypy.rlib.debug import debug_start, debug_stop, debug_print
+from pypy.rlib.debug import debug_print
 from pypy.rlib.objectmodel import specialize
 
+
 LEVEL_UNKNOWN    = '\x00'
 LEVEL_NONNULL    = '\x01'
 LEVEL_KNOWNCLASS = '\x02'     # might also mean KNOWNARRAYDESCR, for arrays
@@ -20,6 +20,8 @@
 MODE_ARRAY   = '\x00'
 MODE_STR     = '\x01'
 MODE_UNICODE = '\x02'
+
+
 class LenBound(object):
     def __init__(self, mode, descr, bound):
         self.mode = mode
diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py
--- a/pypy/jit/metainterp/optimizeopt/rewrite.py
+++ b/pypy/jit/metainterp/optimizeopt/rewrite.py
@@ -1,8 +1,11 @@
 from pypy.jit.codewriter.effectinfo import EffectInfo
-from pypy.jit.metainterp.history import ConstInt, make_hashable_int
+from pypy.jit.metainterp import compile
+from pypy.jit.metainterp.history import (Const, ConstInt, BoxInt, BoxFloat,
+    BoxPtr, make_hashable_int)
 from pypy.jit.metainterp.optimize import InvalidLoop
 from pypy.jit.metainterp.optimizeopt.intutils import IntBound
-from pypy.jit.metainterp.optimizeopt.optimizer import *
+from pypy.jit.metainterp.optimizeopt.optimizer import (Optimization, REMOVED,
+    CONST_0, CONST_1)
 from pypy.jit.metainterp.optimizeopt.util import _findall, make_dispatcher_method
 from pypy.jit.metainterp.resoperation import (opboolinvers, opboolreflex, rop,
     ResOperation)
@@ -426,14 +429,33 @@
         source_start_box = self.get_constant_box(op.getarg(3))
         dest_start_box = self.get_constant_box(op.getarg(4))
         length = self.get_constant_box(op.getarg(5))
-        if (source_value.is_virtual() and source_start_box and dest_start_box
-            and length and (dest_value.is_virtual() or length.getint() <= 8)):
+        extrainfo = op.getdescr().get_extra_info()
+        if (source_start_box and dest_start_box
+            and length and (dest_value.is_virtual() or length.getint() <= 8) and
+            (source_value.is_virtual() or length.getint() <= 8) and
+            len(extrainfo.write_descrs_arrays) == 1):   # <-sanity check
             from pypy.jit.metainterp.optimizeopt.virtualize import VArrayValue
-            assert isinstance(source_value, VArrayValue)
             source_start = source_start_box.getint()
             dest_start = dest_start_box.getint()
+            # XXX fish fish fish
+            arraydescr = extrainfo.write_descrs_arrays[0]
             for index in range(length.getint()):
-                val = source_value.getitem(index + source_start)
+                if source_value.is_virtual():
+                    assert isinstance(source_value, VArrayValue)
+                    val = source_value.getitem(index + source_start)
+                else:
+                    if arraydescr.is_array_of_pointers():
+                        resbox = BoxPtr()
+                    elif arraydescr.is_array_of_floats():
+                        resbox = BoxFloat()
+                    else:
+                        resbox = BoxInt()
+                    newop = ResOperation(rop.GETARRAYITEM_GC,
+                                      [op.getarg(1),
+                                       ConstInt(index + source_start)], resbox,
+                                       descr=arraydescr)
+                    self.optimizer.propagate_forward(newop)
+                    val = self.getvalue(resbox)
                 if dest_value.is_virtual():
                     dest_value.setitem(index + dest_start, val)
                 else:
@@ -441,7 +463,7 @@
                                          [op.getarg(2),
                                           ConstInt(index + dest_start),
                                           val.get_key_box()], None,
-                                         descr=source_value.arraydescr)
+                                         descr=arraydescr)
                     self.emit_operation(newop)
             return True
         if length and length.getint() == 0:
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
@@ -3239,6 +3239,42 @@
         '''
         self.optimize_loop(ops, expected)
 
+    def test_arraycopy_not_virtual_2(self):
+        ops = '''
+        [p0]
+        p1 = new_array(3, descr=arraydescr)
+        call(0, p0, p1, 0, 0, 3, descr=arraycopydescr)
+        i0 = getarrayitem_gc(p1, 0, descr=arraydescr)
+        jump(i0)
+        '''
+        expected = '''
+        [p0]
+        i0 = getarrayitem_gc(p0, 0, descr=arraydescr)
+        i1 = getarrayitem_gc(p0, 1, descr=arraydescr) # removed by the backend
+        i2 = getarrayitem_gc(p0, 2, descr=arraydescr) # removed by the backend
+        jump(i0)
+        '''
+        self.optimize_loop(ops, expected)
+
+    def test_arraycopy_not_virtual_3(self):
+        ops = '''
+        [p0, p1]
+        call(0, p0, p1, 0, 0, 3, descr=arraycopydescr)
+        i0 = getarrayitem_gc(p1, 0, descr=arraydescr)
+        jump(i0)
+        '''
+        expected = '''
+        [p0, p1]
+        i0 = getarrayitem_gc(p0, 0, descr=arraydescr)
+        i1 = getarrayitem_gc(p0, 1, descr=arraydescr)
+        i2 = getarrayitem_gc(p0, 2, descr=arraydescr)
+        setarrayitem_gc(p1, 0, i0, descr=arraydescr)
+        setarrayitem_gc(p1, 1, i1, descr=arraydescr)
+        setarrayitem_gc(p1, 2, i2, descr=arraydescr)
+        jump(i0)
+        '''
+        self.optimize_loop(ops, expected)
+
     def test_arraycopy_no_elem(self):
         """ this was actually observed in the wild
         """
diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py
--- a/pypy/jit/metainterp/optimizeopt/unroll.py
+++ b/pypy/jit/metainterp/optimizeopt/unroll.py
@@ -4,6 +4,7 @@
 from pypy.jit.metainterp.history import TreeLoop, TargetToken, JitCellToken
 from pypy.jit.metainterp.jitexc import JitException
 from pypy.jit.metainterp.optimize import InvalidLoop
+from pypy.rlib.debug import debug_print, debug_start, debug_stop
 from pypy.jit.metainterp.optimizeopt.optimizer import *
 from pypy.jit.metainterp.optimizeopt.generalize import KillHugeIntBounds
 from pypy.jit.metainterp.inliner import Inliner
diff --git a/pypy/jit/metainterp/test/test_list.py b/pypy/jit/metainterp/test/test_list.py
--- a/pypy/jit/metainterp/test/test_list.py
+++ b/pypy/jit/metainterp/test/test_list.py
@@ -128,6 +128,17 @@
         res = self.interp_operations(f, [], listops=True)
         assert res == 10
 
+    def test_arraycopy_bug(self): 
+        def f():
+            l = [1, 2, 3, 4]
+            l2 = [1, 2, 3, 4]
+            l[2] = 13
+            l2[0:len(l2)] = l[:]
+            return l2[0] + l2[1] + l2[2] + l2[3]
+
+        res = self.interp_operations(f, [], listops=True)
+        assert res == f()
+
     def test_arraycopy_full(self):
         jitdriver = JitDriver(greens = [], reds = ['n'])
         def f(n):
diff --git a/pypy/module/__builtin__/test/test_buffer.py b/pypy/module/__builtin__/test/test_buffer.py
--- a/pypy/module/__builtin__/test/test_buffer.py
+++ b/pypy/module/__builtin__/test/test_buffer.py
@@ -117,6 +117,8 @@
         b[:] = '12345'
         assert a.tostring() == 'hello 12345'
         raises(IndexError, 'b[5] = "."')
+        b[4:2] = ''
+        assert a.tostring() == 'hello 12345'
 
         b = buffer(b, 2)
         assert len(b) == 3
diff --git a/pypy/module/_cffi_backend/cbuffer.py b/pypy/module/_cffi_backend/cbuffer.py
--- a/pypy/module/_cffi_backend/cbuffer.py
+++ b/pypy/module/_cffi_backend/cbuffer.py
@@ -1,6 +1,7 @@
 from pypy.interpreter.error import operationerrfmt
 from pypy.interpreter.buffer import RWBuffer
-from pypy.interpreter.gateway import unwrap_spec
+from pypy.interpreter.gateway import unwrap_spec, interp2app
+from pypy.interpreter.typedef import TypeDef
 from pypy.rpython.lltypesystem import rffi
 from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray
 
@@ -34,6 +35,16 @@
         for i in range(len(string)):
             raw_cdata[i] = string[i]
 
+LLBuffer.typedef = TypeDef(
+    "buffer",
+    __module__ = "_cffi_backend",
+    __len__ = interp2app(RWBuffer.descr_len),
+    __getitem__ = interp2app(RWBuffer.descr_getitem),
+    __setitem__ = interp2app(RWBuffer.descr_setitem),
+    __buffer__ = interp2app(RWBuffer.descr__buffer__),
+    )
+LLBuffer.typedef.acceptable_as_base_class = False
+
 
 @unwrap_spec(cdata=cdataobj.W_CData, size=int)
 def buffer(space, cdata, size=-1):
diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py
--- a/pypy/module/_cffi_backend/ctypefunc.py
+++ b/pypy/module/_cffi_backend/ctypefunc.py
@@ -4,9 +4,8 @@
 
 import sys
 from pypy.interpreter.error import OperationError, operationerrfmt
-from pypy.interpreter.error import wrap_oserror
 from pypy.rpython.lltypesystem import lltype, llmemory, rffi
-from pypy.rlib import jit, clibffi, jit_libffi, rposix
+from pypy.rlib import jit, clibffi, jit_libffi
 from pypy.rlib.jit_libffi import CIF_DESCRIPTION, CIF_DESCRIPTION_P
 from pypy.rlib.jit_libffi import FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP
 from pypy.rlib.jit_libffi import SIZE_OF_FFI_ARG
@@ -152,9 +151,6 @@
                     if flag == 1:
                         raw_string = rffi.cast(rffi.CCHARPP, data)[0]
                         lltype.free(raw_string, flavor='raw')
-                    elif flag == 2:
-                        file = rffi.cast(rffi.CCHARPP, data)[0]
-                        rffi_fclose(file)
             lltype.free(buffer, flavor='raw')
         return w_res
 
@@ -169,27 +165,6 @@
     assert isinstance(abi, int)
     return space.wrap(abi)
 
-rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP)
-rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT)
-
-def prepare_file_call_argument(fileobj):
-    import os
-    space = fileobj.space
-    fileobj.direct_flush()
-    fd = fileobj.direct_fileno()
-    if fd < 0:
-        raise OperationError(space.w_ValueError,
-                             space.wrap("file has no OS file descriptor"))
-    try:
-        fd2 = os.dup(fd)
-        f = rffi_fdopen(fd2, fileobj.mode)
-        if not f:
-            os.close(fd2)
-            raise OSError(rposix.get_errno(), "fdopen failed")
-    except OSError, e:
-        raise wrap_oserror(space, e)
-    return f
-
 # ____________________________________________________________
 
 
diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py
--- a/pypy/module/_cffi_backend/ctypeptr.py
+++ b/pypy/module/_cffi_backend/ctypeptr.py
@@ -3,9 +3,11 @@
 """
 
 from pypy.interpreter.error import OperationError, operationerrfmt
+from pypy.interpreter.error import wrap_oserror
 from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.rlib.objectmodel import keepalive_until_here
 from pypy.rlib.rarithmetic import ovfcheck
+from pypy.rlib import rposix
 
 from pypy.module._cffi_backend.ctypeobj import W_CType
 from pypy.module._cffi_backend import cdataobj, misc, ctypeprim
@@ -236,6 +238,22 @@
         p = rffi.ptradd(cdata, i * self.ctitem.size)
         return cdataobj.W_CData(space, p, self)
 
+    def cast(self, w_ob):
+        if self.is_file:
+            value = self.prepare_file(w_ob)
+            if value:
+                return cdataobj.W_CData(self.space, value, self)
+        return W_CTypePtrBase.cast(self, w_ob)
+
+    def prepare_file(self, w_ob):
+        from pypy.module._file.interp_file import W_File
+        from pypy.module._cffi_backend import ctypefunc
+        ob = self.space.interpclass_w(w_ob)
+        if isinstance(ob, W_File):
+            return prepare_file_argument(self.space, ob)
+        else:
+            return lltype.nullptr(rffi.CCHARP.TO)
+
     def _prepare_pointer_call_argument(self, w_init, cdata):
         space = self.space
         if (space.isinstance_w(w_init, space.w_list) or
@@ -245,11 +263,8 @@
             # from a string, we add the null terminator
             length = space.int_w(space.len(w_init)) + 1
         elif self.is_file:
-            from pypy.module._file.interp_file import W_File
-            from pypy.module._cffi_backend import ctypefunc
-            ob = space.interpclass_w(w_init)
-            if isinstance(ob, W_File):
-                result = ctypefunc.prepare_file_call_argument(ob)
+            result = self.prepare_file(w_init)
+            if result:
                 rffi.cast(rffi.CCHARPP, cdata)[0] = result
                 return 2
             return 0
@@ -303,3 +318,33 @@
         else:
             raise OperationError(space.w_TypeError,
                      space.wrap("expected a 'cdata struct-or-union' object"))
+
+# ____________________________________________________________
+
+
+rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP)
+rffi_setbuf = rffi.llexternal("setbuf", [rffi.CCHARP,rffi.CCHARP], lltype.Void)
+rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT)
+
+class CffiFileObj(object):
+    _immutable_ = True
+    def __init__(self, fd, mode):
+        self.llf = rffi_fdopen(fd, mode)
+        if not self.llf:
+            raise OSError(rposix.get_errno(), "fdopen failed")
+        rffi_setbuf(self.llf, lltype.nullptr(rffi.CCHARP.TO))
+    def close(self):
+        rffi_fclose(self.llf)
+
+def prepare_file_argument(space, fileobj):
+    fileobj.direct_flush()
+    if fileobj.cffi_fileobj is None:
+        fd = fileobj.direct_fileno()
+        if fd < 0:
+            raise OperationError(space.w_ValueError,
+                                 space.wrap("file has no OS file descriptor"))
+        try:
+            fileobj.cffi_fileobj = CffiFileObj(fd, fileobj.mode)
+        except OSError, e:
+            raise wrap_oserror(space, e)
+    return fileobj.cffi_fileobj.llf
diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -5,9 +5,8 @@
     type_or_class = "type"
     mandatory_b_prefix = ''
     mandatory_u_prefix = 'u'
-    readbuf = str
-    bufchar = lambda x: x
     bytechr = chr
+    bitem2bchr = lambda x: x
     class U(object):
         def __add__(self, other):
             return eval('u'+repr(other).replace(r'\\u', r'\u')
@@ -20,12 +19,8 @@
     unichr = chr
     mandatory_b_prefix = 'b'
     mandatory_u_prefix = ''
-    readbuf = lambda buf: buf.tobytes()
-    if sys.version_info < (3, 3):
-        bufchar = lambda x: bytes([ord(x)])
-    else:
-        bufchar = ord
     bytechr = lambda n: bytes([n])
+    bitem2bchr = bytechr
     u = ""
 
 def size_of_int():
@@ -1811,36 +1806,80 @@
     assert (p < s) ^ (p > s)
 
 def test_buffer():
+    try:
+        import __builtin__
+    except ImportError:
+        import builtins as __builtin__
     BShort = new_primitive_type("short")
     s = newp(new_pointer_type(BShort), 100)
     assert sizeof(s) == size_of_ptr()
     assert sizeof(BShort) == 2
-    assert len(readbuf(buffer(s))) == 2
+    assert len(buffer(s)) == 2
     #
     BChar = new_primitive_type("char")
     BCharArray = new_array_type(new_pointer_type(BChar), None)
     c = newp(BCharArray, b"hi there")
+    #
     buf = buffer(c)
-    assert readbuf(buf) == b"hi there\x00"
+    assert str(buf).startswith('<_cffi_backend.buffer object at 0x')
+    # --mb_length--
     assert len(buf) == len(b"hi there\x00")
-    assert buf[0] == bufchar('h')
-    assert buf[2] == bufchar(' ')
-    assert list(buf) == list(map(bufchar, "hi there\x00"))
-    buf[2] = bufchar('-')
-    assert c[2] == b'-'
-    assert readbuf(buf) == b"hi-there\x00"
-    c[2] = b'!'
-    assert buf[2] == bufchar('!')
-    assert readbuf(buf) == b"hi!there\x00"
-    c[2] = b'-'
-    buf[:2] = b'HI'
-    assert string(c) == b'HI-there'
-    if sys.version_info < (3,) or sys.version_info >= (3, 3):
-        assert buf[:4:2] == b'H-'
-        if '__pypy__' not in sys.builtin_module_names:
-            # XXX pypy doesn't support the following assignment so far
-            buf[:4:2] = b'XY'
-            assert string(c) == b'XIYthere'
+    # --mb_item--
+    for i in range(-12, 12):
+        try:
+            expected = b"hi there\x00"[i]
+        except IndexError:
+            py.test.raises(IndexError, "buf[i]")
+        else:
+            assert buf[i] == bitem2bchr(expected)
+    # --mb_slice--
+    assert buf[:] == b"hi there\x00"
+    for i in range(-12, 12):
+        assert buf[i:] == b"hi there\x00"[i:]
+        assert buf[:i] == b"hi there\x00"[:i]
+        for j in range(-12, 12):
+            assert buf[i:j] == b"hi there\x00"[i:j]
+    # --misc--
+    assert list(buf) == list(map(bitem2bchr, b"hi there\x00"))
+    # --mb_as_buffer--
+    if hasattr(__builtin__, 'buffer'):          # Python <= 2.7
+        py.test.raises(TypeError, __builtin__.buffer, c)
+        bf1 = __builtin__.buffer(buf)
+        assert len(bf1) == len(buf) and bf1[3] == "t"
+    if hasattr(__builtin__, 'memoryview'):      # Python >= 2.7
+        py.test.raises(TypeError, memoryview, c)
+        mv1 = memoryview(buf)
+        assert len(mv1) == len(buf) and mv1[3] in (b"t", ord(b"t"))
+    # --mb_ass_item--
+    expected = list(map(bitem2bchr, b"hi there\x00"))
+    for i in range(-12, 12):
+        try:
+            expected[i] = bytechr(i & 0xff)
+        except IndexError:
+            py.test.raises(IndexError, "buf[i] = bytechr(i & 0xff)")
+        else:
+            buf[i] = bytechr(i & 0xff)
+        assert list(buf) == expected
+    # --mb_ass_slice--
+    buf[:] = b"hi there\x00"
+    assert list(buf) == list(c) == list(map(bitem2bchr, b"hi there\x00"))
+    py.test.raises(ValueError, 'buf[:] = b"shorter"')
+    py.test.raises(ValueError, 'buf[:] = b"this is much too long!"')
+    buf[4:2] = b""   # no effect, but should work
+    assert buf[:] == b"hi there\x00"
+    expected = list(map(bitem2bchr, b"hi there\x00"))
+    x = 0
+    for i in range(-12, 12):
+        for j in range(-12, 12):
+            start = i if i >= 0 else i + len(buf)
+            stop  = j if j >= 0 else j + len(buf)
+            start = max(0, min(len(buf), start))
+            stop  = max(0, min(len(buf), stop))
+            sample = bytechr(x & 0xff) * (stop - start)
+            x += 1
+            buf[i:j] = sample
+            expected[i:j] = map(bitem2bchr, sample)
+            assert list(buf) == expected
 
 def test_getcname():
     BUChar = new_primitive_type("unsigned char")
@@ -2212,6 +2251,11 @@
     assert len(p) == 4
     assert list(p) == [b"f", b"o", b"o", b"\x00"]
 
+# XXX hack
+if sys.version_info >= (3,):
+    import posix, io
+    posix.fdopen = io.open
+
 def test_FILE():
     if sys.platform == "win32":
         py.test.skip("testing FILE not implemented")
@@ -2229,19 +2273,20 @@
     #
     import posix
     fdr, fdw = posix.pipe()
-    fr1 = posix.fdopen(fdr, 'r', 256)
-    fw1 = posix.fdopen(fdw, 'w', 256)
+    fr1 = posix.fdopen(fdr, 'rb', 256)
+    fw1 = posix.fdopen(fdw, 'wb', 256)
     #
     fw1.write(b"X")
     res = fputs(b"hello world\n", fw1)
     assert res >= 0
-    fw1.close()
+    fw1.flush()     # should not be needed
     #
     p = newp(new_array_type(BCharP, 100), None)
     res = fscanf(fr1, b"%s\n", p)
     assert res == 1
     assert string(p) == b"Xhello"
     fr1.close()
+    fw1.close()
 
 def test_FILE_only_for_FILE_arg():
     if sys.platform == "win32":
@@ -2262,5 +2307,38 @@
     fw1 = posix.fdopen(fdw, 'w')
     #
     e = py.test.raises(TypeError, fputs, b"hello world\n", fw1)
-    assert str(e.value) == ("initializer for ctype 'struct NOT_FILE *' must "
-                            "be a cdata pointer, not file")
+    assert str(e.value).startswith(
+        "initializer for ctype 'struct NOT_FILE *' must "
+        "be a cdata pointer, not ")
+
+def test_FILE_object():
+    if sys.platform == "win32":
+        py.test.skip("testing FILE not implemented")
+    #
+    BFILE = new_struct_type("_IO_FILE")
+    BFILEP = new_pointer_type(BFILE)
+    BChar = new_primitive_type("char")
+    BCharP = new_pointer_type(BChar)
+    BInt = new_primitive_type("int")
+    BFunc = new_function_type((BCharP, BFILEP), BInt, False)
+    BFunc2 = new_function_type((BFILEP,), BInt, False)
+    ll = find_and_load_library('c')
+    fputs = ll.load_function(BFunc, "fputs")
+    fileno = ll.load_function(BFunc2, "fileno")
+    #
+    import posix
+    fdr, fdw = posix.pipe()
+    fw1 = posix.fdopen(fdw, 'wb', 256)
+    #
+    fw1p = cast(BFILEP, fw1)
+    fw1.write(b"X")
+    fw1.flush()
+    res = fputs(b"hello\n", fw1p)
+    assert res >= 0
+    res = fileno(fw1p)
+    assert (res == fdw) == (sys.version_info < (3,))
+    fw1.close()
+    #
+    data = posix.read(fdr, 256)
+    assert data == b"Xhello\n"
+    posix.close(fdr)
diff --git a/pypy/module/_cffi_backend/test/test_ztranslation.py b/pypy/module/_cffi_backend/test/test_ztranslation.py
--- a/pypy/module/_cffi_backend/test/test_ztranslation.py
+++ b/pypy/module/_cffi_backend/test/test_ztranslation.py
@@ -1,8 +1,21 @@
 from pypy.objspace.fake.checkmodule import checkmodule
+from pypy.module._cffi_backend import ctypeptr
+from pypy.rpython.lltypesystem import lltype, rffi
 
 # side-effect: FORMAT_LONGDOUBLE must be built before test_checkmodule()
 from pypy.module._cffi_backend import misc
 
 
 def test_checkmodule():
-    checkmodule('_cffi_backend')
+    # prepare_file_argument() is not working without translating the _file
+    # module too
+    def dummy_prepare_file_argument(space, fileobj):
+        return lltype.nullptr(rffi.CCHARP.TO)
+    old = ctypeptr.prepare_file_argument
+    try:
+        ctypeptr.prepare_file_argument = dummy_prepare_file_argument
+        #
+        checkmodule('_cffi_backend')
+        #
+    finally:
+        ctypeptr.prepare_file_argument = old
diff --git a/pypy/module/_file/interp_file.py b/pypy/module/_file/interp_file.py
--- a/pypy/module/_file/interp_file.py
+++ b/pypy/module/_file/interp_file.py
@@ -32,6 +32,7 @@
     encoding = None
     errors   = None
     fd       = -1
+    cffi_fileobj = None    # pypy/module/_cffi_backend
 
     newlines = 0     # Updated when the stream is closed
 
@@ -148,7 +149,14 @@
                 del openstreams[stream]
             except KeyError:
                 pass
-            stream.close()
+            # close the stream.  If cffi_fileobj is None, we close the
+            # underlying fileno too.  Otherwise, we leave that to
+            # cffi_fileobj.close().
+            cffifo = self.cffi_fileobj
+            self.cffi_fileobj = None
+            stream.close1(cffifo is None)
+            if cffifo is not None:
+                cffifo.close()
 
     def direct_fileno(self):
         self.getstream()    # check if the file is still open
diff --git a/pypy/module/_multiprocessing/test/test_connection.py b/pypy/module/_multiprocessing/test/test_connection.py
--- a/pypy/module/_multiprocessing/test/test_connection.py
+++ b/pypy/module/_multiprocessing/test/test_connection.py
@@ -10,7 +10,8 @@
 
 class AppTestBufferTooShort:
     def setup_class(cls):
-        space = gettestobjspace(usemodules=('_multiprocessing', 'thread', 'signal'))
+        space = gettestobjspace(usemodules=('_multiprocessing', 'thread',
+                                            'signal', 'itertools'))
         cls.space = space
 
         if option.runappdirect:
diff --git a/pypy/module/_multiprocessing/test/test_memory.py b/pypy/module/_multiprocessing/test/test_memory.py
--- a/pypy/module/_multiprocessing/test/test_memory.py
+++ b/pypy/module/_multiprocessing/test/test_memory.py
@@ -3,7 +3,8 @@
 class AppTestMemory:
     def setup_class(cls):
         space = gettestobjspace(
-            usemodules=('_multiprocessing', 'mmap', '_rawffi', '_ffi'))
+            usemodules=('_multiprocessing', 'mmap', '_rawffi', '_ffi',
+                        'itertools'))
         cls.space = space
 
     def test_address_of(self):
diff --git a/pypy/module/bz2/interp_bz2.py b/pypy/module/bz2/interp_bz2.py
--- a/pypy/module/bz2/interp_bz2.py
+++ b/pypy/module/bz2/interp_bz2.py
@@ -357,8 +357,8 @@
             buffering = 1024   # minimum amount of compressed data read at once
         self.buffering = buffering
 
-    def close(self):
-        self.stream.close()
+    def close1(self, closefileno):
+        self.stream.close1(closefileno)
 
     def tell(self):
         return self.readlength
@@ -479,9 +479,9 @@
         self.compressor = W_BZ2Compressor(space, compresslevel)
         self.writtenlength = 0
 
-    def close(self):
+    def close1(self, closefileno):
         self.stream.write(self.space.str_w(self.compressor.flush()))
-        self.stream.close()
+        self.stream.close1(closefileno)
 
     def write(self, data):
         self.stream.write(self.space.str_w(self.compressor.compress(data)))
diff --git a/pypy/module/cpyext/dictobject.py b/pypy/module/cpyext/dictobject.py
--- a/pypy/module/cpyext/dictobject.py
+++ b/pypy/module/cpyext/dictobject.py
@@ -198,8 +198,8 @@
 @specialize.memo()
 def make_frozendict(space):
     return space.appexec([], '''():
-    import collections
-    class FrozenDict(collections.Mapping):
+    import _abcoll
+    class FrozenDict(_abcoll.Mapping):
         def __init__(self, *args, **kwargs):
             self._d = dict(*args, **kwargs)
         def __iter__(self):
diff --git a/pypy/module/cpyext/test/test_import.py b/pypy/module/cpyext/test/test_import.py
--- a/pypy/module/cpyext/test/test_import.py
+++ b/pypy/module/cpyext/test/test_import.py
@@ -4,9 +4,9 @@
 
 class TestImport(BaseApiTest):
     def test_import(self, space, api):
-        pdb = api.PyImport_Import(space.wrap("pdb"))
-        assert pdb
-        assert space.getattr(pdb, space.wrap("pm"))
+        stat = api.PyImport_Import(space.wrap("stat"))
+        assert stat
+        assert space.getattr(stat, space.wrap("S_IMODE"))
 
     def test_addmodule(self, space, api):
         with rffi.scoped_str2charp("sys") as modname:
@@ -32,10 +32,10 @@
         assert space.is_true(space.contains(w_dict, space.wrap(testmod)))
 
     def test_reload(self, space, api):
-        pdb = api.PyImport_Import(space.wrap("pdb"))
-        space.delattr(pdb, space.wrap("set_trace"))
-        pdb = api.PyImport_ReloadModule(pdb)
-        assert space.getattr(pdb, space.wrap("set_trace"))
+        stat = api.PyImport_Import(space.wrap("stat"))
+        space.delattr(stat, space.wrap("S_IMODE"))
+        stat = api.PyImport_ReloadModule(stat)
+        assert space.getattr(stat, space.wrap("S_IMODE"))
 
 class AppTestImportLogic(AppTestCpythonExtensionBase):
     def test_import_logic(self):
diff --git a/pypy/module/imp/test/test_app.py b/pypy/module/imp/test/test_app.py
--- a/pypy/module/imp/test/test_app.py
+++ b/pypy/module/imp/test/test_app.py
@@ -3,6 +3,8 @@
 
 class AppTestImpModule:
     def setup_class(cls):
+        from pypy.conftest import gettestobjspace
+        cls.space = gettestobjspace(usemodules=('imp', 'itertools'))
         cls.w_imp = cls.space.getbuiltinmodule('imp')
         cls.w_file_module = cls.space.wrap(__file__)
 
diff --git a/pypy/module/imp/test/test_import.py b/pypy/module/imp/test/test_import.py
--- a/pypy/module/imp/test/test_import.py
+++ b/pypy/module/imp/test/test_import.py
@@ -38,7 +38,7 @@
                     test_reload = "def test():\n    raise ValueError\n",
                     infinite_reload = "import infinite_reload; reload(infinite_reload)",
                     del_sys_module = "import sys\ndel sys.modules['del_sys_module']\n",
-                    itertools = "hello_world = 42\n",
+                    _md5 = "hello_world = 42\n",
                     gc = "should_never_be_seen = 42\n",
                     )
     root.ensure("notapackage", dir=1)    # empty, no __init__.py
@@ -148,7 +148,7 @@
 class AppTestImport:
 
     def setup_class(cls): # interpreter-level
-        cls.space = gettestobjspace(usemodules=['itertools'])
+        cls.space = gettestobjspace(usemodules=['_md5'])
         cls.w_runappdirect = cls.space.wrap(conftest.option.runappdirect)
         cls.saved_modules = _setup(cls.space)
         #XXX Compile class
@@ -597,34 +597,34 @@
 
     def test_shadow_extension_1(self):
         if self.runappdirect: skip("hard to test: module is already imported")
-        # 'import itertools' is supposed to find itertools.py if there is
+        # 'import _md5' is supposed to find _md5.py if there is
         # one in sys.path.
         import sys
-        assert 'itertools' not in sys.modules
-        import itertools
-        assert hasattr(itertools, 'hello_world')
-        assert not hasattr(itertools, 'count')
-        assert '(built-in)' not in repr(itertools)
-        del sys.modules['itertools']
+        assert '_md5' not in sys.modules
+        import _md5
+        assert hasattr(_md5, 'hello_world')
+        assert not hasattr(_md5, 'count')
+        assert '(built-in)' not in repr(_md5)
+        del sys.modules['_md5']
 
     def test_shadow_extension_2(self):
         if self.runappdirect: skip("hard to test: module is already imported")
-        # 'import itertools' is supposed to find the built-in module even
+        # 'import _md5' is supposed to find the built-in module even
         # if there is also one in sys.path as long as it is *after* the
         # special entry '.../lib_pypy/__extensions__'.  (Note that for now
-        # there is one in lib_pypy/itertools.py, which should not be seen
+        # there is one in lib_pypy/_md5.py, which should not be seen
         # either; hence the (built-in) test below.)
         import sys
-        assert 'itertools' not in sys.modules
+        assert '_md5' not in sys.modules
         sys.path.append(sys.path.pop(0))
         try:
-            import itertools
-            assert not hasattr(itertools, 'hello_world')
-            assert hasattr(itertools, 'izip')
-            assert '(built-in)' in repr(itertools)
+            import _md5
+            assert not hasattr(_md5, 'hello_world')
+            assert hasattr(_md5, 'digest_size')
+            assert '(built-in)' in repr(_md5)
         finally:
             sys.path.insert(0, sys.path.pop())
-        del sys.modules['itertools']
+        del sys.modules['_md5']
 
     def test_invalid_pathname(self):
         import imp
@@ -1005,7 +1005,7 @@
 class AppTestImportHooks(object):
 
     def setup_class(cls):
-        space = cls.space = gettestobjspace(usemodules=('struct',))
+        space = cls.space = gettestobjspace(usemodules=('struct', 'itertools'))
         mydir = os.path.dirname(__file__)
         cls.w_hooktest = space.wrap(os.path.join(mydir, 'hooktest'))
         space.appexec([space.wrap(mydir)], """
diff --git a/pypy/module/math/test/test_math.py b/pypy/module/math/test/test_math.py
--- a/pypy/module/math/test/test_math.py
+++ b/pypy/module/math/test/test_math.py
@@ -6,7 +6,7 @@
 
 class AppTestMath:
     def setup_class(cls):
-        cls.space = gettestobjspace(usemodules=['math', 'struct'])
+        cls.space = gettestobjspace(usemodules=['math', 'struct', 'itertools'])
         cls.w_cases = cls.space.wrap(test_direct.MathTests.TESTCASES)
         cls.w_consistent_host = cls.space.wrap(test_direct.consistent_host)
 
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/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py
--- a/pypy/module/micronumpy/arrayimpl/concrete.py
+++ b/pypy/module/micronumpy/arrayimpl/concrete.py
@@ -10,6 +10,7 @@
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.rlib import jit
 from pypy.rlib.rawstorage import free_raw_storage
+from pypy.rlib.debug import make_sure_not_resized
 
 class ConcreteArrayIterator(base.BaseArrayIterator):
     def __init__(self, array):
@@ -44,10 +45,10 @@
     def __init__(self, array):
         self.array = array
         self.offset = array.start
-        self.skip = array.strides[0]
+        self.skip = array.get_strides()[0]
         self.dtype = array.dtype
         self.index = 0
-        self.size = array.shape[0]
+        self.size = array.get_shape()[0]
 
     def next(self):
         self.offset += self.skip
@@ -115,8 +116,8 @@
 class AxisIterator(base.BaseArrayIterator):
     def __init__(self, array, shape, dim):
         self.shape = shape
-        strides = array.strides
-        backstrides = array.backstrides
+        strides = array.get_strides()
+        backstrides = array.get_backstrides()
         if len(shape) == len(strides):
             # keepdims = True
             self.strides = strides[:dim] + [0] + strides[dim + 1:]
@@ -166,9 +167,23 @@
 class BaseConcreteArray(base.BaseArrayImplementation):
     start = 0
     parent = None
+
+    # JIT hints that length of all those arrays is a constant
     
     def get_shape(self):
-        return self.shape
+        shape = self.shape
+        jit.hint(len(shape), promote=True)
+        return shape
+
+    def get_strides(self):
+        strides = self.strides
+        jit.hint(len(strides), promote=True)
+        return strides
+
+    def get_backstrides(self):
+        backstrides = self.backstrides
+        jit.hint(len(backstrides), promote=True)
+        return backstrides
 
     def getitem(self, index):
         return self.dtype.getitem(self, index)
@@ -181,7 +196,7 @@
         if impl.is_scalar():
             self.fill(impl.get_scalar_value())
             return
-        shape = shape_agreement(space, self.shape, arr)
+        shape = shape_agreement(space, self.get_shape(), arr)
         if impl.storage == self.storage:
             impl = impl.copy()
         loop.setslice(shape, self, impl)
@@ -193,8 +208,8 @@
         # Since we got to here, prod(new_shape) == self.size
         new_strides = None
         if self.size > 0:
-            new_strides = calc_new_strides(new_shape, self.shape,
-                                           self.strides, self.order)
+            new_strides = calc_new_strides(new_shape, self.get_shape(),
+                                           self.get_strides(), self.order)
         if new_strides:
             # We can create a view, strides somehow match up.
             ndims = len(new_shape)
@@ -211,31 +226,34 @@
     @jit.unroll_safe
     def _lookup_by_index(self, space, view_w):
         item = self.start
+        strides = self.get_strides()
         for i, w_index in enumerate(view_w):
             if space.isinstance_w(w_index, space.w_slice):
                 raise IndexError
             idx = int_w(space, w_index)
             if idx < 0:
-                idx = self.shape[i] + idx
-            if idx < 0 or idx >= self.shape[i]:
+                idx = self.get_shape()[i] + idx
+            if idx < 0 or idx >= self.get_shape()[i]:
                 raise operationerrfmt(space.w_IndexError,
-                      "index (%d) out of range (0<=index<%d", i, self.shape[i],
+                      "index (%d) out of range (0<=index<%d", i, self.get_shape()[i],
                 )
-            item += idx * self.strides[i]
+            item += idx * strides[i]
         return item
 
     @jit.unroll_safe
     def _lookup_by_unwrapped_index(self, space, lst):
         item = self.start
-        assert len(lst) == len(self.shape)
+        shape = self.get_shape()
+        strides = self.get_strides()
+        assert len(lst) == len(shape)
         for i, idx in enumerate(lst):
             if idx < 0:
-                idx = self.shape[i] + idx
-            if idx < 0 or idx >= self.shape[i]:
+                idx = shape[i] + idx
+            if idx < 0 or idx >= shape[i]:
                 raise operationerrfmt(space.w_IndexError,
-                      "index (%d) out of range (0<=index<%d", i, self.shape[i],
+                      "index (%d) out of range (0<=index<%d", i, shape[i],
                 )
-            item += idx * self.strides[i]
+            item += idx * strides[i]
         return item
 
     def getitem_index(self, space, index):
@@ -255,7 +273,8 @@
             raise IndexError
         if isinstance(w_idx, W_NDimArray):
             raise ArrayArgumentException
-        shape_len = len(self.shape)
+        shape = self.get_shape()
+        shape_len = len(shape)
         if shape_len == 0:
             raise OperationError(space.w_IndexError, space.wrap(
                 "0-d arrays can't be indexed"))
@@ -299,7 +318,7 @@
             return RecordChunk(idx)
         if (space.isinstance_w(w_idx, space.w_int) or
             space.isinstance_w(w_idx, space.w_slice)):
-            return Chunks([Chunk(*space.decode_index4(w_idx, self.shape[0]))])
+            return Chunks([Chunk(*space.decode_index4(w_idx, self.get_shape()[0]))])
         elif space.is_w(w_idx, space.w_None):
             return Chunks([NewAxisChunk()])
         result = []
@@ -309,7 +328,7 @@
                 result.append(NewAxisChunk())
             else:
                 result.append(Chunk(*space.decode_index4(w_item,
-                                                         self.shape[i])))
+                                                         self.get_shape()[i])))
                 i += 1
         return Chunks(result)
 
@@ -333,37 +352,37 @@
             view.implementation.setslice(space, w_value)
 
     def transpose(self):
-        if len(self.shape) < 2:
+        if len(self.get_shape()) < 2:
             return self
         strides = []
         backstrides = []
         shape = []
-        for i in range(len(self.shape) - 1, -1, -1):
-            strides.append(self.strides[i])
-            backstrides.append(self.backstrides[i])
-            shape.append(self.shape[i])
+        for i in range(len(self.get_shape()) - 1, -1, -1):
+            strides.append(self.get_strides()[i])
+            backstrides.append(self.get_backstrides()[i])
+            shape.append(self.get_shape()[i])
         return SliceArray(self.start, strides,
                           backstrides, shape, self)
 
     def copy(self):
-        strides, backstrides = support.calc_strides(self.shape, self.dtype,
+        strides, backstrides = support.calc_strides(self.get_shape(), self.dtype,
                                                     self.order)
-        impl = ConcreteArray(self.shape, self.dtype, self.order, strides,
+        impl = ConcreteArray(self.get_shape(), self.dtype, self.order, strides,
                              backstrides)
-        return loop.setslice(self.shape, impl, self)
+        return loop.setslice(self.get_shape(), impl, self)
 
     def create_axis_iter(self, shape, dim):
         return AxisIterator(self, shape, dim)
 
     def create_dot_iter(self, shape, skip):
-        r = calculate_dot_strides(self.strides, self.backstrides,
+        r = calculate_dot_strides(self.get_strides(), self.get_backstrides(),
                                   shape, skip)
         return MultiDimViewIterator(self, self.start, r[0], r[1], shape)
 
     def swapaxes(self, axis1, axis2):
-        shape = self.shape[:]
-        strides = self.strides[:]
-        backstrides = self.backstrides[:]
+        shape = self.get_shape()[:]
+        strides = self.get_strides()[:]
+        backstrides = self.get_backstrides()[:]
         shape[axis1], shape[axis2] = shape[axis2], shape[axis1]   
         strides[axis1], strides[axis2] = strides[axis2], strides[axis1]
         backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1] 
@@ -375,6 +394,9 @@
 
 class ConcreteArray(BaseConcreteArray):
     def __init__(self, shape, dtype, order, strides, backstrides):
+        make_sure_not_resized(shape)
+        make_sure_not_resized(strides)
+        make_sure_not_resized(backstrides)
         self.shape = shape
         self.size = support.product(shape) * dtype.get_size()
         self.storage = dtype.itemtype.malloc(self.size)
@@ -383,11 +405,12 @@
         self.strides = strides
         self.backstrides = backstrides
 
-    def create_iter(self, shape):
-        if shape == self.shape:
+    def create_iter(self, shape=None):
+        if shape is None or shape == self.get_shape():
             return ConcreteArrayIterator(self)
-        r = calculate_broadcast_strides(self.strides, self.backstrides,
-                                        self.shape, shape)
+        r = calculate_broadcast_strides(self.get_strides(),
+                                        self.get_backstrides(),
+                                        self.get_shape(), shape)
         return MultiDimViewIterator(self, 0, r[0], r[1], shape)
 
     def fill(self, box):
@@ -420,25 +443,27 @@
     def fill(self, box):
         loop.fill(self, box.convert_to(self.dtype))
 
-    def create_iter(self, shape):
-        if shape != self.shape:
-            r = calculate_broadcast_strides(self.strides, self.backstrides,
-                                            self.shape, shape)
+    def create_iter(self, shape=None):
+        if shape is not None and shape != self.get_shape():
+            r = calculate_broadcast_strides(self.get_strides(),
+                                            self.get_backstrides(),
+                                            self.get_shape(), shape)
             return MultiDimViewIterator(self.parent,
                                         self.start, r[0], r[1], shape)
-        if len(self.shape) == 1:
+        if len(self.get_shape()) == 1:
             return OneDimViewIterator(self)
-        return MultiDimViewIterator(self.parent, self.start, self.strides,
-                                    self.backstrides, self.shape)
+        return MultiDimViewIterator(self.parent, self.start,
+                                    self.get_strides(),
+                                    self.get_backstrides(), self.get_shape())
 
     def set_shape(self, space, new_shape):
-        if len(self.shape) < 2 or self.size == 0:
+        if len(self.get_shape()) < 2 or self.size == 0:
             # TODO: this code could be refactored into calc_strides
             # but then calc_strides would have to accept a stepping factor
             strides = []
             backstrides = []
             dtype = self.dtype
-            s = self.strides[0] // dtype.get_size()
+            s = self.get_strides()[0] // dtype.get_size()
             if self.order == 'C':
                 new_shape.reverse()
             for sh in new_shape:
@@ -451,7 +476,8 @@
                 new_shape.reverse()
             return SliceArray(self.start, strides, backstrides, new_shape,
                               self)
-        new_strides = calc_new_strides(new_shape, self.shape, self.strides,
+        new_strides = calc_new_strides(new_shape, self.get_shape(),
+                                       self.get_strides(),
                                        self.order)
         if new_strides is None:
             raise OperationError(space.w_AttributeError, space.wrap(
diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py
--- a/pypy/module/micronumpy/arrayimpl/scalar.py
+++ b/pypy/module/micronumpy/arrayimpl/scalar.py
@@ -34,7 +34,7 @@
     def get_shape(self):
         return []
 
-    def create_iter(self, shape):
+    def create_iter(self, shape=None):
         return ScalarIterator(self.value)
 
     def get_scalar_value(self):
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/dot.py b/pypy/module/micronumpy/dot.py
--- a/pypy/module/micronumpy/dot.py
+++ b/pypy/module/micronumpy/dot.py
@@ -11,12 +11,12 @@
         right_critical_dim = len(right_shape) - 2
         right_critical_dim_size = right_shape[right_critical_dim]
         assert right_critical_dim >= 0
-        out_shape += left_shape[:-1] + \
-                     right_shape[0:right_critical_dim] + \
-                     right_shape[right_critical_dim + 1:]
+        out_shape = out_shape + left_shape[:-1] + \
+                    right_shape[0:right_critical_dim] + \
+                    right_shape[right_critical_dim + 1:]
     elif len(right_shape) > 0:
         #dot does not reduce for scalars
-        out_shape += left_shape[:-1]
+        out_shape = out_shape + left_shape[:-1]
     if my_critical_dim_size != right_critical_dim_size:
         raise OperationError(space.w_ValueError, space.wrap(
                                         "objects are not aligned"))
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,7 +275,6 @@
             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):
         from pypy.module.micronumpy.interp_dtype import new_unicode_dtype
@@ -474,6 +477,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_numarray.py b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -25,7 +25,7 @@
     shape = []
     for w_item in space.fixedview(w_size):
         shape.append(space.int_w(w_item))
-    return shape
+    return shape[:]
 
 class __extend__(W_NDimArray):
     @jit.unroll_safe
@@ -190,7 +190,7 @@
         return space.call_function(cache.w_array_str, self)
 
     def dump_data(self):
-        i = self.create_iter(self.get_shape())
+        i = self.create_iter()
         first = True
         dtype = self.get_dtype()
         s = StringBuilder()
@@ -206,8 +206,6 @@
         return s.build()
 
     def create_iter(self, shape=None):
-        if shape is None:
-            shape = self.get_shape()
         return self.implementation.create_iter(shape)
 
     def create_axis_iter(self, shape, dim):
@@ -396,7 +394,7 @@
         if self.get_size() > 1:
             raise OperationError(space.w_ValueError, space.wrap(
                 "The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()"))
-        iter = self.create_iter(self.get_shape())
+        iter = self.create_iter()
         return space.wrap(space.is_true(iter.getitem()))
 
     def _binop_impl(ufunc_name):
@@ -681,7 +679,7 @@
     if ndmin > len(shape):
         shape = [1] * (ndmin - len(shape)) + shape
     arr = W_NDimArray.from_shape(shape, dtype, order=order)
-    arr_iter = arr.create_iter(arr.get_shape())
+    arr_iter = arr.create_iter()
     for w_elem in elems_w:
         arr_iter.setitem(dtype.coerce(space, w_elem))
         arr_iter.next()
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,
@@ -413,6 +423,7 @@
         return interp_dtype.get_dtype_cache(space).builtin_dtypes[dtypenum]
 
 
+ at jit.unroll_safe
 def find_unaryop_result_dtype(space, dt, promote_to_float=False,
     promote_bools=False, promote_to_largest=False, allow_complex=True):
     if promote_bools and (dt.kind == interp_dtype.BOOLLTR):
@@ -446,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:
@@ -472,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/iter.py b/pypy/module/micronumpy/iter.py
--- a/pypy/module/micronumpy/iter.py
+++ b/pypy/module/micronumpy/iter.py
@@ -59,8 +59,8 @@
     def apply(self, arr):
         ofs, subdtype = arr.dtype.fields[self.name]
         # strides backstrides are identical, ofs only changes start
-        return W_NDimArray.new_slice(arr.start + ofs, arr.strides,
-                                     arr.backstrides,
+        return W_NDimArray.new_slice(arr.start + ofs, arr.get_strides(),
+                                     arr.get_backstrides(),
                                      arr.shape, arr, subdtype)
 
 class Chunks(BaseChunk):
@@ -80,8 +80,8 @@
 
     def apply(self, arr):
         shape = self.extend_shape(arr.shape)
-        r = calculate_slice_strides(arr.shape, arr.start, arr.strides,
-                                    arr.backstrides, self.l)
+        r = calculate_slice_strides(arr.shape, arr.start, arr.get_strides(),
+                                    arr.get_backstrides(), self.l)
         _, start, strides, backstrides = r
         return W_NDimArray.new_slice(start, strides[:], backstrides[:],
                                      shape[:], arr)
diff --git a/pypy/module/micronumpy/loop.py b/pypy/module/micronumpy/loop.py
--- a/pypy/module/micronumpy/loop.py
+++ b/pypy/module/micronumpy/loop.py
@@ -89,7 +89,7 @@
                               reds = ['obj', 'obj_iter', 'cur_value'])
 
 def compute_reduce(obj, calc_dtype, func, done_func, identity):
-    obj_iter = obj.create_iter(obj.get_shape())
+    obj_iter = obj.create_iter()
     if identity is None:
         cur_value = obj_iter.getitem().convert_to(calc_dtype)
         obj_iter.next()
@@ -109,7 +109,7 @@
     return cur_value
 
 def fill(arr, box):
-    arr_iter = arr.create_iter(arr.get_shape())
+    arr_iter = arr.create_iter()
     while not arr_iter.done():
         arr_iter.setitem(box)
         arr_iter.next()
@@ -159,7 +159,7 @@
 
 def do_axis_reduce(shape, func, arr, dtype, axis, out, identity):
     out_iter = out.create_axis_iter(arr.get_shape(), axis)
-    arr_iter = arr.create_iter(arr.get_shape())
+    arr_iter = arr.create_iter()
     if identity is not None:
         identity = identity.convert_to(dtype)
     shapelen = len(shape)
@@ -192,7 +192,7 @@
         result = 0
         idx = 1
         dtype = arr.get_dtype()
-        iter = arr.create_iter(arr.get_shape())
+        iter = arr.create_iter()
         cur_best = iter.getitem()
         iter.next()
         shapelen = len(arr.get_shape())
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/strides.py b/pypy/module/micronumpy/strides.py
--- a/pypy/module/micronumpy/strides.py
+++ b/pypy/module/micronumpy/strides.py
@@ -15,16 +15,22 @@
     jit.isconstant(len(chunks))
 )
 def calculate_slice_strides(shape, start, strides, backstrides, chunks):
-    rstrides = []
-    rbackstrides = []
+    size = 0
+    for chunk in chunks:
+        if chunk.step != 0:
+            size += 1
+    rstrides = [0] * size
+    rbackstrides = [0] * size
     rstart = start
-    rshape = []
+    rshape = [0] * size
     i = -1
+    j = 0
     for i, chunk in enumerate_chunks(chunks):
         if chunk.step != 0:
-            rstrides.append(strides[i] * chunk.step)
-            rbackstrides.append(strides[i] * (chunk.lgt - 1) * chunk.step)
-            rshape.append(chunk.lgt)
+            rstrides[j] = strides[i] * chunk.step
+            rbackstrides[j] = strides[i] * (chunk.lgt - 1) * chunk.step
+            rshape[j] = chunk.lgt
+            j += 1
         rstart += strides[i] * chunk.start
     # add a reminder
     s = i + 1
@@ -64,13 +70,13 @@
     while True:
         new_batch = []
         if not batch:
-            return shape, []
+            return shape[:], []
         if is_single_elem(space, batch[0], is_rec_type):
             for w_elem in batch:
                 if not is_single_elem(space, w_elem, is_rec_type):
                     raise OperationError(space.w_ValueError, space.wrap(
                         "setting an array element with a sequence"))
-            return shape, batch
+            return shape[:], batch
         size = space.len_w(batch[0])
         for w_elem in batch:
             if (is_single_elem(space, w_elem, is_rec_type) or
@@ -104,6 +110,7 @@
             i //= shape[s]
     return coords, step, lngth
 
+ at jit.unroll_safe
 def shape_agreement(space, shape1, w_arr2, broadcast_down=True):
     if w_arr2 is None:
         return shape1
@@ -126,6 +133,7 @@
         )
     return ret
 
+ at jit.unroll_safe
 def _shape_agreement(shape1, shape2):
     """ Checks agreement about two shapes with respect to broadcasting. Returns
     the resulting shape.
@@ -255,19 +263,19 @@
                     cur_step = steps[oldI]
                     n_old_elems_to_use *= old_shape[oldI]
     assert len(new_strides) == len(new_shape)
-    return new_strides
+    return new_strides[:]
 
 
 def calculate_dot_strides(strides, backstrides, res_shape, skip_dims):
-    rstrides = []
-    rbackstrides = []
-    j=0
+    rstrides = [0] * len(res_shape)
+    rbackstrides = [0] * len(res_shape)
+    j = 0
     for i in range(len(res_shape)):
         if i in skip_dims:
-            rstrides.append(0)
-            rbackstrides.append(0)
+            rstrides[i] = 0
+            rbackstrides[i] = 0
         else:
-            rstrides.append(strides[j])
-            rbackstrides.append(backstrides[j])
+            rstrides[i] = strides[j]
+            rbackstrides[i] = backstrides[j]
             j += 1
     return rstrides, rbackstrides
diff --git a/pypy/module/micronumpy/support.py b/pypy/module/micronumpy/support.py
--- a/pypy/module/micronumpy/support.py
+++ b/pypy/module/micronumpy/support.py
@@ -8,6 +8,7 @@
         i *= x
     return i
 
+ at jit.unroll_safe
 def calc_strides(shape, dtype, order):
     strides = []
     backstrides = []
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
@@ -344,6 +344,13 @@
         assert a[-1] == 8
         raises(IndexError, "a[-6]")
 
+    def test_getitem_float(self):
+        from _numpypy import array
+        a = array([1, 2, 3, 4])
+        assert a[1.2] == 2
+        assert a[1.6] == 2
+        assert a[-1.2] == 4
+
     def test_getitem_tuple(self):
         from _numpypy import array
         a = array(range(5))
@@ -2238,7 +2245,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'
+


More information about the pypy-commit mailing list