[pypy-commit] pypy numpypy-out: merge default in

mattip noreply at buildbot.pypy.org
Sat Feb 25 22:25:16 CET 2012


Author: mattip
Branch: numpypy-out
Changeset: r52905:6e5f01f9a1b9
Date: 2012-02-25 23:19 +0200
http://bitbucket.org/pypy/pypy/changeset/6e5f01f9a1b9/

Log:	merge default in

diff --git a/lib_pypy/_ctypes/array.py b/lib_pypy/_ctypes/array.py
--- a/lib_pypy/_ctypes/array.py
+++ b/lib_pypy/_ctypes/array.py
@@ -1,9 +1,9 @@
-
+import _ffi
 import _rawffi
 
 from _ctypes.basics import _CData, cdata_from_address, _CDataMeta, sizeof
 from _ctypes.basics import keepalive_key, store_reference, ensure_objects
-from _ctypes.basics import CArgObject
+from _ctypes.basics import CArgObject, as_ffi_pointer
 
 class ArrayMeta(_CDataMeta):
     def __new__(self, name, cls, typedict):
@@ -211,6 +211,9 @@
     def _to_ffi_param(self):
         return self._get_buffer_value()
 
+    def _as_ffi_pointer_(self, ffitype):
+        return as_ffi_pointer(self, ffitype)
+
 ARRAY_CACHE = {}
 
 def create_array_type(base, length):
@@ -228,5 +231,6 @@
             _type_ = base
         )
         cls = ArrayMeta(name, (Array,), tpdict)
+        cls._ffiargtype = _ffi.types.Pointer(base.get_ffi_argtype())
         ARRAY_CACHE[key] = cls
         return cls
diff --git a/lib_pypy/_ctypes/basics.py b/lib_pypy/_ctypes/basics.py
--- a/lib_pypy/_ctypes/basics.py
+++ b/lib_pypy/_ctypes/basics.py
@@ -230,5 +230,16 @@
     }
 
 
+# called from primitive.py, pointer.py, array.py
+def as_ffi_pointer(value, ffitype):
+    my_ffitype = type(value).get_ffi_argtype()
+    # for now, we always allow types.pointer, else a lot of tests
+    # break. We need to rethink how pointers are represented, though
+    if my_ffitype is not ffitype and ffitype is not _ffi.types.void_p:
+        raise ArgumentError("expected %s instance, got %s" % (type(value),
+                                                              ffitype))
+    return value._get_buffer_value()
+
+
 # used by "byref"
 from _ctypes.pointer import pointer
diff --git a/lib_pypy/_ctypes/pointer.py b/lib_pypy/_ctypes/pointer.py
--- a/lib_pypy/_ctypes/pointer.py
+++ b/lib_pypy/_ctypes/pointer.py
@@ -3,7 +3,7 @@
 import _ffi
 from _ctypes.basics import _CData, _CDataMeta, cdata_from_address, ArgumentError
 from _ctypes.basics import keepalive_key, store_reference, ensure_objects
-from _ctypes.basics import sizeof, byref
+from _ctypes.basics import sizeof, byref, as_ffi_pointer
 from _ctypes.array import Array, array_get_slice_params, array_slice_getitem,\
      array_slice_setitem
 
@@ -119,14 +119,6 @@
     def _as_ffi_pointer_(self, ffitype):
         return as_ffi_pointer(self, ffitype)
 
-def as_ffi_pointer(value, ffitype):
-    my_ffitype = type(value).get_ffi_argtype()
-    # for now, we always allow types.pointer, else a lot of tests
-    # break. We need to rethink how pointers are represented, though
-    if my_ffitype is not ffitype and ffitype is not _ffi.types.void_p:
-        raise ArgumentError("expected %s instance, got %s" % (type(value),
-                                                              ffitype))
-    return value._get_buffer_value()
 
 def _cast_addr(obj, _, tp):
     if not (isinstance(tp, _CDataMeta) and tp._is_pointer_like()):
diff --git a/lib_pypy/ctypes_config_cache/pyexpat.ctc.py b/lib_pypy/ctypes_config_cache/pyexpat.ctc.py
deleted file mode 100644
--- a/lib_pypy/ctypes_config_cache/pyexpat.ctc.py
+++ /dev/null
@@ -1,45 +0,0 @@
-"""
-'ctypes_configure' source for pyexpat.py.
-Run this to rebuild _pyexpat_cache.py.
-"""
-
-import ctypes
-from ctypes import c_char_p, c_int, c_void_p, c_char
-from ctypes_configure import configure
-import dumpcache
-
-
-class CConfigure:
-    _compilation_info_ = configure.ExternalCompilationInfo(
-        includes = ['expat.h'],
-        libraries = ['expat'],
-        pre_include_lines = [
-        '#define XML_COMBINED_VERSION (10000*XML_MAJOR_VERSION+100*XML_MINOR_VERSION+XML_MICRO_VERSION)'],
-        )
-
-    XML_Char = configure.SimpleType('XML_Char', c_char)
-    XML_COMBINED_VERSION = configure.ConstantInteger('XML_COMBINED_VERSION')
-    for name in ['XML_PARAM_ENTITY_PARSING_NEVER',
-                 'XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE',
-                 'XML_PARAM_ENTITY_PARSING_ALWAYS']:
-        locals()[name] = configure.ConstantInteger(name)
-
-    XML_Encoding = configure.Struct('XML_Encoding',[
-                                    ('data', c_void_p),
-                                    ('convert', c_void_p),
-                                    ('release', c_void_p),
-                                    ('map', c_int * 256)])
-    XML_Content = configure.Struct('XML_Content',[
-        ('numchildren', c_int),
-        ('children', c_void_p),
-        ('name', c_char_p),
-        ('type', c_int),
-        ('quant', c_int),
-    ])
-    # this is insanely stupid
-    XML_FALSE = configure.ConstantInteger('XML_FALSE')
-    XML_TRUE = configure.ConstantInteger('XML_TRUE')
-
-config = configure.configure(CConfigure)
-
-dumpcache.dumpcache2('pyexpat', config)
diff --git a/lib_pypy/ctypes_config_cache/test/test_cache.py b/lib_pypy/ctypes_config_cache/test/test_cache.py
--- a/lib_pypy/ctypes_config_cache/test/test_cache.py
+++ b/lib_pypy/ctypes_config_cache/test/test_cache.py
@@ -39,10 +39,6 @@
     d = run('resource.ctc.py', '_resource_cache.py')
     assert 'RLIM_NLIMITS' in d
 
-def test_pyexpat():
-    d = run('pyexpat.ctc.py', '_pyexpat_cache.py')
-    assert 'XML_COMBINED_VERSION' in d
-
 def test_locale():
     d = run('locale.ctc.py', '_locale_cache.py')
     assert 'LC_ALL' in d
diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py
--- a/lib_pypy/datetime.py
+++ b/lib_pypy/datetime.py
@@ -271,8 +271,9 @@
     raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset))
 
 def _check_date_fields(year, month, day):
-    if not isinstance(year, (int, long)):
-        raise TypeError('int expected')
+    for value in [year, day]:
+        if not isinstance(value, (int, long)):
+            raise TypeError('int expected')
     if not MINYEAR <= year <= MAXYEAR:
         raise ValueError('year must be in %d..%d' % (MINYEAR, MAXYEAR), year)
     if not 1 <= month <= 12:
@@ -282,8 +283,9 @@
         raise ValueError('day must be in 1..%d' % dim, day)
 
 def _check_time_fields(hour, minute, second, microsecond):
-    if not isinstance(hour, (int, long)):
-        raise TypeError('int expected')
+    for value in [hour, minute, second, microsecond]:
+        if not isinstance(value, (int, long)):
+            raise TypeError('int expected')
     if not 0 <= hour <= 23:
         raise ValueError('hour must be in 0..23', hour)
     if not 0 <= minute <= 59:
diff --git a/lib_pypy/pyexpat.py b/lib_pypy/pyexpat.py
deleted file mode 100644
--- a/lib_pypy/pyexpat.py
+++ /dev/null
@@ -1,448 +0,0 @@
-
-import ctypes
-import ctypes.util
-from ctypes import c_char_p, c_int, c_void_p, POINTER, c_char, c_wchar_p
-import sys
-
-# load the platform-specific cache made by running pyexpat.ctc.py
-from ctypes_config_cache._pyexpat_cache import *
-
-try: from __pypy__ import builtinify
-except ImportError: builtinify = lambda f: f
-
-
-lib = ctypes.CDLL(ctypes.util.find_library('expat'))
-
-
-XML_Content.children = POINTER(XML_Content)
-XML_Parser = ctypes.c_void_p # an opaque pointer
-assert XML_Char is ctypes.c_char # this assumption is everywhere in
-# cpython's expat, let's explode
-
-def declare_external(name, args, res):
-    func = getattr(lib, name)
-    func.args = args
-    func.restype = res
-    globals()[name] = func
-
-declare_external('XML_ParserCreate', [c_char_p], XML_Parser)
-declare_external('XML_ParserCreateNS', [c_char_p, c_char], XML_Parser)
-declare_external('XML_Parse', [XML_Parser, c_char_p, c_int, c_int], c_int)
-currents = ['CurrentLineNumber', 'CurrentColumnNumber',
-            'CurrentByteIndex']
-for name in currents:
-    func = getattr(lib, 'XML_Get' + name)
-    func.args = [XML_Parser]
-    func.restype = c_int
-
-declare_external('XML_SetReturnNSTriplet', [XML_Parser, c_int], None)
-declare_external('XML_GetSpecifiedAttributeCount', [XML_Parser], c_int)
-declare_external('XML_SetParamEntityParsing', [XML_Parser, c_int], None)
-declare_external('XML_GetErrorCode', [XML_Parser], c_int)
-declare_external('XML_StopParser', [XML_Parser, c_int], None)
-declare_external('XML_ErrorString', [c_int], c_char_p)
-declare_external('XML_SetBase', [XML_Parser, c_char_p], None)
-if XML_COMBINED_VERSION >= 19505:
-    declare_external('XML_UseForeignDTD', [XML_Parser, c_int], None)
-
-declare_external('XML_SetUnknownEncodingHandler', [XML_Parser, c_void_p,
-                                                   c_void_p], None)
-declare_external('XML_FreeContentModel', [XML_Parser, POINTER(XML_Content)],
-                 None)
-declare_external('XML_ExternalEntityParserCreate', [XML_Parser,c_char_p,
-                                                    c_char_p],
-                 XML_Parser)
-
-handler_names = [
-    'StartElement',
-    'EndElement',
-    'ProcessingInstruction',
-    'CharacterData',
-    'UnparsedEntityDecl',
-    'NotationDecl',
-    'StartNamespaceDecl',
-    'EndNamespaceDecl',
-    'Comment',
-    'StartCdataSection',
-    'EndCdataSection',
-    'Default',
-    'DefaultHandlerExpand',
-    'NotStandalone',
-    'ExternalEntityRef',
-    'StartDoctypeDecl',
-    'EndDoctypeDecl',
-    'EntityDecl',
-    'XmlDecl',
-    'ElementDecl',
-    'AttlistDecl',
-    ]
-if XML_COMBINED_VERSION >= 19504:
-    handler_names.append('SkippedEntity')
-setters = {}
-
-for name in handler_names:
-    if name == 'DefaultHandlerExpand':
-        newname = 'XML_SetDefaultHandlerExpand'
-    else:
-        name += 'Handler'
-        newname = 'XML_Set' + name
-    cfunc = getattr(lib, newname)
-    cfunc.args = [XML_Parser, ctypes.c_void_p]
-    cfunc.result = ctypes.c_int
-    setters[name] = cfunc
-
-class ExpatError(Exception):
-    def __str__(self):
-        return self.s
-
-error = ExpatError
-
-class XMLParserType(object):
-    specified_attributes = 0
-    ordered_attributes = 0
-    returns_unicode = 1
-    encoding = 'utf-8'
-    def __init__(self, encoding, namespace_separator, _hook_external_entity=False):
-        self.returns_unicode = 1
-        if encoding:
-            self.encoding = encoding
-        if not _hook_external_entity:
-            if namespace_separator is None:
-                self.itself = XML_ParserCreate(encoding)
-            else:
-                self.itself = XML_ParserCreateNS(encoding, ord(namespace_separator))
-            if not self.itself:
-                raise RuntimeError("Creating parser failed")
-            self._set_unknown_encoding_handler()
-        self.storage = {}
-        self.buffer = None
-        self.buffer_size = 8192
-        self.character_data_handler = None
-        self.intern = {}
-        self.__exc_info = None
-
-    def _flush_character_buffer(self):
-        if not self.buffer:
-            return
-        res = self._call_character_handler(''.join(self.buffer))
-        self.buffer = []
-        return res
-
-    def _call_character_handler(self, buf):
-        if self.character_data_handler:
-            self.character_data_handler(buf)
-
-    def _set_unknown_encoding_handler(self):
-        def UnknownEncoding(encodingData, name, info_p):
-            info = info_p.contents
-            s = ''.join([chr(i) for i in range(256)])
-            u = s.decode(self.encoding, 'replace')
-            for i in range(len(u)):
-                if u[i] == u'\xfffd':
-                    info.map[i] = -1
-                else:
-                    info.map[i] = ord(u[i])
-            info.data = None
-            info.convert = None
-            info.release = None
-            return 1
-        
-        CB = ctypes.CFUNCTYPE(c_int, c_void_p, c_char_p, POINTER(XML_Encoding))
-        cb = CB(UnknownEncoding)
-        self._unknown_encoding_handler = (cb, UnknownEncoding)
-        XML_SetUnknownEncodingHandler(self.itself, cb, None)
-
-    def _set_error(self, code):
-        e = ExpatError()
-        e.code = code
-        lineno = lib.XML_GetCurrentLineNumber(self.itself)
-        colno = lib.XML_GetCurrentColumnNumber(self.itself)
-        e.offset = colno
-        e.lineno = lineno
-        err = XML_ErrorString(code)[:200]
-        e.s = "%s: line: %d, column: %d" % (err, lineno, colno)
-        e.message = e.s
-        self._error = e
-
-    def Parse(self, data, is_final=0):
-        res = XML_Parse(self.itself, data, len(data), is_final)
-        if res == 0:
-            self._set_error(XML_GetErrorCode(self.itself))
-            if self.__exc_info:
-                exc_info = self.__exc_info
-                self.__exc_info = None
-                raise exc_info[0], exc_info[1], exc_info[2]
-            else:
-                raise self._error
-        self._flush_character_buffer()
-        return res
-
-    def _sethandler(self, name, real_cb):
-        setter = setters[name]
-        try:
-            cb = self.storage[(name, real_cb)]
-        except KeyError:
-            cb = getattr(self, 'get_cb_for_%s' % name)(real_cb)
-            self.storage[(name, real_cb)] = cb
-        except TypeError:
-            # weellll...
-            cb = getattr(self, 'get_cb_for_%s' % name)(real_cb)
-        setter(self.itself, cb)
-
-    def _wrap_cb(self, cb):
-        def f(*args):
-            try:
-                return cb(*args)
-            except:
-                self.__exc_info = sys.exc_info()
-                XML_StopParser(self.itself, XML_FALSE)
-        return f
-
-    def get_cb_for_StartElementHandler(self, real_cb):
-        def StartElement(unused, name, attrs):
-            # unpack name and attrs
-            conv = self.conv
-            self._flush_character_buffer()
-            if self.specified_attributes:
-                max = XML_GetSpecifiedAttributeCount(self.itself)
-            else:
-                max = 0
-            while attrs[max]:
-                max += 2 # copied
-            if self.ordered_attributes:
-                res = [attrs[i] for i in range(max)]
-            else:
-                res = {}
-                for i in range(0, max, 2):
-                    res[conv(attrs[i])] = conv(attrs[i + 1])
-            real_cb(conv(name), res)
-        StartElement = self._wrap_cb(StartElement)
-        CB = ctypes.CFUNCTYPE(None, c_void_p, c_char_p, POINTER(c_char_p))
-        return CB(StartElement)
-
-    def get_cb_for_ExternalEntityRefHandler(self, real_cb):
-        def ExternalEntity(unused, context, base, sysId, pubId):
-            self._flush_character_buffer()
-            conv = self.conv
-            res = real_cb(conv(context), conv(base), conv(sysId),
-                          conv(pubId))
-            if res is None:
-                return 0
-            return res
-        ExternalEntity = self._wrap_cb(ExternalEntity)
-        CB = ctypes.CFUNCTYPE(c_int, c_void_p, *([c_char_p] * 4))
-        return CB(ExternalEntity)
-
-    def get_cb_for_CharacterDataHandler(self, real_cb):
-        def CharacterData(unused, s, lgt):
-            if self.buffer is None:
-                self._call_character_handler(self.conv(s[:lgt]))
-            else:
-                if len(self.buffer) + lgt > self.buffer_size:
-                    self._flush_character_buffer()
-                    if self.character_data_handler is None:
-                        return
-                if lgt >= self.buffer_size:
-                    self._call_character_handler(s[:lgt])
-                    self.buffer = []
-                else:
-                    self.buffer.append(s[:lgt])
-        CharacterData = self._wrap_cb(CharacterData)
-        CB = ctypes.CFUNCTYPE(None, c_void_p, POINTER(c_char), c_int)
-        return CB(CharacterData)
-
-    def get_cb_for_NotStandaloneHandler(self, real_cb):
-        def NotStandaloneHandler(unused):
-            return real_cb()
-        NotStandaloneHandler = self._wrap_cb(NotStandaloneHandler)
-        CB = ctypes.CFUNCTYPE(c_int, c_void_p)
-        return CB(NotStandaloneHandler)
-
-    def get_cb_for_EntityDeclHandler(self, real_cb):
-        def EntityDecl(unused, ename, is_param, value, value_len, base,
-                       system_id, pub_id, not_name):
-            self._flush_character_buffer()
-            if not value:
-                value = None
-            else:
-                value = value[:value_len]
-            args = [ename, is_param, value, base, system_id,
-                    pub_id, not_name]
-            args = [self.conv(arg) for arg in args]
-            real_cb(*args)
-        EntityDecl = self._wrap_cb(EntityDecl)
-        CB = ctypes.CFUNCTYPE(None, c_void_p, c_char_p, c_int, c_char_p,
-                               c_int, c_char_p, c_char_p, c_char_p, c_char_p)
-        return CB(EntityDecl)
-
-    def _conv_content_model(self, model):
-        children = tuple([self._conv_content_model(model.children[i])
-                          for i in range(model.numchildren)])
-        return (model.type, model.quant, self.conv(model.name),
-                children)
-
-    def get_cb_for_ElementDeclHandler(self, real_cb):
-        def ElementDecl(unused, name, model):
-            self._flush_character_buffer()
-            modelobj = self._conv_content_model(model[0])
-            real_cb(name, modelobj)
-            XML_FreeContentModel(self.itself, model)
-
-        ElementDecl = self._wrap_cb(ElementDecl)
-        CB = ctypes.CFUNCTYPE(None, c_void_p, c_char_p, POINTER(XML_Content))
-        return CB(ElementDecl)
-
-    def _new_callback_for_string_len(name, sign):
-        def get_callback_for_(self, real_cb):
-            def func(unused, s, len):
-                self._flush_character_buffer()
-                arg = self.conv(s[:len])
-                real_cb(arg)
-            func.func_name = name
-            func = self._wrap_cb(func)
-            CB = ctypes.CFUNCTYPE(*sign)
-            return CB(func)
-        get_callback_for_.func_name = 'get_cb_for_' + name
-        return get_callback_for_
-    
-    for name in ['DefaultHandlerExpand',
-                 'DefaultHandler']:
-        sign = [None, c_void_p, POINTER(c_char), c_int]
-        name = 'get_cb_for_' + name
-        locals()[name] = _new_callback_for_string_len(name, sign)
-
-    def _new_callback_for_starargs(name, sign):
-        def get_callback_for_(self, real_cb):
-            def func(unused, *args):
-                self._flush_character_buffer()
-                args = [self.conv(arg) for arg in args]
-                real_cb(*args)
-            func.func_name = name
-            func = self._wrap_cb(func)
-            CB = ctypes.CFUNCTYPE(*sign)
-            return CB(func)
-        get_callback_for_.func_name = 'get_cb_for_' + name
-        return get_callback_for_
-    
-    for name, num_or_sign in [
-        ('EndElementHandler', 1),
-        ('ProcessingInstructionHandler', 2),
-        ('UnparsedEntityDeclHandler', 5),
-        ('NotationDeclHandler', 4),
-        ('StartNamespaceDeclHandler', 2),
-        ('EndNamespaceDeclHandler', 1),
-        ('CommentHandler', 1),
-        ('StartCdataSectionHandler', 0),
-        ('EndCdataSectionHandler', 0),
-        ('StartDoctypeDeclHandler', [None, c_void_p] + [c_char_p] * 3 + [c_int]),
-        ('XmlDeclHandler', [None, c_void_p, c_char_p, c_char_p, c_int]),
-        ('AttlistDeclHandler', [None, c_void_p] + [c_char_p] * 4 + [c_int]),
-        ('EndDoctypeDeclHandler', 0),
-        ('SkippedEntityHandler', [None, c_void_p, c_char_p, c_int]),
-        ]:
-        if isinstance(num_or_sign, int):
-            sign = [None, c_void_p] + [c_char_p] * num_or_sign
-        else:
-            sign = num_or_sign
-        name = 'get_cb_for_' + name
-        locals()[name] = _new_callback_for_starargs(name, sign)
-
-    def conv_unicode(self, s):
-        if s is None or isinstance(s, int):
-            return s
-        return s.decode(self.encoding, "strict")
-
-    def __setattr__(self, name, value):
-        # forest of ifs...
-        if name in ['ordered_attributes',
-                    'returns_unicode', 'specified_attributes']:
-            if value:
-                if name == 'returns_unicode':
-                    self.conv = self.conv_unicode
-                self.__dict__[name] = 1
-            else:
-                if name == 'returns_unicode':
-                    self.conv = lambda s: s
-                self.__dict__[name] = 0
-        elif name == 'buffer_text':
-            if value:
-                self.buffer = []
-            else:
-                self._flush_character_buffer()
-                self.buffer = None
-        elif name == 'buffer_size':
-            if not isinstance(value, int):
-                raise TypeError("Expected int")
-            if value <= 0:
-                raise ValueError("Expected positive int")
-            self.__dict__[name] = value
-        elif name == 'namespace_prefixes':
-            XML_SetReturnNSTriplet(self.itself, int(bool(value)))
-        elif name in setters:
-            if name == 'CharacterDataHandler':
-                # XXX we need to flush buffer here
-                self._flush_character_buffer()
-                self.character_data_handler = value
-            #print name
-            #print value
-            #print
-            self._sethandler(name, value)
-        else:
-            self.__dict__[name] = value
-
-    def SetParamEntityParsing(self, arg):
-        XML_SetParamEntityParsing(self.itself, arg)
-
-    if XML_COMBINED_VERSION >= 19505:
-        def UseForeignDTD(self, arg=True):
-            if arg:
-                flag = XML_TRUE
-            else:
-                flag = XML_FALSE
-            XML_UseForeignDTD(self.itself, flag)
-
-    def __getattr__(self, name):
-        if name == 'buffer_text':
-            return self.buffer is not None
-        elif name in currents:
-            return getattr(lib, 'XML_Get' + name)(self.itself)
-        elif name == 'ErrorColumnNumber':
-            return lib.XML_GetCurrentColumnNumber(self.itself)
-        elif name == 'ErrorLineNumber':
-            return lib.XML_GetCurrentLineNumber(self.itself)
-        return self.__dict__[name]
-
-    def ParseFile(self, file):
-        return self.Parse(file.read(), False)
-
-    def SetBase(self, base):
-        XML_SetBase(self.itself, base)
-
-    def ExternalEntityParserCreate(self, context, encoding=None):
-        """ExternalEntityParserCreate(context[, encoding])
-        Create a parser for parsing an external entity based on the
-        information passed to the ExternalEntityRefHandler."""
-        new_parser = XMLParserType(encoding, None, True)
-        new_parser.itself = XML_ExternalEntityParserCreate(self.itself,
-                                                           context, encoding)
-        new_parser._set_unknown_encoding_handler()
-        return new_parser
-
- at builtinify
-def ErrorString(errno):
-    return XML_ErrorString(errno)[:200]
-
- at builtinify
-def ParserCreate(encoding=None, namespace_separator=None, intern=None):
-    if (not isinstance(encoding, str) and
-        not encoding is None):
-        raise TypeError("ParserCreate() argument 1 must be string or None, not %s" % encoding.__class__.__name__)
-    if (not isinstance(namespace_separator, str) and
-        not namespace_separator is None):
-        raise TypeError("ParserCreate() argument 2 must be string or None, not %s" % namespace_separator.__class__.__name__)
-    if namespace_separator is not None:
-        if len(namespace_separator) > 1:
-            raise ValueError('namespace_separator must be at most one character, omitted, or None')
-        if len(namespace_separator) == 0:
-            namespace_separator = None
-    return XMLParserType(encoding, namespace_separator)
diff --git a/lib_pypy/pypy_test/test_pyexpat.py b/lib_pypy/pypy_test/test_pyexpat.py
deleted file mode 100644
--- a/lib_pypy/pypy_test/test_pyexpat.py
+++ /dev/null
@@ -1,665 +0,0 @@
-# XXX TypeErrors on calling handlers, or on bad return values from a
-# handler, are obscure and unhelpful.
-
-from __future__ import absolute_import
-import StringIO, sys
-import unittest, py
-
-from lib_pypy.ctypes_config_cache import rebuild
-rebuild.rebuild_one('pyexpat.ctc.py')
-
-from lib_pypy import pyexpat
-#from xml.parsers import expat
-expat = pyexpat
-
-from test.test_support import sortdict, run_unittest
-
-
-class TestSetAttribute:
-    def setup_method(self, meth):
-        self.parser = expat.ParserCreate(namespace_separator='!')
-        self.set_get_pairs = [
-            [0, 0],
-            [1, 1],
-            [2, 1],
-            [0, 0],
-            ]
-
-    def test_returns_unicode(self):
-        for x, y in self.set_get_pairs:
-            self.parser.returns_unicode = x
-            assert self.parser.returns_unicode == y
-
-    def test_ordered_attributes(self):
-        for x, y in self.set_get_pairs:
-            self.parser.ordered_attributes = x
-            assert self.parser.ordered_attributes == y
-
-    def test_specified_attributes(self):
-        for x, y in self.set_get_pairs:
-            self.parser.specified_attributes = x
-            assert self.parser.specified_attributes == y
-
-
-data = '''\
-<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
-<?xml-stylesheet href="stylesheet.css"?>
-<!-- comment data -->
-<!DOCTYPE quotations SYSTEM "quotations.dtd" [
-<!ELEMENT root ANY>
-<!ATTLIST root attr1 CDATA #REQUIRED attr2 CDATA #IMPLIED>
-<!NOTATION notation SYSTEM "notation.jpeg">
-<!ENTITY acirc "&#226;">
-<!ENTITY external_entity SYSTEM "entity.file">
-<!ENTITY unparsed_entity SYSTEM "entity.file" NDATA notation>
-%unparsed_entity;
-]>
-
-<root attr1="value1" attr2="value2&#8000;">
-<myns:subelement xmlns:myns="http://www.python.org/namespace">
-     Contents of subelements
-</myns:subelement>
-<sub2><![CDATA[contents of CDATA section]]></sub2>
-&external_entity;
-&skipped_entity;
-</root>
-'''
-
-
-# Produce UTF-8 output
-class TestParse:
-    class Outputter:
-        def __init__(self):
-            self.out = []
-
-        def StartElementHandler(self, name, attrs):
-            self.out.append('Start element: ' + repr(name) + ' ' +
-                            sortdict(attrs))
-
-        def EndElementHandler(self, name):
-            self.out.append('End element: ' + repr(name))
-
-        def CharacterDataHandler(self, data):
-            data = data.strip()
-            if data:
-                self.out.append('Character data: ' + repr(data))
-
-        def ProcessingInstructionHandler(self, target, data):
-            self.out.append('PI: ' + repr(target) + ' ' + repr(data))
-
-        def StartNamespaceDeclHandler(self, prefix, uri):
-            self.out.append('NS decl: ' + repr(prefix) + ' ' + repr(uri))
-
-        def EndNamespaceDeclHandler(self, prefix):
-            self.out.append('End of NS decl: ' + repr(prefix))
-
-        def StartCdataSectionHandler(self):
-            self.out.append('Start of CDATA section')
-
-        def EndCdataSectionHandler(self):
-            self.out.append('End of CDATA section')
-
-        def CommentHandler(self, text):
-            self.out.append('Comment: ' + repr(text))
-
-        def NotationDeclHandler(self, *args):
-            name, base, sysid, pubid = args
-            self.out.append('Notation declared: %s' %(args,))
-
-        def UnparsedEntityDeclHandler(self, *args):
-            entityName, base, systemId, publicId, notationName = args
-            self.out.append('Unparsed entity decl: %s' %(args,))
-
-        def NotStandaloneHandler(self):
-            self.out.append('Not standalone')
-            return 1
-
-        def ExternalEntityRefHandler(self, *args):
-            context, base, sysId, pubId = args
-            self.out.append('External entity ref: %s' %(args[1:],))
-            return 1
-
-        def StartDoctypeDeclHandler(self, *args):
-            self.out.append(('Start doctype', args))
-            return 1
-
-        def EndDoctypeDeclHandler(self):
-            self.out.append("End doctype")
-            return 1
-
-        def EntityDeclHandler(self, *args):
-            self.out.append(('Entity declaration', args))
-            return 1
-
-        def XmlDeclHandler(self, *args):
-            self.out.append(('XML declaration', args))
-            return 1
-
-        def ElementDeclHandler(self, *args):
-            self.out.append(('Element declaration', args))
-            return 1
-
-        def AttlistDeclHandler(self, *args):
-            self.out.append(('Attribute list declaration', args))
-            return 1
-
-        def SkippedEntityHandler(self, *args):
-            self.out.append(("Skipped entity", args))
-            return 1
-
-        def DefaultHandler(self, userData):
-            pass
-
-        def DefaultHandlerExpand(self, userData):
-            pass
-
-    handler_names = [
-        'StartElementHandler', 'EndElementHandler', 'CharacterDataHandler',
-        'ProcessingInstructionHandler', 'UnparsedEntityDeclHandler',
-        'NotationDeclHandler', 'StartNamespaceDeclHandler',
-        'EndNamespaceDeclHandler', 'CommentHandler',
-        'StartCdataSectionHandler', 'EndCdataSectionHandler', 'DefaultHandler',
-        'DefaultHandlerExpand', 'NotStandaloneHandler',
-        'ExternalEntityRefHandler', 'StartDoctypeDeclHandler',
-        'EndDoctypeDeclHandler', 'EntityDeclHandler', 'XmlDeclHandler',
-        'ElementDeclHandler', 'AttlistDeclHandler', 'SkippedEntityHandler',
-        ]
-
-    def test_utf8(self):
-
-        out = self.Outputter()
-        parser = expat.ParserCreate(namespace_separator='!')
-        for name in self.handler_names:
-            setattr(parser, name, getattr(out, name))
-        parser.returns_unicode = 0
-        parser.Parse(data, 1)
-
-        # Verify output
-        operations = out.out
-        expected_operations = [
-            ('XML declaration', (u'1.0', u'iso-8859-1', 0)),
-            'PI: \'xml-stylesheet\' \'href="stylesheet.css"\'',
-            "Comment: ' comment data '",
-            "Not standalone",
-            ("Start doctype", ('quotations', 'quotations.dtd', None, 1)),
-            ('Element declaration', (u'root', (2, 0, None, ()))),
-            ('Attribute list declaration', ('root', 'attr1', 'CDATA', None,
-                1)),
-            ('Attribute list declaration', ('root', 'attr2', 'CDATA', None,
-                0)),
-            "Notation declared: ('notation', None, 'notation.jpeg', None)",
-            ('Entity declaration', ('acirc', 0, '\xc3\xa2', None, None, None, None)),
-            ('Entity declaration', ('external_entity', 0, None, None,
-                'entity.file', None, None)),
-            "Unparsed entity decl: ('unparsed_entity', None, 'entity.file', None, 'notation')",
-            "Not standalone",
-            "End doctype",
-            "Start element: 'root' {'attr1': 'value1', 'attr2': 'value2\\xe1\\xbd\\x80'}",
-            "NS decl: 'myns' 'http://www.python.org/namespace'",
-            "Start element: 'http://www.python.org/namespace!subelement' {}",
-            "Character data: 'Contents of subelements'",
-            "End element: 'http://www.python.org/namespace!subelement'",
-            "End of NS decl: 'myns'",
-            "Start element: 'sub2' {}",
-            'Start of CDATA section',
-            "Character data: 'contents of CDATA section'",
-            'End of CDATA section',
-            "End element: 'sub2'",
-            "External entity ref: (None, 'entity.file', None)",
-            ('Skipped entity', ('skipped_entity', 0)),
-            "End element: 'root'",
-        ]
-        for operation, expected_operation in zip(operations, expected_operations):
-            assert operation == expected_operation
-
-    def test_unicode(self):
-        # Try the parse again, this time producing Unicode output
-        out = self.Outputter()
-        parser = expat.ParserCreate(namespace_separator='!')
-        parser.returns_unicode = 1
-        for name in self.handler_names:
-            setattr(parser, name, getattr(out, name))
-
-        parser.Parse(data, 1)
-
-        operations = out.out
-        expected_operations = [
-            ('XML declaration', (u'1.0', u'iso-8859-1', 0)),
-            'PI: u\'xml-stylesheet\' u\'href="stylesheet.css"\'',
-            "Comment: u' comment data '",
-            "Not standalone",
-            ("Start doctype", ('quotations', 'quotations.dtd', None, 1)),
-            ('Element declaration', (u'root', (2, 0, None, ()))),
-            ('Attribute list declaration', ('root', 'attr1', 'CDATA', None,
-                1)),
-            ('Attribute list declaration', ('root', 'attr2', 'CDATA', None,
-                0)),
-            "Notation declared: (u'notation', None, u'notation.jpeg', None)",
-            ('Entity declaration', (u'acirc', 0, u'\xe2', None, None, None,
-                None)),
-            ('Entity declaration', (u'external_entity', 0, None, None,
-                 u'entity.file', None, None)),
-            "Unparsed entity decl: (u'unparsed_entity', None, u'entity.file', None, u'notation')",
-            "Not standalone",
-            "End doctype",
-            "Start element: u'root' {u'attr1': u'value1', u'attr2': u'value2\\u1f40'}",
-            "NS decl: u'myns' u'http://www.python.org/namespace'",
-            "Start element: u'http://www.python.org/namespace!subelement' {}",
-            "Character data: u'Contents of subelements'",
-            "End element: u'http://www.python.org/namespace!subelement'",
-            "End of NS decl: u'myns'",
-            "Start element: u'sub2' {}",
-            'Start of CDATA section',
-            "Character data: u'contents of CDATA section'",
-            'End of CDATA section',
-            "End element: u'sub2'",
-            "External entity ref: (None, u'entity.file', None)",
-            ('Skipped entity', ('skipped_entity', 0)),
-            "End element: u'root'",
-        ]
-        for operation, expected_operation in zip(operations, expected_operations):
-            assert operation == expected_operation
-
-    def test_parse_file(self):
-        # Try parsing a file
-        out = self.Outputter()
-        parser = expat.ParserCreate(namespace_separator='!')
-        parser.returns_unicode = 1
-        for name in self.handler_names:
-            setattr(parser, name, getattr(out, name))
-        file = StringIO.StringIO(data)
-
-        parser.ParseFile(file)
-
-        operations = out.out
-        expected_operations = [
-            ('XML declaration', (u'1.0', u'iso-8859-1', 0)),
-            'PI: u\'xml-stylesheet\' u\'href="stylesheet.css"\'',
-            "Comment: u' comment data '",
-            "Not standalone",
-            ("Start doctype", ('quotations', 'quotations.dtd', None, 1)),
-            ('Element declaration', (u'root', (2, 0, None, ()))),
-            ('Attribute list declaration', ('root', 'attr1', 'CDATA', None,
-                1)),
-            ('Attribute list declaration', ('root', 'attr2', 'CDATA', None,
-                0)),
-            "Notation declared: (u'notation', None, u'notation.jpeg', None)",
-            ('Entity declaration', ('acirc', 0, u'\xe2', None, None, None, None)),
-            ('Entity declaration', (u'external_entity', 0, None, None, u'entity.file', None, None)),
-            "Unparsed entity decl: (u'unparsed_entity', None, u'entity.file', None, u'notation')",
-            "Not standalone",
-            "End doctype",
-            "Start element: u'root' {u'attr1': u'value1', u'attr2': u'value2\\u1f40'}",
-            "NS decl: u'myns' u'http://www.python.org/namespace'",
-            "Start element: u'http://www.python.org/namespace!subelement' {}",
-            "Character data: u'Contents of subelements'",
-            "End element: u'http://www.python.org/namespace!subelement'",
-            "End of NS decl: u'myns'",
-            "Start element: u'sub2' {}",
-            'Start of CDATA section',
-            "Character data: u'contents of CDATA section'",
-            'End of CDATA section',
-            "End element: u'sub2'",
-            "External entity ref: (None, u'entity.file', None)",
-            ('Skipped entity', ('skipped_entity', 0)),
-            "End element: u'root'",
-        ]
-        for operation, expected_operation in zip(operations, expected_operations):
-            assert operation == expected_operation
-
-
-class TestNamespaceSeparator:
-    def test_legal(self):
-        # Tests that make sure we get errors when the namespace_separator value
-        # is illegal, and that we don't for good values:
-        expat.ParserCreate()
-        expat.ParserCreate(namespace_separator=None)
-        expat.ParserCreate(namespace_separator=' ')
-
-    def test_illegal(self):
-        try:
-            expat.ParserCreate(namespace_separator=42)
-            raise AssertionError
-        except TypeError, e:
-            assert str(e) == (
-                'ParserCreate() argument 2 must be string or None, not int')
-
-        try:
-            expat.ParserCreate(namespace_separator='too long')
-            raise AssertionError
-        except ValueError, e:
-            assert str(e) == (
-                'namespace_separator must be at most one character, omitted, or None')
-
-    def test_zero_length(self):
-        # ParserCreate() needs to accept a namespace_separator of zero length
-        # to satisfy the requirements of RDF applications that are required
-        # to simply glue together the namespace URI and the localname.  Though
-        # considered a wart of the RDF specifications, it needs to be supported.
-        #
-        # See XML-SIG mailing list thread starting with
-        # http://mail.python.org/pipermail/xml-sig/2001-April/005202.html
-        #
-        expat.ParserCreate(namespace_separator='') # too short
-
-
-class TestInterning:
-    def test(self):
-        py.test.skip("Not working")
-        # Test the interning machinery.
-        p = expat.ParserCreate()
-        L = []
-        def collector(name, *args):
-            L.append(name)
-        p.StartElementHandler = collector
-        p.EndElementHandler = collector
-        p.Parse("<e> <e/> <e></e> </e>", 1)
-        tag = L[0]
-        assert len(L) == 6
-        for entry in L:
-            # L should have the same string repeated over and over.
-            assert tag is entry
-
-
-class TestBufferText:
-    def setup_method(self, meth):
-        self.stuff = []
-        self.parser = expat.ParserCreate()
-        self.parser.buffer_text = 1
-        self.parser.CharacterDataHandler = self.CharacterDataHandler
-
-    def check(self, expected, label):
-        assert self.stuff == expected, (
-                "%s\nstuff    = %r\nexpected = %r"
-                % (label, self.stuff, map(unicode, expected)))
-
-    def CharacterDataHandler(self, text):
-        self.stuff.append(text)
-
-    def StartElementHandler(self, name, attrs):
-        self.stuff.append("<%s>" % name)
-        bt = attrs.get("buffer-text")
-        if bt == "yes":
-            self.parser.buffer_text = 1
-        elif bt == "no":
-            self.parser.buffer_text = 0
-
-    def EndElementHandler(self, name):
-        self.stuff.append("</%s>" % name)
-
-    def CommentHandler(self, data):
-        self.stuff.append("<!--%s-->" % data)
-
-    def setHandlers(self, handlers=[]):
-        for name in handlers:
-            setattr(self.parser, name, getattr(self, name))
-
-    def test_default_to_disabled(self):
-        parser = expat.ParserCreate()
-        assert not parser.buffer_text
-
-    def test_buffering_enabled(self):
-        # Make sure buffering is turned on
-        assert self.parser.buffer_text
-        self.parser.Parse("<a>1<b/>2<c/>3</a>", 1)
-        assert self.stuff == ['123'], (
-                          "buffered text not properly collapsed")
-
-    def test1(self):
-        # XXX This test exposes more detail of Expat's text chunking than we
-        # XXX like, but it tests what we need to concisely.
-        self.setHandlers(["StartElementHandler"])
-        self.parser.Parse("<a>1<b buffer-text='no'/>2\n3<c buffer-text='yes'/>4\n5</a>", 1)
-        assert self.stuff == (
-                          ["<a>", "1", "<b>", "2", "\n", "3", "<c>", "4\n5"]), (
-                          "buffering control not reacting as expected")
-
-    def test2(self):
-        self.parser.Parse("<a>1<b/>&lt;2&gt;<c/>&#32;\n&#x20;3</a>", 1)
-        assert self.stuff == ["1<2> \n 3"], (
-                          "buffered text not properly collapsed")
-
-    def test3(self):
-        self.setHandlers(["StartElementHandler"])
-        self.parser.Parse("<a>1<b/>2<c/>3</a>", 1)
-        assert self.stuff == ["<a>", "1", "<b>", "2", "<c>", "3"], (
-                          "buffered text not properly split")
-
-    def test4(self):
-        self.setHandlers(["StartElementHandler", "EndElementHandler"])
-        self.parser.CharacterDataHandler = None
-        self.parser.Parse("<a>1<b/>2<c/>3</a>", 1)
-        assert self.stuff == (
-                          ["<a>", "<b>", "</b>", "<c>", "</c>", "</a>"])
-
-    def test5(self):
-        self.setHandlers(["StartElementHandler", "EndElementHandler"])
-        self.parser.Parse("<a>1<b></b>2<c/>3</a>", 1)
-        assert self.stuff == (
-            ["<a>", "1", "<b>", "</b>", "2", "<c>", "</c>", "3", "</a>"])
-
-    def test6(self):
-        self.setHandlers(["CommentHandler", "EndElementHandler",
-                    "StartElementHandler"])
-        self.parser.Parse("<a>1<b/>2<c></c>345</a> ", 1)
-        assert self.stuff == (
-            ["<a>", "1", "<b>", "</b>", "2", "<c>", "</c>", "345", "</a>"]), (
-            "buffered text not properly split")
-
-    def test7(self):
-        self.setHandlers(["CommentHandler", "EndElementHandler",
-                    "StartElementHandler"])
-        self.parser.Parse("<a>1<b/>2<c></c>3<!--abc-->4<!--def-->5</a> ", 1)
-        assert self.stuff == (
-                          ["<a>", "1", "<b>", "</b>", "2", "<c>", "</c>", "3",
-                           "<!--abc-->", "4", "<!--def-->", "5", "</a>"]), (
-                          "buffered text not properly split")
-
-
-# Test handling of exception from callback:
-class TestHandlerException:
-    def StartElementHandler(self, name, attrs):
-        raise RuntimeError(name)
-
-    def test(self):
-        parser = expat.ParserCreate()
-        parser.StartElementHandler = self.StartElementHandler
-        try:
-            parser.Parse("<a><b><c/></b></a>", 1)
-            raise AssertionError
-        except RuntimeError, e:
-            assert e.args[0] == 'a', (
-                              "Expected RuntimeError for element 'a', but" + \
-                              " found %r" % e.args[0])
-
-
-# Test Current* members:
-class TestPosition:
-    def StartElementHandler(self, name, attrs):
-        self.check_pos('s')
-
-    def EndElementHandler(self, name):
-        self.check_pos('e')
-
-    def check_pos(self, event):
-        pos = (event,
-               self.parser.CurrentByteIndex,
-               self.parser.CurrentLineNumber,
-               self.parser.CurrentColumnNumber)
-        assert self.upto < len(self.expected_list)
-        expected = self.expected_list[self.upto]
-        assert pos == expected, (
-                'Expected position %s, got position %s' %(pos, expected))
-        self.upto += 1
-
-    def test(self):
-        self.parser = expat.ParserCreate()
-        self.parser.StartElementHandler = self.StartElementHandler
-        self.parser.EndElementHandler = self.EndElementHandler
-        self.upto = 0
-        self.expected_list = [('s', 0, 1, 0), ('s', 5, 2, 1), ('s', 11, 3, 2),
-                              ('e', 15, 3, 6), ('e', 17, 4, 1), ('e', 22, 5, 0)]
-
-        xml = '<a>\n <b>\n  <c/>\n </b>\n</a>'
-        self.parser.Parse(xml, 1)
-
-
-class Testsf1296433:
-    def test_parse_only_xml_data(self):
-        # http://python.org/sf/1296433
-        #
-        xml = "<?xml version='1.0' encoding='iso8859'?><s>%s</s>" % ('a' * 1025)
-        # this one doesn't crash
-        #xml = "<?xml version='1.0'?><s>%s</s>" % ('a' * 10000)
-
-        class SpecificException(Exception):
-            pass
-
-        def handler(text):
-            raise SpecificException
-
-        parser = expat.ParserCreate()
-        parser.CharacterDataHandler = handler
-
-        py.test.raises(Exception, parser.Parse, xml)
-
-class TestChardataBuffer:
-    """
-    test setting of chardata buffer size
-    """
-
-    def test_1025_bytes(self):
-        assert self.small_buffer_test(1025) == 2
-
-    def test_1000_bytes(self):
-        assert self.small_buffer_test(1000) == 1
-
-    def test_wrong_size(self):
-        parser = expat.ParserCreate()
-        parser.buffer_text = 1
-        def f(size):
-            parser.buffer_size = size
-
-        py.test.raises(TypeError, f, sys.maxint+1)
-        py.test.raises(ValueError, f, -1)
-        py.test.raises(ValueError, f, 0)
-
-    def test_unchanged_size(self):
-        xml1 = ("<?xml version='1.0' encoding='iso8859'?><s>%s" % ('a' * 512))
-        xml2 = 'a'*512 + '</s>'
-        parser = expat.ParserCreate()
-        parser.CharacterDataHandler = self.counting_handler
-        parser.buffer_size = 512
-        parser.buffer_text = 1
-
-        # Feed 512 bytes of character data: the handler should be called
-        # once.
-        self.n = 0
-        parser.Parse(xml1)
-        assert self.n == 1
-
-        # Reassign to buffer_size, but assign the same size.
-        parser.buffer_size = parser.buffer_size
-        assert self.n == 1
-
-        # Try parsing rest of the document
-        parser.Parse(xml2)
-        assert self.n == 2
-
-
-    def test_disabling_buffer(self):
-        xml1 = "<?xml version='1.0' encoding='iso8859'?><a>%s" % ('a' * 512)
-        xml2 = ('b' * 1024)
-        xml3 = "%s</a>" % ('c' * 1024)
-        parser = expat.ParserCreate()
-        parser.CharacterDataHandler = self.counting_handler
-        parser.buffer_text = 1
-        parser.buffer_size = 1024
-        assert parser.buffer_size == 1024
-
-        # Parse one chunk of XML
-        self.n = 0
-        parser.Parse(xml1, 0)
-        assert parser.buffer_size == 1024
-        assert self.n == 1
-
-        # Turn off buffering and parse the next chunk.
-        parser.buffer_text = 0
-        assert not parser.buffer_text
-        assert parser.buffer_size == 1024
-        for i in range(10):
-            parser.Parse(xml2, 0)
-        assert self.n == 11
-
-        parser.buffer_text = 1
-        assert parser.buffer_text
-        assert parser.buffer_size == 1024
-        parser.Parse(xml3, 1)
-        assert self.n == 12
-
-
-
-    def make_document(self, bytes):
-        return ("<?xml version='1.0'?><tag>" + bytes * 'a' + '</tag>')
-
-    def counting_handler(self, text):
-        self.n += 1
-
-    def small_buffer_test(self, buffer_len):
-        xml = "<?xml version='1.0' encoding='iso8859'?><s>%s</s>" % ('a' * buffer_len)
-        parser = expat.ParserCreate()
-        parser.CharacterDataHandler = self.counting_handler
-        parser.buffer_size = 1024
-        parser.buffer_text = 1
-
-        self.n = 0
-        parser.Parse(xml)
-        return self.n
-
-    def test_change_size_1(self):
-        xml1 = "<?xml version='1.0' encoding='iso8859'?><a><s>%s" % ('a' * 1024)
-        xml2 = "aaa</s><s>%s</s></a>" % ('a' * 1025)
-        parser = expat.ParserCreate()
-        parser.CharacterDataHandler = self.counting_handler
-        parser.buffer_text = 1
-        parser.buffer_size = 1024
-        assert parser.buffer_size == 1024
-
-        self.n = 0
-        parser.Parse(xml1, 0)
-        parser.buffer_size *= 2
-        assert parser.buffer_size == 2048
-        parser.Parse(xml2, 1)
-        assert self.n == 2
-
-    def test_change_size_2(self):
-        xml1 = "<?xml version='1.0' encoding='iso8859'?><a>a<s>%s" % ('a' * 1023)
-        xml2 = "aaa</s><s>%s</s></a>" % ('a' * 1025)
-        parser = expat.ParserCreate()
-        parser.CharacterDataHandler = self.counting_handler
-        parser.buffer_text = 1
-        parser.buffer_size = 2048
-        assert parser.buffer_size == 2048
-
-        self.n=0
-        parser.Parse(xml1, 0)
-        parser.buffer_size /= 2
-        assert parser.buffer_size == 1024
-        parser.Parse(xml2, 1)
-        assert self.n == 4
-
-    def test_segfault(self):
-        py.test.raises(TypeError, expat.ParserCreate, 1234123123)
-
-def test_invalid_data():
-    parser = expat.ParserCreate()
-    parser.Parse('invalid.xml', 0)
-    try:
-        parser.Parse("", 1)
-    except expat.ExpatError, e:
-        assert e.code == 2 # XXX is this reliable?
-        assert e.lineno == 1
-        assert e.message.startswith('syntax error')
-    else:
-        py.test.fail("Did not raise")
-
diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py
--- a/pypy/config/translationoption.py
+++ b/pypy/config/translationoption.py
@@ -105,7 +105,8 @@
     BoolOption("sandbox", "Produce a fully-sandboxed executable",
                default=False, cmdline="--sandbox",
                requires=[("translation.thread", False)],
-               suggests=[("translation.gc", "generation")]),
+               suggests=[("translation.gc", "generation"),
+                         ("translation.gcrootfinder", "shadowstack")]),
     BoolOption("rweakref", "The backend supports RPython-level weakrefs",
                default=True),
 
