[pypy-commit] pypy reflex-support: merge default into branch

wlav noreply at buildbot.pypy.org
Wed Mar 14 14:27:07 CET 2012


Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r53556:3a12457d80db
Date: 2012-03-14 06:25 -0700
http://bitbucket.org/pypy/pypy/changeset/3a12457d80db/

Log:	merge default into branch

diff --git a/lib-python/conftest.py b/lib-python/conftest.py
--- a/lib-python/conftest.py
+++ b/lib-python/conftest.py
@@ -311,7 +311,7 @@
     RegrTest('test_mimetypes.py'),
     RegrTest('test_MimeWriter.py', core=False),
     RegrTest('test_minidom.py'),
-    RegrTest('test_mmap.py'),
+    RegrTest('test_mmap.py', usemodules="mmap"),
     RegrTest('test_module.py', core=True),
     RegrTest('test_modulefinder.py'),
     RegrTest('test_msilib.py', skip=only_win32),
diff --git a/lib-python/modified-2.7/distutils/command/bdist_wininst.py b/lib-python/modified-2.7/distutils/command/bdist_wininst.py
--- a/lib-python/modified-2.7/distutils/command/bdist_wininst.py
+++ b/lib-python/modified-2.7/distutils/command/bdist_wininst.py
@@ -298,7 +298,8 @@
                              bitmaplen,        # number of bytes in bitmap
                              )
         file.write(header)
-        file.write(open(arcname, "rb").read())
+        with open(arcname, "rb") as arcfile:
+            file.write(arcfile.read())
 
     # create_exe()
 
diff --git a/lib-python/modified-2.7/opcode.py b/lib-python/modified-2.7/opcode.py
--- a/lib-python/modified-2.7/opcode.py
+++ b/lib-python/modified-2.7/opcode.py
@@ -192,5 +192,6 @@
 def_op('LOOKUP_METHOD', 201)          # Index in name list
 hasname.append(201)
 def_op('CALL_METHOD', 202)            # #args not including 'self'
+def_op('BUILD_LIST_FROM_ARG', 203)
 
 del def_op, name_op, jrel_op, jabs_op
diff --git a/lib-python/modified-2.7/test/test_dis.py b/lib-python/modified-2.7/test/test_dis.py
new file mode 100644
--- /dev/null
+++ b/lib-python/modified-2.7/test/test_dis.py
@@ -0,0 +1,150 @@
+# Minimal tests for dis module
+
+from test.test_support import run_unittest
+import unittest
+import sys
+import dis
+import StringIO
+
+
+def _f(a):
+    print a
+    return 1
+
+dis_f = """\
+ %-4d         0 LOAD_FAST                0 (a)
+              3 PRINT_ITEM
+              4 PRINT_NEWLINE
+
+ %-4d         5 LOAD_CONST               1 (1)
+              8 RETURN_VALUE
+"""%(_f.func_code.co_firstlineno + 1,
+     _f.func_code.co_firstlineno + 2)
+
+
+def bug708901():
+    for res in range(1,
+                     10):
+        pass
+
+dis_bug708901 = """\
+ %-4d         0 SETUP_LOOP              23 (to 26)
+              3 LOAD_GLOBAL              0 (range)
+              6 LOAD_CONST               1 (1)
+
+ %-4d         9 LOAD_CONST               2 (10)
+             12 CALL_FUNCTION            2
+             15 GET_ITER
+        >>   16 FOR_ITER                 6 (to 25)
+             19 STORE_FAST               0 (res)
+
+ %-4d        22 JUMP_ABSOLUTE           16
+        >>   25 POP_BLOCK
+        >>   26 LOAD_CONST               0 (None)
+             29 RETURN_VALUE
+"""%(bug708901.func_code.co_firstlineno + 1,
+     bug708901.func_code.co_firstlineno + 2,
+     bug708901.func_code.co_firstlineno + 3)
+
+
+def bug1333982(x=[]):
+    assert 0, ([s for s in x] +
+              1)
+    pass
+
+dis_bug1333982 = """\
+ %-4d         0 LOAD_CONST               1 (0)
+              3 POP_JUMP_IF_TRUE        38
+              6 LOAD_GLOBAL              0 (AssertionError)
+              9 LOAD_FAST                0 (x)
+             12 BUILD_LIST_FROM_ARG      0
+             15 GET_ITER
+        >>   16 FOR_ITER                12 (to 31)
+             19 STORE_FAST               1 (s)
+             22 LOAD_FAST                1 (s)
+             25 LIST_APPEND              2
+             28 JUMP_ABSOLUTE           16
+
+ %-4d   >>   31 LOAD_CONST               2 (1)
+             34 BINARY_ADD
+             35 RAISE_VARARGS            2
+
+ %-4d   >>   38 LOAD_CONST               0 (None)
+             41 RETURN_VALUE
+"""%(bug1333982.func_code.co_firstlineno + 1,
+     bug1333982.func_code.co_firstlineno + 2,
+     bug1333982.func_code.co_firstlineno + 3)
+
+_BIG_LINENO_FORMAT = """\
+%3d           0 LOAD_GLOBAL              0 (spam)
+              3 POP_TOP
+              4 LOAD_CONST               0 (None)
+              7 RETURN_VALUE
+"""
+
+class DisTests(unittest.TestCase):
+    def do_disassembly_test(self, func, expected):
+        s = StringIO.StringIO()
+        save_stdout = sys.stdout
+        sys.stdout = s
+        dis.dis(func)
+        sys.stdout = save_stdout
+        got = s.getvalue()
+        # Trim trailing blanks (if any).
+        lines = got.split('\n')
+        lines = [line.rstrip() for line in lines]
+        expected = expected.split("\n")
+        import difflib
+        if expected != lines:
+            self.fail(
+                "events did not match expectation:\n" +
+                "\n".join(difflib.ndiff(expected,
+                                        lines)))
+
+    def test_opmap(self):
+        self.assertEqual(dis.opmap["STOP_CODE"], 0)
+        self.assertIn(dis.opmap["LOAD_CONST"], dis.hasconst)
+        self.assertIn(dis.opmap["STORE_NAME"], dis.hasname)
+
+    def test_opname(self):
+        self.assertEqual(dis.opname[dis.opmap["LOAD_FAST"]], "LOAD_FAST")
+
+    def test_boundaries(self):
+        self.assertEqual(dis.opmap["EXTENDED_ARG"], dis.EXTENDED_ARG)
+        self.assertEqual(dis.opmap["STORE_NAME"], dis.HAVE_ARGUMENT)
+
+    def test_dis(self):
+        self.do_disassembly_test(_f, dis_f)
+
+    def test_bug_708901(self):
+        self.do_disassembly_test(bug708901, dis_bug708901)
+
+    def test_bug_1333982(self):
+        # This one is checking bytecodes generated for an `assert` statement,
+        # so fails if the tests are run with -O.  Skip this test then.
+        if __debug__:
+            self.do_disassembly_test(bug1333982, dis_bug1333982)
+
+    def test_big_linenos(self):
+        def func(count):
+            namespace = {}
+            func = "def foo():\n " + "".join(["\n "] * count + ["spam\n"])
+            exec func in namespace
+            return namespace['foo']
+
+        # Test all small ranges
+        for i in xrange(1, 300):
+            expected = _BIG_LINENO_FORMAT % (i + 2)
+            self.do_disassembly_test(func(i), expected)
+
+        # Test some larger ranges too
+        for i in xrange(300, 5000, 10):
+            expected = _BIG_LINENO_FORMAT % (i + 2)
+            self.do_disassembly_test(func(i), expected)
+
+def test_main():
+    run_unittest(DisTests)
+
+
+if __name__ == "__main__":
+    test_main()
diff --git a/lib_pypy/_csv.py b/lib_pypy/_csv.py
--- a/lib_pypy/_csv.py
+++ b/lib_pypy/_csv.py
@@ -414,7 +414,7 @@
 
     def _parse_add_char(self, c):
         if len(self.field) + len(c) > _field_limit:
-            raise Error("field larget than field limit (%d)" % (_field_limit))
+            raise Error("field larger than field limit (%d)" % (_field_limit))
         self.field += c
         
 
diff --git a/lib_pypy/_ctypes/builtin.py b/lib_pypy/_ctypes/builtin.py
--- a/lib_pypy/_ctypes/builtin.py
+++ b/lib_pypy/_ctypes/builtin.py
@@ -31,24 +31,20 @@
     arg = cobj._get_buffer_value()
     return _rawffi.wcharp2rawunicode(arg, lgt)
 
-class ErrorObject(local):
-    def __init__(self):
-        self.errno = 0
-        self.winerror = 0
-_error_object = ErrorObject()
+_err = local()
 
 def get_errno():
-    return _error_object.errno
+    return getattr(_err, "errno", 0)
 
 def set_errno(errno):
-    old_errno = _error_object.errno
-    _error_object.errno = errno
+    old_errno = get_errno()
+    _err.errno = errno
     return old_errno
 
 def get_last_error():
-    return _error_object.winerror
+    return getattr(_err, "winerror", 0)
 
 def set_last_error(winerror):
-    old_winerror = _error_object.winerror
-    _error_object.winerror = winerror
+    old_winerror = get_last_error()
+    _err.winerror = winerror
     return old_winerror
diff --git a/lib_pypy/_ctypes/function.py b/lib_pypy/_ctypes/function.py
--- a/lib_pypy/_ctypes/function.py
+++ b/lib_pypy/_ctypes/function.py
@@ -3,7 +3,7 @@
 from _ctypes.primitive import SimpleType, _SimpleCData
 from _ctypes.basics import ArgumentError, keepalive_key
 from _ctypes.basics import is_struct_shape
-from _ctypes.builtin import set_errno, set_last_error
+from _ctypes.builtin import get_errno, set_errno, get_last_error, set_last_error
 import _rawffi
 import _ffi
 import sys
@@ -350,16 +350,24 @@
     def _call_funcptr(self, funcptr, *newargs):
 
         if self._flags_ & _rawffi.FUNCFLAG_USE_ERRNO:
-            set_errno(_rawffi.get_errno())
+            tmp = _rawffi.get_errno()
+            _rawffi.set_errno(get_errno())
+            set_errno(tmp)
         if self._flags_ & _rawffi.FUNCFLAG_USE_LASTERROR:
-            set_last_error(_rawffi.get_last_error())
+            tmp = _rawffi.get_last_error()
+            _rawffi.set_last_error(get_last_error())
+            set_last_error(tmp)
         try:
             result = funcptr(*newargs)
         finally:
             if self._flags_ & _rawffi.FUNCFLAG_USE_ERRNO:
-                set_errno(_rawffi.get_errno())
+                tmp = _rawffi.get_errno()
+                _rawffi.set_errno(get_errno())
+                set_errno(tmp)
             if self._flags_ & _rawffi.FUNCFLAG_USE_LASTERROR:
-                set_last_error(_rawffi.get_last_error())
+                tmp = _rawffi.get_last_error()
+                _rawffi.set_last_error(get_last_error())
+                set_last_error(tmp)
         #
         try:
             return self._build_result(self._restype_, result, newargs)
diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py
--- a/pypy/annotation/builtin.py
+++ b/pypy/annotation/builtin.py
@@ -37,7 +37,11 @@
     try:
         realresult = func(*args)
     except (ValueError, OverflowError):