diff --git a/pypy/doc/config/objspace.usemodules.pyexpat.txt b/pypy/doc/config/objspace.usemodules.pyexpat.txt
--- a/pypy/doc/config/objspace.usemodules.pyexpat.txt
+++ b/pypy/doc/config/objspace.usemodules.pyexpat.txt
@@ -1,2 +1,1 @@
-Use (experimental) pyexpat module written in RPython, instead of CTypes
-version which is used by default.
+Use the pyexpat module, written in RPython.
diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst
--- a/pypy/doc/cpython_differences.rst
+++ b/pypy/doc/cpython_differences.rst
@@ -313,5 +313,10 @@
   implementation detail that shows up because of internal C-level slots
   that PyPy does not have.
 
+* the ``__dict__`` attribute of new-style classes returns a normal dict, as
+  opposed to a dict proxy like in CPython. Mutating the dict will change the
+  type and vice versa. For builtin types, a dictionary will be returned that
+  cannot be changed (but still looks and behaves like a normal dictionary).
+
 
 .. include:: _ref.txt
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -328,7 +328,7 @@
                 raise
             modname = self.str_w(w_modname)
             mod = self.interpclass_w(w_mod)
-            if isinstance(mod, Module):
+            if isinstance(mod, Module) and not mod.startup_called:
                 self.timer.start("startup " + modname)
                 mod.init(self)
                 self.timer.stop("startup " + modname)
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -60,11 +60,10 @@
         self.pycode = code
         eval.Frame.__init__(self, space, w_globals)
         self.locals_stack_w = [None] * (code.co_nlocals + code.co_stacksize)
-        self.nlocals = code.co_nlocals
         self.valuestackdepth = code.co_nlocals
         self.lastblock = None
         make_sure_not_resized(self.locals_stack_w)
-        check_nonneg(self.nlocals)
+        check_nonneg(self.valuestackdepth)
         #
         if space.config.objspace.honor__builtins__:
             self.builtin = space.builtin.pick_builtin(w_globals)
@@ -144,8 +143,8 @@
     def execute_frame(self, w_inputvalue=None, operr=None):
         """Execute this frame.  Main entry point to the interpreter.
         The optional arguments are there to handle a generator's frame:
-        w_inputvalue is for generator.send()) and operr is for
-        generator.throw()).
+        w_inputvalue is for generator.send() and operr is for
+        generator.throw().
         """
         # the following 'assert' is an annotation hint: it hides from
         # the annotator all methods that are defined in PyFrame but
@@ -195,7 +194,7 @@
 
     def popvalue(self):
         depth = self.valuestackdepth - 1
-        assert depth >= self.nlocals, "pop from empty value stack"
+        assert depth >= self.pycode.co_nlocals, "pop from empty value stack"
         w_object = self.locals_stack_w[depth]
         self.locals_stack_w[depth] = None
         self.valuestackdepth = depth
@@ -223,7 +222,7 @@
     def peekvalues(self, n):
         values_w = [None] * n
         base = self.valuestackdepth - n
-        assert base >= self.nlocals
+        assert base >= self.pycode.co_nlocals
         while True:
             n -= 1
             if n < 0:
@@ -235,7 +234,8 @@
     def dropvalues(self, n):
         n = hint(n, promote=True)
         finaldepth = self.valuestackdepth - n
-        assert finaldepth >= self.nlocals, "stack underflow in dropvalues()"
+        assert finaldepth >= self.pycode.co_nlocals, (
+            "stack underflow in dropvalues()")
         while True:
             n -= 1
             if n < 0:
@@ -267,13 +267,15 @@
         # Contrast this with CPython where it's PEEK(-1).
         index_from_top = hint(index_from_top, promote=True)
         index = self.valuestackdepth + ~index_from_top
-        assert index >= self.nlocals, "peek past the bottom of the stack"
+        assert index >= self.pycode.co_nlocals, (
+            "peek past the bottom of the stack")
         return self.locals_stack_w[index]
 
     def settopvalue(self, w_object, index_from_top=0):
         index_from_top = hint(index_from_top, promote=True)
         index = self.valuestackdepth + ~index_from_top
-        assert index >= self.nlocals, "settop past the bottom of the stack"
+        assert index >= self.pycode.co_nlocals, (
+            "settop past the bottom of the stack")
         self.locals_stack_w[index] = w_object
 
     @jit.unroll_safe
@@ -320,12 +322,13 @@
         else:
             f_lineno = self.f_lineno
 
-        values_w = self.locals_stack_w[self.nlocals:self.valuestackdepth]
+        nlocals = self.pycode.co_nlocals
+        values_w = self.locals_stack_w[nlocals:self.valuestackdepth]
         w_valuestack = maker.slp_into_tuple_with_nulls(space, values_w)
         
         w_blockstack = nt([block._get_state_(space) for block in self.get_blocklist()])
         w_fastlocals = maker.slp_into_tuple_with_nulls(
-            space, self.locals_stack_w[:self.nlocals])
+            space, self.locals_stack_w[:nlocals])
         if self.last_exception is None:
             w_exc_value = space.w_None
             w_tb = space.w_None
@@ -442,7 +445,7 @@
         """Initialize the fast locals from a list of values,
         where the order is according to self.pycode.signature()."""
         scope_len = len(scope_w)
-        if scope_len > self.nlocals:
+        if scope_len > self.pycode.co_nlocals:
             raise ValueError, "new fastscope is longer than the allocated area"
         # don't assign directly to 'locals_stack_w[:scope_len]' to be
         # virtualizable-friendly
@@ -456,7 +459,7 @@
         pass
 
     def getfastscopelength(self):
-        return self.nlocals
+        return self.pycode.co_nlocals
 
     def getclosure(self):
         return None
diff --git a/pypy/interpreter/test/test_objspace.py b/pypy/interpreter/test/test_objspace.py
--- a/pypy/interpreter/test/test_objspace.py
+++ b/pypy/interpreter/test/test_objspace.py
@@ -322,3 +322,14 @@
             space.ALL_BUILTIN_MODULES.pop()
             del space._builtinmodule_list
             mods = space.get_builtinmodule_to_install()
+
+    def test_dont_reload_builtin_mods_on_startup(self):
+        from pypy.tool.option import make_config, make_objspace
+        config = make_config(None)
+        space = make_objspace(config)
+        w_executable = space.wrap('executable')
+        assert space.str_w(space.getattr(space.sys, w_executable)) == 'py.py'
+        space.setattr(space.sys, w_executable, space.wrap('foobar'))
+        assert space.str_w(space.getattr(space.sys, w_executable)) == 'foobar'
+        space.startup()
+        assert space.str_w(space.getattr(space.sys, w_executable)) == 'foobar'
diff --git a/pypy/interpreter/test/test_zpy.py b/pypy/interpreter/test/test_zpy.py
--- a/pypy/interpreter/test/test_zpy.py
+++ b/pypy/interpreter/test/test_zpy.py
@@ -17,14 +17,14 @@
 def test_executable():
     """Ensures sys.executable points to the py.py script"""
     # TODO : watch out for spaces/special chars in pypypath
-    output = run(sys.executable, pypypath,
+    output = run(sys.executable, pypypath, '-S',
                  "-c", "import sys;print sys.executable")
     assert output.splitlines()[-1] == pypypath
 
 def test_special_names():
     """Test the __name__ and __file__ special global names"""
     cmd = "print __name__; print '__file__' in globals()"
-    output = run(sys.executable, pypypath, '-c', cmd)
+    output = run(sys.executable, pypypath, '-S', '-c', cmd)
     assert output.splitlines()[-2] == '__main__'
     assert output.splitlines()[-1] == 'False'
 
@@ -33,24 +33,24 @@
     tmpfile.write("print __name__; print __file__\n")
     tmpfile.close()
 
-    output = run(sys.executable, pypypath, tmpfilepath)
+    output = run(sys.executable, pypypath, '-S', tmpfilepath)
     assert output.splitlines()[-2] == '__main__'
     assert output.splitlines()[-1] == str(tmpfilepath)
 
 def test_argv_command():
     """Some tests on argv"""
     # test 1 : no arguments
-    output = run(sys.executable, pypypath,
+    output = run(sys.executable, pypypath, '-S',
                  "-c", "import sys;print sys.argv")
     assert output.splitlines()[-1] == str(['-c'])
 
     # test 2 : some arguments after
-    output = run(sys.executable, pypypath,
+    output = run(sys.executable, pypypath, '-S',
                  "-c", "import sys;print sys.argv", "hello")
     assert output.splitlines()[-1] == str(['-c','hello'])
     
     # test 3 : additionnal pypy parameters
-    output = run(sys.executable, pypypath,
+    output = run(sys.executable, pypypath, '-S',
                  "-O", "-c", "import sys;print sys.argv", "hello")
     assert output.splitlines()[-1] == str(['-c','hello'])
 
@@ -65,15 +65,15 @@
     tmpfile.close()
 
     # test 1 : no arguments
-    output = run(sys.executable, pypypath, tmpfilepath)
+    output = run(sys.executable, pypypath, '-S', tmpfilepath)
     assert output.splitlines()[-1] == str([tmpfilepath])
     
     # test 2 : some arguments after
-    output = run(sys.executable, pypypath, tmpfilepath, "hello")
+    output = run(sys.executable, pypypath, '-S', tmpfilepath, "hello")
     assert output.splitlines()[-1] == str([tmpfilepath,'hello'])
     
     # test 3 : additionnal pypy parameters
-    output = run(sys.executable, pypypath, "-O", tmpfilepath, "hello")
+    output = run(sys.executable, pypypath, '-S', "-O", tmpfilepath, "hello")
     assert output.splitlines()[-1] == str([tmpfilepath,'hello'])
     
 
@@ -95,7 +95,7 @@
     tmpfile.write(TB_NORMALIZATION_CHK)
     tmpfile.close()
 
-    popen = subprocess.Popen([sys.executable, str(pypypath), tmpfilepath],
+    popen = subprocess.Popen([sys.executable, str(pypypath), '-S', tmpfilepath],
                              stderr=subprocess.PIPE)
     _, stderr = popen.communicate()
     assert stderr.endswith('KeyError: <normalized>\n')
diff --git a/pypy/jit/backend/llsupport/gc.py b/pypy/jit/backend/llsupport/gc.py
--- a/pypy/jit/backend/llsupport/gc.py
+++ b/pypy/jit/backend/llsupport/gc.py
@@ -1,7 +1,6 @@
 import os
 from pypy.rlib import rgc
 from pypy.rlib.objectmodel import we_are_translated, specialize
-from pypy.rlib.debug import fatalerror
 from pypy.rlib.rarithmetic import ovfcheck
 from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr
 from pypy.rpython.lltypesystem import llgroup
diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py
--- a/pypy/jit/backend/test/runner_test.py
+++ b/pypy/jit/backend/test/runner_test.py
@@ -2221,6 +2221,35 @@
         print 'step 4 ok'
         print '-'*79
 
+    def test_guard_not_invalidated_and_label(self):
+        # test that the guard_not_invalidated reserves enough room before
+        # the label.  If it doesn't, then in this example after we invalidate
+        # the guard, jumping to the label will hit the invalidation code too
+        cpu = self.cpu
+        i0 = BoxInt()
+        faildescr = BasicFailDescr(1)
+        labeldescr = TargetToken()
+        ops = [
+            ResOperation(rop.GUARD_NOT_INVALIDATED, [], None, descr=faildescr),
+            ResOperation(rop.LABEL, [i0], None, descr=labeldescr),
+            ResOperation(rop.FINISH, [i0], None, descr=BasicFailDescr(3)),
+        ]
+        ops[0].setfailargs([])
+        looptoken = JitCellToken()
+        self.cpu.compile_loop([i0], ops, looptoken)
+        # mark as failing
+        self.cpu.invalidate_loop(looptoken)
+        # attach a bridge
+        i2 = BoxInt()
+        ops = [
+            ResOperation(rop.JUMP, [ConstInt(333)], None, descr=labeldescr),
+        ]
+        self.cpu.compile_bridge(faildescr, [], ops, looptoken)
+        # run: must not be caught in an infinite loop
+        fail = self.cpu.execute_token(looptoken, 16)
+        assert fail.identifier == 3
+        assert self.cpu.get_latest_value_int(0) == 333
+
     # pure do_ / descr features
 
     def test_do_operations(self):
diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py
--- a/pypy/jit/backend/x86/regalloc.py
+++ b/pypy/jit/backend/x86/regalloc.py
@@ -165,7 +165,6 @@
         self.jump_target_descr = None
         self.close_stack_struct = 0
         self.final_jump_op = None
-        self.min_bytes_before_label = 0
 
     def _prepare(self, inputargs, operations, allgcrefs):
         self.fm = X86FrameManager()
@@ -199,8 +198,13 @@
         operations = self._prepare(inputargs, operations, allgcrefs)
         self._update_bindings(arglocs, inputargs)
         self.param_depth = prev_depths[1]
+        self.min_bytes_before_label = 0
         return operations
 
+    def ensure_next_label_is_at_least_at_position(self, at_least_position):
+        self.min_bytes_before_label = max(self.min_bytes_before_label,
+                                          at_least_position)
+
     def reserve_param(self, n):
         self.param_depth = max(self.param_depth, n)
 
@@ -468,7 +472,11 @@
         self.assembler.mc.mark_op(None) # end of the loop
 
     def flush_loop(self):
-        # rare case: if the loop is too short, pad with NOPs
+        # rare case: if the loop is too short, or if we are just after
+        # a GUARD_NOT_INVALIDATED, pad with NOPs.  Important!  This must
+        # be called to ensure that there are enough bytes produced,
+        # because GUARD_NOT_INVALIDATED or redirect_call_assembler()
+        # will maybe overwrite them.
         mc = self.assembler.mc
         while mc.get_relative_pos() < self.min_bytes_before_label:
             mc.NOP()
@@ -558,7 +566,15 @@
     def consider_guard_no_exception(self, op):
         self.perform_guard(op, [], None)
 
-    consider_guard_not_invalidated = consider_guard_no_exception
+    def consider_guard_not_invalidated(self, op):
+        mc = self.assembler.mc
+        n = mc.get_relative_pos()
+        self.perform_guard(op, [], None)
+        assert n == mc.get_relative_pos()
+        # ensure that the next label is at least 5 bytes farther than
+        # the current position.  Otherwise, when invalidating the guard,
+        # we would overwrite randomly the next label's position.
+        self.ensure_next_label_is_at_least_at_position(n + 5)
 
     def consider_guard_exception(self, op):
         loc = self.rm.make_sure_var_in_reg(op.getarg(0))
diff --git a/pypy/jit/backend/x86/support.py b/pypy/jit/backend/x86/support.py
--- a/pypy/jit/backend/x86/support.py
+++ b/pypy/jit/backend/x86/support.py
@@ -1,6 +1,7 @@
 import sys
 from pypy.rpython.lltypesystem import lltype, rffi, llmemory
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
+from pypy.jit.backend.x86.arch import WORD
 
 
 def values_array(TP, size):
@@ -37,8 +38,13 @@
 
 if sys.platform == 'win32':
     ensure_sse2_floats = lambda : None
+    # XXX check for SSE2 on win32 too
 else:
+    if WORD == 4:
+        extra = ['-DPYPY_X86_CHECK_SSE2']
+    else:
+        extra = []
     ensure_sse2_floats = rffi.llexternal_use_eci(ExternalCompilationInfo(
         compile_extra = ['-msse2', '-mfpmath=sse',
-                         '-DPYPY_CPU_HAS_STANDARD_PRECISION'],
+                         '-DPYPY_CPU_HAS_STANDARD_PRECISION'] + extra,
         ))
diff --git a/pypy/jit/backend/x86/test/test_ztranslation.py b/pypy/jit/backend/x86/test/test_ztranslation.py
--- a/pypy/jit/backend/x86/test/test_ztranslation.py
+++ b/pypy/jit/backend/x86/test/test_ztranslation.py
@@ -52,6 +52,7 @@
             set_param(jitdriver, "trace_eagerness", 2)
             total = 0
             frame = Frame(i)
+            j = float(j)
             while frame.i > 3:
                 jitdriver.can_enter_jit(frame=frame, total=total, j=j)
                 jitdriver.jit_merge_point(frame=frame, total=total, j=j)
diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py
--- a/pypy/jit/metainterp/optimizeopt/optimizer.py
+++ b/pypy/jit/metainterp/optimizeopt/optimizer.py
@@ -567,7 +567,7 @@
         assert isinstance(descr, compile.ResumeGuardDescr)
         modifier = resume.ResumeDataVirtualAdder(descr, self.resumedata_memo)
         try:
-            newboxes = modifier.finish(self.values, self.pendingfields)
+            newboxes = modifier.finish(self, self.pendingfields)
             if len(newboxes) > self.metainterp_sd.options.failargs_limit:
                 raise resume.TagOverflow
         except resume.TagOverflow:
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -7760,6 +7760,59 @@
         """
         self.optimize_loop(ops, expected)
         
+    def test_constant_failargs(self):
+        ops = """
+        [p1, i2, i3]
+        setfield_gc(p1, ConstPtr(myptr), descr=nextdescr)
+        p16 = getfield_gc(p1, descr=nextdescr)
+        guard_true(i2) [p16, i3]
+        jump(p1, i3, i2)
+        """
+        preamble = """
+        [p1, i2, i3]
+        setfield_gc(p1, ConstPtr(myptr), descr=nextdescr)
+        guard_true(i2) [i3]
+        jump(p1, i3)
+        """
+        expected = """
+        [p1, i3]
+        guard_true(i3) []
+        jump(p1, 1)
+        """
+        self.optimize_loop(ops, expected, preamble)
+
+    def test_issue1048(self):
+        ops = """
+        [p1, i2, i3]
+        p16 = getfield_gc(p1, descr=nextdescr)
+        guard_true(i2) [p16]
+        setfield_gc(p1, ConstPtr(myptr), descr=nextdescr)
+        jump(p1, i3, i2)
+        """
+        expected = """
+        [p1, i3]
+        guard_true(i3) []
+        jump(p1, 1)
+        """
+        self.optimize_loop(ops, expected)
+
+    def test_issue1048_ok(self):
+        ops = """
+        [p1, i2, i3]
+        p16 = getfield_gc(p1, descr=nextdescr)
+        call(p16, descr=nonwritedescr)
+        guard_true(i2) [p16]
+        setfield_gc(p1, ConstPtr(myptr), descr=nextdescr)
+        jump(p1, i3, i2)
+        """
+        expected = """
+        [p1, i3]
+        call(ConstPtr(myptr), descr=nonwritedescr)
+        guard_true(i3) []
+        jump(p1, 1)
+        """
+        self.optimize_loop(ops, expected)
+
 class TestLLtype(OptimizeOptTest, LLtypeMixin):
     pass
 
diff --git a/pypy/jit/metainterp/resume.py b/pypy/jit/metainterp/resume.py
--- a/pypy/jit/metainterp/resume.py
+++ b/pypy/jit/metainterp/resume.py
@@ -182,23 +182,22 @@
 
     # env numbering
 
-    def number(self, values, snapshot):
+    def number(self, optimizer, snapshot):
         if snapshot is None:
             return lltype.nullptr(NUMBERING), {}, 0
         if snapshot in self.numberings:
              numb, liveboxes, v = self.numberings[snapshot]
              return numb, liveboxes.copy(), v
 
-        numb1, liveboxes, v = self.number(values, snapshot.prev)
+        numb1, liveboxes, v = self.number(optimizer, snapshot.prev)
         n = len(liveboxes)-v
         boxes = snapshot.boxes
         length = len(boxes)
         numb = lltype.malloc(NUMBERING, length)
         for i in range(length):
             box = boxes[i]
-            value = values.get(box, None)
-            if value is not None:
-                box = value.get_key_box()
+            value = optimizer.getvalue(box)
+            box = value.get_key_box()
 
             if isinstance(box, Const):
                 tagged = self.getconst(box)
@@ -318,14 +317,14 @@
         _, tagbits = untag(tagged)
         return tagbits == TAGVIRTUAL
 
-    def finish(self, values, pending_setfields=[]):
+    def finish(self, optimizer, pending_setfields=[]):
         # compute the numbering
         storage = self.storage
         # make sure that nobody attached resume data to this guard yet
         assert not storage.rd_numb
         snapshot = storage.rd_snapshot
         assert snapshot is not None # is that true?
-        numb, liveboxes_from_env, v = self.memo.number(values, snapshot)
+        numb, liveboxes_from_env, v = self.memo.number(optimizer, snapshot)
         self.liveboxes_from_env = liveboxes_from_env
         self.liveboxes = {}
         storage.rd_numb = numb
@@ -341,23 +340,23 @@
                 liveboxes[i] = box
             else:
                 assert tagbits == TAGVIRTUAL
-                value = values[box]
+                value = optimizer.getvalue(box)
                 value.get_args_for_fail(self)
 
         for _, box, fieldbox, _ in pending_setfields:
             self.register_box(box)
             self.register_box(fieldbox)
-            value = values[fieldbox]
+            value = optimizer.getvalue(fieldbox)
             value.get_args_for_fail(self)
 
-        self._number_virtuals(liveboxes, values, v)
+        self._number_virtuals(liveboxes, optimizer, v)
         self._add_pending_fields(pending_setfields)
 
         storage.rd_consts = self.memo.consts
         dump_storage(storage, liveboxes)
         return liveboxes[:]
 
-    def _number_virtuals(self, liveboxes, values, num_env_virtuals):
+    def _number_virtuals(self, liveboxes, optimizer, num_env_virtuals):
         # !! 'liveboxes' is a list that is extend()ed in-place !!
         memo = self.memo
         new_liveboxes = [None] * memo.num_cached_boxes()
@@ -397,7 +396,7 @@
             memo.nvholes += length - len(vfieldboxes)
             for virtualbox, fieldboxes in vfieldboxes.iteritems():
                 num, _ = untag(self.liveboxes[virtualbox])
-                value = values[virtualbox]
+                value = optimizer.getvalue(virtualbox)
                 fieldnums = [self._gettagged(box)
                              for box in fieldboxes]
                 vinfo = value.make_virtual_info(self, fieldnums)
diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py
--- a/pypy/jit/metainterp/test/test_ajit.py
+++ b/pypy/jit/metainterp/test/test_ajit.py
@@ -2943,11 +2943,18 @@
         self.check_resops(arraylen_gc=3)
 
     def test_ulonglong_mod(self):
-        myjitdriver = JitDriver(greens = [], reds = ['n', 'sa', 'i'])
+        myjitdriver = JitDriver(greens = [], reds = ['n', 'a'])
+        class A:
+            pass
         def f(n):
             sa = i = rffi.cast(rffi.ULONGLONG, 1)
+            a = A()
             while i < rffi.cast(rffi.ULONGLONG, n):
-                myjitdriver.jit_merge_point(sa=sa, n=n, i=i)
+                a.sa = sa
+                a.i = i
+                myjitdriver.jit_merge_point(n=n, a=a)
+                sa = a.sa
+                i = a.i
                 sa += sa % i
                 i += 1
         res = self.meta_interp(f, [32])
diff --git a/pypy/jit/metainterp/test/test_resume.py b/pypy/jit/metainterp/test/test_resume.py
--- a/pypy/jit/metainterp/test/test_resume.py
+++ b/pypy/jit/metainterp/test/test_resume.py
@@ -18,6 +18,19 @@
     rd_virtuals = None
     rd_pendingfields = None
 
+
+class FakeOptimizer(object):
+    def __init__(self, values):
+        self.values = values
+        
+    def getvalue(self, box):
+        try:
+            value = self.values[box]
+        except KeyError:
+            value = self.values[box] = OptValue(box)
+        return value
+        
+
 def test_tag():
     assert tag(3, 1) == rffi.r_short(3<<2|1)
     assert tag(-3, 2) == rffi.r_short(-3<<2|2)
@@ -500,7 +513,7 @@
     capture_resumedata(fs, None, [], storage)
     memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())
     modifier = ResumeDataVirtualAdder(storage, memo)
-    liveboxes = modifier.finish({})
+    liveboxes = modifier.finish(FakeOptimizer({}))
     metainterp = MyMetaInterp()
 
     b1t, b2t, b3t = [BoxInt(), BoxPtr(), BoxInt()]
@@ -524,7 +537,7 @@
     capture_resumedata(fs, [b4], [], storage)
     memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())
     modifier = ResumeDataVirtualAdder(storage, memo)
-    liveboxes = modifier.finish({})
+    liveboxes = modifier.finish(FakeOptimizer({}))
     metainterp = MyMetaInterp()
 
     b1t, b2t, b3t, b4t = [BoxInt(), BoxPtr(), BoxInt(), BoxPtr()]
@@ -553,10 +566,10 @@
     
     memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())
     modifier = ResumeDataVirtualAdder(storage, memo)
-    liveboxes = modifier.finish({})
+    liveboxes = modifier.finish(FakeOptimizer({}))
 
     modifier = ResumeDataVirtualAdder(storage2, memo)
-    liveboxes2 = modifier.finish({})
+    liveboxes2 = modifier.finish(FakeOptimizer({}))
 
     metainterp = MyMetaInterp()
 
@@ -617,7 +630,7 @@
     memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())
     values = {b2: virtual_value(b2, b5, c4)}
     modifier = ResumeDataVirtualAdder(storage, memo)
-    liveboxes = modifier.finish(values)
+    liveboxes = modifier.finish(FakeOptimizer(values))
     assert len(storage.rd_virtuals) == 1
     assert storage.rd_virtuals[0].fieldnums == [tag(-1, TAGBOX),
                                                 tag(0, TAGCONST)]
@@ -628,7 +641,7 @@
     values = {b2: virtual_value(b2, b4, v6), b6: v6}
     memo.clear_box_virtual_numbers()
     modifier = ResumeDataVirtualAdder(storage2, memo)
-    liveboxes2 = modifier.finish(values)
+    liveboxes2 = modifier.finish(FakeOptimizer(values))
     assert len(storage2.rd_virtuals) == 2    
     assert storage2.rd_virtuals[0].fieldnums == [tag(len(liveboxes2)-1, TAGBOX),
                                                  tag(-1, TAGVIRTUAL)]
@@ -674,7 +687,7 @@
     memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())
     values = {b2: virtual_value(b2, b5, c4)}
     modifier = ResumeDataVirtualAdder(storage, memo)
-    liveboxes = modifier.finish(values)
+    liveboxes = modifier.finish(FakeOptimizer(values))
     assert len(storage.rd_virtuals) == 1
     assert storage.rd_virtuals[0].fieldnums == [tag(-1, TAGBOX),
                                                 tag(0, TAGCONST)]
@@ -684,7 +697,7 @@
     capture_resumedata(fs, None, [], storage2)
     values[b4] = virtual_value(b4, b6, c4)
     modifier = ResumeDataVirtualAdder(storage2, memo)
-    liveboxes = modifier.finish(values)
+    liveboxes = modifier.finish(FakeOptimizer(values))
     assert len(storage2.rd_virtuals) == 2
     assert storage2.rd_virtuals[1].fieldnums == storage.rd_virtuals[0].fieldnums
     assert storage2.rd_virtuals[1] is storage.rd_virtuals[0]
@@ -703,7 +716,7 @@
     v1.setfield(LLtypeMixin.nextdescr, v2)
     values = {b1: v1, b2: v2}
     modifier = ResumeDataVirtualAdder(storage, memo)
-    liveboxes = modifier.finish(values)
+    liveboxes = modifier.finish(FakeOptimizer(values))
     assert liveboxes == [b3]
     assert len(storage.rd_virtuals) == 2
     assert storage.rd_virtuals[0].fieldnums == [tag(-1, TAGBOX),
@@ -776,7 +789,7 @@
 
     memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())
 
-    numb, liveboxes, v = memo.number({}, snap1)
+    numb, liveboxes, v = memo.number(FakeOptimizer({}), snap1)
     assert v == 0
 
     assert liveboxes == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX),
@@ -788,7 +801,7 @@
                                     tag(0, TAGBOX), tag(2, TAGINT)]
     assert not numb.prev.prev
 
-    numb2, liveboxes2, v = memo.number({}, snap2)
+    numb2, liveboxes2, v = memo.number(FakeOptimizer({}), snap2)
     assert v == 0
     
     assert liveboxes2 == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX),
@@ -813,7 +826,8 @@
             return self.virt
 
     # renamed
-    numb3, liveboxes3, v = memo.number({b3: FakeValue(False, c4)}, snap3)
+    numb3, liveboxes3, v = memo.number(FakeOptimizer({b3: FakeValue(False, c4)}),
+                                       snap3)
     assert v == 0
     
     assert liveboxes3 == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX)}
@@ -825,7 +839,8 @@
     env4 = [c3, b4, b1, c3]
     snap4 = Snapshot(snap, env4)    
 
-    numb4, liveboxes4, v = memo.number({b4: FakeValue(True, b4)}, snap4)
+    numb4, liveboxes4, v = memo.number(FakeOptimizer({b4: FakeValue(True, b4)}),
+                                       snap4)
     assert v == 1
     
     assert liveboxes4 == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX),
@@ -837,8 +852,9 @@
     env5 = [b1, b4, b5]
     snap5 = Snapshot(snap4, env5)    
 
-    numb5, liveboxes5, v = memo.number({b4: FakeValue(True, b4),
-                                        b5: FakeValue(True, b5)}, snap5)
+    numb5, liveboxes5, v = memo.number(FakeOptimizer({b4: FakeValue(True, b4),
+                                                      b5: FakeValue(True, b5)}),
+                                       snap5)
     assert v == 2
     
     assert liveboxes5 == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX),
@@ -940,7 +956,7 @@
     storage = make_storage(b1s, b2s, b3s)
     memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())    
     modifier = ResumeDataVirtualAdder(storage, memo)
-    liveboxes = modifier.finish({})
+    liveboxes = modifier.finish(FakeOptimizer({}))
     assert storage.rd_snapshot is None
     cpu = MyCPU([])
     reader = ResumeDataDirectReader(MyMetaInterp(cpu), storage)
@@ -954,14 +970,14 @@
     storage = make_storage(b1s, b2s, b3s)
     memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())
     modifier = ResumeDataVirtualAdder(storage, memo)
-    modifier.finish({})
+    modifier.finish(FakeOptimizer({}))
     assert len(memo.consts) == 2
     assert storage.rd_consts is memo.consts
 
     b1s, b2s, b3s = [ConstInt(sys.maxint), ConstInt(2**17), ConstInt(-65)]
     storage2 = make_storage(b1s, b2s, b3s)
     modifier2 = ResumeDataVirtualAdder(storage2, memo)
-    modifier2.finish({})
+    modifier2.finish(FakeOptimizer({}))
     assert len(memo.consts) == 3    
     assert storage2.rd_consts is memo.consts
 
@@ -1022,7 +1038,7 @@
 
     val = FakeValue()
     values = {b1s: val, b2s: val}  
-    liveboxes = modifier.finish(values)
+    liveboxes = modifier.finish(FakeOptimizer(values))
     assert storage.rd_snapshot is None
     b1t, b3t = [BoxInt(11), BoxInt(33)]
     newboxes = _resume_remap(liveboxes, [b1_2, b3s], b1t, b3t)
@@ -1043,7 +1059,7 @@
     storage = make_storage(b1s, b2s, b3s)
     memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())        
     modifier = ResumeDataVirtualAdder(storage, memo)
-    liveboxes = modifier.finish({})
+    liveboxes = modifier.finish(FakeOptimizer({}))
     b2t, b3t = [BoxPtr(demo55o), BoxInt(33)]
     newboxes = _resume_remap(liveboxes, [b2s, b3s], b2t, b3t)
     metainterp = MyMetaInterp()
@@ -1086,7 +1102,7 @@
     values = {b2s: v2, b4s: v4}
 
     liveboxes = []
-    modifier._number_virtuals(liveboxes, values, 0)
+    modifier._number_virtuals(liveboxes, FakeOptimizer(values), 0)
     storage.rd_consts = memo.consts[:]
     storage.rd_numb = None
     # resume
@@ -1156,7 +1172,7 @@
     modifier.register_virtual_fields(b2s, [b4s, c1s])
     liveboxes = []
     values = {b2s: v2}
-    modifier._number_virtuals(liveboxes, values, 0)
+    modifier._number_virtuals(liveboxes, FakeOptimizer(values), 0)
     dump_storage(storage, liveboxes)
     storage.rd_consts = memo.consts[:]
     storage.rd_numb = None
@@ -1203,7 +1219,7 @@
     v2.setfield(LLtypeMixin.bdescr, OptValue(b4s))
     modifier.register_virtual_fields(b2s, [c1s, b4s])
     liveboxes = []
-    modifier._number_virtuals(liveboxes, {b2s: v2}, 0)
+    modifier._number_virtuals(liveboxes, FakeOptimizer({b2s: v2}), 0)
     dump_storage(storage, liveboxes)
     storage.rd_consts = memo.consts[:]
     storage.rd_numb = None
@@ -1249,7 +1265,7 @@
 
     values = {b4s: v4, b2s: v2}
     liveboxes = []
-    modifier._number_virtuals(liveboxes, values, 0)
+    modifier._number_virtuals(liveboxes, FakeOptimizer(values), 0)
     assert liveboxes == [b2s, b4s] or liveboxes == [b4s, b2s]
     modifier._add_pending_fields([(LLtypeMixin.nextdescr, b2s, b4s, -1)])
     storage.rd_consts = memo.consts[:]
diff --git a/pypy/jit/metainterp/warmspot.py b/pypy/jit/metainterp/warmspot.py
--- a/pypy/jit/metainterp/warmspot.py
+++ b/pypy/jit/metainterp/warmspot.py
@@ -453,7 +453,7 @@
                     if sys.stdout == sys.__stdout__:
                         import pdb; pdb.post_mortem(tb)
                     raise e.__class__, e, tb
-                fatalerror('~~~ Crash in JIT! %s' % (e,), traceback=True)
+                fatalerror('~~~ Crash in JIT! %s' % (e,))
         crash_in_jit._dont_inline_ = True
 
         if self.translator.rtyper.type_system.name == 'lltypesystem':
diff --git a/pypy/jit/tl/tinyframe/tinyframe.py b/pypy/jit/tl/tinyframe/tinyframe.py
--- a/pypy/jit/tl/tinyframe/tinyframe.py
+++ b/pypy/jit/tl/tinyframe/tinyframe.py
@@ -210,7 +210,7 @@
     def repr(self):
         return "<function %s(%s)>" % (self.outer.repr(), self.inner.repr())
 
-driver = JitDriver(greens = ['code', 'i'], reds = ['self'],
+driver = JitDriver(greens = ['i', 'code'], reds = ['self'],
                    virtualizables = ['self'])
 
 class Frame(object):
diff --git a/pypy/module/_demo/test/test_sieve.py b/pypy/module/_demo/test/test_sieve.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/_demo/test/test_sieve.py
@@ -0,0 +1,12 @@
+from pypy.conftest import gettestobjspace
+
+
+class AppTestSieve:
+    def setup_class(cls):
+        cls.space = gettestobjspace(usemodules=('_demo',))
+
+    def test_sieve(self):
+        import _demo
+        lst = _demo.sieve(100)
+        assert lst == [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41,
+                       43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
diff --git a/pypy/module/_io/__init__.py b/pypy/module/_io/__init__.py
--- a/pypy/module/_io/__init__.py
+++ b/pypy/module/_io/__init__.py
@@ -28,6 +28,7 @@
         }
 
     def init(self, space):
+        MixedModule.init(self, space)
         w_UnsupportedOperation = space.call_function(
             space.w_type,
             space.wrap('UnsupportedOperation'),
@@ -35,3 +36,9 @@
             space.newdict())
         space.setattr(self, space.wrap('UnsupportedOperation'),
                       w_UnsupportedOperation)
+
+    def shutdown(self, space):
+        # at shutdown, flush all open streams.  Ignore I/O errors.
+        from pypy.module._io.interp_iobase import get_autoflushher
+        get_autoflushher(space).flush_all(space)
+
diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py
--- a/pypy/module/_io/interp_iobase.py
+++ b/pypy/module/_io/interp_iobase.py
@@ -5,6 +5,8 @@
 from pypy.interpreter.gateway import interp2app
 from pypy.interpreter.error import OperationError, operationerrfmt
 from pypy.rlib.rstring import StringBuilder
+from pypy.rlib import rweakref
+
 
 DEFAULT_BUFFER_SIZE = 8192
 
@@ -43,6 +45,8 @@
         self.space = space
         self.w_dict = space.newdict()
         self.__IOBase_closed = False
+        self.streamholder = None # needed by AutoFlusher
+        get_autoflushher(space).add(self)
 
     def getdict(self, space):
         return self.w_dict
@@ -98,6 +102,7 @@
             space.call_method(self, "flush")
         finally:
             self.__IOBase_closed = True
+            get_autoflushher(space).remove(self)
 
     def flush_w(self, space):
         if self._CLOSED():
@@ -303,3 +308,57 @@
     read = interp2app(W_RawIOBase.read_w),
     readall = interp2app(W_RawIOBase.readall_w),
 )
+
+
+# ------------------------------------------------------------
+# functions to make sure that all streams are flushed on exit
+# ------------------------------------------------------------
+
+class StreamHolder(object):
+
+    def __init__(self, w_iobase):
+        self.w_iobase_ref = rweakref.ref(w_iobase)
+        w_iobase.autoflusher = self
+
+    def autoflush(self, space):
+        w_iobase = self.w_iobase_ref()
+        if w_iobase is not None:
+            try:
+                space.call_method(w_iobase, 'flush')
+            except OperationError, e:
+                # if it's an IOError, ignore it
+                if not e.match(space, space.w_IOError):
+                    raise
+        
+
+class AutoFlusher(object):
+    
+    def __init__(self, space):
+        self.streams = {}
+
+    def add(self, w_iobase):
+        assert w_iobase.streamholder is None
+        holder = StreamHolder(w_iobase)
+        w_iobase.streamholder = holder
+        self.streams[holder] = None
+
+    def remove(self, w_iobase):
+        holder = w_iobase.streamholder
+        if holder is not None:
+            del self.streams[holder]
+
+    def flush_all(self, space):
+        while self.streams:
+            for streamholder in self.streams.keys():
+                try:
+                    del self.streams[streamholder]
+                except KeyError:
+                    pass    # key was removed in the meantime
+                else:
+                    streamholder.autoflush(space)
+
+
+def get_autoflushher(space):
+    return space.fromcache(AutoFlusher)
+
+
diff --git a/pypy/module/_io/test/test_fileio.py b/pypy/module/_io/test/test_fileio.py
--- a/pypy/module/_io/test/test_fileio.py
+++ b/pypy/module/_io/test/test_fileio.py
@@ -160,3 +160,37 @@
         f.close()
         assert repr(f) == "<_io.FileIO [closed]>"
 
+def test_flush_at_exit():
+    from pypy import conftest
+    from pypy.tool.option import make_config, make_objspace
+    from pypy.tool.udir import udir
+
+    tmpfile = udir.join('test_flush_at_exit')
+    config = make_config(conftest.option)
+    space = make_objspace(config)
+    space.appexec([space.wrap(str(tmpfile))], """(tmpfile):
+        import io
+        f = io.open(tmpfile, 'w', encoding='ascii')
+        f.write('42')
+        # no flush() and no close()
+        import sys; sys._keepalivesomewhereobscure = f
+    """)
+    space.finish()
+    assert tmpfile.read() == '42'
+
+def test_flush_at_exit_IOError():
+    from pypy import conftest
+    from pypy.tool.option import make_config, make_objspace
+
+    config = make_config(conftest.option)
+    space = make_objspace(config)
+    space.appexec([], """():
+        import io
+        class MyStream(io.IOBase):
+            def flush(self):
+                raise IOError
+
+        s = MyStream()
+        import sys; sys._keepalivesomewhereobscure = s
+    """)
+    space.finish() # the IOError has been ignored
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -23,6 +23,7 @@
 from pypy.interpreter.function import StaticMethod
 from pypy.objspace.std.sliceobject import W_SliceObject
 from pypy.module.__builtin__.descriptor import W_Property
+from pypy.module.__builtin__.interp_classobj import W_ClassObject
 from pypy.module.__builtin__.interp_memoryview import W_MemoryView
 from pypy.rlib.entrypoint import entrypoint
 from pypy.rlib.unroll import unrolling_iterable
@@ -383,6 +384,8 @@
         "Dict": "space.w_dict",
         "Tuple": "space.w_tuple",
         "List": "space.w_list",
+        "Set": "space.w_set",
+        "FrozenSet": "space.w_frozenset",
         "Int": "space.w_int",
         "Bool": "space.w_bool",
         "Float": "space.w_float",
@@ -397,13 +400,14 @@
         'Module': 'space.gettypeobject(Module.typedef)',
         'Property': 'space.gettypeobject(W_Property.typedef)',
         'Slice': 'space.gettypeobject(W_SliceObject.typedef)',
+        'Class': 'space.gettypeobject(W_ClassObject.typedef)',
         'StaticMethod': 'space.gettypeobject(StaticMethod.typedef)',
         'CFunction': 'space.gettypeobject(cpyext.methodobject.W_PyCFunctionObject.typedef)',
         'WrapperDescr': 'space.gettypeobject(cpyext.methodobject.W_PyCMethodObject.typedef)'
         }.items():
         GLOBALS['Py%s_Type#' % (cpyname, )] = ('PyTypeObject*', pypyexpr)
 
-    for cpyname in 'Method List Int Long Dict Tuple Class'.split():
+    for cpyname in 'Method List Long Dict Tuple Class'.split():
         FORWARD_DECLS.append('typedef struct { PyObject_HEAD } '
                              'Py%sObject' % (cpyname, ))
 build_exported_objects()
@@ -432,16 +436,16 @@
         ('buf', rffi.VOIDP),
         ('obj', PyObject),
         ('len', Py_ssize_t),
-        # ('itemsize', Py_ssize_t),
+        ('itemsize', Py_ssize_t),
 
-        # ('readonly', lltype.Signed),
-        # ('ndim', lltype.Signed),
-        # ('format', rffi.CCHARP),
-        # ('shape', Py_ssize_tP),
-        # ('strides', Py_ssize_tP),
-        # ('suboffets', Py_ssize_tP),
-        # ('smalltable', rffi.CFixedArray(Py_ssize_t, 2)),
-        # ('internal', rffi.VOIDP)
+        ('readonly', lltype.Signed),
+        ('ndim', lltype.Signed),
+        ('format', rffi.CCHARP),
+        ('shape', Py_ssize_tP),
+        ('strides', Py_ssize_tP),
+        ('suboffsets', Py_ssize_tP),
+        #('smalltable', rffi.CFixedArray(Py_ssize_t, 2)),
+        ('internal', rffi.VOIDP)
         ))
 
 @specialize.memo()
diff --git a/pypy/module/cpyext/dictobject.py b/pypy/module/cpyext/dictobject.py
--- a/pypy/module/cpyext/dictobject.py
+++ b/pypy/module/cpyext/dictobject.py
@@ -6,6 +6,7 @@
 from pypy.module.cpyext.pyobject import RefcountState
 from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
 from pypy.interpreter.error import OperationError
+from pypy.rlib.objectmodel import specialize
 
 @cpython_api([], PyObject)
 def PyDict_New(space):
@@ -183,11 +184,34 @@
         w_item = space.call_method(w_iter, "next")
         w_key, w_value = space.fixedview(w_item, 2)
         state = space.fromcache(RefcountState)
-        pkey[0]   = state.make_borrowed(w_dict, w_key)
-        pvalue[0] = state.make_borrowed(w_dict, w_value)
+        if pkey:
+            pkey[0]   = state.make_borrowed(w_dict, w_key)
+        if pvalue:
+            pvalue[0] = state.make_borrowed(w_dict, w_value)
         ppos[0] += 1
     except OperationError, e:
         if not e.match(space, space.w_StopIteration):
             raise
         return 0
     return 1
+
+ at specialize.memo()
+def make_frozendict(space):
+    return space.appexec([], '''():
+    import collections
+    class FrozenDict(collections.Mapping):
+        def __init__(self, *args, **kwargs):
+            self._d = dict(*args, **kwargs)
+        def __iter__(self):
+            return iter(self._d)
+        def __len__(self):
+            return len(self._d)
+        def __getitem__(self, key):
+            return self._d[key]
+    return FrozenDict''')
+
+ at cpython_api([PyObject], PyObject)
+def PyDictProxy_New(space, w_dict):
+    w_frozendict = make_frozendict(space)
+    return space.call_function(w_frozendict, w_dict)
+
diff --git a/pypy/module/cpyext/eval.py b/pypy/module/cpyext/eval.py
--- a/pypy/module/cpyext/eval.py
+++ b/pypy/module/cpyext/eval.py
@@ -1,16 +1,24 @@
 from pypy.interpreter.error import OperationError
+from pypy.interpreter.astcompiler import consts
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.module.cpyext.api import (
     cpython_api, CANNOT_FAIL, CONST_STRING, FILEP, fread, feof, Py_ssize_tP,
     cpython_struct)
 from pypy.module.cpyext.pyobject import PyObject, borrow_from
 from pypy.module.cpyext.pyerrors import PyErr_SetFromErrno
+from pypy.module.cpyext.funcobject import PyCodeObject
 from pypy.module.__builtin__ import compiling
 
 PyCompilerFlags = cpython_struct(
-    "PyCompilerFlags", ())
+    "PyCompilerFlags", (("cf_flags", rffi.INT),))
 PyCompilerFlagsPtr = lltype.Ptr(PyCompilerFlags)
 
+PyCF_MASK = (consts.CO_FUTURE_DIVISION | 
+             consts.CO_FUTURE_ABSOLUTE_IMPORT |
+             consts.CO_FUTURE_WITH_STATEMENT |
+             consts.CO_FUTURE_PRINT_FUNCTION |
+             consts.CO_FUTURE_UNICODE_LITERALS)
+
 @cpython_api([PyObject, PyObject, PyObject], PyObject)
 def PyEval_CallObjectWithKeywords(space, w_obj, w_arg, w_kwds):
     return space.call(w_obj, w_arg, w_kwds)
@@ -48,6 +56,17 @@
         return None
     return borrow_from(None, caller.w_globals)
 
+ at cpython_api([PyCodeObject, PyObject, PyObject], PyObject)
+def PyEval_EvalCode(space, w_code, w_globals, w_locals):
+    """This is a simplified interface to PyEval_EvalCodeEx(), with just
+    the code object, and the dictionaries of global and local variables.
+    The other arguments are set to NULL."""
+    if w_globals is None:
+        w_globals = space.w_None
+    if w_locals is None:
+        w_locals = space.w_None
+    return compiling.eval(space, w_code, w_globals, w_locals)
+
 @cpython_api([PyObject, PyObject], PyObject)
 def PyObject_CallObject(space, w_obj, w_arg):
     """
@@ -74,7 +93,7 @@
 Py_file_input = 257
 Py_eval_input = 258
 
-def compile_string(space, source, filename, start):
+def compile_string(space, source, filename, start, flags=0):
     w_source = space.wrap(source)
     start = rffi.cast(lltype.Signed, start)
     if start == Py_file_input:
@@ -86,7 +105,7 @@
     else:
         raise OperationError(space.w_ValueError, space.wrap(
             "invalid mode parameter for compilation"))
-    return compiling.compile(space, w_source, filename, mode)
+    return compiling.compile(space, w_source, filename, mode, flags)
 
 def run_string(space, source, filename, start, w_globals, w_locals):
     w_code = compile_string(space, source, filename, start)
@@ -109,6 +128,24 @@
     filename = "<string>"
     return run_string(space, source, filename, start, w_globals, w_locals)
 
+ at cpython_api([rffi.CCHARP, rffi.INT_real, PyObject, PyObject,
+              PyCompilerFlagsPtr], PyObject)
+def PyRun_StringFlags(space, source, start, w_globals, w_locals, flagsptr):
+    """Execute Python source code from str in the context specified by the
+    dictionaries globals and locals with the compiler flags specified by
+    flags.  The parameter start specifies the start token that should be used to
+    parse the source code.
+
+    Returns the result of executing the code as a Python object, or NULL if an
+    exception was raised."""
+    source = rffi.charp2str(source)
+    if flagsptr:
+        flags = rffi.cast(lltype.Signed, flagsptr.c_cf_flags)
+    else:
+        flags = 0
+    w_code = compile_string(space, source, "<string>", start, flags)
+    return compiling.eval(space, w_code, w_globals, w_locals)
+
 @cpython_api([FILEP, CONST_STRING, rffi.INT_real, PyObject, PyObject], PyObject)
 def PyRun_File(space, fp, filename, start, w_globals, w_locals):
     """This is a simplified interface to PyRun_FileExFlags() below, leaving
@@ -150,7 +187,7 @@
 
 @cpython_api([rffi.CCHARP, rffi.CCHARP, rffi.INT_real, PyCompilerFlagsPtr],
              PyObject)
-def Py_CompileStringFlags(space, source, filename, start, flags):
+def Py_CompileStringFlags(space, source, filename, start, flagsptr):
     """Parse and compile the Python source code in str, returning the
     resulting code object.  The start token is given by start; this
     can be used to constrain the code which can be compiled and should
@@ -160,7 +197,30 @@
     returns NULL if the code cannot be parsed or compiled."""
     source = rffi.charp2str(source)
     filename = rffi.charp2str(filename)
-    if flags:
-        raise OperationError(space.w_NotImplementedError, space.wrap(
-                "cpyext Py_CompileStringFlags does not accept flags"))
-    return compile_string(space, source, filename, start)
+    if flagsptr:
+        flags = rffi.cast(lltype.Signed, flagsptr.c_cf_flags)
+    else:
+        flags = 0
+    return compile_string(space, source, filename, start, flags)
+
+ at cpython_api([PyCompilerFlagsPtr], rffi.INT_real, error=CANNOT_FAIL)
+def PyEval_MergeCompilerFlags(space, cf):
+    """This function changes the flags of the current evaluation
+    frame, and returns true on success, false on failure."""
+    flags = rffi.cast(lltype.Signed, cf.c_cf_flags)
+    result = flags != 0
+    current_frame = space.getexecutioncontext().gettopframe_nohidden()
+    if current_frame:
+        codeflags = current_frame.pycode.co_flags
+        compilerflags = codeflags & PyCF_MASK
+        if compilerflags:
+            result = 1
+            flags |= compilerflags
+        # No future keyword at the moment
+        # if codeflags & CO_GENERATOR_ALLOWED:
+        #     result = 1
+        #     flags |= CO_GENERATOR_ALLOWED
+    cf.c_cf_flags = rffi.cast(rffi.INT, flags)
+    return result
+
+        
diff --git a/pypy/module/cpyext/funcobject.py b/pypy/module/cpyext/funcobject.py
--- a/pypy/module/cpyext/funcobject.py
+++ b/pypy/module/cpyext/funcobject.py
@@ -1,6 +1,6 @@
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.module.cpyext.api import (
-    PyObjectFields, generic_cpy_call, CONST_STRING,
+    PyObjectFields, generic_cpy_call, CONST_STRING, CANNOT_FAIL,
     cpython_api, bootstrap_function, cpython_struct, build_type_checkers)
 from pypy.module.cpyext.pyobject import (
     PyObject, make_ref, from_ref, Py_DecRef, make_typedescr, borrow_from)
@@ -48,6 +48,7 @@
 
 PyFunction_Check, PyFunction_CheckExact = build_type_checkers("Function", Function)
 PyMethod_Check, PyMethod_CheckExact = build_type_checkers("Method", Method)
+PyCode_Check, PyCode_CheckExact = build_type_checkers("Code", PyCode)
 
 def function_attach(space, py_obj, w_obj):
     py_func = rffi.cast(PyFunctionObject, py_obj)
@@ -167,3 +168,9 @@
                              freevars=[],
                              cellvars=[]))
 
+ at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
+def PyCode_GetNumFree(space, w_co):
+    """Return the number of free variables in co."""
+    co = space.interp_w(PyCode, w_co)
+    return len(co.co_freevars)
+
diff --git a/pypy/module/cpyext/include/Python.h b/pypy/module/cpyext/include/Python.h
--- a/pypy/module/cpyext/include/Python.h
+++ b/pypy/module/cpyext/include/Python.h
@@ -113,6 +113,7 @@
 #include "compile.h"
 #include "frameobject.h"
 #include "eval.h"
+#include "pymath.h"
 #include "pymem.h"
 #include "pycobject.h"
 #include "pycapsule.h"
diff --git a/pypy/module/cpyext/include/code.h b/pypy/module/cpyext/include/code.h
--- a/pypy/module/cpyext/include/code.h
+++ b/pypy/module/cpyext/include/code.h
@@ -13,13 +13,19 @@
 
 /* Masks for co_flags above */
 /* These values are also in funcobject.py */
-#define CO_OPTIMIZED	0x0001
-#define CO_NEWLOCALS	0x0002
-#define CO_VARARGS	0x0004
-#define CO_VARKEYWORDS	0x0008
+#define CO_OPTIMIZED    0x0001
+#define CO_NEWLOCALS    0x0002
+#define CO_VARARGS      0x0004
+#define CO_VARKEYWORDS  0x0008
 #define CO_NESTED       0x0010
 #define CO_GENERATOR    0x0020
 
+#define CO_FUTURE_DIVISION         0x02000
+#define CO_FUTURE_ABSOLUTE_IMPORT  0x04000
+#define CO_FUTURE_WITH_STATEMENT   0x08000
+#define CO_FUTURE_PRINT_FUNCTION   0x10000
+#define CO_FUTURE_UNICODE_LITERALS 0x20000
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/pypy/module/cpyext/include/intobject.h b/pypy/module/cpyext/include/intobject.h
--- a/pypy/module/cpyext/include/intobject.h
+++ b/pypy/module/cpyext/include/intobject.h
@@ -7,6 +7,11 @@
 extern "C" {
 #endif
 
+typedef struct {
+    PyObject_HEAD
+    long ob_ival;
+} PyIntObject;
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/pypy/module/cpyext/include/methodobject.h b/pypy/module/cpyext/include/methodobject.h
--- a/pypy/module/cpyext/include/methodobject.h
+++ b/pypy/module/cpyext/include/methodobject.h
@@ -26,6 +26,7 @@
     PyObject_HEAD
     PyMethodDef *m_ml; /* Description of the C function to call */
     PyObject    *m_self; /* Passed as 'self' arg to the C func, can be NULL */
+    PyObject    *m_module; /* The __module__ attribute, can be anything */
 } PyCFunctionObject;
 
 /* Flag passed to newmethodobject */
diff --git a/pypy/module/cpyext/include/object.h b/pypy/module/cpyext/include/object.h
--- a/pypy/module/cpyext/include/object.h
+++ b/pypy/module/cpyext/include/object.h
@@ -131,18 +131,18 @@
 
     /* This is Py_ssize_t so it can be
        pointed to by strides in simple case.*/
-    /* Py_ssize_t itemsize; */
-    /* int readonly; */
-    /* int ndim; */
-    /* char *format; */
-    /* Py_ssize_t *shape; */
-    /* Py_ssize_t *strides; */
-    /* Py_ssize_t *suboffsets; */
+    Py_ssize_t itemsize;
+    int readonly;
+    int ndim;
+    char *format;
+    Py_ssize_t *shape;
+    Py_ssize_t *strides;
+    Py_ssize_t *suboffsets;
 
     /* static store for shape and strides of
        mono-dimensional buffers. */
     /* Py_ssize_t smalltable[2]; */
-    /* void *internal; */
+    void *internal;
 } Py_buffer;
 
 
diff --git a/pypy/module/cpyext/include/pymath.h b/pypy/module/cpyext/include/pymath.h
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/include/pymath.h
@@ -0,0 +1,20 @@
+#ifndef Py_PYMATH_H
+#define Py_PYMATH_H
+
+/**************************************************************************
+Symbols and macros to supply platform-independent interfaces to mathematical
+functions and constants
+**************************************************************************/
+
+/* HUGE_VAL is supposed to expand to a positive double infinity.  Python
+ * uses Py_HUGE_VAL instead because some platforms are broken in this
+ * respect.  We used to embed code in pyport.h to try to worm around that,
+ * but different platforms are broken in conflicting ways.  If you're on
+ * a platform where HUGE_VAL is defined incorrectly, fiddle your Python
+ * config to #define Py_HUGE_VAL to something that works on your platform.
+ */
+#ifndef Py_HUGE_VAL
+#define Py_HUGE_VAL HUGE_VAL
+#endif
+
+#endif /* Py_PYMATH_H */
diff --git a/pypy/module/cpyext/include/pystate.h b/pypy/module/cpyext/include/pystate.h
--- a/pypy/module/cpyext/include/pystate.h
+++ b/pypy/module/cpyext/include/pystate.h
@@ -10,6 +10,7 @@
 
 typedef struct _ts {
     PyInterpreterState *interp;
+    PyObject *dict;  /* Stores per-thread state */
 } PyThreadState;
 
 #define Py_BEGIN_ALLOW_THREADS { \
@@ -24,4 +25,6 @@
     enum {PyGILState_LOCKED, PyGILState_UNLOCKED}
         PyGILState_STATE;
 
+#define PyThreadState_GET() PyThreadState_Get()
+
 #endif /* !Py_PYSTATE_H */
diff --git a/pypy/module/cpyext/include/pythonrun.h b/pypy/module/cpyext/include/pythonrun.h
--- a/pypy/module/cpyext/include/pythonrun.h
+++ b/pypy/module/cpyext/include/pythonrun.h
@@ -19,6 +19,14 @@
     int cf_flags;  /* bitmask of CO_xxx flags relevant to future */
 } PyCompilerFlags;
 
+#define PyCF_MASK (CO_FUTURE_DIVISION | CO_FUTURE_ABSOLUTE_IMPORT | \
+                   CO_FUTURE_WITH_STATEMENT | CO_FUTURE_PRINT_FUNCTION | \
+                   CO_FUTURE_UNICODE_LITERALS)
+#define PyCF_MASK_OBSOLETE (CO_NESTED)
+#define PyCF_SOURCE_IS_UTF8  0x0100
+#define PyCF_DONT_IMPLY_DEDENT 0x0200
+#define PyCF_ONLY_AST 0x0400
+
 #define Py_CompileString(str, filename, start) Py_CompileStringFlags(str, filename, start, NULL)
 
 #ifdef __cplusplus
diff --git a/pypy/module/cpyext/include/pythread.h b/pypy/module/cpyext/include/pythread.h
--- a/pypy/module/cpyext/include/pythread.h
+++ b/pypy/module/cpyext/include/pythread.h
@@ -1,6 +1,8 @@
 #ifndef Py_PYTHREAD_H
 #define Py_PYTHREAD_H
 
+#define WITH_THREAD
+
 typedef void *PyThread_type_lock;
 #define WAIT_LOCK	1
 #define NOWAIT_LOCK	0
diff --git a/pypy/module/cpyext/include/structmember.h b/pypy/module/cpyext/include/structmember.h
--- a/pypy/module/cpyext/include/structmember.h
+++ b/pypy/module/cpyext/include/structmember.h
@@ -20,7 +20,7 @@
 } PyMemberDef;
 
 
-/* Types */
+/* Types. These constants are also in structmemberdefs.py. */
 #define T_SHORT		0
 #define T_INT		1
 #define T_LONG		2
@@ -42,9 +42,12 @@
 #define T_LONGLONG	17
 #define T_ULONGLONG	 18
 
-/* Flags */
+/* Flags. These constants are also in structmemberdefs.py. */
 #define READONLY      1
 #define RO            READONLY                /* Shorthand */
+#define READ_RESTRICTED 2
+#define PY_WRITE_RESTRICTED 4
+#define RESTRICTED    (READ_RESTRICTED | PY_WRITE_RESTRICTED)
 
 
 #ifdef __cplusplus
diff --git a/pypy/module/cpyext/intobject.py b/pypy/module/cpyext/intobject.py
--- a/pypy/module/cpyext/intobject.py
+++ b/pypy/module/cpyext/intobject.py
@@ -2,11 +2,37 @@
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.interpreter.error import OperationError
 from pypy.module.cpyext.api import (
-    cpython_api, build_type_checkers, PyObject,
-    CONST_STRING, CANNOT_FAIL, Py_ssize_t)
+    cpython_api, cpython_struct, build_type_checkers, bootstrap_function,
+    PyObject, PyObjectFields, CONST_STRING, CANNOT_FAIL, Py_ssize_t)
+from pypy.module.cpyext.pyobject import (
+    make_typedescr, track_reference, RefcountState, from_ref)
 from pypy.rlib.rarithmetic import r_uint, intmask, LONG_TEST
+from pypy.objspace.std.intobject import W_IntObject
 import sys
 
+PyIntObjectStruct = lltype.ForwardReference()
+PyIntObject = lltype.Ptr(PyIntObjectStruct)
+PyIntObjectFields = PyObjectFields + \
+    (("ob_ival", rffi.LONG),)
+cpython_struct("PyIntObject", PyIntObjectFields, PyIntObjectStruct)
+
+ at bootstrap_function
+def init_intobject(space):
+    "Type description of PyIntObject"
+    make_typedescr(space.w_int.instancetypedef,
+                   basestruct=PyIntObject.TO,
+                   realize=int_realize)
+
+def int_realize(space, obj):
+    intval = rffi.cast(lltype.Signed, rffi.cast(PyIntObject, obj).c_ob_ival)
+    w_type = from_ref(space, rffi.cast(PyObject, obj.c_ob_type))
+    w_obj = space.allocate_instance(W_IntObject, w_type)
+    w_obj.__init__(intval)
+    track_reference(space, obj, w_obj)
+    state = space.fromcache(RefcountState)
+    state.set_lifeline(w_obj, obj)
+    return w_obj
+
 PyInt_Check, PyInt_CheckExact = build_type_checkers("Int")
 
 @cpython_api([], lltype.Signed, error=CANNOT_FAIL)
diff --git a/pypy/module/cpyext/methodobject.py b/pypy/module/cpyext/methodobject.py
--- a/pypy/module/cpyext/methodobject.py
+++ b/pypy/module/cpyext/methodobject.py
@@ -32,6 +32,7 @@
     PyObjectFields + (
      ('m_ml', lltype.Ptr(PyMethodDef)),
      ('m_self', PyObject),
+     ('m_module', PyObject),
      ))
 PyCFunctionObject = lltype.Ptr(PyCFunctionObjectStruct)
 
@@ -47,11 +48,13 @@
     assert isinstance(w_obj, W_PyCFunctionObject)
     py_func.c_m_ml = w_obj.ml
     py_func.c_m_self = make_ref(space, w_obj.w_self)
+    py_func.c_m_module = make_ref(space, w_obj.w_module)
 
 @cpython_api([PyObject], lltype.Void, external=False)
 def cfunction_dealloc(space, py_obj):
     py_func = rffi.cast(PyCFunctionObject, py_obj)
     Py_DecRef(space, py_func.c_m_self)
+    Py_DecRef(space, py_func.c_m_module)
     from pypy.module.cpyext.object import PyObject_dealloc
     PyObject_dealloc(space, py_obj)
 
diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py
--- a/pypy/module/cpyext/object.py
+++ b/pypy/module/cpyext/object.py
@@ -193,7 +193,7 @@
     if not obj:
         PyErr_NoMemory(space)
     obj.c_ob_type = type
-    _Py_NewReference(space, obj)
+    obj.c_ob_refcnt = 1
     return obj
 
 @cpython_api([PyVarObject, PyTypeObjectPtr, Py_ssize_t], PyObject)
@@ -381,6 +381,15 @@
     This is the equivalent of the Python expression hash(o)."""
     return space.int_w(space.hash(w_obj))
 
+ at cpython_api([PyObject], PyObject)
+def PyObject_Dir(space, w_o):
+    """This is equivalent to the Python expression dir(o), returning a (possibly
+    empty) list of strings appropriate for the object argument, or NULL if there
+    was an error.  If the argument is NULL, this is like the Python dir(),
+    returning the names of the current locals; in this case, if no execution frame
+    is active then NULL is returned but PyErr_Occurred() will return false."""
+    return space.call_function(space.builtin.get('dir'), w_o)
+
 @cpython_api([PyObject, rffi.CCHARPP, Py_ssize_tP], rffi.INT_real, error=-1)
 def PyObject_AsCharBuffer(space, obj, bufferp, sizep):
     """Returns a pointer to a read-only memory location usable as
@@ -430,6 +439,8 @@
     return 0
 
 
+PyBUF_WRITABLE = 0x0001  # Copied from object.h
+
 @cpython_api([lltype.Ptr(Py_buffer), PyObject, rffi.VOIDP, Py_ssize_t,
               lltype.Signed, lltype.Signed], rffi.INT, error=CANNOT_FAIL)
 def PyBuffer_FillInfo(space, view, obj, buf, length, readonly, flags):
@@ -445,6 +456,18 @@
     view.c_len = length
     view.c_obj = obj
     Py_IncRef(space, obj)
+    view.c_itemsize = 1
+    if flags & PyBUF_WRITABLE:
+        rffi.setintfield(view, 'c_readonly', 0)
+    else:
+        rffi.setintfield(view, 'c_readonly', 1)
+    rffi.setintfield(view, 'c_ndim', 0)
+    view.c_format = lltype.nullptr(rffi.CCHARP.TO)
+    view.c_shape = lltype.nullptr(Py_ssize_tP.TO)
+    view.c_strides = lltype.nullptr(Py_ssize_tP.TO)
+    view.c_suboffsets = lltype.nullptr(Py_ssize_tP.TO)
+    view.c_internal = lltype.nullptr(rffi.VOIDP.TO)
+
     return 0
 
 
diff --git a/pypy/module/cpyext/pyfile.py b/pypy/module/cpyext/pyfile.py
--- a/pypy/module/cpyext/pyfile.py
+++ b/pypy/module/cpyext/pyfile.py
@@ -1,7 +1,8 @@
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.module.cpyext.api import (
-    cpython_api, CONST_STRING, FILEP, build_type_checkers)
+    cpython_api, CANNOT_FAIL, CONST_STRING, FILEP, build_type_checkers)
 from pypy.module.cpyext.pyobject import PyObject, borrow_from
+from pypy.module.cpyext.object import Py_PRINT_RAW
 from pypy.interpreter.error import OperationError
 from pypy.module._file.interp_file import W_File
 
@@ -61,11 +62,49 @@
 def PyFile_WriteString(space, s, w_p):
     """Write string s to file object p.  Return 0 on success or -1 on
     failure; the appropriate exception will be set."""
-    w_s = space.wrap(rffi.charp2str(s))
-    space.call_method(w_p, "write", w_s)
+    w_str = space.wrap(rffi.charp2str(s))
+    space.call_method(w_p, "write", w_str)
+    return 0
+
+ at cpython_api([PyObject, PyObject, rffi.INT_real], rffi.INT_real, error=-1)
+def PyFile_WriteObject(space, w_obj, w_p, flags):
+    """
+    Write object obj to file object p.  The only supported flag for flags is
+    Py_PRINT_RAW; if given, the str() of the object is written
+    instead of the repr().  Return 0 on success or -1 on failure; the
+    appropriate exception will be set."""
+    if rffi.cast(lltype.Signed, flags) & Py_PRINT_RAW:
+        w_str = space.str(w_obj)
+    else:
+        w_str = space.repr(w_obj)
+    space.call_method(w_p, "write", w_str)
     return 0
 
 @cpython_api([PyObject], PyObject)
 def PyFile_Name(space, w_p):
     """Return the name of the file specified by p as a string object."""
-    return borrow_from(w_p, space.getattr(w_p, space.wrap("name")))
\ No newline at end of file
+    return borrow_from(w_p, space.getattr(w_p, space.wrap("name")))
+
+ at cpython_api([PyObject, rffi.INT_real], rffi.INT_real, error=CANNOT_FAIL)
+def PyFile_SoftSpace(space, w_p, newflag):
+    """
+    This function exists for internal use by the interpreter.  Set the
+    softspace attribute of p to newflag and return the previous value.
+    p does not have to be a file object for this function to work
+    properly; any object is supported (thought its only interesting if
+    the softspace attribute can be set).  This function clears any
+    errors, and will return 0 as the previous value if the attribute
+    either does not exist or if there were errors in retrieving it.
+    There is no way to detect errors from this function, but doing so
+    should not be needed."""
+    try:
+        if rffi.cast(lltype.Signed, newflag):
+            w_newflag = space.w_True
+        else:
+            w_newflag = space.w_False
+        oldflag = space.int_w(space.getattr(w_p, space.wrap("softspace")))
+        space.setattr(w_p, space.wrap("softspace"), w_newflag)
+        return oldflag
+    except OperationError, e:
+        return 0
+
diff --git a/pypy/module/cpyext/pyobject.py b/pypy/module/cpyext/pyobject.py
--- a/pypy/module/cpyext/pyobject.py
+++ b/pypy/module/cpyext/pyobject.py
@@ -17,6 +17,7 @@
 
 class BaseCpyTypedescr(object):
     basestruct = PyObject.TO
+    W_BaseObject = W_ObjectObject
 
     def get_dealloc(self, space):
         from pypy.module.cpyext.typeobject import subtype_dealloc
@@ -51,10 +52,14 @@
     def attach(self, space, pyobj, w_obj):
         pass
 
-    def realize(self, space, ref):
-        # For most types, a reference cannot exist without
-        # a real interpreter object
-        raise InvalidPointerException(str(ref))
+    def realize(self, space, obj):
+        w_type = from_ref(space, rffi.cast(PyObject, obj.c_ob_type))
+        w_obj = space.allocate_instance(self.W_BaseObject, w_type)
+        track_reference(space, obj, w_obj)
+        if w_type is not space.gettypefor(self.W_BaseObject):
+            state = space.fromcache(RefcountState)
+            state.set_lifeline(w_obj, obj)
+        return w_obj
 
 typedescr_cache = {}
 
@@ -369,13 +374,7 @@
     obj.c_ob_refcnt = 1
     w_type = from_ref(space, rffi.cast(PyObject, obj.c_ob_type))
     assert isinstance(w_type, W_TypeObject)
-    if w_type.is_cpytype():
-        w_obj = space.allocate_instance(W_ObjectObject, w_type)
-        track_reference(space, obj, w_obj)
-        state = space.fromcache(RefcountState)
-        state.set_lifeline(w_obj, obj)
-    else:
-        assert False, "Please add more cases in _Py_NewReference()"
+    get_typedescr(w_type.instancetypedef).realize(space, obj)
 
 def _Py_Dealloc(space, obj):
     from pypy.module.cpyext.api import generic_cpy_call_dont_decref
diff --git a/pypy/module/cpyext/pystate.py b/pypy/module/cpyext/pystate.py
--- a/pypy/module/cpyext/pystate.py
+++ b/pypy/module/cpyext/pystate.py
@@ -1,12 +1,19 @@
 from pypy.module.cpyext.api import (
     cpython_api, generic_cpy_call, CANNOT_FAIL, CConfig, cpython_struct)
+from pypy.module.cpyext.pyobject import PyObject, Py_DecRef, make_ref
 from pypy.rpython.lltypesystem import rffi, lltype
 
 PyInterpreterStateStruct = lltype.ForwardReference()
 PyInterpreterState = lltype.Ptr(PyInterpreterStateStruct)
 cpython_struct(
-    "PyInterpreterState", [('next', PyInterpreterState)], PyInterpreterStateStruct)
-PyThreadState = lltype.Ptr(cpython_struct("PyThreadState", [('interp', PyInterpreterState)]))
+    "PyInterpreterState",
+    [('next', PyInterpreterState)],
+    PyInterpreterStateStruct)
+PyThreadState = lltype.Ptr(cpython_struct(
+    "PyThreadState", 
+    [('interp', PyInterpreterState),
+     ('dict', PyObject),
+     ]))
 
 @cpython_api([], PyThreadState, error=CANNOT_FAIL)
 def PyEval_SaveThread(space):
@@ -38,41 +45,49 @@
     return 1
 
 # XXX: might be generally useful
-def encapsulator(T, flavor='raw'):
+def encapsulator(T, flavor='raw', dealloc=None):
     class MemoryCapsule(object):
-        def __init__(self, alloc=True):
-            if alloc:
+        def __init__(self, space):
+            self.space = space
+            if space is not None:
                 self.memory = lltype.malloc(T, flavor=flavor)
             else:
                 self.memory = lltype.nullptr(T)
         def __del__(self):
             if self.memory:
+                if dealloc and self.space:
+                    dealloc(self.memory, self.space)
                 lltype.free(self.memory, flavor=flavor)
     return MemoryCapsule
 
-ThreadStateCapsule = encapsulator(PyThreadState.TO)
+def ThreadState_dealloc(ts, space):
+    assert space is not None
+    Py_DecRef(space, ts.c_dict)
+ThreadStateCapsule = encapsulator(PyThreadState.TO,
+                                  dealloc=ThreadState_dealloc)
 
 from pypy.interpreter.executioncontext import ExecutionContext
-ExecutionContext.cpyext_threadstate = ThreadStateCapsule(alloc=False)
+ExecutionContext.cpyext_threadstate = ThreadStateCapsule(None)
 
 class InterpreterState(object):
     def __init__(self, space):
         self.interpreter_state = lltype.malloc(
             PyInterpreterState.TO, flavor='raw', zero=True, immortal=True)
 
-    def new_thread_state(self):
-        capsule = ThreadStateCapsule()
+    def new_thread_state(self, space):
+        capsule = ThreadStateCapsule(space)
         ts = capsule.memory
         ts.c_interp = self.interpreter_state
+        ts.c_dict = make_ref(space, space.newdict())
         return capsule
 
     def get_thread_state(self, space):
         ec = space.getexecutioncontext()
-        return self._get_thread_state(ec).memory
+        return self._get_thread_state(space, ec).memory
 
-    def _get_thread_state(self, ec):
+    def _get_thread_state(self, space, ec):
         if ec.cpyext_threadstate.memory == lltype.nullptr(PyThreadState.TO):
-            ec.cpyext_threadstate = self.new_thread_state()
+            ec.cpyext_threadstate = self.new_thread_state(space)
 
         return ec.cpyext_threadstate
 
@@ -81,6 +96,11 @@
     state = space.fromcache(InterpreterState)
     return state.get_thread_state(space)
 
+ at cpython_api([], PyObject, error=CANNOT_FAIL)
+def PyThreadState_GetDict(space):
+    state = space.fromcache(InterpreterState)
+    return state.get_thread_state(space).c_dict
+
 @cpython_api([PyThreadState], PyThreadState, error=CANNOT_FAIL)
 def PyThreadState_Swap(space, tstate):
     """Swap the current thread state with the thread state given by the argument
diff --git a/pypy/module/cpyext/pythonrun.py b/pypy/module/cpyext/pythonrun.py
--- a/pypy/module/cpyext/pythonrun.py
+++ b/pypy/module/cpyext/pythonrun.py
@@ -14,6 +14,20 @@
     value."""
     return space.fromcache(State).get_programname()
 
+ at cpython_api([], rffi.CCHARP)
+def Py_GetVersion(space):
+    """Return the version of this Python interpreter.  This is a
+    string that looks something like
+
+    "1.5 (\#67, Dec 31 1997, 22:34:28) [GCC 2.7.2.2]"
+
+    The first word (up to the first space character) is the current
+    Python version; the first three characters are the major and minor
+    version separated by a period.  The returned string points into
+    static storage; the caller should not modify its value.  The value
+    is available to Python code as sys.version."""
+    return space.fromcache(State).get_version()
+
 @cpython_api([lltype.Ptr(lltype.FuncType([], lltype.Void))], rffi.INT_real, error=-1)
 def Py_AtExit(space, func_ptr):
     """Register a cleanup function to be called by Py_Finalize().  The cleanup
diff --git a/pypy/module/cpyext/setobject.py b/pypy/module/cpyext/setobject.py
--- a/pypy/module/cpyext/setobject.py
+++ b/pypy/module/cpyext/setobject.py
@@ -54,6 +54,20 @@
     return 0
 
 
+ at cpython_api([PyObject], PyObject)
+def PySet_Pop(space, w_set):
+    """Return a new reference to an arbitrary object in the set, and removes the
+    object from the set.  Return NULL on failure.  Raise KeyError if the
+    set is empty. Raise a SystemError if set is an not an instance of
+    set or its subtype."""
+    return space.call_method(w_set, "pop")
+
+ at cpython_api([PyObject], rffi.INT_real, error=-1)
+def PySet_Clear(space, w_set):
+    """Empty an existing set of all elements."""
+    space.call_method(w_set, 'clear')
+    return 0
+
 @cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL)
 def PySet_GET_SIZE(space, w_s):
     """Macro form of PySet_Size() without error checking."""
diff --git a/pypy/module/cpyext/slotdefs.py b/pypy/module/cpyext/slotdefs.py
--- a/pypy/module/cpyext/slotdefs.py
+++ b/pypy/module/cpyext/slotdefs.py
@@ -185,6 +185,15 @@
         space.fromcache(State).check_and_raise_exception(always=True)
     return space.wrap(res)
 
+def wrap_delitem(space, w_self, w_args, func):
+    func_target = rffi.cast(objobjargproc, func)
+    check_num_args(space, w_args, 1)
+    w_key, = space.fixedview(w_args)
+    res = generic_cpy_call(space, func_target, w_self, w_key, None)
+    if rffi.cast(lltype.Signed, res) == -1:
+        space.fromcache(State).check_and_raise_exception(always=True)
+    return space.w_None
+
 def wrap_ssizessizeargfunc(space, w_self, w_args, func):
     func_target = rffi.cast(ssizessizeargfunc, func)
     check_num_args(space, w_args, 2)
@@ -291,6 +300,14 @@
 def slot_nb_int(space, w_self):
     return space.int(w_self)
 
+ at cpython_api([PyObject], PyObject, external=False)
+def slot_tp_iter(space, w_self):
+    return space.iter(w_self)
+
+ at cpython_api([PyObject], PyObject, external=False)
+def slot_tp_iternext(space, w_self):
+    return space.next(w_self)
+
 from pypy.rlib.nonconst import NonConstant
 
 SLOTS = {}
@@ -632,6 +649,19 @@
     TPSLOT("__buffer__", "tp_as_buffer.c_bf_getreadbuffer", None, "wrap_getreadbuffer", ""),
 )
 
+# partial sort to solve some slot conflicts:
+# Number slots before Mapping slots before Sequence slots.
+# These are the only conflicts between __name__ methods
+def slotdef_sort_key(slotdef):
+    if slotdef.slot_name.startswith('tp_as_number'):
+        return 1
+    if slotdef.slot_name.startswith('tp_as_mapping'):
+        return 2
+    if slotdef.slot_name.startswith('tp_as_sequence'):
+        return 3
+    return 0
+slotdefs = sorted(slotdefs, key=slotdef_sort_key)
+
 slotdefs_for_tp_slots = unrolling_iterable(
     [(x.method_name, x.slot_name, x.slot_names, x.slot_func)
      for x in slotdefs])
diff --git a/pypy/module/cpyext/state.py b/pypy/module/cpyext/state.py
--- a/pypy/module/cpyext/state.py
+++ b/pypy/module/cpyext/state.py
@@ -10,6 +10,7 @@
         self.space = space
         self.reset()
         self.programname = lltype.nullptr(rffi.CCHARP.TO)
+        self.version = lltype.nullptr(rffi.CCHARP.TO)
 
     def reset(self):
         from pypy.module.cpyext.modsupport import PyMethodDef
@@ -102,6 +103,15 @@
             lltype.render_immortal(self.programname)
         return self.programname
 
+    def get_version(self):
+        if not self.version:
+            space = self.space
+            w_version = space.sys.get('version')
+            version = space.str_w(w_version)
+            self.version = rffi.str2charp(version)
+            lltype.render_immortal(self.version)
+        return self.version
+
     def find_extension(self, name, path):
         from pypy.module.cpyext.modsupport import PyImport_AddModule
         from pypy.interpreter.module import Module
diff --git a/pypy/module/cpyext/stringobject.py b/pypy/module/cpyext/stringobject.py
--- a/pypy/module/cpyext/stringobject.py
+++ b/pypy/module/cpyext/stringobject.py
@@ -250,6 +250,26 @@
     s = rffi.charp2str(string)
     return space.new_interned_str(s)
 
+ at cpython_api([PyObjectP], lltype.Void)
+def PyString_InternInPlace(space, string):
+    """Intern the argument *string in place.  The argument must be the
+    address of a pointer variable pointing to a Python string object.
+    If there is an existing interned string that is the same as
+    *string, it sets *string to it (decrementing the reference count
+    of the old string object and incrementing the reference count of
+    the interned string object), otherwise it leaves *string alone and
+    interns it (incrementing its reference count).  (Clarification:
+    even though there is a lot of talk about reference counts, think
+    of this function as reference-count-neutral; you own the object
+    after the call if and only if you owned it before the call.)
+
+    This function is not available in 3.x and does not have a PyBytes
+    alias."""
+    w_str = from_ref(space, string[0])
+    w_str = space.new_interned_w_str(w_str)
+    Py_DecRef(space, string[0])
+    string[0] = make_ref(space, w_str)
+
 @cpython_api([PyObject, rffi.CCHARP, rffi.CCHARP], PyObject)
 def PyString_AsEncodedObject(space, w_str, encoding, errors):
     """Encode a string object using the codec registered for encoding and return
diff --git a/pypy/module/cpyext/structmemberdefs.py b/pypy/module/cpyext/structmemberdefs.py
--- a/pypy/module/cpyext/structmemberdefs.py
+++ b/pypy/module/cpyext/structmemberdefs.py
@@ -1,3 +1,5 @@
+# These constants are also in include/structmember.h
+
 T_SHORT = 0
 T_INT = 1
 T_LONG = 2
@@ -18,3 +20,6 @@
 T_ULONGLONG = 18
 
 READONLY = RO = 1
+READ_RESTRICTED = 2
+WRITE_RESTRICTED = 4
+RESTRICTED = READ_RESTRICTED | WRITE_RESTRICTED
diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py
--- a/pypy/module/cpyext/stubs.py
+++ b/pypy/module/cpyext/stubs.py
@@ -1,5 +1,5 @@
 from pypy.module.cpyext.api import (
-    cpython_api, PyObject, PyObjectP, CANNOT_FAIL, Py_buffer
+    cpython_api, PyObject, PyObjectP, CANNOT_FAIL
     )
 from pypy.module.cpyext.complexobject import Py_complex_ptr as Py_complex
 from pypy.rpython.lltypesystem import rffi, lltype
@@ -10,6 +10,7 @@
 PyMethodDef = rffi.VOIDP
 PyGetSetDef = rffi.VOIDP
 PyMemberDef = rffi.VOIDP
+Py_buffer = rffi.VOIDP
 va_list = rffi.VOIDP
 PyDateTime_Date = rffi.VOIDP
 PyDateTime_DateTime = rffi.VOIDP
@@ -32,10 +33,6 @@
 def _PyObject_Del(space, op):
     raise NotImplementedError
 
- at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
-def PyObject_CheckBuffer(space, obj):
-    raise NotImplementedError
-
 @cpython_api([rffi.CCHARP], Py_ssize_t, error=CANNOT_FAIL)
 def PyBuffer_SizeFromFormat(space, format):
     """Return the implied ~Py_buffer.itemsize from the struct-stype
@@ -185,16 +182,6 @@
     used as the positional and keyword parameters to the object's constructor."""
     raise NotImplementedError
 
- at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
-def PyCode_Check(space, co):
-    """Return true if co is a code object"""
-    raise NotImplementedError
-
- at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
-def PyCode_GetNumFree(space, co):
-    """Return the number of free variables in co."""
-    raise NotImplementedError
-
 @cpython_api([PyObject], rffi.INT_real, error=-1)
 def PyCodec_Register(space, search_function):
     """Register a new codec search function.
@@ -684,28 +671,6 @@
     """
     raise NotImplementedError
 
- at cpython_api([PyObject, rffi.INT_real], rffi.INT_real, error=CANNOT_FAIL)
-def PyFile_SoftSpace(space, p, newflag):
-    """
-    This function exists for internal use by the interpreter.  Set the
-    softspace attribute of p to newflag and return the previous value.
-    p does not have to be a file object for this function to work properly; any
-    object is supported (thought its only interesting if the softspace
-    attribute can be set).  This function clears any errors, and will return 0
-    as the previous value if the attribute either does not exist or if there were
-    errors in retrieving it.  There is no way to detect errors from this function,
-    but doing so should not be needed."""
-    raise NotImplementedError
-
- at cpython_api([PyObject, PyObject, rffi.INT_real], rffi.INT_real, error=-1)
-def PyFile_WriteObject(space, obj, p, flags):
-    """
-    Write object obj to file object p.  The only supported flag for flags is
-    Py_PRINT_RAW; if given, the str() of the object is written
-    instead of the repr().  Return 0 on success or -1 on failure; the
-    appropriate exception will be set."""
-    raise NotImplementedError
-
 @cpython_api([], PyObject)
 def PyFloat_GetInfo(space):
     """Return a structseq instance which contains information about the
@@ -1097,19 +1062,6 @@
     raise NotImplementedError
 
 @cpython_api([], rffi.CCHARP)
-def Py_GetVersion(space):
-    """Return the version of this Python interpreter.  This is a string that looks
-    something like
-
-    "1.5 (\#67, Dec 31 1997, 22:34:28) [GCC 2.7.2.2]"
-
-    The first word (up to the first space character) is the current Python version;
-    the first three characters are the major and minor version separated by a
-    period.  The returned string points into static storage; the caller should not
-    modify its value.  The value is available to Python code as sys.version."""
-    raise NotImplementedError
-
- at cpython_api([], rffi.CCHARP)
 def Py_GetPlatform(space):
     """Return the platform identifier for the current platform.  On Unix, this
     is formed from the"official" name of the operating system, converted to lower
@@ -1331,28 +1283,6 @@
     that haven't been explicitly destroyed at that point."""
     raise NotImplementedError
 
- at cpython_api([rffi.VOIDP], lltype.Void)
-def Py_AddPendingCall(space, func):
-    """Post a notification to the Python main thread.  If successful, func will
-    be called with the argument arg at the earliest convenience.  func will be
-    called having the global interpreter lock held and can thus use the full
-    Python API and can take any action such as setting object attributes to
-    signal IO completion.  It must return 0 on success, or -1 signalling an
-    exception.  The notification function won't be interrupted to perform another
-    asynchronous notification recursively, but it can still be interrupted to
-    switch threads if the global interpreter lock is released, for example, if it
-    calls back into Python code.
-
-    This function returns 0 on success in which case the notification has been
-    scheduled.  Otherwise, for example if the notification buffer is full, it
-    returns -1 without setting any exception.
-
-    This function can be called on any thread, be it a Python thread or some
-    other system thread.  If it is a Python thread, it doesn't matter if it holds
-    the global interpreter lock or not.
-    """
-    raise NotImplementedError
-
 @cpython_api([Py_tracefunc, PyObject], lltype.Void)
 def PyEval_SetProfile(space, func, obj):
     """Set the profiler function to func.  The obj parameter is passed to the
@@ -1685,15 +1615,6 @@
     """
     raise NotImplementedError
 
- at cpython_api([PyObject], PyObject)
-def PyObject_Dir(space, o):
-    """This is equivalent to the Python expression dir(o), returning a (possibly
-    empty) list of strings appropriate for the object argument, or NULL if there
-    was an error.  If the argument is NULL, this is like the Python dir(),
-    returning the names of the current locals; in this case, if no execution frame
-    is active then NULL is returned but PyErr_Occurred() will return false."""
-    raise NotImplementedError
-
 @cpython_api([], PyFrameObject)
 def PyEval_GetFrame(space):
     """Return the current thread state's frame, which is NULL if no frame is
@@ -1802,34 +1723,6 @@
     building-up new frozensets with PySet_Add()."""
     raise NotImplementedError
 
- at cpython_api([PyObject], PyObject)
-def PySet_Pop(space, set):
-    """Return a new reference to an arbitrary object in the set, and removes the
-    object from the set.  Return NULL on failure.  Raise KeyError if the
-    set is empty. Raise a SystemError if set is an not an instance of
-    set or its subtype."""
-    raise NotImplementedError
-
- at cpython_api([PyObject], rffi.INT_real, error=-1)
-def PySet_Clear(space, set):
-    """Empty an existing set of all elements."""
-    raise NotImplementedError
-
- at cpython_api([PyObjectP], lltype.Void)
-def PyString_InternInPlace(space, string):
-    """Intern the argument *string in place.  The argument must be the address of a
-    pointer variable pointing to a Python string object.  If there is an existing
-    interned string that is the same as *string, it sets *string to it
-    (decrementing the reference count of the old string object and incrementing the
-    reference count of the interned string object), otherwise it leaves *string
-    alone and interns it (incrementing its reference count).  (Clarification: even
-    though there is a lot of talk about reference counts, think of this function as
-    reference-count-neutral; you own the object after the call if and only if you
-    owned it before the call.)
-
-    This function is not available in 3.x and does not have a PyBytes alias."""
-    raise NotImplementedError
-
 @cpython_api([rffi.CCHARP, Py_ssize_t, rffi.CCHARP, rffi.CCHARP], PyObject)
 def PyString_Decode(space, s, size, encoding, errors):
     """Create an object by decoding size bytes of the encoded buffer s using the
@@ -1950,26 +1843,6 @@
     """
     raise NotImplementedError
 
- at cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL)
-def Py_UNICODE_ISTITLE(space, ch):
-    """Return 1 or 0 depending on whether ch is a titlecase character."""
-    raise NotImplementedError
-
- at cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL)
-def Py_UNICODE_ISDIGIT(space, ch):
-    """Return 1 or 0 depending on whether ch is a digit character."""
-    raise NotImplementedError
-
- at cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL)
-def Py_UNICODE_ISNUMERIC(space, ch):
-    """Return 1 or 0 depending on whether ch is a numeric character."""
-    raise NotImplementedError
-
- at cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL)
-def Py_UNICODE_ISALPHA(space, ch):
-    """Return 1 or 0 depending on whether ch is an alphabetic character."""
-    raise NotImplementedError
-
 @cpython_api([rffi.CCHARP], PyObject)
 def PyUnicode_FromFormat(space, format):
     """Take a C printf()-style format string and a variable number of
@@ -2414,17 +2287,6 @@
     use the default error handling."""
     raise NotImplementedError
 