-        return s_ImpossibleValue   # no possible answer for this precise input
+        # no possible answer for this precise input.  Be conservative
+        # and keep the computation non-constant.  Example:
+        # unichr(constant-that-doesn't-fit-16-bits) on platforms where
+        # the underlying Python has sys.maxunicode == 0xffff.
+        return s_result
     s_realresult = immutablevalue(realresult)
     if not s_result.contains(s_realresult):
         raise Exception("%s%r returned %r, which is not contained in %s" % (
diff --git a/pypy/annotation/classdef.py b/pypy/annotation/classdef.py
--- a/pypy/annotation/classdef.py
+++ b/pypy/annotation/classdef.py
@@ -134,12 +134,19 @@
             if self.name not in homedef.classdesc.all_enforced_attrs:
                 self.attr_allowed = False
                 if not self.readonly:
-                    raise NoSuchAttrError(homedef, self.name)
+                    raise NoSuchAttrError(
+                        "setting forbidden attribute %r on %r" % (
+                        self.name, homedef))
 
     def modified(self, classdef='?'):
         self.readonly = False
         if not self.attr_allowed:
-            raise NoSuchAttrError(classdef, self.name)
+            raise NoSuchAttrError(
+                "Attribute %r on %r should be read-only.\n" % (self.name,
+                                                               classdef) +
+                "This error can be caused by another 'getattr' that promoted\n"
+                "the attribute here; the list of read locations is:\n" +
+                '\n'.join([str(loc[0]) for loc in self.read_locations]))
 
 
 class ClassDef(object):
diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py
--- a/pypy/annotation/test/test_annrpython.py
+++ b/pypy/annotation/test/test_annrpython.py
@@ -1,15 +1,12 @@
 from __future__ import with_statement
-import autopath
 import py.test
 import sys
 from pypy import conftest
-from pypy.tool.udir import udir
 
 from pypy.annotation import model as annmodel
 from pypy.annotation.annrpython import RPythonAnnotator as _RPythonAnnotator
 from pypy.translator.translator import graphof as tgraphof
 from pypy.annotation import policy
-from pypy.annotation import specialize
 from pypy.annotation.listdef import ListDef, ListChangeUnallowed
 from pypy.annotation.dictdef import DictDef
 from pypy.objspace.flow.model import *
@@ -2556,6 +2553,26 @@
         s = a.build_types(f, [int])
         assert s.knowntype == int
 
+    def test_slots_reads(self):
+        class A(object):
+            __slots__ = ()
+        class B(A):
+            def __init__(self, x):
+                self.x = x
+        def f(x):
+            if x:
+                a = A()
+            else:
+                a = B(x)
+            return a.x   # should explode here
+
+        a = self.RPythonAnnotator()
+        e = py.test.raises(Exception, a.build_types, f, [int])
+        # this should explode on reading the attribute 'a.x', but it can
+        # sometimes explode on 'self.x = x', which does not make much sense.
+        # But it looks hard to fix in general: we don't know yet during 'a.x'
+        # if the attribute x will be read-only or read-write.
+
     def test_unboxed_value(self):
         class A(object):
             __slots__ = ()
diff --git a/pypy/interpreter/astcompiler/assemble.py b/pypy/interpreter/astcompiler/assemble.py
--- a/pypy/interpreter/astcompiler/assemble.py
+++ b/pypy/interpreter/astcompiler/assemble.py
@@ -610,6 +610,8 @@
     ops.JUMP_IF_FALSE_OR_POP : 0,
     ops.POP_JUMP_IF_TRUE : -1,
     ops.POP_JUMP_IF_FALSE : -1,
+
+    ops.BUILD_LIST_FROM_ARG: 1,
 }
 
 
diff --git a/pypy/interpreter/astcompiler/codegen.py b/pypy/interpreter/astcompiler/codegen.py
--- a/pypy/interpreter/astcompiler/codegen.py
+++ b/pypy/interpreter/astcompiler/codegen.py
@@ -965,7 +965,7 @@
         self.emit_op_arg(ops.CALL_METHOD, (kwarg_count << 8) | arg_count)
         return True
 
-    def _listcomp_generator(self, gens, gen_index, elt):
+    def _listcomp_generator(self, gens, gen_index, elt, single=False):
         start = self.new_block()
         skip = self.new_block()
         if_cleanup = self.new_block()
@@ -973,6 +973,8 @@
         gen = gens[gen_index]
         assert isinstance(gen, ast.comprehension)
         gen.iter.walkabout(self)
+        if single:
+            self.emit_op_arg(ops.BUILD_LIST_FROM_ARG, 0)
         self.emit_op(ops.GET_ITER)
         self.use_next_block(start)
         self.emit_jump(ops.FOR_ITER, anchor)
@@ -998,8 +1000,12 @@
 
     def visit_ListComp(self, lc):
         self.update_position(lc.lineno)
-        self.emit_op_arg(ops.BUILD_LIST, 0)
-        self._listcomp_generator(lc.generators, 0, lc.elt)
+        if len(lc.generators) != 1 or lc.generators[0].ifs:
+            single = False
+            self.emit_op_arg(ops.BUILD_LIST, 0)
+        else:
+            single = True
+        self._listcomp_generator(lc.generators, 0, lc.elt, single=single)
 
     def _comp_generator(self, node, generators, gen_index):
         start = self.new_block()
diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py
--- a/pypy/interpreter/astcompiler/test/test_compiler.py
+++ b/pypy/interpreter/astcompiler/test/test_compiler.py
@@ -908,3 +908,17 @@
             return d['f'](5)
         """)
         assert 'generator' in space.str_w(space.repr(w_generator))
+        
+    def test_list_comprehension(self):
+        source = "def f(): [i for i in l]"
+        source2 = "def f(): [i for i in l for j in l]"
+        source3 = "def f(): [i for i in l if i]"
+        counts = self.count_instructions(source)
+        assert ops.BUILD_LIST not in counts
+        assert counts[ops.BUILD_LIST_FROM_ARG] == 1
+        counts = self.count_instructions(source2)
+        assert counts[ops.BUILD_LIST] == 1
+        assert ops.BUILD_LIST_FROM_ARG not in counts
+        counts = self.count_instructions(source3)
+        assert counts[ops.BUILD_LIST] == 1
+        assert ops.BUILD_LIST_FROM_ARG not in counts
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -7,7 +7,8 @@
 from pypy.interpreter.miscutils import ThreadLocals
 from pypy.tool.cache import Cache
 from pypy.tool.uid import HUGEVAL_BYTES
-from pypy.rlib.objectmodel import we_are_translated, newlist, compute_unique_id
+from pypy.rlib.objectmodel import we_are_translated, newlist_hint,\
+     compute_unique_id
 from pypy.rlib.debug import make_sure_not_resized
 from pypy.rlib.timer import DummyTimer, Timer
 from pypy.rlib.rarithmetic import r_uint
@@ -833,7 +834,7 @@
             items = []
         else:
             try:
-                items = newlist(lgt_estimate)
+                items = newlist_hint(lgt_estimate)
             except MemoryError:
                 items = [] # it might have lied
         #
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -15,9 +15,8 @@
 from pypy.rlib.rarithmetic import r_uint, intmask
 from pypy.rlib.unroll import unrolling_iterable
 from pypy.rlib.debug import check_nonneg
-from pypy.tool.stdlib_opcode import (bytecode_spec, host_bytecode_spec,
-                                     unrolling_all_opcode_descs, opmap,
-                                     host_opmap)
+from pypy.tool.stdlib_opcode import (bytecode_spec,
+                                     unrolling_all_opcode_descs)
 
 def unaryoperation(operationname):
     """NOT_RPYTHON"""
@@ -713,6 +712,19 @@
         w_list = self.space.newlist(items)
         self.pushvalue(w_list)
 
+    def BUILD_LIST_FROM_ARG(self, _, next_instr):
+        # this is a little dance, because list has to be before the
+        # value
+        last_val = self.popvalue()
+        try:
+            lgt = self.space.len_w(last_val)
+        except OperationError, e:
+            if e.async(self.space):
+                raise
+            lgt = 0 # oh well
+        self.pushvalue(self.space.newlist([], sizehint=lgt))
+        self.pushvalue(last_val)
+
     def LOAD_ATTR(self, nameindex, next_instr):
         "obj.attributename"
         w_obj = self.popvalue()
diff --git a/pypy/jit/codewriter/jtransform.py b/pypy/jit/codewriter/jtransform.py
--- a/pypy/jit/codewriter/jtransform.py
+++ b/pypy/jit/codewriter/jtransform.py
@@ -365,7 +365,7 @@
     def handle_builtin_call(self, op):
         oopspec_name, args = support.decode_builtin_call(op)
         # dispatch to various implementations depending on the oopspec_name
-        if oopspec_name.startswith('list.') or oopspec_name == 'newlist':
+        if oopspec_name.startswith('list.') or oopspec_name.startswith('newlist'):
             prepare = self._handle_list_call
         elif oopspec_name.startswith('stroruni.'):
             prepare = self._handle_stroruni_call
@@ -1494,6 +1494,14 @@
                                arraydescr, v_length],
                               op.result)
 
+    def do_resizable_newlist_hint(self, op, args, arraydescr, lengthdescr,
+                                  itemsdescr, structdescr):
+        v_hint = self._get_initial_newlist_length(op, args)
+        return SpaceOperation('newlist_hint',
+                              [structdescr, lengthdescr, itemsdescr,
+                               arraydescr, v_hint],
+                              op.result)
+
     def do_resizable_list_getitem(self, op, args, arraydescr, lengthdescr,
                                   itemsdescr, structdescr):
         v_index, extraop = self._prepare_list_getset(op, lengthdescr, args,
diff --git a/pypy/jit/codewriter/support.py b/pypy/jit/codewriter/support.py
--- a/pypy/jit/codewriter/support.py
+++ b/pypy/jit/codewriter/support.py
@@ -144,6 +144,10 @@
 _ll_1_newlist.need_result_type = True
 _ll_2_newlist.need_result_type = True
 
+def _ll_1_newlist_hint(LIST, hint):
+    return LIST.ll_newlist_hint(hint)
+_ll_1_newlist_hint.need_result_type = True
+
 def _ll_1_list_len(l):
     return l.ll_length()
 def _ll_2_list_getitem(l, index):
diff --git a/pypy/jit/metainterp/blackhole.py b/pypy/jit/metainterp/blackhole.py
--- a/pypy/jit/metainterp/blackhole.py
+++ b/pypy/jit/metainterp/blackhole.py
@@ -982,6 +982,15 @@
         cpu.bh_setfield_gc_r(result, itemsdescr, items)
         return result
 
+    @arguments("cpu", "d", "d", "d", "d", "i", returns="r")
+    def bhimpl_newlist_hint(cpu, structdescr, lengthdescr, itemsdescr,
+                            arraydescr, lengthhint):
+        result = cpu.bh_new(structdescr)
+        cpu.bh_setfield_gc_i(result, lengthdescr, 0)
+        items = cpu.bh_new_array(arraydescr, lengthhint)
+        cpu.bh_setfield_gc_r(result, itemsdescr, items)
+        return result
+
     @arguments("cpu", "r", "d", "d", "i", returns="i")
     def bhimpl_getlistitem_gc_i(cpu, lst, itemsdescr, arraydescr, index):
         items = cpu.bh_getfield_gc_r(lst, itemsdescr)
diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -509,6 +509,15 @@
         self._opimpl_setfield_gc_any(sbox, itemsdescr, abox)
         return sbox
 
+    @arguments("descr", "descr", "descr", "descr", "box")
+    def opimpl_newlist_hint(self, structdescr, lengthdescr, itemsdescr,
+                            arraydescr, sizehintbox):
+        sbox = self.opimpl_new(structdescr)
+        self._opimpl_setfield_gc_any(sbox, lengthdescr, history.CONST_FALSE)
+        abox = self.opimpl_new_array(arraydescr, sizehintbox)
+        self._opimpl_setfield_gc_any(sbox, itemsdescr, abox)
+        return sbox
+
     @arguments("box", "descr", "descr", "box")
     def _opimpl_getlistitem_gc_any(self, listbox, itemsdescr, arraydescr,
                                    indexbox):
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
@@ -1,4 +1,5 @@
 import py
+from pypy.rlib.objectmodel import newlist_hint
 from pypy.rlib.jit import JitDriver
 from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
 
@@ -228,6 +229,27 @@
         self.check_resops({'jump': 1, 'int_gt': 2, 'int_add': 2,
                            'guard_true': 2, 'int_sub': 2})
 
+    def test_newlist_hint(self):
+        def f(i):
+            l = newlist_hint(i)
+            return len(l)
+
+        r = self.interp_operations(f, [3])
+        assert r == 0
+
+    def test_newlist_hint_optimized(self):
+        driver = JitDriver(greens = [], reds = ['i'])
+
+        def f(i):
+            while i > 0:
+                driver.jit_merge_point(i=i)
+                l = newlist_hint(5)
+                l.append(1)
+                i -= l[0]
+
+        self.meta_interp(f, [10], listops=True)
+        self.check_resops(new_array=0, call=0)
+
 class TestOOtype(ListTests, OOJitMixin):
     pass
 
diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py
--- a/pypy/module/__pypy__/__init__.py
+++ b/pypy/module/__pypy__/__init__.py
@@ -1,5 +1,5 @@
+import sys
 
-# Package initialisation
 from pypy.interpreter.mixedmodule import MixedModule
 from pypy.module.imp.importing import get_pyc_magic
 
@@ -12,6 +12,19 @@
         "UnicodeBuilder": "interp_builders.W_UnicodeBuilder",
     }
 
+class TimeModule(MixedModule):
+    appleveldefs = {}
+    interpleveldefs = {}
+    if sys.platform.startswith("linux"):
+        interpleveldefs["clock_gettime"] = "interp_time.clock_gettime"
+        interpleveldefs["clock_getres"] = "interp_time.clock_getres"
+        for name in [
+            "CLOCK_REALTIME", "CLOCK_MONOTONIC", "CLOCK_MONOTONIC_RAW",
+            "CLOCK_PROCESS_CPUTIME_ID", "CLOCK_THREAD_CPUTIME_ID"
+        ]:
+            interpleveldefs[name] = "space.wrap(interp_time.%s)" % name
+
+
 class Module(MixedModule):
     appleveldefs = {
     }
@@ -32,6 +45,7 @@
 
     submodules = {
         "builders": BuildersModule,
+        "time": TimeModule,
     }
 
     def setup_after_space_initialization(self):
diff --git a/pypy/module/__pypy__/interp_time.py b/pypy/module/__pypy__/interp_time.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/__pypy__/interp_time.py
@@ -0,0 +1,64 @@
+import sys
+
+from pypy.interpreter.error import exception_from_errno
+from pypy.interpreter.gateway import unwrap_spec
+from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.rpython.tool import rffi_platform
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
+
+
+class CConfig:
+    _compilation_info_ = ExternalCompilationInfo(
+        includes=["time.h"],
+        libraries=["rt"],
+    )
+
+    HAS_CLOCK_GETTIME = rffi_platform.Has('clock_gettime')
+
+    CLOCK_REALTIME = rffi_platform.DefinedConstantInteger("CLOCK_REALTIME")
+    CLOCK_MONOTONIC = rffi_platform.DefinedConstantInteger("CLOCK_MONOTONIC")
+    CLOCK_MONOTONIC_RAW = rffi_platform.DefinedConstantInteger("CLOCK_MONOTONIC_RAW")
+    CLOCK_PROCESS_CPUTIME_ID = rffi_platform.DefinedConstantInteger("CLOCK_PROCESS_CPUTIME_ID")
+    CLOCK_THREAD_CPUTIME_ID = rffi_platform.DefinedConstantInteger("CLOCK_THREAD_CPUTIME_ID")
+
+    TIMESPEC = rffi_platform.Struct("struct timespec", [
+        ("tv_sec", rffi.TIME_T),
+        ("tv_nsec", rffi.LONG),
+    ])
+
+cconfig = rffi_platform.configure(CConfig)
+
+HAS_CLOCK_GETTIME = cconfig["HAS_CLOCK_GETTIME"]
+
+CLOCK_REALTIME = cconfig["CLOCK_REALTIME"]
+CLOCK_MONOTONIC = cconfig["CLOCK_MONOTONIC"]
+CLOCK_MONOTONIC_RAW = cconfig["CLOCK_MONOTONIC_RAW"]
+CLOCK_PROCESS_CPUTIME_ID = cconfig["CLOCK_PROCESS_CPUTIME_ID"]
+CLOCK_THREAD_CPUTIME_ID = cconfig["CLOCK_THREAD_CPUTIME_ID"]
+
+TIMESPEC = cconfig["TIMESPEC"]
+
+c_clock_gettime = rffi.llexternal("clock_gettime",
+    [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT,
+    compilation_info=CConfig._compilation_info_, threadsafe=False
+)
+c_clock_getres = rffi.llexternal("clock_getres",
+    [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT,
+    compilation_info=CConfig._compilation_info_, threadsafe=False
+)
+
+ at unwrap_spec(clk_id="c_int")
+def clock_gettime(space, clk_id):
+    with lltype.scoped_alloc(TIMESPEC) as tp:
+        ret = c_clock_gettime(clk_id, tp)
+        if ret != 0:
+            raise exception_from_errno(space, space.w_IOError)
+        return space.wrap(tp.c_tv_sec + tp.c_tv_nsec * 1e-9)
+
+ at unwrap_spec(clk_id="c_int")
+def clock_getres(space, clk_id):
+    with lltype.scoped_alloc(TIMESPEC) as tp:
+        ret = c_clock_getres(clk_id, tp)
+        if ret != 0:
+            raise exception_from_errno(space, space.w_IOError)
+        return space.wrap(tp.c_tv_sec + tp.c_tv_nsec * 1e-9)
diff --git a/pypy/module/__pypy__/test/test_time.py b/pypy/module/__pypy__/test/test_time.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/__pypy__/test/test_time.py
@@ -0,0 +1,26 @@
+import py
+
+from pypy.module.__pypy__.interp_time import HAS_CLOCK_GETTIME
+
+
+class AppTestTime(object):
+    def setup_class(cls):
+        if not HAS_CLOCK_GETTIME:
+            py.test.skip("need time.clock_gettime")
+
+    def test_clock_realtime(self):
+        from __pypy__ import time
+        res = time.clock_gettime(time.CLOCK_REALTIME)
+        assert isinstance(res, float)
+
+    def test_clock_monotonic(self):
+        from __pypy__ import time
+        a = time.clock_gettime(time.CLOCK_MONOTONIC)
+        b = time.clock_gettime(time.CLOCK_MONOTONIC)
+        assert a <= b
+
+    def test_clock_getres(self):
+        from __pypy__ import time
+        res = time.clock_getres(time.CLOCK_REALTIME)
+        assert res > 0.0
+        assert res <= 1.0
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
@@ -107,6 +107,10 @@
         ('logical_xor', 'logical_xor'),
         ('logical_not', 'logical_not'),
         ('logical_or', 'logical_or'),
+        ('log', 'log'),
+        ('log2', 'log2'),
+        ('log10', 'log10'),
+        ('log1p', 'log1p'),
     ]:
         interpleveldefs[exposed] = "interp_ufuncs.get(space).%s" % impl
 
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
@@ -80,6 +80,7 @@
     descr_mul = _binop_impl("multiply")
     descr_div = _binop_impl("divide")
     descr_truediv = _binop_impl("true_divide")
+    descr_floordiv = _binop_impl("floor_divide")
     descr_mod = _binop_impl("mod")
     descr_pow = _binop_impl("power")
     descr_lshift = _binop_impl("left_shift")
@@ -100,6 +101,7 @@
     descr_rmul = _binop_right_impl("multiply")
     descr_rdiv = _binop_right_impl("divide")
     descr_rtruediv = _binop_right_impl("true_divide")
+    descr_rfloordiv = _binop_right_impl("floor_divide")
     descr_rmod = _binop_right_impl("mod")
     descr_rpow = _binop_right_impl("power")
     descr_rlshift = _binop_right_impl("left_shift")
@@ -208,6 +210,7 @@
     __mul__ = interp2app(W_GenericBox.descr_mul),
     __div__ = interp2app(W_GenericBox.descr_div),
     __truediv__ = interp2app(W_GenericBox.descr_truediv),
+    __floordiv__ = interp2app(W_GenericBox.descr_floordiv),
     __mod__ = interp2app(W_GenericBox.descr_mod),
     __divmod__ = interp2app(W_GenericBox.descr_divmod),
     __pow__ = interp2app(W_GenericBox.descr_pow),
@@ -222,6 +225,7 @@
     __rmul__ = interp2app(W_GenericBox.descr_rmul),
     __rdiv__ = interp2app(W_GenericBox.descr_rdiv),
     __rtruediv__ = interp2app(W_GenericBox.descr_rtruediv),
+    __rfloordiv__ = interp2app(W_GenericBox.descr_rfloordiv),
     __rmod__ = interp2app(W_GenericBox.descr_rmod),
     __rdivmod__ = interp2app(W_GenericBox.descr_rdivmod),
     __rpow__ = interp2app(W_GenericBox.descr_rpow),
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
@@ -102,6 +102,7 @@
     descr_mul = _binop_impl("multiply")
     descr_div = _binop_impl("divide")
     descr_truediv = _binop_impl("true_divide")
+    descr_floordiv = _binop_impl("floor_divide")
     descr_mod = _binop_impl("mod")
     descr_pow = _binop_impl("power")
     descr_lshift = _binop_impl("left_shift")
@@ -136,6 +137,7 @@
     descr_rmul = _binop_right_impl("multiply")
     descr_rdiv = _binop_right_impl("divide")
     descr_rtruediv = _binop_right_impl("true_divide")
+    descr_rfloordiv = _binop_right_impl("floor_divide")
     descr_rmod = _binop_right_impl("mod")
     descr_rpow = _binop_right_impl("power")
     descr_rlshift = _binop_right_impl("left_shift")
@@ -1250,6 +1252,7 @@
     __mul__ = interp2app(BaseArray.descr_mul),
     __div__ = interp2app(BaseArray.descr_div),
     __truediv__ = interp2app(BaseArray.descr_truediv),
+    __floordiv__ = interp2app(BaseArray.descr_floordiv),
     __mod__ = interp2app(BaseArray.descr_mod),
     __divmod__ = interp2app(BaseArray.descr_divmod),
     __pow__ = interp2app(BaseArray.descr_pow),
@@ -1264,6 +1267,7 @@
     __rmul__ = interp2app(BaseArray.descr_rmul),
     __rdiv__ = interp2app(BaseArray.descr_rdiv),
     __rtruediv__ = interp2app(BaseArray.descr_rtruediv),
+    __rfloordiv__ = interp2app(BaseArray.descr_rfloordiv),
     __rmod__ = interp2app(BaseArray.descr_rmod),
     __rdivmod__ = interp2app(BaseArray.descr_rdivmod),
     __rpow__ = interp2app(BaseArray.descr_rpow),
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
@@ -388,6 +388,7 @@
                                              "int_only": True}),
             ("bitwise_xor", "bitwise_xor", 2, {"int_only": True}),
             ("invert", "invert", 1, {"int_only": True}),
+            ("floor_divide", "floordiv", 2, {"promote_bools": True}),
             ("divide", "div", 2, {"promote_bools": True}),
             ("true_divide", "div", 2, {"promote_to_float": True}),
             ("mod", "mod", 2, {"promote_bools": True}),
@@ -441,6 +442,11 @@
             ("arcsinh", "arcsinh", 1, {"promote_to_float": True}),
             ("arccosh", "arccosh", 1, {"promote_to_float": True}),
             ("arctanh", "arctanh", 1, {"promote_to_float": True}),
+
+            ("log", "log", 1, {"promote_to_float": True}),
+            ("log2", "log2", 1, {"promote_to_float": True}),
+            ("log10", "log10", 1, {"promote_to_float": True}),
+            ("log1p", "log1p", 1, {"promote_to_float": True}),
         ]:
             self.add_ufunc(space, *ufunc_def)
 
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
@@ -625,6 +625,56 @@
         for i in range(5):
             assert b[i] == i / 5.0
 
+    def test_floordiv(self):
+        from math import isnan
+        from _numpypy import array, dtype
+
+        a = array(range(1, 6))
+        b = a // a
+        assert (b == [1, 1, 1, 1, 1]).all()
+
+        a = array(range(1, 6), dtype=bool)
+        b = a // a
+        assert b.dtype is dtype("int8")
+        assert (b == [1, 1, 1, 1, 1]).all()
+
+        a = array([-1, 0, 1])
+        b = array([0, 0, 0])
+        c = a // b
+        assert (c == [0, 0, 0]).all()
+
+        a = array([-1.0, 0.0, 1.0])
+        b = array([0.0, 0.0, 0.0])
+        c = a // b
+        assert c[0] == float('-inf')
+        assert isnan(c[1])
+        assert c[2] == float('inf')
+
+        b = array([-0.0, -0.0, -0.0])
+        c = a // b
+        assert c[0] == float('inf')
+        assert isnan(c[1])
+        assert c[2] == float('-inf')
+
+    def test_floordiv_other(self):
+        from _numpypy import array
+        a = array(range(5))
+        b = array([2, 2, 2, 2, 2], float)
+        c = a // b
+        assert (c == [0, 0, 1, 1, 2]).all()
+
+    def test_rfloordiv(self):
+        from _numpypy import array
+        a = array(range(1, 6))
+        b = 3 // a
+        assert (b == [3, 1, 1, 0, 0]).all()
+
+    def test_floordiv_constant(self):
+        from _numpypy import array
+        a = array(range(5))
+        b = a // 2
+        assert (b == [0, 0, 1, 1, 2]).all()
+
     def test_truediv(self):
         from operator import truediv
         from _numpypy import arange
diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py
--- a/pypy/module/micronumpy/test/test_ufuncs.py
+++ b/pypy/module/micronumpy/test/test_ufuncs.py
@@ -481,3 +481,26 @@
         assert (logical_xor([True, False, True, False], [1, 2, 0, 0])
                 == [False, True, True, False]).all()
         assert (logical_not([True, False]) == [False, True]).all()
+
+    def test_logn(self):
+        import math
+        from _numpypy import log, log2, log10
+
+        for log_func, base in [(log, math.e), (log2, 2), (log10, 10)]:
+            for v in [float('-nan'), float('-inf'), -1, float('nan')]:
+                assert math.isnan(log_func(v))
+            for v in [-0.0, 0.0]:
+                assert log_func(v) == float("-inf")
+            assert log_func(float('inf')) == float('inf')
+            assert (log_func([1, base]) == [0, 1]).all()
+
+    def test_log1p(self):
+        import math
+        from _numpypy import log1p
+
+        for v in [float('-nan'), float('-inf'), -2, float('nan')]:
+            assert math.isnan(log1p(v))
+        for v in [-1]:
+            assert log1p(v) == float("-inf")
+        assert log1p(float('inf')) == float('inf')
+        assert (log1p([0, 1e-50, math.e - 1]) == [0, 1e-50, 1]).all()
diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py
--- a/pypy/module/micronumpy/types.py
+++ b/pypy/module/micronumpy/types.py
@@ -280,6 +280,12 @@
         return v1 / v2
 
     @simple_binary_op
+    def floordiv(self, v1, v2):
+        if v2 == 0:
+            return 0
+        return v1 // v2
+
+    @simple_binary_op
     def mod(self, v1, v2):
         return v1 % v2
 
@@ -418,6 +424,15 @@
             return rfloat.copysign(rfloat.INFINITY, v1 * v2)
 
     @simple_binary_op
+    def floordiv(self, v1, v2):
+        try:
+            return v1 // v2
+        except ZeroDivisionError:
+            if v1 == v2 == 0.0:
+                return rfloat.NAN
+            return rfloat.copysign(rfloat.INFINITY, v1 * v2)
+
+    @simple_binary_op
     def mod(self, v1, v2):
         return math.fmod(v1, v2)
 
@@ -533,6 +548,48 @@
     def isinf(self, v):
         return rfloat.isinf(v)
 
+    @simple_unary_op
+    def log(self, v):
+        try:
+            return math.log(v)
+        except ValueError:
+            if v == 0.0:
+                # CPython raises ValueError here, so we have to check
+                # the value to find the correct numpy return value
+                return -rfloat.INFINITY
+            return rfloat.NAN
+
+    @simple_unary_op
+    def log2(self, v):
+        try:
+            return math.log(v, 2)
+        except ValueError:
+            if v == 0.0:
+                # CPython raises ValueError here, so we have to check
+                # the value to find the correct numpy return value
+                return -rfloat.INFINITY
+            return rfloat.NAN
+
+    @simple_unary_op
+    def log10(self, v):
+        try:
+            return math.log10(v)
+        except ValueError:
+            if v == 0.0:
+                # CPython raises ValueError here, so we have to check
+                # the value to find the correct numpy return value
+                return -rfloat.INFINITY
+            return rfloat.NAN
+
+    @simple_unary_op
+    def log1p(self, v):
+        try:
+            return rfloat.log1p(v)
+        except OverflowError:
+            return -rfloat.INFINITY
+        except ValueError:
+            return rfloat.NAN
+
 
 class Float32(BaseType, Float):
     T = rffi.FLOAT
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_errno.py b/pypy/module/test_lib_pypy/ctypes_tests/test_errno.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/test_lib_pypy/ctypes_tests/test_errno.py
@@ -0,0 +1,21 @@
+import py
+
+import ctypes
+from _ctypes import function
+
+_rawffi = py.test.importorskip("_rawffi")
+
+class TestErrno:
+
+    def test_errno_saved_and_restored(self):
+        def check():
+            assert _rawffi.get_errno() == 42
+            assert ctypes.get_errno() == old
+        check.free_temp_buffers = lambda *args: None
+        f = function.CFuncPtr()
+        old = _rawffi.get_errno()
+        f._flags_ = _rawffi.FUNCFLAG_USE_ERRNO
+        ctypes.set_errno(42)
+        f._call_funcptr(check)
+        assert _rawffi.get_errno() == old
+        ctypes.set_errno(0)
diff --git a/pypy/objspace/flow/operation.py b/pypy/objspace/flow/operation.py
--- a/pypy/objspace/flow/operation.py
+++ b/pypy/objspace/flow/operation.py
@@ -30,10 +30,7 @@
 
 def new_style_type(x):
     """Simulate a situation where every class is new-style"""
-    t = getattr(x, '__class__', type(x))
-    if t is types.ClassType:   # guess who's here?  exception classes...
-        t = type
-    return t
+    return getattr(x, '__class__', type(x))
 
 def do_int(x):
     return x.__int__()
diff --git a/pypy/objspace/std/abstractstring.py b/pypy/objspace/std/abstractstring.py
new file mode 100644
--- /dev/null
+++ b/pypy/objspace/std/abstractstring.py
@@ -0,0 +1,176 @@
+from pypy.objspace.std.model import W_Object
+from pypy.rlib.objectmodel import specialize
+
+
+class Mixin_BaseStringMethods(object):
+    __slots__ = ()
+
+    def isalnum(w_self, space):
+        return w_self._all_true(space, w_self._isalnum)
+
+    def isalpha(w_self, space):
+        return w_self._all_true(space, w_self._isalpha)
+
+    def isdigit(w_self, space):
+        return w_self._all_true(space, w_self._isdigit)
+
+    def islower(w_self, space):
+        return w_self._none_false_one_true(space,
+                w_self._islower, w_self._isupper)
+
+    def isspace(w_self, space):
+        return w_self._all_true(space, w_self._isspace)
+
+    def isupper(w_self, space):
+        return w_self._none_false_one_true(space,
+                w_self._isupper, w_self._islower)
+
+    def istitle(w_self, space):
+        return w_self._title(space)
+
+    def lower(w_self, space):
+        return w_self._transform(space, w_self._lower)
+
+    def swapcase(w_self, space):
+        return w_self._transform(space, w_self._swapcase)
+
+    def upper(w_self, space):
+        return w_self._transform(space, w_self._upper)
+
+
+class AbstractCharIterator(object):
+
+    def __init__(self, sequence):
+        self.sequence = sequence
+        self.pos = 0
+
+    def __len__(self):
+        return len(self.sequence)
+
+    def __iter__(self):
+        return self
+
+    def next(self):
+        ch = self.nextchar()
+        if ch is None:
+            raise StopIteration
+        return ch
+
+    # XXX deprecate nextchar() method
+    def nextchar(self):
+        if self.pos >= len(self):
+            return None
+        idx = self.pos
+        self.pos += 1
+        return self.sequence[idx]
+
+
+class W_AbstractBaseStringObject(W_Object):
+    __slots__ = ()
+
+    def __repr__(w_self):
+        """ representation for debugging purposes """
+        return "%s(%r)" % (w_self.__class__.__name__, w_self.raw_value())
+
+    def builder(w_self, space, size=0):
+        raise NotImplemented, "method not implemented"
+
+    def construct(w_self, space, data):
+        raise NotImplemented, "method not implemented"
+
+    def immutable_unique_id(w_self, space):
+        if w_self.user_overridden_class:
+            return None
+        return space.wrap(compute_unique_id(w_self.unwrap(space)))
+
+    def is_w(self, space, w_other):
+        if not isinstance(w_other, W_AbstractBaseStringObject):
+            return False
+        if self is w_other:
+            return True
+        if self.user_overridden_class or w_other.user_overridden_class:
+            return False
+        return self.unwrap(space) is w_other.unwrap(space)
+
+    def iterator(w_self, space):
+        return AbstractCharIterator(w_self.unwrap(space))
+
+    def length(w_self, space):
+        return len(w_self.unwrap(space))
+
+    def raw_value(w_self):
+        raise NotImplemented, "method not implemented"
+
+    def str_w(w_self, space):
+        raise NotImplemented, "method not implemented"
+
+    def unicode_w(w_self, space):
+        raise NotImplemented, "method not implemented"
+
+    def unwrap(w_self, space):
+        raise NotImplemented, "method not implemented"
+
+    @specialize.arg(2)
+    def _all_true(w_self, space, func):
+        """Test all elements of a list with func for True.
+        Returns True only if all elements test True."""
+        size = w_self.length(space)
+        it = w_self.iterator(space)
+        if size == 0:
+            return space.w_False
+        if size == 1:
+            return space.newbool(func(it.nextchar()))
+        # not all it objects will support iterator protocol, eg rope
+        for pos in range(size):
+            ch = it.nextchar()
+            if not func(ch):
+                return space.w_False
+        return space.w_True
+
+    @specialize.arg(2, 3)
+    def _none_false_one_true(w_self, space, pred, inverse):
+        """Test all elements against predicate and inverse.
+        Returns True only if all elements fail inverse and at least one
+        element passes predicate."""
+        v = w_self.unwrap(space)
+        if len(v) == 1:
+            c = v[0]
+            return space.newbool(pred(c))
+        status = False
+        for idx in range(len(v)):
+            if inverse(v[idx]):
+                return space.w_False
+            elif not status and pred(v[idx]):
+                status = True
+        return space.newbool(status)
+
+    def _title(w_self, space):
+        input = w_self.unwrap(space)
+        cased = False
+        previous_is_cased = False
+
+        for pos in range(0, len(input)):
+            ch = input[pos]
+            if w_self._isupper(ch):
+                if previous_is_cased:
+                    return space.w_False
+                previous_is_cased = True
+                cased = True
+            elif w_self._islower(ch):
+                if not previous_is_cased:
+                    return space.w_False
+                cased = True
+            else:
+                previous_is_cased = False
+
+        return space.newbool(cased)
+
+    @specialize.arg(2)
+    def _transform(w_self, space, func):
+        sz = w_self.length(space)
+        it = w_self.iterator(space)
+        bd = w_self.builder(space, sz)
+        for pos in range(sz):
+            ch = it.nextchar()
+            bd.append(func(ch))
+        return w_self.construct(space, bd.build())
diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py
--- a/pypy/objspace/std/bytearrayobject.py
+++ b/pypy/objspace/std/bytearrayobject.py
@@ -19,22 +19,45 @@
 from pypy.interpreter import gateway
 from pypy.interpreter.argument import Signature
 from pypy.interpreter.buffer import RWBuffer
+from pypy.objspace.std.abstractstring import \
+        W_AbstractBaseStringObject, Mixin_BaseStringMethods
 from pypy.objspace.std.bytearraytype import (
     makebytearraydata_w, getbytevalue,
     new_bytearray
 )
-from pypy.tool.sourcetools import func_with_new_name
 
 
-class W_BytearrayObject(W_Object):
+class Mixin_BytearrayMethods(Mixin_BaseStringMethods):
+    __slots__ = ()
+
+
+class W_AbstractBytearrayObject(stringobject.W_AbstractStringObject):
+    __slots__ = ()
+
+
+class W_BytearrayObject(W_AbstractBytearrayObject, Mixin_BytearrayMethods):
     from pypy.objspace.std.bytearraytype import bytearray_typedef as typedef
 
     def __init__(w_self, data):
         w_self.data = data
 
-    def __repr__(w_self):
-        """ representation for debugging purposes """
-        return "%s(%s)" % (w_self.__class__.__name__, ''.join(w_self.data))
+    def builder(w_self, space, size=0):
+        return StringBuilder(size)
+
+    def construct(w_self, space, data):
+        return W_BytearrayObject(data)
+
+    def raw_value(w_self):
+        return w_self.data
+
+    def str_w(w_self, space):
+        return w_self.data
+
+    def unicode_w(w_self, space):
+        # XXX should this use the default encoding?
+        from pypy.objspace.std.unicodetype import plain_str2unicode
+        return plain_str2unicode(space, w_self.data)
+
 
 registerimplementation(W_BytearrayObject)
 
@@ -279,6 +302,36 @@
 def str__Bytearray(space, w_bytearray):
     return space.wrap(''.join(w_bytearray.data))
 
+def str_isalnum__Bytearray(space, w_self):
+    return w_self.isalnum(space)
+
+def str_isalpha__Bytearray(space, w_self):
+    return w_self.isalpha(space)
+
+def str_isdigit__Bytearray(space, w_self):
+    return w_self.isdigit(space)
+
+def str_islower__Bytearray(space, w_self):
+    return w_self.islower(space)
+
+def str_isspace__Bytearray(space, w_self):
+    return w_self.isspace(space)
+
+def str_istitle__Bytearray(space, w_self):
+    return w_self.istitle(space)
+
+def str_isupper__Bytearray(space, w_self):
+    return w_self.isupper(space)
+
+def str_lower__Bytearray(space, w_self):
+    return w_self.lower(space)
+
+def str_upper__Bytearray(space, w_self):
+    return w_self.upper(space)
+
+def str_swapcase__Bytearray(space, w_self):
+    return w_self.swapcase(space)
+
 def str_count__Bytearray_Int_ANY_ANY(space, w_bytearray, w_char, w_start, w_stop):
     char = w_char.intval
     bytearray = w_bytearray.data
@@ -372,34 +425,6 @@
     w_str = str__Bytearray(space, w_bytearray)
     return stringobject.str_decode__String_ANY_ANY(space, w_str, w_encoding, w_errors)
 
-def str_islower__Bytearray(space, w_bytearray):
-    w_str = str__Bytearray(space, w_bytearray)
-    return stringobject.str_islower__String(space, w_str)
-
-def str_isupper__Bytearray(space, w_bytearray):
-    w_str = str__Bytearray(space, w_bytearray)
-    return stringobject.str_isupper__String(space, w_str)
-
-def str_isalpha__Bytearray(space, w_bytearray):
-    w_str = str__Bytearray(space, w_bytearray)
-    return stringobject.str_isalpha__String(space, w_str)
-
-def str_isalnum__Bytearray(space, w_bytearray):
-    w_str = str__Bytearray(space, w_bytearray)
-    return stringobject.str_isalnum__String(space, w_str)
-
-def str_isdigit__Bytearray(space, w_bytearray):
-    w_str = str__Bytearray(space, w_bytearray)
-    return stringobject.str_isdigit__String(space, w_str)
-
-def str_istitle__Bytearray(space, w_bytearray):
-    w_str = str__Bytearray(space, w_bytearray)
-    return stringobject.str_istitle__String(space, w_str)
-
-def str_isspace__Bytearray(space, w_bytearray):
-    w_str = str__Bytearray(space, w_bytearray)
-    return stringobject.str_isspace__String(space, w_str)
-
 def bytearray_insert__Bytearray_Int_ANY(space, w_bytearray, w_idx, w_other):
     where = space.int_w(w_idx)
     length = len(w_bytearray.data)
@@ -460,26 +485,11 @@
                                                          w_str2, w_max)
     return String2Bytearray(space, w_res)
 
-def str_upper__Bytearray(space, w_bytearray):
-    w_str = str__Bytearray(space, w_bytearray)
-    w_res = stringobject.str_upper__String(space, w_str)
-    return String2Bytearray(space, w_res)
-
-def str_lower__Bytearray(space, w_bytearray):
-    w_str = str__Bytearray(space, w_bytearray)
-    w_res = stringobject.str_lower__String(space, w_str)
-    return String2Bytearray(space, w_res)
-
 def str_title__Bytearray(space, w_bytearray):
     w_str = str__Bytearray(space, w_bytearray)
     w_res = stringobject.str_title__String(space, w_str)
     return String2Bytearray(space, w_res)
 
-def str_swapcase__Bytearray(space, w_bytearray):
-    w_str = str__Bytearray(space, w_bytearray)
-    w_res = stringobject.str_swapcase__String(space, w_str)
-    return String2Bytearray(space, w_res)
-
 def str_capitalize__Bytearray(space, w_bytearray):
     w_str = str__Bytearray(space, w_bytearray)
     w_res = stringobject.str_capitalize__String(space, w_str)
diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py
--- a/pypy/objspace/std/dictmultiobject.py
+++ b/pypy/objspace/std/dictmultiobject.py
@@ -2,6 +2,7 @@
 from pypy.objspace.std.model import registerimplementation, W_Object
 from pypy.objspace.std.register_all import register_all
 from pypy.objspace.std.settype import set_typedef as settypedef
+from pypy.objspace.std.frozensettype import frozenset_typedef as frozensettypedef
 from pypy.interpreter import gateway
 from pypy.interpreter.argument import Signature
 from pypy.interpreter.error import OperationError, operationerrfmt
@@ -488,7 +489,7 @@
 
 class _UnwrappedIteratorMixin:
     _mixin_ = True
-    
+
     def __init__(self, space, strategy, dictimplementation):
         IteratorImplementation.__init__(self, space, dictimplementation)
         self.iterator = strategy.unerase(dictimplementation.dstorage).iteritems()
@@ -837,10 +838,12 @@
         return all_contained_in(space, w_dictview, w_otherview)
     return space.w_False
 eq__DictViewKeys_settypedef = eq__DictViewKeys_DictViewKeys
+eq__DictViewKeys_frozensettypedef = eq__DictViewKeys_DictViewKeys
 
 eq__DictViewKeys_DictViewItems = eq__DictViewKeys_DictViewKeys
 eq__DictViewItems_DictViewItems = eq__DictViewKeys_DictViewKeys
 eq__DictViewItems_settypedef = eq__DictViewItems_DictViewItems
+eq__DictViewItems_frozensettypedef = eq__DictViewItems_DictViewItems
 
 def repr__DictViewKeys(space, w_dictview):
     w_seq = space.call_function(space.w_list, w_dictview)
diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -7,7 +7,7 @@
 from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
 from pypy.objspace.std import slicetype
 from pypy.interpreter import gateway, baseobjspace
-from pypy.rlib.objectmodel import instantiate, specialize
+from pypy.rlib.objectmodel import instantiate, specialize, newlist_hint
 from pypy.rlib.listsort import make_timsort_class
 from pypy.rlib import rerased, jit, debug
 from pypy.interpreter.argument import Signature
@@ -32,9 +32,11 @@
     storage = strategy.erase(None)
     return W_ListObject.from_storage_and_strategy(space, storage, strategy)
 
- at jit.look_inside_iff(lambda space, list_w: jit.isconstant(len(list_w)) and len(list_w) < UNROLL_CUTOFF)
-def get_strategy_from_list_objects(space, list_w):
+ at jit.look_inside_iff(lambda space, list_w, sizehint: jit.isconstant(len(list_w)) and len(list_w) < UNROLL_CUTOFF)
+def get_strategy_from_list_objects(space, list_w, sizehint):
     if not list_w:
+        if sizehint != -1:
+            return SizeListStrategy(space, sizehint)
         return space.fromcache(EmptyListStrategy)
 
     # check for ints
@@ -75,11 +77,13 @@
 class W_ListObject(W_AbstractListObject):
     from pypy.objspace.std.listtype import list_typedef as typedef
 
-    def __init__(w_self, space, wrappeditems):
+    def __init__(w_self, space, wrappeditems, sizehint=-1):
         assert isinstance(wrappeditems, list)
         w_self.space = space
         if space.config.objspace.std.withliststrategies:
-            w_self.strategy = get_strategy_from_list_objects(space, wrappeditems)
+            w_self.strategy = get_strategy_from_list_objects(space,
+                                                             wrappeditems,
+                                                             sizehint)
         else:
             w_self.strategy = space.fromcache(ObjectListStrategy)
         w_self.init_from_list_w(wrappeditems)
@@ -255,6 +259,7 @@
 
 
 class ListStrategy(object):
+    sizehint = -1
 
     def __init__(self, space):
         self.space = space
@@ -336,6 +341,7 @@
     def sort(self, w_list, reverse):
         raise NotImplementedError
 
+
 class EmptyListStrategy(ListStrategy):
     """EmptyListStrategy is used when a W_List withouth elements is created.
     The storage is None. When items are added to the W_List a new RPython list
@@ -397,7 +403,7 @@
         else:
             strategy = self.space.fromcache(ObjectListStrategy)
 
-        storage = strategy.get_empty_storage()
+        storage = strategy.get_empty_storage(self.sizehint)
         w_list.strategy = strategy
         w_list.lstorage = storage
 
@@ -438,6 +444,13 @@
     def reverse(self, w_list):
         pass
 
+class SizeListStrategy(EmptyListStrategy):
+    """ Like empty, but when modified it'll preallocate the size to sizehint
+    """
+    def __init__(self, space, sizehint):
+        self.sizehint = sizehint
+        ListStrategy.__init__(self, space)
+
 class RangeListStrategy(ListStrategy):
     """RangeListStrategy is used when a list is created using the range method.
     The storage is a tuple containing only three integers start, step and length
@@ -660,8 +673,10 @@
         l = [self.unwrap(w_item) for w_item in list_w]
         w_list.lstorage = self.erase(l)
 
-    def get_empty_storage(self):
-        return self.erase([])
+    def get_empty_storage(self, sizehint):
+        if sizehint == -1:
+            return self.erase([])
+        return self.erase(newlist_hint(sizehint))
 
     def clone(self, w_list):
         l = self.unerase(w_list.lstorage)
diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py
--- a/pypy/objspace/std/newformat.py
+++ b/pypy/objspace/std/newformat.py
@@ -10,6 +10,10 @@
 
 
 @specialize.argtype(1)
+ at jit.look_inside_iff(lambda space, s, start, end:
+       jit.isconstant(s) and
+       jit.isconstant(start) and
+       jit.isconstant(end))
 def _parse_int(space, s, start, end):
     """Parse a number and check for overflows"""
     result = 0
@@ -91,9 +95,18 @@
                         if s[i] == "{":
                             i += 1
                             markup_follows = False
-                    # Attach literal data
+                    # Attach literal data, ending with { or }
                     out.append_slice(s, last_literal, i - 1)
                     if not markup_follows:
+                        if self.parser_list_w is not None:
+                            end_literal = i - 1
+                            assert end_literal > last_literal
+                            literal = self.template[last_literal:end_literal]
+                            w_entry = space.newtuple([
+                                space.wrap(literal),
+                                space.w_None, space.w_None, space.w_None])
+                            self.parser_list_w.append(w_entry)
+                            self.last_end = i
                         last_literal = i
                         continue
                     nested = 1
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -300,8 +300,9 @@
         make_sure_not_resized(list_w)
         return wraptuple(self, list_w)
 
-    def newlist(self, list_w):
-        return W_ListObject(self, list_w)
+    def newlist(self, list_w, sizehint=-1):
+        assert not list_w or sizehint == -1
+        return W_ListObject(self, list_w, sizehint)
 
     def newlist_str(self, list_s):
         return W_ListObject.newlist_str(self, list_s)
diff --git a/pypy/objspace/std/ropeobject.py b/pypy/objspace/std/ropeobject.py
--- a/pypy/objspace/std/ropeobject.py
+++ b/pypy/objspace/std/ropeobject.py
@@ -17,9 +17,26 @@
 from pypy.objspace.std.stringobject import (
     mod__String_ANY as mod__Rope_ANY,
     str_format__String as str_format__Rope,
-    _upper, _lower, DEFAULT_NOOP_TABLE)
+    DEFAULT_NOOP_TABLE)
 
-class W_RopeObject(stringobject.W_AbstractStringObject):
+
+class RopeBuilder(object):
+    """Mimic sufficent StringBuilder API for over simple character arrays"""
+
+    def __init__(self, size=0):
+        self.data = [' '] * size
+        self.pos = 0
+
+    def append(self, ch):
+        self.data[self.pos] = ch
+        self.pos += 1
+
+    def build(self):
+        return rope.rope_from_charlist(self.data)
+
+
+class W_RopeObject(stringobject.W_AbstractStringObject,
+        stringobject.Mixin_StringMethods):
     from pypy.objspace.std.stringtype import str_typedef as typedef
     _immutable_fields_ = ['_node']
 
@@ -28,24 +45,34 @@
             assert node.is_bytestring()
         w_self._node = node
 
-    def __repr__(w_self):
-        """ representation for debugging purposes """
-        return "%s(%r)" % (w_self.__class__.__name__, w_self._node)
+    def builder(w_self, space, size=0):
+        return RopeBuilder(size)
 
-    def unwrap(w_self, space):
+    def construct(w_self, space, data):
+        return W_RopeObject(data)
+
+    def iterator(w_self, space):
+        return rope.ItemIterator(w_self._node)
+
+    def length(w_self, space):
+        return w_self._node.length()
+
+    def raw_value(w_self):
+        return w_self._node
+
+    def str_w(w_self, space):
         return w_self._node.flatten_string()
-    str_w = unwrap
+
+    def unicode_w(w_self, space):
+        # XXX should this use the default encoding?
+        from pypy.objspace.std.unicodetype import plain_str2unicode
+        return plain_str2unicode(space, w_self._node.flatten_string())
 
     def create_if_subclassed(w_self):
         if type(w_self) is W_RopeObject:
             return w_self
         return W_RopeObject(w_self._node)
 
-    def unicode_w(w_self, space):
-        # XXX should this use the default encoding?
-        from pypy.objspace.std.unicodetype import plain_str2unicode
-        return plain_str2unicode(space, w_self._node.flatten_string())
-
 W_RopeObject.EMPTY = W_RopeObject(rope.LiteralStringNode.EMPTY)
 W_RopeObject.PREBUILT = [W_RopeObject(rope.LiteralStringNode.PREBUILT[i])
                              for i in range(256)]
@@ -69,123 +96,43 @@
 
 registerimplementation(W_RopeIterObject)
 
-def _is_generic(space, w_self, fun):
-    l = w_self._node.length()
-    if l == 0:
-        return space.w_False
-    iter = rope.ItemIterator(w_self._node)
-    for i in range(l):
-        if not fun(iter.nextchar()):
-            return space.w_False
-    return space.w_True
-_is_generic._annspecialcase_ = "specialize:arg(2)"
-
-_isspace = lambda c: c.isspace()
-_isdigit = lambda c: c.isdigit()
-_isalpha = lambda c: c.isalpha()
-_isalnum = lambda c: c.isalnum()
-
 def str_isspace__Rope(space, w_self):
-    return _is_generic(space, w_self, _isspace)
+    return w_self.isspace(space)
 
 def str_isdigit__Rope(space, w_self):
-    return _is_generic(space, w_self, _isdigit)
+    return w_self.isdigit(space)
 
 def str_isalpha__Rope(space, w_self):
-    return _is_generic(space, w_self, _isalpha)
+    return w_self.isalpha(space)
 
 def str_isalnum__Rope(space, w_self):
-    return _is_generic(space, w_self, _isalnum)
+    return w_self.isalnum(space)
 
 def str_isupper__Rope(space, w_self):
     """Return True if all cased characters in S are uppercase and there is
 at least one cased character in S, False otherwise."""
-    l = w_self._node.length()
-
-    if l == 0:
-        return space.w_False
-    cased = False
-    iter = rope.ItemIterator(w_self._node)
-    for idx in range(l):
-        c = iter.nextchar()
-        if c.islower():
-            return space.w_False
-        elif not cased and c.isupper():
-            cased = True
-    return space.newbool(cased)
+    return w_self.isupper(space)
 
 def str_islower__Rope(space, w_self):
     """Return True if all cased characters in S are lowercase and there is
 at least one cased character in S, False otherwise."""
-    l = w_self._node.length()
-
-    if l == 0:
-        return space.w_False
-    cased = False
-    iter = rope.ItemIterator(w_self._node)
-    for idx in range(l):
-        c = iter.nextchar()
-        if c.isupper():
-            return space.w_False
-        elif not cased and c.islower():
-            cased = True
-    return space.newbool(cased)
+    return w_self.islower(space)
 
 def str_istitle__Rope(space, w_self):
     """Return True if S is a titlecased string and there is at least one
 character in S, i.e. uppercase characters may only follow uncased
 characters and lowercase characters only cased ones. Return False
 otherwise."""
-    cased = False
-    previous_is_cased = False
+    return w_self.istitle(space)
 
-    iter = rope.ItemIterator(w_self._node)
-    for pos in range(0, w_self._node.length()):
-        ch = iter.nextchar()
-        if ch.isupper():
-            if previous_is_cased:
-                return space.w_False
-            previous_is_cased = True
-            cased = True
-        elif ch.islower():
-            if not previous_is_cased:
-                return space.w_False
-            cased = True
-        else:
-            previous_is_cased = False
+def str_lower__Rope(space, w_self):
+    return w_self.lower(space)
 
-    return space.newbool(cased)
-
-def _local_transform(node, transform):
-    l = node.length()
-    res = [' '] * l
-    iter = rope.ItemIterator(node)
-    for i in range(l):
-        ch = iter.nextchar()
-        res[i] = transform(ch)
-
-    return W_RopeObject(rope.rope_from_charlist(res))
-_local_transform._annspecialcase_ = "specialize:arg(1)"
+def str_swapcase__Rope(space, w_self):
+    return w_self.swapcase(space)
 
 def str_upper__Rope(space, w_self):
-    return _local_transform(w_self._node, _upper)
-
-def str_lower__Rope(space, w_self):
-    return _local_transform(w_self._node, _lower)
-
-def _swapcase(ch):
-    if ch.isupper():
-        o = ord(ch) + 32
-        return chr(o)
-    elif ch.islower():
-        o = ord(ch) - 32
-        return chr(o)
-    else:
-        return ch
-
-def str_swapcase__Rope(space, w_self):
-    return _local_transform(w_self._node, _swapcase)
-
+    return w_self.upper(space)
 
 def str_capitalize__Rope(space, w_self):
     node = w_self._node
@@ -223,9 +170,9 @@
     for pos in range(0, length):
         ch = iter.nextchar()
         if not prev_letter.isalpha():
-            buffer[pos] = _upper(ch)
+            buffer[pos] = w_self._upper(ch)
         else:
-            buffer[pos] = _lower(ch)
+            buffer[pos] = w_self._lower(ch)
 
         prev_letter = buffer[pos]
 
diff --git a/pypy/objspace/std/ropeunicodeobject.py b/pypy/objspace/std/ropeunicodeobject.py
--- a/pypy/objspace/std/ropeunicodeobject.py
+++ b/pypy/objspace/std/ropeunicodeobject.py
@@ -4,7 +4,6 @@
 from pypy.interpreter.error import OperationError, operationerrfmt
 from pypy.interpreter import gateway
 from pypy.objspace.std.stringobject import W_StringObject
-from pypy.objspace.std.unicodeobject import _normalize_index
 from pypy.objspace.std.ropeobject import W_RopeObject
 from pypy.objspace.std.noneobject import W_NoneObject
 from pypy.rlib import rope
@@ -14,7 +13,6 @@
 from pypy.objspace.std.tupleobject import W_TupleObject
 from pypy.rlib.rarithmetic import intmask, ovfcheck
 from pypy.module.unicodedata import unicodedb
-from pypy.tool.sourcetools import func_with_new_name
 
 from pypy.objspace.std.formatting import mod_format
 
@@ -77,6 +75,22 @@
     return encode_object(space, w_unistr, encoding, errors)
 
 
+# XXX create shared base class with RopeBuilder
+class RopeUnicodeBuilder(object):
+    """Mimic sufficent StringBuilder API for over simple character arrays"""
+
+    def __init__(self, size=0):
+        self.data = [u' '] * size
+        self.pos = 0
+
+    def append(self, ch):
+        self.data[self.pos] = ch
+        self.pos += 1
+
+    def build(self):
+        return rope.rope_from_unicharlist(self.data)
+
+
 class W_RopeUnicodeObject(unicodeobject.W_AbstractUnicodeObject):
     from pypy.objspace.std.unicodetype import unicode_typedef as typedef
     _immutable_fields_ = ['_node']
@@ -84,32 +98,36 @@
     def __init__(w_self, node):
         w_self._node = node
 
-    def __repr__(w_self):
-        """ representation for debugging purposes """
-        return "%s(%r)" % (w_self.__class__.__name__, w_self._node)
+    def builder(w_self, space, size=0):
+        return RopeUnicodeBuilder(size)
 
-    def unwrap(w_self, space):
-        # for testing
-        return w_self._node.flatten_unicode()
+    def construct(w_self, space, data):
+        return W_RopeUnicodeObject(data)
+
+    def iterator(w_self, space):
+        return rope.ItemIterator(w_self._node)
+
+    def length(w_self, space):
+        return w_self._node.length()
+
+    def raw_value(w_self):
+        return w_self._node
 
     def str_w(w_self, space):
         return space.str_w(space.str(w_self))
 
+    def unicode_w(self, space):
+        return self._node.flatten_unicode()
+
     def create_if_subclassed(w_self):
         if type(w_self) is W_RopeUnicodeObject:
             return w_self
         return W_RopeUnicodeObject(w_self._node)
 
-    def unicode_w(self, space):
-        return self._node.flatten_unicode()
-
 W_RopeUnicodeObject.EMPTY = W_RopeUnicodeObject(rope.LiteralStringNode.EMPTY)
 
 registerimplementation(W_RopeUnicodeObject)
 
-def _isspace(uchar_ord):
-    return unicodedb.isspace(uchar_ord)
-
 def ropeunicode_w(space, w_str):
     if isinstance(w_str, W_RopeUnicodeObject):
         return w_str._node
@@ -319,81 +337,38 @@
 def mul__ANY_RopeUnicode(space, w_times, w_uni):
     return mul__RopeUnicode_ANY(space, w_uni, w_times)
 
+def unicode_isspace__RopeUnicode(space, w_self):
+    return w_self.isspace(space)
 
-def make_generic(funcname):
-    def func(space, w_self):
-        node = w_self._node
-        if node.length() == 0:
-            return space.w_False
-        iter = rope.ItemIterator(node)
-        for idx in range(node.length()):
-            if not getattr(unicodedb, funcname)(iter.nextint()):
-                return space.w_False
-        return space.w_True
-    return func_with_new_name(func, "unicode_%s__RopeUnicode" % (funcname, ))
+def unicode_isalpha__RopeUnicode(space, w_self):
+    return w_self.isalpha(space)
 
-unicode_isspace__RopeUnicode = make_generic("isspace")
-unicode_isalpha__RopeUnicode = make_generic("isalpha")
-unicode_isalnum__RopeUnicode = make_generic("isalnum")
-unicode_isdecimal__RopeUnicode = make_generic("isdecimal")
-unicode_isdigit__RopeUnicode = make_generic("isdigit")
-unicode_isnumeric__RopeUnicode = make_generic("isnumeric")
+def unicode_isalnum__RopeUnicode(space, w_self):
+    return w_self.isalnum(space)
 
-def unicode_islower__RopeUnicode(space, w_unicode):
-    cased = False
-    iter = rope.ItemIterator(w_unicode._node)
-    while 1:
-        try:
-            ch = iter.nextint()
-        except StopIteration:
-            return space.newbool(cased)
-        if (unicodedb.isupper(ch) or
-            unicodedb.istitle(ch)):
-            return space.w_False
-        if not cased and unicodedb.islower(ch):
-            cased = True
+def unicode_isdecimal__RopeUnicode(space, w_self):
+    return w_self.isdecimal(space)
 
-def unicode_isupper__RopeUnicode(space, w_unicode):
-    cased = False
-    iter = rope.ItemIterator(w_unicode._node)
-    while 1:
-        try:
-            ch = iter.nextint()
-        except StopIteration:
-            return space.newbool(cased)
-        if (unicodedb.islower(ch) or
-            unicodedb.istitle(ch)):
-            return space.w_False
-        if not cased and unicodedb.isupper(ch):
-            cased = True
+def unicode_isdigit__RopeUnicode(space, w_self):
+    return w_self.isdigit(space)
 
-def unicode_istitle__RopeUnicode(space, w_unicode):
-    cased = False
-    previous_is_cased = False
-    iter = rope.ItemIterator(w_unicode._node)
-    while 1:
-        try:
-            ch = iter.nextint()
-        except StopIteration:
-            return space.newbool(cased)
-        if (unicodedb.isupper(ch) or
-            unicodedb.istitle(ch)):
-            if previous_is_cased:
-                return space.w_False
-            previous_is_cased = cased = True
-        elif unicodedb.islower(ch):
-            if not previous_is_cased:
-                return space.w_False
-            previous_is_cased = cased = True
-        else:
-            previous_is_cased = False
+def unicode_isnumeric__RopeUnicode(space, w_self):
+    return w_self.isnumeric(space)
 
+def unicode_islower__RopeUnicode(space, w_self):
+    return w_self.islower(space)
+
+def unicode_isupper__RopeUnicode(space, w_self):
+    return w_self.isupper(space)
+
+def unicode_istitle__RopeUnicode(space, w_self):
+    return w_self.istitle(space)
 
 def _contains(i, uni):
     return unichr(i) in uni
 
 def unicode_strip__RopeUnicode_None(space, w_self, w_chars):
-    return W_RopeUnicodeObject(rope.strip(w_self._node, True, True, _isspace))
+    return W_RopeUnicodeObject(rope.strip(w_self._node, True, True, unicodedb.isspace))
 def unicode_strip__RopeUnicode_RopeUnicode(space, w_self, w_chars):
     return W_RopeUnicodeObject(rope.strip(w_self._node, True, True, _contains,
                                w_chars._node.flatten_unicode()))
@@ -403,7 +378,7 @@
                              unicode_from_string(space, w_chars))
 
 def unicode_lstrip__RopeUnicode_None(space, w_self, w_chars):
-    return W_RopeUnicodeObject(rope.strip(w_self._node, True, False, _isspace))
+    return W_RopeUnicodeObject(rope.strip(w_self._node, True, False, unicodedb.isspace))
 def unicode_lstrip__RopeUnicode_RopeUnicode(space, w_self, w_chars):
     return W_RopeUnicodeObject(rope.strip(w_self._node, True, False, _contains,
                                w_chars._node.flatten_unicode()))
@@ -412,7 +387,7 @@
                              unicode_from_string(space, w_chars))
 
 def unicode_rstrip__RopeUnicode_None(space, w_self, w_chars):
-    return W_RopeUnicodeObject(rope.strip(w_self._node, False, True, _isspace))
+    return W_RopeUnicodeObject(rope.strip(w_self._node, False, True, unicodedb.isspace))
 def unicode_rstrip__RopeUnicode_RopeUnicode(space, w_self, w_chars):
     return W_RopeUnicodeObject(rope.strip(w_self._node, False, True, _contains,
                                w_chars._node.flatten_unicode()))
@@ -450,38 +425,14 @@
         previous_is_cased = unicodedb.iscased(unichar)
     return W_RopeUnicodeObject(rope.rope_from_unicharlist(result))
 
+def unicode_lower__RopeUnicode(space, w_self):
+    return w_self.lower(space)
 
-def _local_transform(node, transform):
-    l = node.length()
-    res = [u' '] * l
-    iter = rope.ItemIterator(node)
-    for i in range(l):
-        ch = iter.nextint()
-        res[i] = transform(ch)
-
-    return W_RopeUnicodeObject(rope.rope_from_unicharlist(res))
-_local_transform._annspecialcase_ = "specialize:arg(1)"
-
-def _tolower(ordch):
-    return unichr(unicodedb.tolower(ordch))
-def unicode_lower__RopeUnicode(space, w_self):
-    return _local_transform(w_self._node, _tolower)
-
-def _toupper(ordch):
-    return unichr(unicodedb.toupper(ordch))
 def unicode_upper__RopeUnicode(space, w_self):
-    return _local_transform(w_self._node, _toupper)
-
-def _swapcase(ordch):
-    if unicodedb.islower(ordch):
-        return unichr(unicodedb.toupper(ordch))
-    elif unicodedb.isupper(ordch):
-        return unichr(unicodedb.tolower(ordch))
-    else:
-        return unichr(ordch)
+    return w_self.upper(space)
 
 def unicode_swapcase__RopeUnicode(space, w_self):
-    return _local_transform(w_self._node, _swapcase)
+    return w_self.swapcase(space)
 
 def _convert_idx_params(space, w_self, w_start, w_end):
     self = w_self._node
@@ -658,7 +609,7 @@
     selfnode = w_self._node
     maxsplit = space.int_w(w_maxsplit)
     res_w = [W_RopeUnicodeObject(node)
-                for node in rope.split_chars(selfnode, maxsplit, _isspace)]
+                for node in rope.split_chars(selfnode, maxsplit, unicodedb.isspace)]
     return space.newlist(res_w)
 
 def unicode_split__RopeUnicode_RopeUnicode_ANY(space, w_self, w_delim, w_maxsplit):
@@ -677,7 +628,7 @@
     selfnode = w_self._node
     maxsplit = space.int_w(w_maxsplit)
     res_w = [W_RopeUnicodeObject(node)
-                for node in rope.rsplit_chars(selfnode, maxsplit, _isspace)]
+                for node in rope.rsplit_chars(selfnode, maxsplit, unicodedb.isspace)]
     return space.newlist(res_w)
 
 
diff --git a/pypy/objspace/std/stringobject.py b/pypy/objspace/std/stringobject.py
--- a/pypy/objspace/std/stringobject.py
+++ b/pypy/objspace/std/stringobject.py
@@ -15,41 +15,80 @@
 from pypy.rlib.rstring import StringBuilder, split
 from pypy.interpreter.buffer import StringBuffer
 
+from pypy.objspace.std.abstractstring import \
+        W_AbstractBaseStringObject, Mixin_BaseStringMethods
+from pypy.objspace.std.formatting import mod_format
 from pypy.objspace.std.stringtype import sliced, wrapstr, wrapchar, \
      stringendswith, stringstartswith, joined2
 
-from pypy.objspace.std.formatting import mod_format
 
-class W_AbstractStringObject(W_Object):
+class Mixin_StringMethods(Mixin_BaseStringMethods):
     __slots__ = ()
 
-    def is_w(self, space, w_other):
-        if not isinstance(w_other, W_AbstractStringObject):
-            return False
-        if self is w_other:
-            return True
-        if self.user_overridden_class or w_other.user_overridden_class:
-            return False
-        return space.str_w(self) is space.str_w(w_other)
 
-    def immutable_unique_id(self, space):
-        if self.user_overridden_class:
-            return None
-        return space.wrap(compute_unique_id(space.str_w(self)))
+class W_AbstractStringObject(W_AbstractBaseStringObject):
+    __slots__ = ()
 
+    def unwrap(w_self, space):
+        return w_self.str_w(space)
 
-class W_StringObject(W_AbstractStringObject):
+    def _isalnum(self, ch):
+        return ch.isalnum()
+
+    def _isalpha(self, ch):
+        return ch.isalpha()
+
+    def _isdigit(self, ch):
+        return ch.isdigit()
+
+    def _islower(self, ch):
+        return ch.islower()
+
+    def _isspace(self, ch):
+        return ch.isspace()
+
+    def _isupper(self, ch):
+        return ch.isupper()
+
+    def _lower(self, ch):
+        if ch.isupper():
+            o = ord(ch) + 32
+            return chr(o)
+        else:
+            return ch
+
+    def _upper(self, ch):
+        if ch.islower():
+            o = ord(ch) - 32
+            return chr(o)
+        else:
+            return ch
+
+    def _swapcase(self, ch):
+        if ch.isupper():
+            o = ord(ch) + 32
+            return chr(o)
+        elif ch.islower():
+            o = ord(ch) - 32
+            return chr(o)
+        else:
+            return ch
+
+
+class W_StringObject(W_AbstractStringObject, Mixin_StringMethods):
     from pypy.objspace.std.stringtype import str_typedef as typedef
     _immutable_fields_ = ['_value']
 
     def __init__(w_self, str):
         w_self._value = str
 
-    def __repr__(w_self):
-        """ representation for debugging purposes """
-        return "%s(%r)" % (w_self.__class__.__name__, w_self._value)
+    def builder(w_self, space, size=0):
+        return StringBuilder(size)
 
-    def unwrap(w_self, space):
+    def construct(w_self, space, data):
+        return W_StringObject(data)
+
+    def raw_value(w_self):
         return w_self._value
 
     def str_w(w_self, space):
@@ -60,140 +99,50 @@
         from pypy.objspace.std.unicodetype import plain_str2unicode
         return plain_str2unicode(space, w_self._value)
 
+
 registerimplementation(W_StringObject)
 
 W_StringObject.EMPTY = W_StringObject('')
 W_StringObject.PREBUILT = [W_StringObject(chr(i)) for i in range(256)]
 del i
 
- at specialize.arg(2)
-def _is_generic(space, w_self, fun):
-    v = w_self._value
-    if len(v) == 0:
-        return space.w_False
-    if len(v) == 1:
-        c = v[0]
-        return space.newbool(fun(c))
-    else:
-        return _is_generic_loop(space, v, fun)
+def str_isalnum__String(space, w_self):
+    return w_self.isalnum(space)
 
- at specialize.arg(2)
-def _is_generic_loop(space, v, fun):
-    for idx in range(len(v)):
-        if not fun(v[idx]):
-            return space.w_False
-    return space.w_True
+def str_isalpha__String(space, w_self):
+    return w_self.isalpha(space)
 
-def _upper(ch):
-    if ch.islower():
-        o = ord(ch) - 32
-        return chr(o)
-    else:
-        return ch
-
-def _lower(ch):
-    if ch.isupper():
-        o = ord(ch) + 32
-        return chr(o)
-    else:
-        return ch
-
-_isspace = lambda c: c.isspace()
-_isdigit = lambda c: c.isdigit()
-_isalpha = lambda c: c.isalpha()
-_isalnum = lambda c: c.isalnum()
+def str_isdigit__String(space, w_self):
+    return w_self.isdigit(space)
 
 def str_isspace__String(space, w_self):
-    return _is_generic(space, w_self, _isspace)
+    return w_self.isspace(space)
 
-def str_isdigit__String(space, w_self):
-    return _is_generic(space, w_self, _isdigit)
-
-def str_isalpha__String(space, w_self):
-    return _is_generic(space, w_self, _isalpha)
-
-def str_isalnum__String(space, w_self):
-    return _is_generic(space, w_self, _isalnum)
+def str_islower__String(space, w_self):
+    """Return True if all cased characters in S are lowercase and there is
+at least one cased character in S, False otherwise."""
+    return w_self.islower(space)
 
 def str_isupper__String(space, w_self):
     """Return True if all cased characters in S are uppercase and there is
 at least one cased character in S, False otherwise."""
-    v = w_self._value
-    if len(v) == 1:
-        c = v[0]
-        return space.newbool(c.isupper())
-    cased = False
-    for idx in range(len(v)):
-        if v[idx].islower():
-            return space.w_False
-        elif not cased and v[idx].isupper():
-            cased = True
-    return space.newbool(cased)
-
-def str_islower__String(space, w_self):
-    """Return True if all cased characters in S are lowercase and there is
-at least one cased character in S, False otherwise."""
-    v = w_self._value
-    if len(v) == 1:
-        c = v[0]
-        return space.newbool(c.islower())
-    cased = False
-    for idx in range(len(v)):
-        if v[idx].isupper():
-            return space.w_False
-        elif not cased and v[idx].islower():
-            cased = True
-    return space.newbool(cased)
+    return w_self.isupper(space)
 
 def str_istitle__String(space, w_self):
     """Return True if S is a titlecased string and there is at least one
 character in S, i.e. uppercase characters may only follow uncased
 characters and lowercase characters only cased ones. Return False
 otherwise."""
-    input = w_self._value
-    cased = False
-    previous_is_cased = False
+    return w_self.istitle(space)
 
-    for pos in range(0, len(input)):
-        ch = input[pos]
-        if ch.isupper():
-            if previous_is_cased:
-                return space.w_False
-            previous_is_cased = True
-            cased = True
-        elif ch.islower():
-            if not previous_is_cased:
-                return space.w_False
-            cased = True
-        else:
-            previous_is_cased = False
+def str_lower__String(space, w_self):
+    return w_self.lower(space)
 
-    return space.newbool(cased)
+def str_swapcase__String(space, w_self):
+    return w_self.swapcase(space)
 
 def str_upper__String(space, w_self):
-    self = w_self._value
-    return space.wrap(self.upper())
-
-def str_lower__String(space, w_self):
-    self = w_self._value
-    return space.wrap(self.lower())
-
-def str_swapcase__String(space, w_self):
-    self = w_self._value
-    builder = StringBuilder(len(self))
-    for i in range(len(self)):
-        ch = self[i]
-        if ch.isupper():
-            o = ord(ch) + 32
-            builder.append(chr(o))
-        elif ch.islower():
-            o = ord(ch) - 32
-            builder.append(chr(o))
-        else:
-            builder.append(ch)
-
-    return space.wrap(builder.build())
-
+    return w_self.upper(space)
 
 def str_capitalize__String(space, w_self):
     input = w_self._value
@@ -224,10 +173,10 @@
     for pos in range(len(input)):
         ch = input[pos]
         if not prev_letter.isalpha():
-            ch = _upper(ch)
+            ch = w_self._upper(ch)
             builder.append(ch)
         else:
-            ch = _lower(ch)
+            ch = w_self._lower(ch)
             builder.append(ch)
 
         prev_letter = ch
diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py
--- a/pypy/objspace/std/test/test_dictmultiobject.py
+++ b/pypy/objspace/std/test/test_dictmultiobject.py
@@ -613,6 +613,7 @@
         assert len(keys) == 2
         assert set(keys) == set([1, "a"])
         assert keys == set([1, "a"])
+        assert keys == frozenset([1, "a"])
         assert keys != set([1, "a", "b"])
         assert keys != set([1, "b"])
         assert keys != set([1])
@@ -633,6 +634,7 @@
         assert len(items) == 2
         assert set(items) == set([(1, 10), ("a", "ABC")])
         assert items == set([(1, 10), ("a", "ABC")])
+        assert items == frozenset([(1, 10), ("a", "ABC")])
         assert items != set([(1, 10), ("a", "ABC"), "junk"])
         assert items != set([(1, 10), ("a", "def")])
         assert items != set([(1, 10)])
diff --git a/pypy/objspace/std/test/test_listobject.py b/pypy/objspace/std/test/test_listobject.py
--- a/pypy/objspace/std/test/test_listobject.py
+++ b/pypy/objspace/std/test/test_listobject.py
@@ -1,6 +1,7 @@
 # coding: iso-8859-15
 import random
-from pypy.objspace.std.listobject import W_ListObject
+from pypy.objspace.std.listobject import W_ListObject, SizeListStrategy,\
+     IntegerListStrategy, ObjectListStrategy
 from pypy.interpreter.error import OperationError
 
 from pypy.conftest import gettestobjspace, option
@@ -390,6 +391,16 @@
         assert self.space.eq_w(self.space.le(w_list4, w_list3),
                            self.space.w_True)
 
+    def test_sizehint(self):
+        space = self.space
+        w_l = space.newlist([], sizehint=10)
+        assert isinstance(w_l.strategy, SizeListStrategy)
+        space.call_method(w_l, 'append', space.wrap(3))
+        assert isinstance(w_l.strategy, IntegerListStrategy)
+        w_l = space.newlist([], sizehint=10)
+        space.call_method(w_l, 'append', space.w_None)
+        assert isinstance(w_l.strategy, ObjectListStrategy)
+
 
 class AppTestW_ListObject(object):
     def setup_class(cls):
diff --git a/pypy/objspace/std/test/test_newformat.py b/pypy/objspace/std/test/test_newformat.py
--- a/pypy/objspace/std/test/test_newformat.py
+++ b/pypy/objspace/std/test/test_newformat.py
@@ -11,6 +11,7 @@
         assert self.s("}}").format() == self.s("}")
         assert self.s("{} {{ {}").format(1, 2) == self.s("1 { 2")
         assert self.s("{{}}").format() == self.s("{}")
+        assert self.s("{{{{").format() == self.s("{{")
 
     def test_empty(self):
         assert self.s().format() == self.s()
@@ -385,6 +386,12 @@
         for x in l[0]:
             assert isinstance(x, unicode)
 
+    def test_formatter_parser_escape(self):
+        l = list("{{a}}"._formatter_parser())
+        assert l == [('{', None, None, None), ('a}', None, None, None)]
+        l = list("{{{{"._formatter_parser())
+        assert l == [('{', None, None, None), ('{', None, None, None)]
+
     def test_formatter_field_name_split(self):
         first, rest = ''._formatter_field_name_split()
         assert first == ''
diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py
--- a/pypy/objspace/std/test/test_unicodeobject.py
+++ b/pypy/objspace/std/test/test_unicodeobject.py
@@ -195,6 +195,58 @@
         assert u"Brown Fox".title() == u"Brown Fox"
         assert u"bro!wn fox".title() == u"Bro!Wn Fox"
 
+    def test_isalnum(self):
+        assert u"".isalnum() == False
+        assert u"!Bro12345w&&&&n Fox".isalnum() == False
+        assert u"125 Brown Foxes".isalnum() == False
+        assert u"125BrownFoxes".isalnum() == True
+
+    def test_isalpha(self):
+        assert u"".isalpha() == False
+        assert u"!Bro12345w&&&&nFox".isalpha() == False
+        assert u"Brown Foxes".isalpha() == False
+        assert u"125".isalpha() == False
+
+    def test_isdigit(self):
+        assert u"".isdigit() == False
+        assert u"!Bro12345w&&&&nFox".isdigit() == False
+        assert u"Brown Foxes".isdigit() == False
+        assert u"125".isdigit() == True
+
+    def test_isdecimal(self):
+        assert u"".isdecimal() == False
+        assert u"42!".isdecimal() == False
+        assert u"\t1337".isdecimal() == False
+        assert u"6".isdecimal() == True
+
+    def test_isspace(self):
+        assert u"".isspace() == False
+        assert u"!Bro12345w&&&&nFox".isspace() == False
+        assert u" ".isspace() ==  True
+        assert u"\t\t\b\b\n".isspace() == False
+        assert u"\t\t".isspace() == True
+        assert u"\t\t\r\r\n".isspace() == True
+
+    def test_islower(self):
+        assert u"".islower() == False
+        assert u" ".islower() ==  False
+        assert u"\t\t\b\b\n".islower() == False
+        assert u"b".islower() == True
+        assert u"bbb".islower() == True
+        assert u"!bbb".islower() == True
+        assert u"BBB".islower() == False
+        assert u"bbbBBB".islower() == False
+
+    def test_isupper(self):
+        assert u"".isupper() == False
+        assert u" ".isupper() ==  False
+        assert u"\t\t\b\b\n".isupper() == False
+        assert u"B".isupper() == True
+        assert u"BBB".isupper() == True
+        assert u"!BBB".isupper() == True
+        assert u"bbb".isupper() == False
+        assert u"BBBbbb".isupper() == False
+
     def test_istitle(self):
         assert u"".istitle() == False
         assert u"!".istitle() == False
@@ -232,6 +284,12 @@
         assert (u'\u019b\u1d00\u1d86\u0221\u1fb7'.capitalize() ==
                 u'\u019b\u1d00\u1d86\u0221\u1fb7')
 
+    def test_lower(self):
+        assert u"ABC".lower() == u"abc"
+
+    def test_upper(self):
+        assert u"abc".upper() == u"ABC"
+
     def test_rjust(self):
         s = u"abc"
         assert s.rjust(2) == s
diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py
--- a/pypy/objspace/std/tupleobject.py
+++ b/pypy/objspace/std/tupleobject.py
@@ -6,8 +6,11 @@
 from pypy.rlib.rarithmetic import intmask
 from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
 from pypy.objspace.std import slicetype
-from pypy.interpreter import gateway
 from pypy.rlib.debug import make_sure_not_resized
+from pypy.rlib import jit
+
+# Tuples of known length up to UNROLL_TUPLE_LIMIT have unrolled certain methods
+UNROLL_TUPLE_LIMIT = 10
 
 class W_AbstractTupleObject(W_Object):
     __slots__ = ()
@@ -114,18 +117,28 @@
 def mul__ANY_Tuple(space, w_times, w_tuple):
     return mul_tuple_times(space, w_tuple, w_times)
 
+def tuple_unroll_condition(space, w_tuple1, w_tuple2):
+    lgt1 = len(w_tuple1.wrappeditems)
+    lgt2 = len(w_tuple2.wrappeditems)
+    return ((jit.isconstant(lgt1) and lgt1 <= UNROLL_TUPLE_LIMIT) or
+            (jit.isconstant(lgt2) and lgt2 <= UNROLL_TUPLE_LIMIT))
+
+ at jit.look_inside_iff(tuple_unroll_condition)
 def eq__Tuple_Tuple(space, w_tuple1, w_tuple2):
     items1 = w_tuple1.wrappeditems
     items2 = w_tuple2.wrappeditems
-    if len(items1) != len(items2):
+    lgt1 = len(items1)
+    lgt2 = len(items2)
+    if lgt1 != lgt2:
         return space.w_False
-    for i in range(len(items1)):
+    for i in range(lgt1):
         item1 = items1[i]
         item2 = items2[i]
         if not space.eq_w(item1, item2):
             return space.w_False
     return space.w_True
 
+ at jit.look_inside_iff(tuple_unroll_condition)
 def lt__Tuple_Tuple(space, w_tuple1, w_tuple2):
     items1 = w_tuple1.wrappeditems
     items2 = w_tuple2.wrappeditems
@@ -137,6 +150,7 @@
     # No more items to compare -- compare sizes
     return space.newbool(len(items1) < len(items2))
 
+ at jit.look_inside_iff(tuple_unroll_condition)
 def gt__Tuple_Tuple(space, w_tuple1, w_tuple2):
     items1 = w_tuple1.wrappeditems
     items2 = w_tuple2.wrappeditems
@@ -161,6 +175,9 @@
 def hash__Tuple(space, w_tuple):
     return space.wrap(hash_tuple(space, w_tuple.wrappeditems))
 
+ at jit.look_inside_iff(lambda space, wrappeditems:
+                     jit.isconstant(len(wrappeditems)) and
+                     len(wrappeditems) < UNROLL_TUPLE_LIMIT)
 def hash_tuple(space, wrappeditems):
     # this is the CPython 2.4 algorithm (changed from 2.3)
     mult = 1000003
diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py
--- a/pypy/objspace/std/unicodeobject.py
+++ b/pypy/objspace/std/unicodeobject.py
@@ -15,27 +15,61 @@
 from pypy.rlib.rstring import UnicodeBuilder
 from pypy.rlib.runicode import unicode_encode_unicode_escape
 from pypy.module.unicodedata import unicodedb
-from pypy.tool.sourcetools import func_with_new_name
 
+from pypy.objspace.std.abstractstring import \
+        W_AbstractBaseStringObject, Mixin_BaseStringMethods
 from pypy.objspace.std.formatting import mod_format
 from pypy.objspace.std.stringtype import stringstartswith, stringendswith
 
-class W_AbstractUnicodeObject(W_Object):
+
+class Mixin_UnicodeMethods(Mixin_BaseStringMethods):
+    __slows__ = ()
+
+    def isdecimal(w_self, space):
+        return w_self._all_true(space, w_self._isdecimal)
+
+
+class W_AbstractUnicodeObject(W_AbstractBaseStringObject, Mixin_UnicodeMethods):
     __slots__ = ()
 
-    def is_w(self, space, w_other):
-        if not isinstance(w_other, W_AbstractUnicodeObject):
-            return False
-        if self is w_other:
-            return True
-        if self.user_overridden_class or w_other.user_overridden_class:
-            return False
-        return space.unicode_w(self) is space.unicode_w(w_other)
+    def unwrap(w_self, space):
+        return w_self.unicode_w(space)
 
-    def immutable_unique_id(self, space):
-        if self.user_overridden_class:
-            return None
-        return space.wrap(compute_unique_id(space.unicode_w(self)))
+    def _isalnum(self, ch):
+        return unicodedb.isalnum(ord(ch))
+
+    def _isalpha(self, ch):
+        return unicodedb.isalpha(ord(ch))
+
+    def _isdigit(self, ch):
+        return unicodedb.isdigit(ord(ch))
+
+    def _isdecimal(self, ch):
+        return unicodedb.isdecimal(ord(ch))
+
+    def _islower(self, ch):
+        return unicodedb.islower(ord(ch))
+
+    def _isspace(self, ch):
+        return unicodedb.isspace(ord(ch))
+
+    def _isupper(self, ch):
+        return unicodedb.isupper(ord(ch))
+
+    def _lower(self, ch):
+        return unichr(unicodedb.tolower(ord(ch)))
+
+    def _upper(self, ch):
+        return unichr(unicodedb.toupper(ord(ch)))
+
+    def _swapcase(self, ch):
+        num = ord(ch)
+        if unicodedb.islower(num):
+            return unichr(unicodedb.toupper(num))
+        elif unicodedb.isupper(num):
+            return unichr(unicodedb.tolower(num))
+        else:
+            return ch
 
 
 class W_UnicodeObject(W_AbstractUnicodeObject):
@@ -46,24 +80,26 @@
         assert isinstance(unistr, unicode)
         w_self._value = unistr
 
-    def __repr__(w_self):
-        """ representation for debugging purposes """
-        return "%s(%r)" % (w_self.__class__.__name__, w_self._value)
+    def builder(w_self, space, size=0):
+        return UnicodeBuilder(size)
 
-    def unwrap(w_self, space):
-        # for testing
+    def construct(w_self, space, data):
+        return W_UnicodeObject(data)
+
+    def raw_value(w_self):
         return w_self._value
 
+    def str_w(self, space):
+        return space.str_w(space.str(self))
+
+    def unicode_w(self, space):
+        return self._value
+
     def create_if_subclassed(w_self):
         if type(w_self) is W_UnicodeObject:
             return w_self
         return W_UnicodeObject(w_self._value)
 
-    def str_w(self, space):
-        return space.str_w(space.str(self))
-
-    def unicode_w(self, space):
-        return self._value
 
 W_UnicodeObject.EMPTY = W_UnicodeObject(u'')
 
@@ -75,6 +111,7 @@
         raise operationerrfmt(space.w_TypeError,
                               "expected unicode, got '%s'",
                               space.type(w_unistr).getname(space))
+    # XXX remove direct use of _value
     unistr = w_unistr._value
     result = ['\0'] * len(unistr)
     digits = [ '0', '1', '2', '3', '4',
@@ -302,63 +339,32 @@
 def mul__ANY_Unicode(space, w_times, w_uni):
     return mul__Unicode_ANY(space, w_uni, w_times)
 
-def _isspace(uchar):
-    return unicodedb.isspace(ord(uchar))
+def unicode_isspace__Unicode(space, w_self):
+    return w_self.isspace(space)
 
-def make_generic(funcname):
-    def func(space, w_self):
-        v = w_self._value
-        if len(v) == 0:
-            return space.w_False
-        for idx in range(len(v)):
-            if not getattr(unicodedb, funcname)(ord(v[idx])):
-                return space.w_False
-        return space.w_True
-    return func_with_new_name(func, "unicode_%s__Unicode" % (funcname, ))
+def unicode_isalpha__Unicode(space, w_self):
+    return w_self.isalpha(space)
 
-unicode_isspace__Unicode = make_generic("isspace")
-unicode_isalpha__Unicode = make_generic("isalpha")
-unicode_isalnum__Unicode = make_generic("isalnum")
-unicode_isdecimal__Unicode = make_generic("isdecimal")
-unicode_isdigit__Unicode = make_generic("isdigit")
-unicode_isnumeric__Unicode = make_generic("isnumeric")
+def unicode_isalnum__Unicode(space, w_self):
+    return w_self.isalnum(space)
 
-def unicode_islower__Unicode(space, w_unicode):
-    cased = False
-    for uchar in w_unicode._value:
-        if (unicodedb.isupper(ord(uchar)) or
-            unicodedb.istitle(ord(uchar))):
-            return space.w_False
-        if not cased and unicodedb.islower(ord(uchar)):
-            cased = True
-    return space.newbool(cased)
+def unicode_isdecimal__Unicode(space, w_self):
+    return w_self.isdecimal(space)
 
-def unicode_isupper__Unicode(space, w_unicode):
-    cased = False
-    for uchar in w_unicode._value:
-        if (unicodedb.islower(ord(uchar)) or
-            unicodedb.istitle(ord(uchar))):
-            return space.w_False
-        if not cased and unicodedb.isupper(ord(uchar)):
-            cased = True
-    return space.newbool(cased)
+def unicode_isdigit__Unicode(space, w_self):
+    return w_self.isdigit(space)
 
-def unicode_istitle__Unicode(space, w_unicode):
-    cased = False
-    previous_is_cased = False
-    for uchar in w_unicode._value:
-        if (unicodedb.isupper(ord(uchar)) or
-            unicodedb.istitle(ord(uchar))):
-            if previous_is_cased:
-                return space.w_False
-            previous_is_cased = cased = True
-        elif unicodedb.islower(ord(uchar)):
-            if not previous_is_cased:
-                return space.w_False
-            previous_is_cased = cased = True
-        else:
-            previous_is_cased = False
-    return space.newbool(cased)
+def unicode_isnumeric__Unicode(space, w_self):
+    return w_self.isnumeric(space)
+
+def unicode_islower__Unicode(space, w_self):
+    return w_self.islower(space)
+
+def unicode_isupper__Unicode(space, w_self):
+    return w_self.isupper(space)
+
+def unicode_istitle__Unicode(space, w_self):
+    return w_self.istitle(space)
 
 def _strip(space, w_self, w_chars, left, right):
     "internal function called by str_xstrip methods"
@@ -388,11 +394,11 @@
     rpos = len(u_self)
 
     if left:
-        while lpos < rpos and _isspace(u_self[lpos]):
+        while lpos < rpos and w_self._isspace(u_self[lpos]):
            lpos += 1
 
     if right:
-        while rpos > lpos and _isspace(u_self[rpos - 1]):
+        while rpos > lpos and w_self._isspace(u_self[rpos - 1]):
            rpos -= 1
 
     assert rpos >= 0
@@ -458,40 +464,13 @@
     return W_UnicodeObject(builder.build())
 
 def unicode_lower__Unicode(space, w_self):
-    input = w_self._value
-    builder = UnicodeBuilder(len(input))
-    for i in range(len(input)):
-        builder.append(unichr(unicodedb.tolower(ord(input[i]))))
-    return W_UnicodeObject(builder.build())
+    return w_self.lower(space)
 
 def unicode_upper__Unicode(space, w_self):
-    input = w_self._value
-    builder = UnicodeBuilder(len(input))
-    for i in range(len(input)):
-        builder.append(unichr(unicodedb.toupper(ord(input[i]))))
-    return W_UnicodeObject(builder.build())
+    return w_self.upper(space)
 
 def unicode_swapcase__Unicode(space, w_self):
-    input = w_self._value
-    builder = UnicodeBuilder(len(input))
-    for i in range(len(input)):
-        unichar = ord(input[i])
-        if unicodedb.islower(unichar):
-            builder.append(unichr(unicodedb.toupper(unichar)))
-        elif unicodedb.isupper(unichar):
-            builder.append(unichr(unicodedb.tolower(unichar)))
-        else:
-            builder.append(input[i])
-    return W_UnicodeObject(builder.build())
-
-def _normalize_index(length, index):
-    if index < 0:
-        index += length
-        if index < 0:
-            index = 0
-    elif index > length:
-        index = length
-    return index
+    return w_self.swapcase(space)
 
 @specialize.arg(4)
 def _convert_idx_params(space, w_self, w_start, w_end, upper_bound=False):
@@ -666,7 +645,7 @@
     while True:
         # find the beginning of the next word
         while i < length:
-            if not _isspace(value[i]):
+            if not w_self._isspace(value[i]):
                 break   # found
             i += 1
         else:
@@ -677,7 +656,7 @@
             j = length   # take all the rest of the string
         else:
             j = i + 1
-            while j < length and not _isspace(value[j]):
+            while j < length and not w_self._isspace(value[j]):
                 j += 1
             maxsplit -= 1   # NB. if it's already < 0, it stays < 0
 
@@ -709,7 +688,7 @@
     while True:
         # starting from the end, find the end of the next word
         while i >= 0:
-            if not _isspace(value[i]):
+            if not w_self._isspace(value[i]):
                 break   # found
             i -= 1
         else:
@@ -721,7 +700,7 @@
             j = -1   # take all the rest of the string
         else:
             j = i - 1
-            while j >= 0 and not _isspace(value[j]):
+            while j >= 0 and not w_self._isspace(value[j]):
                 j -= 1
             maxsplit -= 1   # NB. if it's already < 0, it stays < 0
 
diff --git a/pypy/rlib/objectmodel.py b/pypy/rlib/objectmodel.py
--- a/pypy/rlib/objectmodel.py
+++ b/pypy/rlib/objectmodel.py
@@ -233,20 +233,22 @@
 
 # ____________________________________________________________
 
-def newlist(sizehint=0):
+def newlist_hint(sizehint=0):
     """ Create a new list, but pass a hint how big the size should be
     preallocated
     """
     return []
 
 class Entry(ExtRegistryEntry):
-    _about_ = newlist
+    _about_ = newlist_hint
 
     def compute_result_annotation(self, s_sizehint):
         from pypy.annotation.model import SomeInteger
 
         assert isinstance(s_sizehint, SomeInteger)
-        return self.bookkeeper.newlist()
+        s_l = self.bookkeeper.newlist()
+        s_l.listdef.listitem.resize()
+        return s_l
 
     def specialize_call(self, orig_hop, i_sizehint=None):
         from pypy.rpython.rlist import rtype_newlist
diff --git a/pypy/rlib/test/test_objectmodel.py b/pypy/rlib/test/test_objectmodel.py
--- a/pypy/rlib/test/test_objectmodel.py
+++ b/pypy/rlib/test/test_objectmodel.py
@@ -442,7 +442,7 @@
 def test_newlist():
     from pypy.annotation.model import SomeInteger
     def f(z):
-        x = newlist(sizehint=38)
+        x = newlist_hint(sizehint=38)
         if z < 0:
             x.append(1)
         return len(x)
@@ -456,7 +456,7 @@
 def test_newlist_nonconst():
     from pypy.annotation.model import SomeInteger
     def f(z):
-        x = newlist(sizehint=z)
+        x = newlist_hint(sizehint=z)
         return len(x)
 
     graph = getgraph(f, [SomeInteger()])
diff --git a/pypy/rpython/lltypesystem/rlist.py b/pypy/rpython/lltypesystem/rlist.py
--- a/pypy/rpython/lltypesystem/rlist.py
+++ b/pypy/rpython/lltypesystem/rlist.py
@@ -60,7 +60,6 @@
         ITEMARRAY = GcArray(ITEM,
                             adtmeths = ADTIFixedList({
                                  "ll_newlist": ll_fixed_newlist,
-                                 "ll_newlist_hint": ll_fixed_newlist,
                                  "ll_newemptylist": ll_fixed_newemptylist,
                                  "ll_length": ll_fixed_length,
                                  "ll_items": ll_fixed_items,
@@ -271,7 +270,7 @@
     l.items = malloc(LIST.items.TO, lengthhint)
     return l
 ll_newlist_hint = typeMethod(ll_newlist_hint)
-ll_newlist_hint.oopspec = 'newlist(lengthhint)'
+ll_newlist_hint.oopspec = 'newlist_hint(lengthhint)'
 
 # should empty lists start with no allocated memory, or with a preallocated
 # minimal number of entries?  XXX compare memory usage versus speed, and
@@ -315,16 +314,16 @@
 
 # fixed size versions
 
+ at typeMethod
 def ll_fixed_newlist(LIST, length):
     ll_assert(length >= 0, "negative fixed list length")
     l = malloc(LIST, length)
     return l
-ll_fixed_newlist = typeMethod(ll_fixed_newlist)
 ll_fixed_newlist.oopspec = 'newlist(length)'
 
+ at typeMethod
 def ll_fixed_newemptylist(LIST):
     return ll_fixed_newlist(LIST, 0)
-ll_fixed_newemptylist = typeMethod(ll_fixed_newemptylist)
 
 def ll_fixed_length(l):
     return len(l)
diff --git a/pypy/rpython/test/test_rlist.py b/pypy/rpython/test/test_rlist.py
--- a/pypy/rpython/test/test_rlist.py
+++ b/pypy/rpython/test/test_rlist.py
@@ -1362,13 +1362,12 @@
                    ("y[*]" in immutable_fields)
 
     def test_hints(self):
-        from pypy.rlib.objectmodel import newlist
-        from pypy.rpython.annlowlevel import hlstr
+        from pypy.rlib.objectmodel import newlist_hint
 
         strings = ['abc', 'def']
         def f(i):
             z = strings[i]
-            x = newlist(sizehint=13)
+            x = newlist_hint(sizehint=13)
             x += z
             return ''.join(x)
 
diff --git a/pypy/translator/c/src/asm_gcc_x86.h b/pypy/translator/c/src/asm_gcc_x86.h
--- a/pypy/translator/c/src/asm_gcc_x86.h
+++ b/pypy/translator/c/src/asm_gcc_x86.h
@@ -124,10 +124,12 @@
 {
     //Read the CPU features.
     int features;
-    asm("mov $1, %%eax\n"
+    asm("movl $1, %%eax\n"
+        "pushl %%ebx\n"
         "cpuid\n"
-        "mov %%edx, %0"
-        : "=g"(features) : : "eax", "ebx", "edx", "ecx");
+        "popl %%ebx\n"
+        "movl %%edx, %0"
+        : "=g"(features) : : "eax", "edx", "ecx");
     
     //Check bits 25 and 26, this indicates SSE2 support
     if (((features & (1 << 25)) == 0) || ((features & (1 << 26)) == 0))
diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py
--- a/pypy/translator/c/test/test_genc.py
+++ b/pypy/translator/c/test/test_genc.py
@@ -16,6 +16,8 @@
 
 def compile(fn, argtypes, view=False, gcpolicy="ref", backendopt=True,
             annotatorpolicy=None):
+    if argtypes is not None and "__pypy__" in sys.builtin_module_names:
+        py.test.skip("requires building cpython extension modules")
     t = Translation(fn, argtypes, gc=gcpolicy, backend="c",
                     policy=annotatorpolicy)
     if not backendopt:


More information about the pypy-commit mailing list