- at cpython_api([PyObject, PyObject, Py_ssize_t, Py_ssize_t, rffi.INT_real], rffi.INT_real, error=-1)
-def PyUnicode_Tailmatch(space, str, substr, start, end, direction):
-    """Return 1 if substr matches str*[*start:end] at the given tail end
-    (direction == -1 means to do a prefix match, direction == 1 a suffix match),
-    0 otherwise. Return -1 if an error occurred.
-
-    This function used an int type for start and end. This
-    might require changes in your code for properly supporting 64-bit
-    systems."""
-    raise NotImplementedError
-
 @cpython_api([PyObject, PyObject, Py_ssize_t, Py_ssize_t, rffi.INT_real], Py_ssize_t, error=-2)
 def PyUnicode_Find(space, str, substr, start, end, direction):
     """Return the first position of substr in str*[*start:end] using the given
@@ -2448,16 +2310,6 @@
     properly supporting 64-bit systems."""
     raise NotImplementedError
 
- at cpython_api([PyObject, PyObject, PyObject, Py_ssize_t], PyObject)
-def PyUnicode_Replace(space, str, substr, replstr, maxcount):
-    """Replace at most maxcount occurrences of substr in str with replstr and
-    return the resulting Unicode object. maxcount == -1 means replace all
-    occurrences.
-
-    This function used an int type for maxcount. This might
-    require changes in your code for properly supporting 64-bit systems."""
-    raise NotImplementedError
-
 @cpython_api([PyObject, PyObject, rffi.INT_real], PyObject)
 def PyUnicode_RichCompare(space, left, right, op):
     """Rich compare two unicode strings and return one of the following:
@@ -2631,17 +2483,6 @@
     source code is read from fp instead of an in-memory string."""
     raise NotImplementedError
 
- at cpython_api([rffi.CCHARP, rffi.INT_real, PyObject, PyObject, PyCompilerFlags], PyObject)
-def PyRun_StringFlags(space, str, start, globals, locals, flags):
-    """Execute Python source code from str in the context specified by the
-    dictionaries globals and locals with the compiler flags specified by
-    flags.  The parameter start specifies the start token that should be used to
-    parse the source code.
-
-    Returns the result of executing the code as a Python object, or NULL if an
-    exception was raised."""
-    raise NotImplementedError
-
 @cpython_api([FILE, rffi.CCHARP, rffi.INT_real, PyObject, PyObject, rffi.INT_real], PyObject)
 def PyRun_FileEx(space, fp, filename, start, globals, locals, closeit):
     """This is a simplified interface to PyRun_FileExFlags() below, leaving
@@ -2662,13 +2503,6 @@
     returns."""
     raise NotImplementedError
 
- at cpython_api([PyCodeObject, PyObject, PyObject], PyObject)
-def PyEval_EvalCode(space, co, globals, locals):
-    """This is a simplified interface to PyEval_EvalCodeEx(), with just
-    the code object, and the dictionaries of global and local variables.
-    The other arguments are set to NULL."""
-    raise NotImplementedError
-
 @cpython_api([PyCodeObject, PyObject, PyObject, PyObjectP, rffi.INT_real, PyObjectP, rffi.INT_real, PyObjectP, rffi.INT_real, PyObject], PyObject)
 def PyEval_EvalCodeEx(space, co, globals, locals, args, argcount, kws, kwcount, defs, defcount, closure):
     """Evaluate a precompiled code object, given a particular environment for its
@@ -2693,12 +2527,6 @@
     throw() methods of generator objects."""
     raise NotImplementedError
 
- at cpython_api([PyCompilerFlags], rffi.INT_real, error=CANNOT_FAIL)
-def PyEval_MergeCompilerFlags(space, cf):
-    """This function changes the flags of the current evaluation frame, and returns
-    true on success, false on failure."""
-    raise NotImplementedError
-
 @cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
 def PyWeakref_Check(space, ob):
     """Return true if ob is either a reference or proxy object.
diff --git a/pypy/module/cpyext/stubsactive.py b/pypy/module/cpyext/stubsactive.py
--- a/pypy/module/cpyext/stubsactive.py
+++ b/pypy/module/cpyext/stubsactive.py
@@ -38,3 +38,31 @@
 def Py_MakePendingCalls(space):
     return 0
 
+pending_call = lltype.Ptr(lltype.FuncType([rffi.VOIDP], rffi.INT_real))
+ at cpython_api([pending_call, rffi.VOIDP], rffi.INT_real, error=-1)
+def Py_AddPendingCall(space, func, arg):
+    """Post a notification to the Python main thread.  If successful,
+    func will be called with the argument arg at the earliest
+    convenience.  func will be called having the global interpreter
+    lock held and can thus use the full Python API and can take any
+    action such as setting object attributes to signal IO completion.
+    It must return 0 on success, or -1 signalling an exception.  The
+    notification function won't be interrupted to perform another
+    asynchronous notification recursively, but it can still be
+    interrupted to switch threads if the global interpreter lock is
+    released, for example, if it calls back into Python code.
+
+    This function returns 0 on success in which case the notification
+    has been scheduled.  Otherwise, for example if the notification
+    buffer is full, it returns -1 without setting any exception.
+
+    This function can be called on any thread, be it a Python thread
+    or some other system thread.  If it is a Python thread, it doesn't
+    matter if it holds the global interpreter lock or not.
+    """
+    return -1
+
+thread_func = lltype.Ptr(lltype.FuncType([rffi.VOIDP], lltype.Void))
+ at cpython_api([thread_func, rffi.VOIDP], rffi.INT_real, error=-1)
+def PyThread_start_new_thread(space, func, arg):
+    return -1
diff --git a/pypy/module/cpyext/test/test_arraymodule.py b/pypy/module/cpyext/test/test_arraymodule.py
--- a/pypy/module/cpyext/test/test_arraymodule.py
+++ b/pypy/module/cpyext/test/test_arraymodule.py
@@ -43,6 +43,15 @@
         assert arr[:2].tolist() == [1,2]
         assert arr[1:3].tolist() == [2,3]
 
+    def test_slice_object(self):
+        module = self.import_module(name='array')
+        arr = module.array('i', [1,2,3,4])
+        assert arr[slice(1,3)].tolist() == [2,3]
+        arr[slice(1,3)] = module.array('i', [21, 22, 23])
+        assert arr.tolist() == [1, 21, 22, 23, 4]
+        del arr[slice(1, 3)]
+        assert arr.tolist() == [1, 23, 4]
+
     def test_buffer(self):
         module = self.import_module(name='array')
         arr = module.array('i', [1,2,3,4])
diff --git a/pypy/module/cpyext/test/test_classobject.py b/pypy/module/cpyext/test/test_classobject.py
--- a/pypy/module/cpyext/test/test_classobject.py
+++ b/pypy/module/cpyext/test/test_classobject.py
@@ -1,4 +1,5 @@
 from pypy.module.cpyext.test.test_api import BaseApiTest
+from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
 from pypy.interpreter.function import Function, Method
 
 class TestClassObject(BaseApiTest):
@@ -51,3 +52,14 @@
         assert api.PyInstance_Check(w_instance)
         assert space.is_true(space.call_method(space.builtin, "isinstance",
                                                w_instance, w_class))
+
+class AppTestStringObject(AppTestCpythonExtensionBase):
+    def test_class_type(self):
+        module = self.import_extension('foo', [
+            ("get_classtype", "METH_NOARGS",
+             """
+                 Py_INCREF(&PyClass_Type);
+                 return &PyClass_Type;
+             """)])
+        class C: pass
+        assert module.get_classtype() is type(C)
diff --git a/pypy/module/cpyext/test/test_cpyext.py b/pypy/module/cpyext/test/test_cpyext.py
--- a/pypy/module/cpyext/test/test_cpyext.py
+++ b/pypy/module/cpyext/test/test_cpyext.py
@@ -744,6 +744,22 @@
         print p
         assert 'py' in p
 
+    def test_get_version(self):
+        mod = self.import_extension('foo', [
+            ('get_version', 'METH_NOARGS',
+             '''
+             char* name1 = Py_GetVersion();
+             char* name2 = Py_GetVersion();
+             if (name1 != name2)
+                 Py_RETURN_FALSE;
+             return PyString_FromString(name1);
+             '''
+             ),
+            ])
+        p = mod.get_version()
+        print p
+        assert 'PyPy' in p
+
     def test_no_double_imports(self):
         import sys, os
         try:
diff --git a/pypy/module/cpyext/test/test_dictobject.py b/pypy/module/cpyext/test/test_dictobject.py
--- a/pypy/module/cpyext/test/test_dictobject.py
+++ b/pypy/module/cpyext/test/test_dictobject.py
@@ -2,6 +2,7 @@
 from pypy.module.cpyext.test.test_api import BaseApiTest
 from pypy.module.cpyext.api import Py_ssize_tP, PyObjectP
 from pypy.module.cpyext.pyobject import make_ref, from_ref
+from pypy.interpreter.error import OperationError
 
 class TestDictObject(BaseApiTest):
     def test_dict(self, space, api):
@@ -110,3 +111,44 @@
 
         assert space.eq_w(space.len(w_copy), space.len(w_dict))
         assert space.eq_w(w_copy, w_dict)
+
+    def test_iterkeys(self, space, api):
+        w_dict = space.sys.getdict(space)
+        py_dict = make_ref(space, w_dict)
+
+        ppos = lltype.malloc(Py_ssize_tP.TO, 1, flavor='raw')
+        pkey = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
+        pvalue = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
+
+        keys_w = []
+        values_w = []
+        try:
+            ppos[0] = 0
+            while api.PyDict_Next(w_dict, ppos, pkey, None):
+                w_key = from_ref(space, pkey[0])
+                keys_w.append(w_key)
+            ppos[0] = 0
+            while api.PyDict_Next(w_dict, ppos, None, pvalue):
+                w_value = from_ref(space, pvalue[0])
+                values_w.append(w_value)
+        finally:
+            lltype.free(ppos, flavor='raw')
+            lltype.free(pkey, flavor='raw')
+            lltype.free(pvalue, flavor='raw')
+
+        api.Py_DecRef(py_dict) # release borrowed references
+
+        assert space.eq_w(space.newlist(keys_w),
+                          space.call_method(w_dict, "keys"))
+        assert space.eq_w(space.newlist(values_w),
+                          space.call_method(w_dict, "values"))
+
+    def test_dictproxy(self, space, api):
+        w_dict = space.sys.get('modules')
+        w_proxy = api.PyDictProxy_New(w_dict)
+        assert space.is_true(space.contains(w_proxy, space.wrap('sys')))
+        raises(OperationError, space.setitem,
+               w_proxy, space.wrap('sys'), space.w_None)
+        raises(OperationError, space.delitem,
+               w_proxy, space.wrap('sys'))
+        raises(OperationError, space.call_method, w_proxy, 'clear')
diff --git a/pypy/module/cpyext/test/test_eval.py b/pypy/module/cpyext/test/test_eval.py
--- a/pypy/module/cpyext/test/test_eval.py
+++ b/pypy/module/cpyext/test/test_eval.py
@@ -2,9 +2,10 @@
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
 from pypy.module.cpyext.test.test_api import BaseApiTest
 from pypy.module.cpyext.eval import (
-    Py_single_input, Py_file_input, Py_eval_input)
+    Py_single_input, Py_file_input, Py_eval_input, PyCompilerFlags)
 from pypy.module.cpyext.api import fopen, fclose, fileno, Py_ssize_tP
 from pypy.interpreter.gateway import interp2app
+from pypy.interpreter.astcompiler import consts
 from pypy.tool.udir import udir
 import sys, os
 
@@ -63,6 +64,22 @@
 
         assert space.int_w(w_res) == 10
 
+    def test_evalcode(self, space, api):
+        w_f = space.appexec([], """():
+            def f(*args):
+                assert isinstance(args, tuple)
+                return len(args) + 8
+            return f
+            """)
+
+        w_t = space.newtuple([space.wrap(1), space.wrap(2)])
+        w_globals = space.newdict()
+        w_locals = space.newdict()
+        space.setitem(w_locals, space.wrap("args"), w_t)
+        w_res = api.PyEval_EvalCode(w_f.code, w_globals, w_locals)
+
+        assert space.int_w(w_res) == 10
+
     def test_run_simple_string(self, space, api):
         def run(code):
             buf = rffi.str2charp(code)
@@ -96,6 +113,20 @@
         assert 42 * 43 == space.unwrap(
             api.PyObject_GetItem(w_globals, space.wrap("a")))
 
+    def test_run_string_flags(self, space, api):
+        flags = lltype.malloc(PyCompilerFlags, flavor='raw')
+        flags.c_cf_flags = rffi.cast(rffi.INT, consts.PyCF_SOURCE_IS_UTF8)
+        w_globals = space.newdict()
+        buf = rffi.str2charp("a = u'caf\xc3\xa9'")
+        try:
+            api.PyRun_StringFlags(buf, Py_single_input,
+                                  w_globals, w_globals, flags)
+        finally:
+            rffi.free_charp(buf)
+        w_a = space.getitem(w_globals, space.wrap("a"))
+        assert space.unwrap(w_a) == u'caf\xe9'
+        lltype.free(flags, flavor='raw')
+
     def test_run_file(self, space, api):
         filepath = udir / "cpyext_test_runfile.py"
         filepath.write("raise ZeroDivisionError")
@@ -256,3 +287,21 @@
         print dir(mod)
         print mod.__dict__
         assert mod.f(42) == 47
+
+    def test_merge_compiler_flags(self):
+        module = self.import_extension('foo', [
+            ("get_flags", "METH_NOARGS",
+             """
+                PyCompilerFlags flags;
+                flags.cf_flags = 0;
+                int result = PyEval_MergeCompilerFlags(&flags);
+                return Py_BuildValue("ii", result, flags.cf_flags);
+             """),
+            ])
+        assert module.get_flags() == (0, 0)
+
+        ns = {'module':module}
+        exec """from __future__ import division    \nif 1:
+                def nested_flags():
+                    return module.get_flags()""" in ns
+        assert ns['nested_flags']() == (1, 0x2000)  # CO_FUTURE_DIVISION
diff --git a/pypy/module/cpyext/test/test_funcobject.py b/pypy/module/cpyext/test/test_funcobject.py
--- a/pypy/module/cpyext/test/test_funcobject.py
+++ b/pypy/module/cpyext/test/test_funcobject.py
@@ -81,6 +81,14 @@
         rffi.free_charp(filename)
         rffi.free_charp(funcname)
 
+    def test_getnumfree(self, space, api):
+        w_function = space.appexec([], """():
+            a = 5
+            def method(x): return a, x
+            return method
+        """)
+        assert api.PyCode_GetNumFree(w_function.code) == 1
+
     def test_classmethod(self, space, api):
         w_function = space.appexec([], """():
             def method(x): return x
diff --git a/pypy/module/cpyext/test/test_intobject.py b/pypy/module/cpyext/test/test_intobject.py
--- a/pypy/module/cpyext/test/test_intobject.py
+++ b/pypy/module/cpyext/test/test_intobject.py
@@ -65,4 +65,97 @@
         values = module.values()
         types = [type(x) for x in values]
         assert types == [int, long, int, int]
-        
+
+    def test_int_subtype(self):
+        module = self.import_extension(
+            'foo', [
+            ("newEnum", "METH_VARARGS",
+             """
+                EnumObject *enumObj;
+                long intval;
+                PyObject *name;
+
+                if (!PyArg_ParseTuple(args, "Oi", &name, &intval))
+                    return NULL;
+
+                PyType_Ready(&Enum_Type);
+                enumObj = PyObject_New(EnumObject, &Enum_Type);
+                if (!enumObj) {
+                    return NULL;
+                }
+
+                enumObj->ob_ival = intval;
+                Py_INCREF(name);
+                enumObj->ob_name = name;
+
+                return (PyObject *)enumObj;
+             """),
+            ], 
+            prologue="""
+            typedef struct
+            {
+                PyObject_HEAD
+                long ob_ival;
+                PyObject* ob_name;
+            } EnumObject;
+
+            static void
+            enum_dealloc(EnumObject *op)
+            {
+                    Py_DECREF(op->ob_name);
+                    Py_TYPE(op)->tp_free((PyObject *)op);
+            }
+
+            static PyMemberDef enum_members[] = {
+                {"name", T_OBJECT, offsetof(EnumObject, ob_name), 0, NULL},
+                {NULL}  /* Sentinel */
+            };
+
+            PyTypeObject Enum_Type = {
+                PyObject_HEAD_INIT(0)
+                /*ob_size*/             0,
+                /*tp_name*/             "Enum",
+                /*tp_basicsize*/        sizeof(EnumObject),
+                /*tp_itemsize*/         0,
+                /*tp_dealloc*/          enum_dealloc,
+                /*tp_print*/            0,
+                /*tp_getattr*/          0,
+                /*tp_setattr*/          0,
+                /*tp_compare*/          0,
+                /*tp_repr*/             0,
+                /*tp_as_number*/        0,
+                /*tp_as_sequence*/      0,
+                /*tp_as_mapping*/       0,
+                /*tp_hash*/             0,
+                /*tp_call*/             0,
+                /*tp_str*/              0,
+                /*tp_getattro*/         0,
+                /*tp_setattro*/         0,
+                /*tp_as_buffer*/        0,
+                /*tp_flags*/            Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
+                /*tp_doc*/              0,
+                /*tp_traverse*/         0,
+                /*tp_clear*/            0,
+                /*tp_richcompare*/      0,
+                /*tp_weaklistoffset*/   0,
+                /*tp_iter*/             0,
+                /*tp_iternext*/         0,
+                /*tp_methods*/          0,
+                /*tp_members*/          enum_members,
+                /*tp_getset*/           0,
+                /*tp_base*/             &PyInt_Type,
+                /*tp_dict*/             0,
+                /*tp_descr_get*/        0,
+                /*tp_descr_set*/        0,
+                /*tp_dictoffset*/       0,
+                /*tp_init*/             0,
+                /*tp_alloc*/            0,
+                /*tp_new*/              0
+            };
+            """)
+
+        a = module.newEnum("ULTIMATE_ANSWER", 42)
+        assert type(a).__name__ == "Enum"
+        assert isinstance(a, int)
+        assert a == int(a) == 42
+        assert a.name == "ULTIMATE_ANSWER"
diff --git a/pypy/module/cpyext/test/test_methodobject.py b/pypy/module/cpyext/test/test_methodobject.py
--- a/pypy/module/cpyext/test/test_methodobject.py
+++ b/pypy/module/cpyext/test/test_methodobject.py
@@ -9,7 +9,7 @@
 
 class AppTestMethodObject(AppTestCpythonExtensionBase):
     def test_call_METH(self):
-        mod = self.import_extension('foo', [
+        mod = self.import_extension('MyModule', [
             ('getarg_O', 'METH_O',
              '''
              Py_INCREF(args);
@@ -51,11 +51,23 @@
              }
              '''
              ),
+            ('getModule', 'METH_O',
+             '''
+             if(PyCFunction_Check(args)) {
+                 PyCFunctionObject* func = (PyCFunctionObject*)args;
+                 Py_INCREF(func->m_module);
+                 return func->m_module;
+             }
+             else {
+                 Py_RETURN_FALSE;
+             }
+             '''
+             ),
             ('isSameFunction', 'METH_O',
              '''
              PyCFunction ptr = PyCFunction_GetFunction(args);
              if (!ptr) return NULL;
-             if (ptr == foo_getarg_O)
+             if (ptr == MyModule_getarg_O)
                  Py_RETURN_TRUE;
              else
                  Py_RETURN_FALSE;
@@ -76,6 +88,7 @@
         assert mod.getarg_OLD(1, 2) == (1, 2)
 
         assert mod.isCFunction(mod.getarg_O) == "getarg_O"
+        assert mod.getModule(mod.getarg_O) == 'MyModule'
         assert mod.isSameFunction(mod.getarg_O)
         raises(TypeError, mod.isSameFunction, 1)
 
diff --git a/pypy/module/cpyext/test/test_object.py b/pypy/module/cpyext/test/test_object.py
--- a/pypy/module/cpyext/test/test_object.py
+++ b/pypy/module/cpyext/test/test_object.py
@@ -191,6 +191,11 @@
         assert api.PyObject_Unicode(space.wrap("\xe9")) is None
         api.PyErr_Clear()
 
+    def test_dir(self, space, api):
+        w_dir = api.PyObject_Dir(space.sys)
+        assert space.isinstance_w(w_dir, space.w_list)
+        assert space.is_true(space.contains(w_dir, space.wrap('modules')))
+
 class AppTestObject(AppTestCpythonExtensionBase):
     def setup_class(cls):
         AppTestCpythonExtensionBase.setup_class.im_func(cls)
diff --git a/pypy/module/cpyext/test/test_pyfile.py b/pypy/module/cpyext/test/test_pyfile.py
--- a/pypy/module/cpyext/test/test_pyfile.py
+++ b/pypy/module/cpyext/test/test_pyfile.py
@@ -1,5 +1,6 @@
 from pypy.module.cpyext.api import fopen, fclose, fwrite
 from pypy.module.cpyext.test.test_api import BaseApiTest
+from pypy.module.cpyext.object import Py_PRINT_RAW
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.tool.udir import udir
 import pytest
@@ -77,3 +78,28 @@
         out = out.replace('\r\n', '\n')
         assert out == "test\n"
 
+    def test_file_writeobject(self, space, api, capfd):
+        w_obj = space.wrap("test\n")
+        w_stdout = space.sys.get("stdout")
+        api.PyFile_WriteObject(w_obj, w_stdout, Py_PRINT_RAW)
+        api.PyFile_WriteObject(w_obj, w_stdout, 0)
+        space.call_method(w_stdout, "flush")
+        out, err = capfd.readouterr()
+        out = out.replace('\r\n', '\n')
+        assert out == "test\n'test\\n'"
+
+    def test_file_softspace(self, space, api, capfd):
+        w_stdout = space.sys.get("stdout")
+        assert api.PyFile_SoftSpace(w_stdout, 1) == 0
+        assert api.PyFile_SoftSpace(w_stdout, 0) == 1
+        
+        api.PyFile_SoftSpace(w_stdout, 1)
+        w_ns = space.newdict()
+        space.exec_("print 1,", w_ns, w_ns)
+        space.exec_("print 2,", w_ns, w_ns)
+        api.PyFile_SoftSpace(w_stdout, 0)
+        space.exec_("print 3", w_ns, w_ns)
+        space.call_method(w_stdout, "flush")
+        out, err = capfd.readouterr()
+        out = out.replace('\r\n', '\n')
+        assert out == " 1 23\n"
diff --git a/pypy/module/cpyext/test/test_pystate.py b/pypy/module/cpyext/test/test_pystate.py
--- a/pypy/module/cpyext/test/test_pystate.py
+++ b/pypy/module/cpyext/test/test_pystate.py
@@ -2,6 +2,7 @@
 from pypy.module.cpyext.test.test_api import BaseApiTest
 from pypy.rpython.lltypesystem.lltype import nullptr
 from pypy.module.cpyext.pystate import PyInterpreterState, PyThreadState
+from pypy.module.cpyext.pyobject import from_ref
 
 class AppTestThreads(AppTestCpythonExtensionBase):
     def test_allow_threads(self):
@@ -49,3 +50,10 @@
 
         api.PyEval_AcquireThread(tstate)
         api.PyEval_ReleaseThread(tstate)
+
+    def test_threadstate_dict(self, space, api):
+        ts = api.PyThreadState_Get()
+        ref = ts.c_dict
+        assert ref == api.PyThreadState_GetDict()
+        w_obj = from_ref(space, ref)
+        assert space.isinstance_w(w_obj, space.w_dict)
diff --git a/pypy/module/cpyext/test/test_setobject.py b/pypy/module/cpyext/test/test_setobject.py
--- a/pypy/module/cpyext/test/test_setobject.py
+++ b/pypy/module/cpyext/test/test_setobject.py
@@ -32,3 +32,13 @@
         w_set = api.PySet_New(space.wrap([1,2,3,4]))
         assert api.PySet_Contains(w_set, space.wrap(1))
         assert not api.PySet_Contains(w_set, space.wrap(0))
+
+    def test_set_pop_clear(self, space, api):
+        w_set = api.PySet_New(space.wrap([1,2,3,4]))
+        w_obj = api.PySet_Pop(w_set)
+        assert space.int_w(w_obj) in (1,2,3,4)
+        assert space.len_w(w_set) == 3
+        api.PySet_Clear(w_set)
+        assert space.len_w(w_set) == 0
+
+    
diff --git a/pypy/module/cpyext/test/test_stringobject.py b/pypy/module/cpyext/test/test_stringobject.py
--- a/pypy/module/cpyext/test/test_stringobject.py
+++ b/pypy/module/cpyext/test/test_stringobject.py
@@ -166,6 +166,20 @@
         res = module.test_string_format(1, "xyz")
         assert res == "bla 1 ble xyz\n"
 
+    def test_intern_inplace(self):
+        module = self.import_extension('foo', [
+            ("test_intern_inplace", "METH_O",
+             '''
+                 PyObject *s = args;
+                 Py_INCREF(s);
+                 PyString_InternInPlace(&s);
+                 return s;
+             '''
+             )
+            ])
+        # This does not test much, but at least the refcounts are checked.
+        assert module.test_intern_inplace('s') == 's'
+
 class TestString(BaseApiTest):
     def test_string_resize(self, space, api):
         py_str = new_empty_str(space, 10)
diff --git a/pypy/module/cpyext/test/test_typeobject.py b/pypy/module/cpyext/test/test_typeobject.py
--- a/pypy/module/cpyext/test/test_typeobject.py
+++ b/pypy/module/cpyext/test/test_typeobject.py
@@ -425,3 +425,32 @@
             ''')
         obj = module.new_obj()
         raises(ZeroDivisionError, obj.__setitem__, 5, None)
+
+    def test_tp_iter(self):
+        module = self.import_extension('foo', [
+           ("tp_iter", "METH_O",
+            '''
+                 if (!args->ob_type->tp_iter)
+                 {
+                     PyErr_SetNone(PyExc_ValueError);
+                     return NULL;
+                 }
+                 return args->ob_type->tp_iter(args);
+             '''
+             ),
+           ("tp_iternext", "METH_O",
+            '''
+                 if (!args->ob_type->tp_iternext)
+                 {
+                     PyErr_SetNone(PyExc_ValueError);
+                     return NULL;
+                 }
+                 return args->ob_type->tp_iternext(args);
+             '''
+             )
+            ])
+        l = [1]
+        it = module.tp_iter(l)
+        assert type(it) is type(iter([]))
+        assert module.tp_iternext(it) == 1
+        raises(StopIteration, module.tp_iternext, it)
diff --git a/pypy/module/cpyext/test/test_unicodeobject.py b/pypy/module/cpyext/test/test_unicodeobject.py
--- a/pypy/module/cpyext/test/test_unicodeobject.py
+++ b/pypy/module/cpyext/test/test_unicodeobject.py
@@ -204,8 +204,18 @@
             assert api.Py_UNICODE_ISSPACE(unichr(char))
         assert not api.Py_UNICODE_ISSPACE(u'a')
 
+        assert api.Py_UNICODE_ISALPHA(u'a')
+        assert not api.Py_UNICODE_ISALPHA(u'0')
+        assert api.Py_UNICODE_ISALNUM(u'a')
+        assert api.Py_UNICODE_ISALNUM(u'0')
+        assert not api.Py_UNICODE_ISALNUM(u'+')
+
         assert api.Py_UNICODE_ISDECIMAL(u'\u0660')
         assert not api.Py_UNICODE_ISDECIMAL(u'a')
+        assert api.Py_UNICODE_ISDIGIT(u'9')
+        assert not api.Py_UNICODE_ISDIGIT(u'@')
+        assert api.Py_UNICODE_ISNUMERIC(u'9')
+        assert not api.Py_UNICODE_ISNUMERIC(u'@')
 
         for char in [0x0a, 0x0d, 0x1c, 0x1d, 0x1e, 0x85, 0x2028, 0x2029]:
             assert api.Py_UNICODE_ISLINEBREAK(unichr(char))
@@ -216,6 +226,9 @@
         assert not api.Py_UNICODE_ISUPPER(u'a')
         assert not api.Py_UNICODE_ISLOWER(u'&#65533;')
         assert api.Py_UNICODE_ISUPPER(u'&#65533;')
+        assert not api.Py_UNICODE_ISTITLE(u'A')
+        assert api.Py_UNICODE_ISTITLE(
+            u'\N{LATIN CAPITAL LETTER L WITH SMALL LETTER J}')
 
     def test_TOLOWER(self, space, api):
         assert api.Py_UNICODE_TOLOWER(u'&#65533;') == u'&#65533;'
@@ -420,3 +433,27 @@
         w_seq = space.wrap([u'a', u'b'])
         w_joined = api.PyUnicode_Join(w_sep, w_seq)
         assert space.unwrap(w_joined) == u'a<sep>b'
+
+    def test_fromordinal(self, space, api):
+        w_char = api.PyUnicode_FromOrdinal(65)
+        assert space.unwrap(w_char) == u'A'
+        w_char = api.PyUnicode_FromOrdinal(0)
+        assert space.unwrap(w_char) == u'\0'
+        w_char = api.PyUnicode_FromOrdinal(0xFFFF)
+        assert space.unwrap(w_char) == u'\uFFFF'
+
+    def test_replace(self, space, api):
+        w_str = space.wrap(u"abababab")
+        w_substr = space.wrap(u"a")
+        w_replstr = space.wrap(u"z")
+        assert u"zbzbabab" == space.unwrap(
+            api.PyUnicode_Replace(w_str, w_substr, w_replstr, 2))
+        assert u"zbzbzbzb" == space.unwrap(
+            api.PyUnicode_Replace(w_str, w_substr, w_replstr, -1))
+
+    def test_tailmatch(self, space, api):
+        w_str = space.wrap(u"abcdef")
+        assert api.PyUnicode_Tailmatch(w_str, space.wrap("cde"), 2, 10, 1) == 1
+        assert api.PyUnicode_Tailmatch(w_str, space.wrap("cde"), 1, 5, -1) == 1
+        self.raises(space, api, TypeError,
+                    api.PyUnicode_Tailmatch, w_str, space.wrap(3), 2, 10, 1)
diff --git a/pypy/module/cpyext/unicodeobject.py b/pypy/module/cpyext/unicodeobject.py
--- a/pypy/module/cpyext/unicodeobject.py
+++ b/pypy/module/cpyext/unicodeobject.py
@@ -12,7 +12,7 @@
     make_typedescr, get_typedescr)
 from pypy.module.cpyext.stringobject import PyString_Check
 from pypy.module.sys.interp_encoding import setdefaultencoding
-from pypy.objspace.std import unicodeobject, unicodetype
+from pypy.objspace.std import unicodeobject, unicodetype, stringtype
 from pypy.rlib import runicode
 from pypy.tool.sourcetools import func_renamer
 import sys
@@ -89,6 +89,11 @@
     return unicodedb.isspace(ord(ch))
 
 @cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL)
+def Py_UNICODE_ISALPHA(space, ch):
+    """Return 1 or 0 depending on whether ch is an alphabetic character."""
+    return unicodedb.isalpha(ord(ch))
+
+ at cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL)
 def Py_UNICODE_ISALNUM(space, ch):
     """Return 1 or 0 depending on whether ch is an alphanumeric character."""
     return unicodedb.isalnum(ord(ch))
@@ -104,6 +109,16 @@
     return unicodedb.isdecimal(ord(ch))
 
 @cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL)
+def Py_UNICODE_ISDIGIT(space, ch):
+    """Return 1 or 0 depending on whether ch is a digit character."""
+    return unicodedb.isdigit(ord(ch))
+
+ at cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL)
+def Py_UNICODE_ISNUMERIC(space, ch):
+    """Return 1 or 0 depending on whether ch is a numeric character."""
+    return unicodedb.isnumeric(ord(ch))
+
+ at cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL)
 def Py_UNICODE_ISLOWER(space, ch):
     """Return 1 or 0 depending on whether ch is a lowercase character."""
     return unicodedb.islower(ord(ch))
@@ -113,6 +128,11 @@
     """Return 1 or 0 depending on whether ch is an uppercase character."""
     return unicodedb.isupper(ord(ch))
 
+ at cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL)
+def Py_UNICODE_ISTITLE(space, ch):
+    """Return 1 or 0 depending on whether ch is a titlecase character."""
+    return unicodedb.istitle(ord(ch))
+
 @cpython_api([Py_UNICODE], Py_UNICODE, error=CANNOT_FAIL)
 def Py_UNICODE_TOLOWER(space, ch):
     """Return the character ch converted to lower case."""
@@ -155,6 +175,11 @@
     except KeyError:
         return -1.0
 
+ at cpython_api([], Py_UNICODE, error=CANNOT_FAIL)
+def PyUnicode_GetMax(space):
+    """Get the maximum ordinal for a Unicode character."""
+    return unichr(runicode.MAXUNICODE)
+
 @cpython_api([PyObject], rffi.CCHARP, error=CANNOT_FAIL)
 def PyUnicode_AS_DATA(space, ref):
     """Return a pointer to the internal buffer of the object. o has to be a
@@ -395,6 +420,16 @@
     w_str = space.wrap(rffi.charpsize2str(s, size))
     return space.call_method(w_str, 'decode', space.wrap("utf-8"))
 
+ at cpython_api([rffi.INT_real], PyObject)
+def PyUnicode_FromOrdinal(space, ordinal):
+    """Create a Unicode Object from the given Unicode code point ordinal.
+
+    The ordinal must be in range(0x10000) on narrow Python builds
+    (UCS2), and range(0x110000) on wide builds (UCS4). A ValueError is
+    raised in case it is not."""
+    w_ordinal = space.wrap(rffi.cast(lltype.Signed, ordinal))
+    return space.call_function(space.builtin.get('unichr'), w_ordinal)
+
 @cpython_api([PyObjectP, Py_ssize_t], rffi.INT_real, error=-1)
 def PyUnicode_Resize(space, ref, newsize):
     # XXX always create a new string so far
@@ -538,6 +573,28 @@
 
 @cpython_api([PyObject, PyObject], PyObject)
 def PyUnicode_Join(space, w_sep, w_seq):
-    """Join a sequence of strings using the given separator and return the resulting
-    Unicode string."""
+    """Join a sequence of strings using the given separator and return
+    the resulting Unicode string."""
     return space.call_method(w_sep, 'join', w_seq)
+
+ at cpython_api([PyObject, PyObject, PyObject, Py_ssize_t], PyObject)
+def PyUnicode_Replace(space, w_str, w_substr, w_replstr, maxcount):
+    """Replace at most maxcount occurrences of substr in str with replstr and
+    return the resulting Unicode object. maxcount == -1 means replace all
+    occurrences."""
+    return space.call_method(w_str, "replace", w_substr, w_replstr,
+                             space.wrap(maxcount))
+
+ at cpython_api([PyObject, PyObject, Py_ssize_t, Py_ssize_t, rffi.INT_real],
+             rffi.INT_real, error=-1)
+def PyUnicode_Tailmatch(space, w_str, w_substr, start, end, direction):
+    """Return 1 if substr matches str[start:end] at the given tail end
+    (direction == -1 means to do a prefix match, direction == 1 a
+    suffix match), 0 otherwise. Return -1 if an error occurred."""
+    str = space.unicode_w(w_str)
+    substr = space.unicode_w(w_substr)
+    if rffi.cast(lltype.Signed, direction) >= 0:
+        return stringtype.stringstartswith(str, substr, start, end)
+    else:
+        return stringtype.stringendswith(str, substr, start, end)
+
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
@@ -67,10 +67,12 @@
         ("arccos", "arccos"),
         ("arcsin", "arcsin"),
         ("arctan", "arctan"),
+        ("arccosh", "arccosh"),
         ("arcsinh", "arcsinh"),
         ("arctanh", "arctanh"),
         ("copysign", "copysign"),
         ("cos", "cos"),
+        ("cosh", "cosh"),
         ("divide", "divide"),
         ("true_divide", "true_divide"),
         ("equal", "equal"),
@@ -90,9 +92,11 @@
         ("reciprocal", "reciprocal"),
         ("sign", "sign"),
         ("sin", "sin"),
+        ("sinh", "sinh"),
         ("subtract", "subtract"),
         ('sqrt', 'sqrt'),
         ("tan", "tan"),
+        ("tanh", "tanh"),
         ('bitwise_and', 'bitwise_and'),
         ('bitwise_or', 'bitwise_or'),
         ('bitwise_xor', 'bitwise_xor'),
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
@@ -1,6 +1,6 @@
 from pypy.interpreter.baseobjspace import Wrappable
 from pypy.interpreter.error import operationerrfmt
-from pypy.interpreter.gateway import interp2app
+from pypy.interpreter.gateway import interp2app, unwrap_spec
 from pypy.interpreter.typedef import TypeDef
 from pypy.objspace.std.floattype import float_typedef
 from pypy.objspace.std.inttype import int_typedef
@@ -29,7 +29,6 @@
     def convert_to(self, dtype):
         return dtype.box(self.value)
 
-
 class W_GenericBox(Wrappable):
     _attrs_ = ()
 
@@ -39,10 +38,10 @@
         )
 
     def descr_str(self, space):
-        return self.descr_repr(space)
+        return space.wrap(self.get_dtype(space).itemtype.str_format(self))
 
-    def descr_repr(self, space):
-        return space.wrap(self.get_dtype(space).itemtype.str_format(self))
+    def descr_format(self, space, w_spec):
+        return space.format(self.item(space), w_spec)
 
     def descr_int(self, space):
         box = self.convert_to(W_LongBox.get_dtype(space))
@@ -190,6 +189,10 @@
     descr__new__, get_dtype = new_dtype_getter("float64")
 
 
+ at unwrap_spec(self=W_GenericBox)
+def descr_index(space, self):
+    return space.index(self.item(space))
+
 
 W_GenericBox.typedef = TypeDef("generic",
     __module__ = "numpypy",
@@ -197,7 +200,8 @@
     __new__ = interp2app(W_GenericBox.descr__new__.im_func),
 
     __str__ = interp2app(W_GenericBox.descr_str),
-    __repr__ = interp2app(W_GenericBox.descr_repr),
+    __repr__ = interp2app(W_GenericBox.descr_str),
+    __format__ = interp2app(W_GenericBox.descr_format),
     __int__ = interp2app(W_GenericBox.descr_int),
     __float__ = interp2app(W_GenericBox.descr_float),
     __nonzero__ = interp2app(W_GenericBox.descr_nonzero),
@@ -248,6 +252,8 @@
 W_BoolBox.typedef = TypeDef("bool_", W_GenericBox.typedef,
     __module__ = "numpypy",
     __new__ = interp2app(W_BoolBox.descr__new__.im_func),
+
+    __index__ = interp2app(descr_index),
 )
 
 W_NumberBox.typedef = TypeDef("number", W_GenericBox.typedef,
@@ -269,36 +275,43 @@
 W_Int8Box.typedef = TypeDef("int8", W_SignedIntegerBox.typedef,
     __module__ = "numpypy",
     __new__ = interp2app(W_Int8Box.descr__new__.im_func),
+    __index__ = interp2app(descr_index),
 )
 
 W_UInt8Box.typedef = TypeDef("uint8", W_UnsignedIntegerBox.typedef,
     __module__ = "numpypy",
     __new__ = interp2app(W_UInt8Box.descr__new__.im_func),
+    __index__ = interp2app(descr_index),
 )
 
 W_Int16Box.typedef = TypeDef("int16", W_SignedIntegerBox.typedef,
     __module__ = "numpypy",
     __new__ = interp2app(W_Int16Box.descr__new__.im_func),
+    __index__ = interp2app(descr_index),
 )
 
 W_UInt16Box.typedef = TypeDef("uint16", W_UnsignedIntegerBox.typedef,
     __module__ = "numpypy",
     __new__ = interp2app(W_UInt16Box.descr__new__.im_func),
+    __index__ = interp2app(descr_index),
 )
 
 W_Int32Box.typedef = TypeDef("int32", (W_SignedIntegerBox.typedef,) + MIXIN_32,
     __module__ = "numpypy",
     __new__ = interp2app(W_Int32Box.descr__new__.im_func),
+    __index__ = interp2app(descr_index),
 )
 
 W_UInt32Box.typedef = TypeDef("uint32", W_UnsignedIntegerBox.typedef,
     __module__ = "numpypy",
     __new__ = interp2app(W_UInt32Box.descr__new__.im_func),
+    __index__ = interp2app(descr_index),
 )
 
 W_Int64Box.typedef = TypeDef("int64", (W_SignedIntegerBox.typedef,) + MIXIN_64,
     __module__ = "numpypy",
     __new__ = interp2app(W_Int64Box.descr__new__.im_func),
+    __index__ = interp2app(descr_index),
 )
 
 if LONG_BIT == 32:
@@ -311,6 +324,7 @@
 W_UInt64Box.typedef = TypeDef("uint64", W_UnsignedIntegerBox.typedef,
     __module__ = "numpypy",
     __new__ = interp2app(W_UInt64Box.descr__new__.im_func),
+    __index__ = interp2app(descr_index),
 )
 
 W_InexactBox.typedef = TypeDef("inexact", W_NumberBox.typedef,
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
@@ -1333,6 +1333,7 @@
     nbytes = GetSetProperty(BaseArray.descr_get_nbytes),
 
     T = GetSetProperty(BaseArray.descr_get_transpose),
+    transpose = interp2app(BaseArray.descr_get_transpose),
     flat = GetSetProperty(BaseArray.descr_get_flatiter),
     ravel = interp2app(BaseArray.descr_ravel),
     item = interp2app(BaseArray.descr_item),
diff --git a/pypy/module/micronumpy/interp_support.py b/pypy/module/micronumpy/interp_support.py
--- a/pypy/module/micronumpy/interp_support.py
+++ b/pypy/module/micronumpy/interp_support.py
@@ -3,7 +3,7 @@
 from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.module.micronumpy import interp_dtype
 from pypy.objspace.std.strutil import strip_spaces
-
+from pypy.rlib import jit
 
 FLOAT_SIZE = rffi.sizeof(lltype.Float)
 
@@ -72,11 +72,20 @@
             "string is smaller than requested size"))
         
     a = W_NDimArray(count, [count], dtype=dtype)
-    for i in range(count):
+    fromstring_loop(a, count, dtype, itemsize, s)
+    return space.wrap(a)
+
+fromstring_driver = jit.JitDriver(greens=[], reds=['count', 'i', 'itemsize',
+                                                   'dtype', 's', 'a'])
+
+def fromstring_loop(a, count, dtype, itemsize, s):
+    i = 0
+    while i < count:
+        fromstring_driver.jit_merge_point(a=a, count=count, dtype=dtype,
+                                          itemsize=itemsize, s=s, i=i)
         val = dtype.itemtype.runpack_str(s[i*itemsize:i*itemsize + itemsize])
         a.dtype.setitem(a.storage, i, val)
-        
-    return space.wrap(a)
+        i += 1
 
 @unwrap_spec(s=str, count=int, sep=str)
 def fromstring(space, s, w_dtype=None, count=-1, sep=''):
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
@@ -546,7 +546,11 @@
             ("arcsin", "arcsin", 1, {"promote_to_float": True}),
             ("arccos", "arccos", 1, {"promote_to_float": True}),
             ("arctan", "arctan", 1, {"promote_to_float": True}),
+            ("sinh", "sinh", 1, {"promote_to_float": True}),
+            ("cosh", "cosh", 1, {"promote_to_float": True}),
+            ("tanh", "tanh", 1, {"promote_to_float": True}),
             ("arcsinh", "arcsinh", 1, {"promote_to_float": True}),
+            ("arccosh", "arccosh", 1, {"promote_to_float": True}),
             ("arctanh", "arctanh", 1, {"promote_to_float": True}),
         ]:
             self.add_ufunc(space, *ufunc_def)
diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py
--- a/pypy/module/micronumpy/test/test_dtypes.py
+++ b/pypy/module/micronumpy/test/test_dtypes.py
@@ -371,6 +371,8 @@
         assert type(a[1]) is numpy.float64
         assert numpy.dtype(float).type is numpy.float64
 
+        assert "{:3f}".format(numpy.float64(3)) == "3.000000"
+
         assert numpy.float64(2.0) == 2.0
         assert numpy.float64('23.4') == numpy.float64(23.4)
         raises(ValueError, numpy.float64, '23.2df')
@@ -387,9 +389,9 @@
         assert b.m() == 12
 
     def test_long_as_index(self):
-        skip("waiting for removal of multimethods of __index__")
-        from _numpypy import int_
+        from _numpypy import int_, float64
         assert (1, 2, 3)[int_(1)] == 2
+        raises(TypeError, lambda: (1, 2, 3)[float64(1)])
 
     def test_int(self):
         import sys
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
@@ -1489,6 +1489,7 @@
         a = array((range(10), range(20, 30)))
         b = a.T
         assert(b[:, 0] == a[0, :]).all()
+        assert (a.transpose() == b).all()
 
     def test_flatiter(self):
         from _numpypy import array, flatiter, 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
@@ -310,6 +310,33 @@
         b = arctan(a)
         assert math.isnan(b[0])
 
+    def test_sinh(self):
+        import math
+        from _numpypy import array, sinh
+
+        a = array([-1, 0, 1, float('inf'), float('-inf')])
+        b = sinh(a)
+        for i in range(len(a)):
+            assert b[i] == math.sinh(a[i])
+
+    def test_cosh(self):
+        import math
+        from _numpypy import array, cosh
+
+        a = array([-1, 0, 1, float('inf'), float('-inf')])
+        b = cosh(a)
+        for i in range(len(a)):
+            assert b[i] == math.cosh(a[i])
+
+    def test_tanh(self):
+        import math
+        from _numpypy import array, tanh
+
+        a = array([-1, 0, 1, float('inf'), float('-inf')])
+        b = tanh(a)
+        for i in range(len(a)):
+            assert b[i] == math.tanh(a[i])
+
     def test_arcsinh(self):
         import math
         from _numpypy import arcsinh
@@ -318,6 +345,15 @@
             assert math.asinh(v) == arcsinh(v)
         assert math.isnan(arcsinh(float("nan")))
 
+    def test_arccosh(self):
+        import math
+        from _numpypy import arccosh
+
+        for v in [1.0, 1.1, 2]:
+            assert math.acosh(v) == arccosh(v)
+        for v in [-1.0, 0, .99]:
+            assert math.isnan(arccosh(v))
+
     def test_arctanh(self):
         import math
         from _numpypy import arctanh
diff --git a/pypy/module/micronumpy/test/test_zjit.py b/pypy/module/micronumpy/test/test_zjit.py
--- a/pypy/module/micronumpy/test/test_zjit.py
+++ b/pypy/module/micronumpy/test/test_zjit.py
@@ -479,38 +479,3 @@
                                 'int_sub': 3,
                                 'jump': 1,
                                 'setinteriorfield_raw': 1})
-
-
-class TestNumpyOld(LLJitMixin):
-    def setup_class(cls):
-        py.test.skip("old")
-        from pypy.module.micronumpy.compile import FakeSpace
-        from pypy.module.micronumpy.interp_dtype import get_dtype_cache
-
-        cls.space = FakeSpace()
-        cls.float64_dtype = get_dtype_cache(cls.space).w_float64dtype
-
-    def test_int32_sum(self):
-        py.test.skip("pypy/jit/backend/llimpl.py needs to be changed to "
-                     "deal correctly with int dtypes for this test to "
-                     "work. skip for now until someone feels up to the task")
-        space = self.space
-        float64_dtype = self.float64_dtype
-        int32_dtype = self.int32_dtype
-
-        def f(n):
-            if NonConstant(False):
-                dtype = float64_dtype
-            else:
-                dtype = int32_dtype
-            ar = W_NDimArray(n, [n], dtype=dtype)
-            i = 0
-            while i < n:
-                ar.get_concrete().setitem(i, int32_dtype.box(7))
-                i += 1
-            v = ar.descr_add(space, ar).descr_sum(space)
-            assert isinstance(v, IntObject)
-            return v.intval
-
-        result = self.meta_interp(f, [5], listops=True, backendopt=True)
-        assert result == f(5)
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
@@ -489,10 +489,28 @@
         return math.atan(v)
 
     @simple_unary_op
+    def sinh(self, v):
+        return math.sinh(v)
+
+    @simple_unary_op
+    def cosh(self, v):
+        return math.cosh(v)
+
+    @simple_unary_op
+    def tanh(self, v):
+        return math.tanh(v)
+
+    @simple_unary_op
     def arcsinh(self, v):
         return math.asinh(v)
 
     @simple_unary_op
+    def arccosh(self, v):
+        if v < 1.0:
+            return rfloat.NAN
+        return math.acosh(v)
+
+    @simple_unary_op
     def arctanh(self, v):
         if v == 1.0 or v == -1.0:
             return math.copysign(rfloat.INFINITY, v)
diff --git a/pypy/module/oracle/interp_error.py b/pypy/module/oracle/interp_error.py
--- a/pypy/module/oracle/interp_error.py
+++ b/pypy/module/oracle/interp_error.py
@@ -72,7 +72,7 @@
                         get(space).w_InternalError,
                         space.wrap("No Oracle error?"))
 
-                self.code = codeptr[0]
+                self.code = rffi.cast(lltype.Signed, codeptr[0])
                 self.w_message = config.w_string(space, textbuf)
             finally:
                 lltype.free(codeptr, flavor='raw')
diff --git a/pypy/module/oracle/interp_variable.py b/pypy/module/oracle/interp_variable.py
--- a/pypy/module/oracle/interp_variable.py
+++ b/pypy/module/oracle/interp_variable.py
@@ -359,14 +359,14 @@
         # Verifies that truncation or other problems did not take place on
         # retrieve.
         if self.isVariableLength:
-            if rffi.cast(lltype.Signed, self.returnCode[pos]) != 0:
+            error_code = rffi.cast(lltype.Signed, self.returnCode[pos])
+            if error_code != 0:
                 error = W_Error(space, self.environment,
                                 "Variable_VerifyFetch()", 0)
-                error.code = self.returnCode[pos]
+                error.code = error_code
                 error.message = space.wrap(
                     "column at array pos %d fetched with error: %d" %
-                    (pos,
-                     rffi.cast(lltype.Signed, self.returnCode[pos])))
+                    (pos, error_code))
                 w_error = get(space).w_DatabaseError
 
                 raise OperationError(get(space).w_DatabaseError,
diff --git a/pypy/module/pypyjit/test_pypy_c/test_instance.py b/pypy/module/pypyjit/test_pypy_c/test_instance.py
--- a/pypy/module/pypyjit/test_pypy_c/test_instance.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_instance.py
@@ -201,3 +201,28 @@
         loop, = log.loops_by_filename(self.filepath)
         assert loop.match_by_id("compare", "") # optimized away
 
+    def test_super(self):
+        def main():
+            class A(object):
+                def m(self, x):
+                    return x + 1
+            class B(A):
+                def m(self, x):
+                    return super(B, self).m(x)
+            i = 0
+            while i < 300:
+                i = B().m(i)
+            return i
+
+        log = self.run(main, [])
+        loop, = log.loops_by_filename(self.filepath)
+        assert loop.match("""
+            i78 = int_lt(i72, 300)
+            guard_true(i78, descr=...)
+            guard_not_invalidated(descr=...)
+            i79 = force_token()
+            i80 = force_token()
+            i81 = int_add(i72, 1)
+            --TICK--
+            jump(..., descr=...)
+        """)
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_fastpath.py b/pypy/module/test_lib_pypy/ctypes_tests/test_fastpath.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_fastpath.py
+++ b/pypy/module/test_lib_pypy/ctypes_tests/test_fastpath.py
@@ -97,6 +97,16 @@
         tf_b.errcheck = errcheck
         assert tf_b(-126) == 'hello'
 
+    def test_array_to_ptr(self):
+        ARRAY = c_int * 8
+        func = dll._testfunc_ai8
+        func.restype = POINTER(c_int)
+        func.argtypes = [ARRAY]
+        array = ARRAY(1, 2, 3, 4, 5, 6, 7, 8)
+        ptr = func(array)
+        assert ptr[0] == 1
+        assert ptr[7] == 8
+
 
 class TestFallbackToSlowpath(BaseCTypesTestChecker):
 
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_prototypes.py b/pypy/module/test_lib_pypy/ctypes_tests/test_prototypes.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_prototypes.py
+++ b/pypy/module/test_lib_pypy/ctypes_tests/test_prototypes.py
@@ -246,6 +246,14 @@
         def func(): pass
         CFUNCTYPE(None, c_int * 3)(func)
 
+    def test_array_to_ptr_wrongtype(self):
+        ARRAY = c_byte * 8
+        func = testdll._testfunc_ai8
+        func.restype = POINTER(c_int)
+        func.argtypes = [c_int * 8]
+        array = ARRAY(1, 2, 3, 4, 5, 6, 7, 8)
+        py.test.raises(ArgumentError, "func(array)")
+
 ################################################################
 
 if __name__ == '__main__':
diff --git a/pypy/module/test_lib_pypy/test_datetime.py b/pypy/module/test_lib_pypy/test_datetime.py
--- a/pypy/module/test_lib_pypy/test_datetime.py
+++ b/pypy/module/test_lib_pypy/test_datetime.py
@@ -1,7 +1,10 @@
 """Additional tests for datetime."""
 
+import py
+
 import time
-import datetime
+from lib_pypy import datetime
+import copy
 import os
 
 def test_utcfromtimestamp():
@@ -26,3 +29,18 @@
 def test_utcfromtimestamp_microsecond():
     dt = datetime.datetime.utcfromtimestamp(0)
     assert isinstance(dt.microsecond, int)
+
+
+def test_integer_args():
+    with py.test.raises(TypeError):
+        datetime.datetime(10, 10, 10.)
+    with py.test.raises(TypeError):
+        datetime.datetime(10, 10, 10, 10, 10.)
+    with py.test.raises(TypeError):
+        datetime.datetime(10, 10, 10, 10, 10, 10.)
+
+def test_utcnow_microsecond():
+    dt = datetime.datetime.utcnow()
+    assert type(dt.microsecond) is int
+
+    copy.copy(dt)
diff --git a/pypy/objspace/fake/objspace.py b/pypy/objspace/fake/objspace.py
--- a/pypy/objspace/fake/objspace.py
+++ b/pypy/objspace/fake/objspace.py
@@ -326,4 +326,5 @@
         return w_some_obj()
 FakeObjSpace.sys = FakeModule()
 FakeObjSpace.sys.filesystemencoding = 'foobar'
+FakeObjSpace.sys.defaultencoding = 'ascii'
 FakeObjSpace.builtin = FakeModule()
diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py
--- a/pypy/objspace/flow/flowcontext.py
+++ b/pypy/objspace/flow/flowcontext.py
@@ -410,7 +410,7 @@
         w_new = Constant(newvalue)
         f = self.crnt_frame
         stack_items_w = f.locals_stack_w
-        for i in range(f.valuestackdepth-1, f.nlocals-1, -1):
+        for i in range(f.valuestackdepth-1, f.pycode.co_nlocals-1, -1):
             w_v = stack_items_w[i]
             if isinstance(w_v, Constant):
                 if w_v.value is oldvalue:
diff --git a/pypy/objspace/flow/test/test_framestate.py b/pypy/objspace/flow/test/test_framestate.py
--- a/pypy/objspace/flow/test/test_framestate.py
+++ b/pypy/objspace/flow/test/test_framestate.py
@@ -25,7 +25,7 @@
         dummy = Constant(None)
         #dummy.dummy = True
         arg_list = ([Variable() for i in range(formalargcount)] +
-                    [dummy] * (frame.nlocals - formalargcount))
+                    [dummy] * (frame.pycode.co_nlocals - formalargcount))
         frame.setfastscope(arg_list)
         return frame
 
@@ -42,7 +42,7 @@
     def test_neq_hacked_framestate(self):
         frame = self.getframe(self.func_simple)
         fs1 = FrameState(frame)
-        frame.locals_stack_w[frame.nlocals-1] = Variable()
+        frame.locals_stack_w[frame.pycode.co_nlocals-1] = Variable()
         fs2 = FrameState(frame)
         assert fs1 != fs2
 
@@ -55,7 +55,7 @@
     def test_union_on_hacked_framestates(self):
         frame = self.getframe(self.func_simple)
         fs1 = FrameState(frame)
-        frame.locals_stack_w[frame.nlocals-1] = Variable()
+        frame.locals_stack_w[frame.pycode.co_nlocals-1] = Variable()
         fs2 = FrameState(frame)
         assert fs1.union(fs2) == fs2  # fs2 is more general
         assert fs2.union(fs1) == fs2  # fs2 is more general
@@ -63,7 +63,7 @@
     def test_restore_frame(self):
         frame = self.getframe(self.func_simple)
         fs1 = FrameState(frame)
-        frame.locals_stack_w[frame.nlocals-1] = Variable()
+        frame.locals_stack_w[frame.pycode.co_nlocals-1] = Variable()
         fs1.restoreframe(frame)
         assert fs1 == FrameState(frame)
 
@@ -82,7 +82,7 @@
     def test_getoutputargs(self):
         frame = self.getframe(self.func_simple)
         fs1 = FrameState(frame)
-        frame.locals_stack_w[frame.nlocals-1] = Variable()
+        frame.locals_stack_w[frame.pycode.co_nlocals-1] = Variable()
         fs2 = FrameState(frame)
         outputargs = fs1.getoutputargs(fs2)
         # 'x' -> 'x' is a Variable
@@ -92,16 +92,16 @@
     def test_union_different_constants(self):
         frame = self.getframe(self.func_simple)
         fs1 = FrameState(frame)
-        frame.locals_stack_w[frame.nlocals-1] = Constant(42)
+        frame.locals_stack_w[frame.pycode.co_nlocals-1] = Constant(42)
         fs2 = FrameState(frame)
         fs3 = fs1.union(fs2)
         fs3.restoreframe(frame)
-        assert isinstance(frame.locals_stack_w[frame.nlocals-1], Variable)
-                                 # ^^^ generalized
+        assert isinstance(frame.locals_stack_w[frame.pycode.co_nlocals-1],
+                          Variable)   # generalized
 
     def test_union_spectag(self):
         frame = self.getframe(self.func_simple)
         fs1 = FrameState(frame)
-        frame.locals_stack_w[frame.nlocals-1] = Constant(SpecTag())
+        frame.locals_stack_w[frame.pycode.co_nlocals-1] = Constant(SpecTag())
         fs2 = FrameState(frame)
         assert fs1.union(fs2) is None   # UnionError
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
@@ -142,6 +142,17 @@
             else:
                 return result
 
+    def popitem(self, w_dict):
+        # this is a bad implementation: if we call popitem() repeatedly,
+        # it ends up taking n**2 time, because the next() calls below
+        # will take longer and longer.  But all interesting strategies
+        # provide a better one.
+        space = self.space
+        iterator = self.iter(w_dict)
+        w_key, w_value = iterator.next()
+        self.delitem(w_dict, w_key)
+        return (w_key, w_value)
+
     def clear(self, w_dict):
         strategy = self.space.fromcache(EmptyDictStrategy)
         storage = strategy.get_empty_storage()
diff --git a/pypy/objspace/std/dictproxyobject.py b/pypy/objspace/std/dictproxyobject.py
--- a/pypy/objspace/std/dictproxyobject.py
+++ b/pypy/objspace/std/dictproxyobject.py
@@ -3,7 +3,7 @@
 from pypy.objspace.std.dictmultiobject import W_DictMultiObject, IteratorImplementation
 from pypy.objspace.std.dictmultiobject import DictStrategy
 from pypy.objspace.std.typeobject import unwrap_cell
-from pypy.interpreter.error import OperationError
+from pypy.interpreter.error import OperationError, operationerrfmt
 
 from pypy.rlib import rerased
 
@@ -44,7 +44,8 @@
                 raise
             if not w_type.is_cpytype():
                 raise
-            # xxx obscure workaround: allow cpyext to write to type->tp_dict.
+            # xxx obscure workaround: allow cpyext to write to type->tp_dict
+            # xxx even in the case of a builtin type.
             # xxx like CPython, we assume that this is only done early after
             # xxx the type is created, and we don't invalidate any cache.
             w_type.dict_w[key] = w_value
@@ -86,8 +87,14 @@
                     for (key, w_value) in self.unerase(w_dict.dstorage).dict_w.iteritems()]
 
     def clear(self, w_dict):
-        self.unerase(w_dict.dstorage).dict_w.clear()
-        self.unerase(w_dict.dstorage).mutated(None)
+        space = self.space
+        w_type = self.unerase(w_dict.dstorage)
+        if (not space.config.objspace.std.mutable_builtintypes
+                and not w_type.is_heaptype()):
+            msg = "can't clear dictionary of type '%s'"
+            raise operationerrfmt(space.w_TypeError, msg, w_type.name)
+        w_type.dict_w.clear()
+        w_type.mutated(None)
 
 class DictProxyIteratorImplementation(IteratorImplementation):
     def __init__(self, space, strategy, dictimplementation):
diff --git a/pypy/objspace/std/test/test_dictproxy.py b/pypy/objspace/std/test/test_dictproxy.py
--- a/pypy/objspace/std/test/test_dictproxy.py
+++ b/pypy/objspace/std/test/test_dictproxy.py
@@ -22,6 +22,9 @@
         assert NotEmpty.string == 1
         raises(TypeError, 'NotEmpty.__dict__.setdefault(15, 1)')
 
+        key, value = NotEmpty.__dict__.popitem()
+        assert (key == 'a' and value == 1) or (key == 'b' and value == 4)
+
     def test_dictproxyeq(self):
         class a(object):
             pass
@@ -43,6 +46,11 @@
         assert s1 == s2
         assert s1.startswith('{') and s1.endswith('}')
 
+    def test_immutable_dict_on_builtin_type(self):
+        raises(TypeError, "int.__dict__['a'] = 1")
+        raises(TypeError, int.__dict__.popitem)
+        raises(TypeError, int.__dict__.clear)
+
 class AppTestUserObjectMethodCache(AppTestUserObject):
     def setup_class(cls):
         cls.space = gettestobjspace(
diff --git a/pypy/objspace/std/test/test_typeobject.py b/pypy/objspace/std/test/test_typeobject.py
--- a/pypy/objspace/std/test/test_typeobject.py
+++ b/pypy/objspace/std/test/test_typeobject.py
@@ -993,7 +993,9 @@
         raises(TypeError, setattr, list, 'append', 42)
         raises(TypeError, setattr, list, 'foobar', 42)
         raises(TypeError, delattr, dict, 'keys')
-        
+        raises(TypeError, 'int.__dict__["a"] = 1')
+        raises(TypeError, 'int.__dict__.clear()')
+
     def test_nontype_in_mro(self):
         class OldStyle:
             pass
diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py
--- a/pypy/objspace/std/typeobject.py
+++ b/pypy/objspace/std/typeobject.py
@@ -345,9 +345,9 @@
 
         return w_self._lookup_where(name)
 
+    @unroll_safe
     def lookup_starting_at(w_self, w_starttype, name):
         space = w_self.space
-        # XXX Optimize this with method cache
         look = False
         for w_class in w_self.mro_w:
             if w_class is w_starttype:
diff --git a/pypy/rlib/debug.py b/pypy/rlib/debug.py
--- a/pypy/rlib/debug.py
+++ b/pypy/rlib/debug.py
@@ -19,14 +19,24 @@
         hop.exception_cannot_occur()
         hop.genop('debug_assert', vlist)
 
-def fatalerror(msg, traceback=False):
+def fatalerror(msg):
+    # print the RPython traceback and abort with a fatal error
     from pypy.rpython.lltypesystem import lltype
     from pypy.rpython.lltypesystem.lloperation import llop
-    if traceback:
-        llop.debug_print_traceback(lltype.Void)
+    llop.debug_print_traceback(lltype.Void)
     llop.debug_fatalerror(lltype.Void, msg)
 fatalerror._dont_inline_ = True
-fatalerror._annspecialcase_ = 'specialize:arg(1)'
+fatalerror._jit_look_inside_ = False
+fatalerror._annenforceargs_ = [str]
+
+def fatalerror_notb(msg):
+    # a variant of fatalerror() that doesn't print the RPython traceback
+    from pypy.rpython.lltypesystem import lltype
+    from pypy.rpython.lltypesystem.lloperation import llop
+    llop.debug_fatalerror(lltype.Void, msg)
+fatalerror_notb._dont_inline_ = True
+fatalerror_notb._jit_look_inside_ = False
+fatalerror_notb._annenforceargs_ = [str]
 
 
 class DebugLog(list):
diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py
--- a/pypy/rlib/jit.py
+++ b/pypy/rlib/jit.py
@@ -450,6 +450,7 @@
             assert v in self.reds
         self._alllivevars = dict.fromkeys(
             [name for name in self.greens + self.reds if '.' not in name])
+        self._heuristic_order = {}   # check if 'reds' and 'greens' are ordered
         self._make_extregistryentries()
         self.get_jitcell_at = get_jitcell_at
         self.set_jitcell_at = set_jitcell_at
@@ -461,13 +462,61 @@
     def _freeze_(self):
         return True
 
+    def _check_arguments(self, livevars):
+        assert dict.fromkeys(livevars) == self._alllivevars
+        # check heuristically that 'reds' and 'greens' are ordered as
+        # the JIT will need them to be: first INTs, then REFs, then
+        # FLOATs.
+        if len(self._heuristic_order) < len(livevars):
+            from pypy.rlib.rarithmetic import (r_singlefloat, r_longlong,
+                                               r_ulonglong, r_uint)
+            added = False
+            for var, value in livevars.items():
+                if var not in self._heuristic_order:
+                    if (r_ulonglong is not r_uint and
+                            isinstance(value, (r_longlong, r_ulonglong))):
+                        assert 0, ("should not pass a r_longlong argument for "
+                                   "now, because on 32-bit machines it needs "
+                                   "to be ordered as a FLOAT but on 64-bit "
+                                   "machines as an INT")
+                    elif isinstance(value, (int, long, r_singlefloat)):
+                        kind = '1:INT'
+                    elif isinstance(value, float):
+                        kind = '3:FLOAT'
+                    elif isinstance(value, (str, unicode)) and len(value) != 1:
+                        kind = '2:REF'
+                    elif isinstance(value, (list, dict)):
+                        kind = '2:REF'
+                    elif (hasattr(value, '__class__')
+                          and value.__class__.__module__ != '__builtin__'):
+                        if hasattr(value, '_freeze_'):
+                            continue   # value._freeze_() is better not called
+                        elif getattr(value, '_alloc_flavor_', 'gc') == 'gc':
+                            kind = '2:REF'
+                        else:
+                            kind = '1:INT'
+                    else:
+                        continue
+                    self._heuristic_order[var] = kind
+                    added = True
+            if added:
+                for color in ('reds', 'greens'):
+                    lst = getattr(self, color)
+                    allkinds = [self._heuristic_order.get(name, '?')
+                                for name in lst]
+                    kinds = [k for k in allkinds if k != '?']
+                    assert kinds == sorted(kinds), (
+                        "bad order of %s variables in the jitdriver: "
+                        "must be INTs, REFs, FLOATs; got %r" %
+                        (color, allkinds))
+
     def jit_merge_point(_self, **livevars):
         # special-cased by ExtRegistryEntry
-        assert dict.fromkeys(livevars) == _self._alllivevars
+        _self._check_arguments(livevars)
 
     def can_enter_jit(_self, **livevars):
         # special-cased by ExtRegistryEntry
-        assert dict.fromkeys(livevars) == _self._alllivevars
+        _self._check_arguments(livevars)
 
     def loop_header(self):
         # special-cased by ExtRegistryEntry
diff --git a/pypy/rlib/libffi.py b/pypy/rlib/libffi.py
--- a/pypy/rlib/libffi.py
+++ b/pypy/rlib/libffi.py
@@ -238,7 +238,7 @@
         self = jit.promote(self)
         if argchain.numargs != len(self.argtypes):
             raise TypeError, 'Wrong number of arguments: %d expected, got %d' %\
-                (argchain.numargs, len(self.argtypes))
+                (len(self.argtypes), argchain.numargs)
         ll_args = self._prepare()
         i = 0
         arg = argchain.first
diff --git a/pypy/rlib/objectmodel.py b/pypy/rlib/objectmodel.py
--- a/pypy/rlib/objectmodel.py
+++ b/pypy/rlib/objectmodel.py
@@ -23,9 +23,11 @@
 
 class _Specialize(object):
     def memo(self):
-        """ Specialize functions based on argument values. All arguments has
-        to be constant at the compile time. The whole function call is replaced
-        by a call result then.
+        """ Specialize the function based on argument values.  All arguments
+        have to be either constants or PBCs (i.e. instances of classes with a
+        _freeze_ method returning True).  The function call is replaced by
+        just its result, or in case several PBCs are used, by some fast
+        look-up of the result.
         """
         def decorated_func(func):
             func._annspecialcase_ = 'specialize:memo'
@@ -33,8 +35,8 @@
         return decorated_func
 
     def arg(self, *args):
-        """ Specialize function based on values of given positions of arguments.
-        They must be compile-time constants in order to work.
+        """ Specialize the function based on the values of given positions
+        of arguments.  They must be compile-time constants in order to work.
 
         There will be a copy of provided function for each combination
         of given arguments on positions in args (that can lead to
@@ -82,8 +84,7 @@
         return decorated_func
 
     def ll_and_arg(self, *args):
-        """ This is like ll(), but instead of specializing on all arguments,
-        specializes on only the arguments at the given positions
+        """ This is like ll(), and additionally like arg(...).
         """
         def decorated_func(func):
             func._annspecialcase_ = 'specialize:ll_and_arg' + self._wrap(args)
diff --git a/pypy/rlib/test/test_jit.py b/pypy/rlib/test/test_jit.py
--- a/pypy/rlib/test/test_jit.py
+++ b/pypy/rlib/test/test_jit.py
@@ -2,6 +2,7 @@
 from pypy.conftest import option
 from pypy.rlib.jit import hint, we_are_jitted, JitDriver, elidable_promote
 from pypy.rlib.jit import JitHintError, oopspec, isconstant
+from pypy.rlib.rarithmetic import r_uint
 from pypy.translator.translator import TranslationContext, graphof
 from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin
 from pypy.rpython.lltypesystem import lltype
@@ -146,6 +147,43 @@
         res = self.interpret(f, [-234])
         assert res == 1
 
+    def test_argument_order_ok(self):
+        myjitdriver = JitDriver(greens=['i1', 'r1', 'f1'], reds=[])
+        class A(object):
+            pass
+        myjitdriver.jit_merge_point(i1=42, r1=A(), f1=3.5)
+        # assert did not raise
+
+    def test_argument_order_wrong(self):
+        myjitdriver = JitDriver(greens=['r1', 'i1', 'f1'], reds=[])
+        class A(object):
+            pass
+        e = raises(AssertionError,
+                   myjitdriver.jit_merge_point, i1=42, r1=A(), f1=3.5)
+
+    def test_argument_order_more_precision_later(self):
+        myjitdriver = JitDriver(greens=['r1', 'i1', 'r2', 'f1'], reds=[])
+        class A(object):
+            pass
+        myjitdriver.jit_merge_point(i1=42, r1=None, r2=None, f1=3.5)
+        e = raises(AssertionError,
+                   myjitdriver.jit_merge_point, i1=42, r1=A(), r2=None, f1=3.5)
+        assert "got ['2:REF', '1:INT', '?', '3:FLOAT']" in repr(e.value)
+
+    def test_argument_order_more_precision_later_2(self):
+        myjitdriver = JitDriver(greens=['r1', 'i1', 'r2', 'f1'], reds=[])
+        class A(object):
+            pass
+        myjitdriver.jit_merge_point(i1=42, r1=None, r2=A(), f1=3.5)
+        e = raises(AssertionError,
+                   myjitdriver.jit_merge_point, i1=42, r1=A(), r2=None, f1=3.5)
+        assert "got ['2:REF', '1:INT', '2:REF', '3:FLOAT']" in repr(e.value)
+
+    def test_argument_order_accept_r_uint(self):
+        # this used to fail on 64-bit, because r_uint == r_ulonglong
+        myjitdriver = JitDriver(greens=['i1'], reds=[])
+        myjitdriver.jit_merge_point(i1=r_uint(42))
+
 
 class TestJITLLtype(BaseTestJIT, LLRtypeMixin):
     pass
diff --git a/pypy/rpython/memory/gc/generation.py b/pypy/rpython/memory/gc/generation.py
--- a/pypy/rpython/memory/gc/generation.py
+++ b/pypy/rpython/memory/gc/generation.py
@@ -41,8 +41,8 @@
 
     # the following values override the default arguments of __init__ when
     # translating to a real backend.
-    TRANSLATION_PARAMS = {'space_size': 8*1024*1024, # XXX adjust
-                          'nursery_size': 896*1024,
+    TRANSLATION_PARAMS = {'space_size': 8*1024*1024,     # 8 MB
+                          'nursery_size': 3*1024*1024,   # 3 MB
                           'min_nursery_size': 48*1024,
                           'auto_nursery_size': True}
 
@@ -92,8 +92,9 @@
         # the GC is fully setup now.  The rest can make use of it.
         if self.auto_nursery_size:
             newsize = nursery_size_from_env()
-            if newsize <= 0:
-                newsize = env.estimate_best_nursery_size()
+            #if newsize <= 0:
+            #    ---disabled--- just use the default value.
+            #    newsize = env.estimate_best_nursery_size()
             if newsize > 0:
                 self.set_nursery_size(newsize)
 
diff --git a/pypy/tool/jitlogparser/parser.py b/pypy/tool/jitlogparser/parser.py
--- a/pypy/tool/jitlogparser/parser.py
+++ b/pypy/tool/jitlogparser/parser.py
@@ -387,7 +387,7 @@
             m = re.search('guard \d+', comm)
             name = m.group(0)
         else:
-            name = comm[2:comm.find(':')-1]
+            name = " ".join(comm[2:].split(" ", 2)[:2])
         if name in dumps:
             bname, start_ofs, dump = dumps[name]
             loop.force_asm = (lambda dump=dump, start_ofs=start_ofs,
diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py
--- a/pypy/tool/release/package.py
+++ b/pypy/tool/release/package.py
@@ -82,6 +82,9 @@
     for file in ['LICENSE', 'README']:
         shutil.copy(str(basedir.join(file)), str(pypydir))
     pypydir.ensure('include', dir=True)
+    if sys.platform == 'win32':
+        shutil.copyfile(str(pypy_c.dirpath().join("libpypy-c.lib")),
+                        str(pypydir.join('include/python27.lib')))
     # we want to put there all *.h and *.inl from trunk/include
     # and from pypy/_interfaces
     includedir = basedir.join('include')
diff --git a/pypy/translator/c/database.py b/pypy/translator/c/database.py
--- a/pypy/translator/c/database.py
+++ b/pypy/translator/c/database.py
@@ -28,11 +28,13 @@
     gctransformer = None
 
     def __init__(self, translator=None, standalone=False,
+                 cpython_extension=False,
                  gcpolicyclass=None,
                  thread_enabled=False,
                  sandbox=False):
         self.translator = translator
         self.standalone = standalone
+        self.cpython_extension = cpython_extension
         self.sandbox    = sandbox
         if gcpolicyclass is None:
             gcpolicyclass = gc.RefcountingGcPolicy
diff --git a/pypy/translator/c/dlltool.py b/pypy/translator/c/dlltool.py
--- a/pypy/translator/c/dlltool.py
+++ b/pypy/translator/c/dlltool.py
@@ -14,11 +14,14 @@
         CBuilder.__init__(self, *args, **kwds)
 
     def getentrypointptr(self):
+        entrypoints = []
         bk = self.translator.annotator.bookkeeper
-        graphs = [bk.getdesc(f).cachedgraph(None) for f, _ in self.functions]
-        return [getfunctionptr(graph) for graph in graphs]
+        for f, _ in self.functions:
+            graph = bk.getdesc(f).getuniquegraph()
+            entrypoints.append(getfunctionptr(graph))
+        return entrypoints
 
-    def gen_makefile(self, targetdir):
+    def gen_makefile(self, targetdir, exe_name=None):
         pass # XXX finish
 
     def compile(self):
diff --git a/pypy/translator/c/extfunc.py b/pypy/translator/c/extfunc.py
--- a/pypy/translator/c/extfunc.py
+++ b/pypy/translator/c/extfunc.py
@@ -106,7 +106,7 @@
     yield ('RPYTHON_EXCEPTION_MATCH',  exceptiondata.fn_exception_match)
     yield ('RPYTHON_TYPE_OF_EXC_INST', exceptiondata.fn_type_of_exc_inst)
     yield ('RPYTHON_RAISE_OSERROR',    exceptiondata.fn_raise_OSError)
-    if not db.standalone:
+    if db.cpython_extension:
         yield ('RPYTHON_PYEXCCLASS2EXC', exceptiondata.fn_pyexcclass2exc)
 
     yield ('RPyExceptionOccurred1',    exctransformer.rpyexc_occured_ptr.value)
diff --git a/pypy/translator/c/gcc/trackgcroot.py b/pypy/translator/c/gcc/trackgcroot.py
--- a/pypy/translator/c/gcc/trackgcroot.py
+++ b/pypy/translator/c/gcc/trackgcroot.py
@@ -471,8 +471,8 @@
         return []
 
     IGNORE_OPS_WITH_PREFIXES = dict.fromkeys([
-        'cmp', 'test', 'set', 'sahf', 'lahf', 'cltd', 'cld', 'std',
-        'rep', 'movs', 'lods', 'stos', 'scas', 'cwtl', 'cwde', 'prefetch',
+        'cmp', 'test', 'set', 'sahf', 'lahf', 'cld', 'std',
+        'rep', 'movs', 'movhp', 'lods', 'stos', 'scas', 'cwde', 'prefetch',
         # floating-point operations cannot produce GC pointers
         'f',
         'cvt', 'ucomi', 'comi', 'subs', 'subp' , 'adds', 'addp', 'xorp',
@@ -484,7 +484,9 @@
         'shl', 'shr', 'sal', 'sar', 'rol', 'ror', 'mul', 'imul', 'div', 'idiv',
         'bswap', 'bt', 'rdtsc',
         'punpck', 'pshufd', 'pcmp', 'pand', 'psllw', 'pslld', 'psllq',
-        'paddq', 'pinsr',
+        'paddq', 'pinsr', 'pmul', 'psrl',
+        # sign-extending moves should not produce GC pointers
+        'cbtw', 'cwtl', 'cwtd', 'cltd', 'cltq', 'cqto',
         # zero-extending moves should not produce GC pointers
         'movz', 
         # locked operations should not move GC pointers, at least so far
@@ -1695,6 +1697,8 @@
             }
             """
         elif self.format in ('elf64', 'darwin64'):
+            if self.format == 'elf64':   # gentoo patch: hardened systems
+                print >> output, "\t.section .note.GNU-stack,\"\",%progbits"
             print >> output, "\t.text"
             print >> output, "\t.globl %s" % _globalname('pypy_asm_stackwalk')
             _variant(elf64='.type pypy_asm_stackwalk, @function',
diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py
--- a/pypy/translator/c/genc.py
+++ b/pypy/translator/c/genc.py
@@ -111,6 +111,7 @@
     _compiled = False
     modulename = None
     split = False
+    cpython_extension = False
     
     def __init__(self, translator, entrypoint, config, gcpolicy=None,
             secondary_entrypoints=()):
@@ -138,6 +139,7 @@
                 raise NotImplementedError("--gcrootfinder=asmgcc requires standalone")
 
         db = LowLevelDatabase(translator, standalone=self.standalone,
+                              cpython_extension=self.cpython_extension,
                               gcpolicyclass=gcpolicyclass,
                               thread_enabled=self.config.translation.thread,
                               sandbox=self.config.translation.sandbox)
@@ -236,6 +238,8 @@
             CBuilder.have___thread = self.translator.platform.check___thread()
         if not self.standalone:
             assert not self.config.translation.instrument
+            if self.cpython_extension:
+                defines['PYPY_CPYTHON_EXTENSION'] = 1
         else:
             defines['PYPY_STANDALONE'] = db.get(pf)
             if self.config.translation.instrument:
@@ -307,13 +311,18 @@
 
 class CExtModuleBuilder(CBuilder):
     standalone = False
+    cpython_extension = True
     _module = None
     _wrapper = None
 
     def get_eci(self):
         from distutils import sysconfig
         python_inc = sysconfig.get_python_inc()
-        eci = ExternalCompilationInfo(include_dirs=[python_inc])
+        eci = ExternalCompilationInfo(
+            include_dirs=[python_inc],
+            includes=["Python.h",
+                      ],
+            )
         return eci.merge(CBuilder.get_eci(self))
 
     def getentrypointptr(self): # xxx
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
@@ -102,6 +102,12 @@
 #endif  /* !PYPY_CPU_HAS_STANDARD_PRECISION */
 
 
+#ifdef PYPY_X86_CHECK_SSE2
+#define PYPY_X86_CHECK_SSE2_DEFINED
+extern void pypy_x86_check_sse2(void);
+#endif
+
+
 /* implementations */
 
 #ifndef PYPY_NOT_MAIN_FILE
@@ -113,4 +119,25 @@
 }
 #  endif
 
+#  ifdef PYPY_X86_CHECK_SSE2
+void pypy_x86_check_sse2(void)
+{
+    //Read the CPU features.
+    int features;
+    asm("mov $1, %%eax\n"
+        "cpuid\n"
+        "mov %%edx, %0"
+        : "=g"(features) : : "eax", "ebx", "edx", "ecx");
+    
+    //Check bits 25 and 26, this indicates SSE2 support
+    if (((features & (1 << 25)) == 0) || ((features & (1 << 26)) == 0))
+    {
+        fprintf(stderr, "Old CPU with no SSE2 support, cannot continue.\n"
+                        "You need to re-translate with "
+                        "'--jit-backend=x86-without-sse2'\n");
+        abort();
+    }
+}
+#  endif
+
 #endif
diff --git a/pypy/translator/c/src/debug_print.c b/pypy/translator/c/src/debug_print.c
--- a/pypy/translator/c/src/debug_print.c
+++ b/pypy/translator/c/src/debug_print.c
@@ -1,3 +1,4 @@
+#define PYPY_NOT_MAIN_FILE
 
 #include <string.h>
 #include <stddef.h>
diff --git a/pypy/translator/c/src/dtoa.c b/pypy/translator/c/src/dtoa.c
--- a/pypy/translator/c/src/dtoa.c
+++ b/pypy/translator/c/src/dtoa.c
@@ -46,13 +46,13 @@
  *     of return type *Bigint all return NULL to indicate a malloc failure.
  *     Similarly, rv_alloc and nrv_alloc (return type char *) return NULL on
  *     failure.  bigcomp now has return type int (it used to be void) and
- *     returns -1 on failure and 0 otherwise.  _Py_dg_dtoa returns NULL
- *     on failure.  _Py_dg_strtod indicates failure due to malloc failure
+ *     returns -1 on failure and 0 otherwise.  __Py_dg_dtoa returns NULL
+ *     on failure.  __Py_dg_strtod indicates failure due to malloc failure
  *     by returning -1.0, setting errno=ENOMEM and *se to s00.
  *
  *  4. The static variable dtoa_result has been removed.  Callers of
- *     _Py_dg_dtoa are expected to call _Py_dg_freedtoa to free
- *     the memory allocated by _Py_dg_dtoa.
+ *     __Py_dg_dtoa are expected to call __Py_dg_freedtoa to free
+ *     the memory allocated by __Py_dg_dtoa.
  *
  *  5. The code has been reformatted to better fit with Python's
  *     C style guide (PEP 7).
@@ -61,7 +61,7 @@
  *     that hasn't been MALLOC'ed, private_mem should only be used when k <=
  *     Kmax.
  *
- *  7. _Py_dg_strtod has been modified so that it doesn't accept strings with
+ *  7. __Py_dg_strtod has been modified so that it doesn't accept strings with
  *     leading whitespace.
  *
  ***************************************************************/
@@ -283,7 +283,7 @@
 #define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
 #define Big1 0xffffffff
 
-/* struct BCinfo is used to pass information from _Py_dg_strtod to bigcomp */
+/* struct BCinfo is used to pass information from __Py_dg_strtod to bigcomp */
 
 typedef struct BCinfo BCinfo;
 struct
@@ -494,7 +494,7 @@
 
 /* convert a string s containing nd decimal digits (possibly containing a
    decimal separator at position nd0, which is ignored) to a Bigint.  This
-   function carries on where the parsing code in _Py_dg_strtod leaves off: on
+   function carries on where the parsing code in __Py_dg_strtod leaves off: on
    entry, y9 contains the result of converting the first 9 digits.  Returns
    NULL on failure. */
 
@@ -1050,7 +1050,7 @@
 }
 
 /* Convert a scaled double to a Bigint plus an exponent.  Similar to d2b,
-   except that it accepts the scale parameter used in _Py_dg_strtod (which
+   except that it accepts the scale parameter used in __Py_dg_strtod (which
    should be either 0 or 2*P), and the normalization for the return value is
    different (see below).  On input, d should be finite and nonnegative, and d
    / 2**scale should be exactly representable as an IEEE 754 double.
@@ -1351,9 +1351,9 @@
 /* The bigcomp function handles some hard cases for strtod, for inputs
    with more than STRTOD_DIGLIM digits.  It's called once an initial
    estimate for the double corresponding to the input string has
-   already been obtained by the code in _Py_dg_strtod.
+   already been obtained by the code in __Py_dg_strtod.
 
-   The bigcomp function is only called after _Py_dg_strtod has found a
+   The bigcomp function is only called after __Py_dg_strtod has found a
    double value rv such that either rv or rv + 1ulp represents the
    correctly rounded value corresponding to the original string.  It
    determines which of these two values is the correct one by
@@ -1368,12 +1368,12 @@
      s0 points to the first significant digit of the input string.
 
      rv is a (possibly scaled) estimate for the closest double value to the
-        value represented by the original input to _Py_dg_strtod.  If
+        value represented by the original input to __Py_dg_strtod.  If
         bc->scale is nonzero, then rv/2^(bc->scale) is the approximation to
         the input value.
 
      bc is a struct containing information gathered during the parsing and
-        estimation steps of _Py_dg_strtod.  Description of fields follows:
+        estimation steps of __Py_dg_strtod.  Description of fields follows:
 
         bc->e0 gives the exponent of the input value, such that dv = (integer
            given by the bd->nd digits of s0) * 10**e0
@@ -1505,7 +1505,7 @@
 }
 
 static double
-_Py_dg_strtod(const char *s00, char **se)
+__Py_dg_strtod(const char *s00, char **se)
 {
     int bb2, bb5, bbe, bd2, bd5, bs2, c, dsign, e, e1, error;
     int esign, i, j, k, lz, nd, nd0, odd, sign;
@@ -1849,7 +1849,7 @@
 
     for(;;) {
 
-        /* This is the main correction loop for _Py_dg_strtod.
+        /* This is the main correction loop for __Py_dg_strtod.
 
            We've got a decimal value tdv, and a floating-point approximation
            srv=rv/2^bc.scale to tdv.  The aim is to determine whether srv is
@@ -2283,7 +2283,7 @@
  */
 
 static void
-_Py_dg_freedtoa(char *s)
+__Py_dg_freedtoa(char *s)
 {
     Bigint *b = (Bigint *)((int *)s - 1);
     b->maxwds = 1 << (b->k = *(int*)b);
@@ -2325,11 +2325,11 @@
  */
 
 /* Additional notes (METD): (1) returns NULL on failure.  (2) to avoid memory
-   leakage, a successful call to _Py_dg_dtoa should always be matched by a
-   call to _Py_dg_freedtoa. */
+   leakage, a successful call to __Py_dg_dtoa should always be matched by a
+   call to __Py_dg_freedtoa. */
 
 static char *
-_Py_dg_dtoa(double dd, int mode, int ndigits,
+__Py_dg_dtoa(double dd, int mode, int ndigits,
             int *decpt, int *sign, char **rve)
 {
     /*  Arguments ndigits, decpt, sign are similar to those
@@ -2926,7 +2926,7 @@
     if (b)
         Bfree(b);
     if (s0)
-        _Py_dg_freedtoa(s0);
+        __Py_dg_freedtoa(s0);
     return NULL;
 }
 
@@ -2947,7 +2947,7 @@
     _PyPy_SET_53BIT_PRECISION_HEADER;
 
     _PyPy_SET_53BIT_PRECISION_START;
-    result = _Py_dg_strtod(s00, se);
+    result = __Py_dg_strtod(s00, se);
     _PyPy_SET_53BIT_PRECISION_END;
     return result;
 }
@@ -2959,14 +2959,14 @@
     _PyPy_SET_53BIT_PRECISION_HEADER;
 
     _PyPy_SET_53BIT_PRECISION_START;
-    result = _Py_dg_dtoa(dd, mode, ndigits, decpt, sign, rve);
+    result = __Py_dg_dtoa(dd, mode, ndigits, decpt, sign, rve);
     _PyPy_SET_53BIT_PRECISION_END;
     return result;
 }
 
 void _PyPy_dg_freedtoa(char *s)
 {
-    _Py_dg_freedtoa(s);
+    __Py_dg_freedtoa(s);
 }
 /* End PYPY hacks */
 
diff --git a/pypy/translator/c/src/exception.h b/pypy/translator/c/src/exception.h
--- a/pypy/translator/c/src/exception.h
+++ b/pypy/translator/c/src/exception.h
@@ -2,7 +2,7 @@
 /************************************************************/
  /***  C header subsection: exceptions                     ***/
 
-#if !defined(PYPY_STANDALONE) && !defined(PYPY_NOT_MAIN_FILE)
+#if defined(PYPY_CPYTHON_EXTENSION) && !defined(PYPY_NOT_MAIN_FILE)
    PyObject *RPythonError;
 #endif 
 
@@ -74,7 +74,7 @@
 	RPyRaiseException(RPYTHON_TYPE_OF_EXC_INST(rexc), rexc);
 }
 
-#ifndef PYPY_STANDALONE
+#ifdef PYPY_CPYTHON_EXTENSION
 void RPyConvertExceptionFromCPython(void)
 {
 	/* convert the CPython exception to an RPython one */
diff --git a/pypy/translator/c/src/g_include.h b/pypy/translator/c/src/g_include.h
--- a/pypy/translator/c/src/g_include.h
+++ b/pypy/translator/c/src/g_include.h
@@ -2,7 +2,7 @@
 /************************************************************/
 /***  C header file for code produced by genc.py          ***/
 
-#ifndef PYPY_STANDALONE
+#ifdef PYPY_CPYTHON_EXTENSION
 #  include "Python.h"
 #  include "compile.h"
 #  include "frameobject.h"
diff --git a/pypy/translator/c/src/g_prerequisite.h b/pypy/translator/c/src/g_prerequisite.h
--- a/pypy/translator/c/src/g_prerequisite.h
+++ b/pypy/translator/c/src/g_prerequisite.h
@@ -5,8 +5,6 @@
 
 #ifdef PYPY_STANDALONE
 #  include "src/commondefs.h"
-#else
-#  include "Python.h"
 #endif
 
 #ifdef _WIN32
diff --git a/pypy/translator/c/src/main.h b/pypy/translator/c/src/main.h
--- a/pypy/translator/c/src/main.h
+++ b/pypy/translator/c/src/main.h
@@ -36,6 +36,9 @@
     RPyListOfString *list;
 
     pypy_asm_stack_bottom();
+#ifdef PYPY_X86_CHECK_SSE2_DEFINED
+    pypy_x86_check_sse2();
+#endif
     instrument_setup();
 
     if (sizeof(void*) != SIZEOF_LONG) {
diff --git a/pypy/translator/c/src/pyobj.h b/pypy/translator/c/src/pyobj.h
--- a/pypy/translator/c/src/pyobj.h
+++ b/pypy/translator/c/src/pyobj.h
@@ -2,7 +2,7 @@
 /************************************************************/
  /***  C header subsection: untyped operations             ***/
   /***  as OP_XXX() macros calling the CPython API          ***/
-
+#ifdef PYPY_CPYTHON_EXTENSION
 
 #define op_bool(r,what) { \
 		int _retval = what; \
@@ -261,3 +261,5 @@
 }
 
 #endif
+
+#endif  /* PYPY_CPYTHON_EXTENSION */
diff --git a/pypy/translator/c/src/support.h b/pypy/translator/c/src/support.h
--- a/pypy/translator/c/src/support.h
+++ b/pypy/translator/c/src/support.h
@@ -104,7 +104,7 @@
 #  define RPyBareItem(array, index)          ((array)[index])
 #endif
 
-#ifndef PYPY_STANDALONE
+#ifdef PYPY_CPYTHON_EXTENSION
 
 /* prototypes */
 
diff --git a/pypy/translator/c/test/test_dlltool.py b/pypy/translator/c/test/test_dlltool.py
--- a/pypy/translator/c/test/test_dlltool.py
+++ b/pypy/translator/c/test/test_dlltool.py
@@ -2,7 +2,6 @@
 from pypy.translator.c.dlltool import DLLDef
 from ctypes import CDLL
 import py
-py.test.skip("fix this if needed")
 
 class TestDLLTool(object):
     def test_basic(self):
@@ -16,8 +15,8 @@
         d = DLLDef('lib', [(f, [int]), (b, [int])])
         so = d.compile()
         dll = CDLL(str(so))
-        assert dll.f(3) == 3
-        assert dll.b(10) == 12
+        assert dll.pypy_g_f(3) == 3
+        assert dll.pypy_g_b(10) == 12
 
     def test_split_criteria(self):
         def f(x):
@@ -28,4 +27,5 @@
 
         d = DLLDef('lib', [(f, [int]), (b, [int])])
         so = d.compile()
-        assert py.path.local(so).dirpath().join('implement.c').check()
+        dirpath = py.path.local(so).dirpath()
+        assert dirpath.join('translator_c_test_test_dlltool.c').check()
diff --git a/pypy/translator/driver.py b/pypy/translator/driver.py
--- a/pypy/translator/driver.py
+++ b/pypy/translator/driver.py
@@ -331,6 +331,7 @@
             raise Exception("stand-alone program entry point must return an "
                             "int (and not, e.g., None or always raise an "
                             "exception).")
+        annotator.complete()
         annotator.simplify()
         return s
 
@@ -558,6 +559,9 @@
                 newsoname = newexename.new(basename=soname.basename)
                 shutil.copy(str(soname), str(newsoname))
                 self.log.info("copied: %s" % (newsoname,))
+                if sys.platform == 'win32':
+                    shutil.copyfile(str(soname.new(ext='lib')),
+                                    str(newsoname.new(ext='lib')))
             self.c_entryp = newexename
         self.log.info('usession directory: %s' % (udir,))
         self.log.info("created: %s" % (self.c_entryp,))
diff --git a/pypy/translator/sandbox/test/test_sandbox.py b/pypy/translator/sandbox/test/test_sandbox.py
--- a/pypy/translator/sandbox/test/test_sandbox.py
+++ b/pypy/translator/sandbox/test/test_sandbox.py
@@ -145,9 +145,9 @@
     g = pipe.stdin
     f = pipe.stdout
     expect(f, g, "ll_os.ll_os_getenv", ("PYPY_GENERATIONGC_NURSERY",), None)
-    if sys.platform.startswith('linux'):  # on Mac, uses another (sandboxsafe) approach
-        expect(f, g, "ll_os.ll_os_open", ("/proc/cpuinfo", 0, 420),
-               OSError(5232, "xyz"))
+    #if sys.platform.startswith('linux'):
+    #    expect(f, g, "ll_os.ll_os_open", ("/proc/cpuinfo", 0, 420),
+    #           OSError(5232, "xyz"))
     expect(f, g, "ll_os.ll_os_getenv", ("PYPY_GC_DEBUG",), None)
     g.close()
     tail = f.read()


More information about the pypy-commit mailing list