[pypy-commit] pypy release-pypy2.7-5.x: merge default into release

mattip pypy.commits at gmail.com
Tue May 30 09:53:11 EDT 2017


Author: Matti Picus <matti.picus at gmail.com>
Branch: release-pypy2.7-5.x
Changeset: r91449:34e9d2c7a2e1
Date: 2017-05-30 16:14 +0300
http://bitbucket.org/pypy/pypy/changeset/34e9d2c7a2e1/

Log:	merge default into release

diff too long, truncating to 2000 out of 52647 lines

diff --git a/.hgignore b/.hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -49,6 +49,11 @@
 ^rpython/translator/goal/target.+-c$
 ^rpython/translator/goal/.+\.exe$
 ^rpython/translator/goal/.+\.dll$
+^rpython/rlib/rvmprof/src/shared/libbacktrace/Makefile$
+^rpython/rlib/rvmprof/src/shared/libbacktrace/config.guess$
+^rpython/rlib/rvmprof/src/shared/libbacktrace/config.h$
+^rpython/rlib/rvmprof/src/shared/libbacktrace/config.log$
+^rpython/rlib/rvmprof/src/shared/libbacktrace/config.status$
 ^pypy/goal/pypy-translation-snapshot$
 ^pypy/goal/pypy-c
 ^pypy/goal/.+\.exe$
@@ -80,5 +85,8 @@
 .hypothesis/
 ^release/
 ^rpython/_cache$
+^\.cache$
 
 pypy/module/cppyy/.+/*\.pcm
+
+
diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -34,3 +34,7 @@
 050d84dd78997f021acf0e133934275d63547cc0 release-pypy2.7-v5.4.1
 0e2d9a73f5a1818d0245d75daccdbe21b2d5c3ef release-pypy2.7-v5.4.1
 aff251e543859ce4508159dd9f1a82a2f553de00 release-pypy2.7-v5.6.0
+fa3249d55d15b9829e1be69cdf45b5a44cec902d release-pypy2.7-v5.7.0
+b16a4363e930f6401bceb499b9520955504c6cb0 release-pypy3.5-v5.7.0
+1aa2d8e03cdfab54b7121e93fda7e98ea88a30bf release-pypy2.7-v5.7.1
+2875f328eae2216a87f3d6f335092832eb031f56 release-pypy3.5-v5.7.1
diff --git a/include/README b/include/README
--- a/include/README
+++ b/include/README
@@ -1,7 +1,11 @@
 This directory contains all the include files needed to build cpython
 extensions with PyPy.  Note that these are just copies of the original headers
-that are in pypy/module/cpyext/include: they are automatically copied from
-there during translation.
+that are in pypy/module/cpyext/{include,parse}: they are automatically copied
+from there during translation.
 
-Moreover, pypy_decl.h and pypy_macros.h are automatically generated, also
-during translation.
+Moreover, some pypy-specific files are automatically generated, also during
+translation. Currently they are:
+* pypy_decl.h
+* pypy_macros.h
+* pypy_numpy.h
+* pypy_structmember_decl.h
diff --git a/lib-python/2.7/distutils/sysconfig_pypy.py b/lib-python/2.7/distutils/sysconfig_pypy.py
--- a/lib-python/2.7/distutils/sysconfig_pypy.py
+++ b/lib-python/2.7/distutils/sysconfig_pypy.py
@@ -61,12 +61,12 @@
 def _init_posix():
     """Initialize the module as appropriate for POSIX systems."""
     g = {}
-    g['CC'] = "gcc -pthread"
-    g['CXX'] = "g++ -pthread"
+    g['CC'] = "cc -pthread"
+    g['CXX'] = "c++ -pthread"
     g['OPT'] = "-DNDEBUG -O2"
     g['CFLAGS'] = "-DNDEBUG -O2"
     g['CCSHARED'] = "-fPIC"
-    g['LDSHARED'] = "gcc -pthread -shared"
+    g['LDSHARED'] = "cc -pthread -shared"
     g['SO'] = [s[0] for s in imp.get_suffixes() if s[2] == imp.C_EXTENSION][0]
     g['AR'] = "ar"
     g['ARFLAGS'] = "rc"
diff --git a/lib-python/2.7/weakref.py b/lib-python/2.7/weakref.py
--- a/lib-python/2.7/weakref.py
+++ b/lib-python/2.7/weakref.py
@@ -36,9 +36,9 @@
 except ImportError:
     def _delitem_if_value_is(d, key, value):
         try:
-            if self.data[key] is value:  # fall-back: there is a potential
+            if d[key] is value:  # fall-back: there is a potential
                 #             race condition in multithreaded programs HERE
-                del self.data[key]
+                del d[key]
         except KeyError:
             pass
 
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
@@ -85,8 +85,9 @@
         res = self.__new__(self)
         ffiarray = self._ffiarray.fromaddress(resarray.buffer, self._length_)
         res._buffer = ffiarray
-        res._base = base
-        res._index = index
+        if base is not None:
+            res._base = base
+            res._index = index
         return res
 
     def _CData_retval(self, resbuffer):
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
@@ -64,8 +64,9 @@
         res = object.__new__(self)
         res.__class__ = self
         res.__dict__['_buffer'] = resbuffer
-        res.__dict__['_base'] = base
-        res.__dict__['_index'] = index
+        if base is not None:
+            res.__dict__['_base'] = base
+            res.__dict__['_index'] = index
         return res
 
     def _CData_retval(self, resbuffer):
diff --git a/lib_pypy/_ctypes/function.py b/lib_pypy/_ctypes/function.py
--- a/lib_pypy/_ctypes/function.py
+++ b/lib_pypy/_ctypes/function.py
@@ -1,4 +1,3 @@
-
 from _ctypes.basics import _CData, _CDataMeta, cdata_from_address
 from _ctypes.primitive import SimpleType, _SimpleCData
 from _ctypes.basics import ArgumentError, keepalive_key
@@ -9,13 +8,16 @@
 import sys
 import traceback
 
-try: from __pypy__ import builtinify
-except ImportError: builtinify = lambda f: f
+
+try:
+    from __pypy__ import builtinify
+except ImportError:
+    builtinify = lambda f: f
 
 # XXX this file needs huge refactoring I fear
 
-PARAMFLAG_FIN   = 0x1
-PARAMFLAG_FOUT  = 0x2
+PARAMFLAG_FIN = 0x1
+PARAMFLAG_FOUT = 0x2
 PARAMFLAG_FLCID = 0x4
 PARAMFLAG_COMBINED = PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID
 
@@ -24,9 +26,9 @@
     PARAMFLAG_FIN,
     PARAMFLAG_FIN | PARAMFLAG_FOUT,
     PARAMFLAG_FIN | PARAMFLAG_FLCID
-    )
+)
 
-WIN64 = sys.platform == 'win32' and sys.maxint == 2**63 - 1
+WIN64 = sys.platform == 'win32' and sys.maxint == 2 ** 63 - 1
 
 
 def get_com_error(errcode, riid, pIunk):
@@ -35,6 +37,7 @@
     from _ctypes import COMError
     return COMError(errcode, None, None)
 
+
 @builtinify
 def call_function(func, args):
     "Only for debugging so far: So that we can call CFunction instances"
@@ -94,14 +97,9 @@
                         "item %d in _argtypes_ has no from_param method" % (
                             i + 1,))
             self._argtypes_ = list(argtypes)
-            self._check_argtypes_for_fastpath()
+
     argtypes = property(_getargtypes, _setargtypes)
 
-    def _check_argtypes_for_fastpath(self):
-        if all([hasattr(argtype, '_ffiargshape_') for argtype in self._argtypes_]):
-            fastpath_cls = make_fastpath_subclass(self.__class__)
-            fastpath_cls.enable_fastpath_maybe(self)
-
     def _getparamflags(self):
         return self._paramflags
 
@@ -126,27 +124,26 @@
                 raise TypeError(
                     "paramflags must be a sequence of (int [,string [,value]]) "
                     "tuples"
-                    )
+                )
             if not isinstance(flag, int):
                 raise TypeError(
                     "paramflags must be a sequence of (int [,string [,value]]) "
                     "tuples"
-                    )
+                )
             _flag = flag & PARAMFLAG_COMBINED
             if _flag == PARAMFLAG_FOUT:
                 typ = self._argtypes_[idx]
                 if getattr(typ, '_ffiargshape_', None) not in ('P', 'z', 'Z'):
                     raise TypeError(
                         "'out' parameter %d must be a pointer type, not %s"
-                        % (idx+1, type(typ).__name__)
-                        )
+                        % (idx + 1, type(typ).__name__)
+                    )
             elif _flag not in VALID_PARAMFLAGS:
                 raise TypeError("paramflag value %d not supported" % flag)
         self._paramflags = paramflags
 
     paramflags = property(_getparamflags, _setparamflags)
 
-
     def _getrestype(self):
         return self._restype_
 
@@ -156,7 +153,7 @@
             from ctypes import c_int
             restype = c_int
         if not (isinstance(restype, _CDataMeta) or restype is None or
-                callable(restype)):
+                    callable(restype)):
             raise TypeError("restype must be a type, a callable, or None")
         self._restype_ = restype
 
@@ -168,15 +165,18 @@
 
     def _geterrcheck(self):
         return getattr(self, '_errcheck_', None)
+
     def _seterrcheck(self, errcheck):
         if not callable(errcheck):
             raise TypeError("The errcheck attribute must be callable")
         self._errcheck_ = errcheck
+
     def _delerrcheck(self):
         try:
             del self._errcheck_
         except AttributeError:
             pass
+
     errcheck = property(_geterrcheck, _seterrcheck, _delerrcheck)
 
     def _ffishapes(self, args, restype):
@@ -188,7 +188,7 @@
                 raise TypeError("invalid result type for callback function")
             restype = restype._ffiargshape_
         else:
-            restype = 'O' # void
+            restype = 'O'  # void
         return argtypes, restype
 
     def _set_address(self, address):
@@ -201,7 +201,7 @@
 
     def __init__(self, *args):
         self.name = None
-        self._objects = {keepalive_key(0):self}
+        self._objects = {keepalive_key(0): self}
         self._needs_free = True
 
         # Empty function object -- this is needed for casts
@@ -222,10 +222,8 @@
             if self._argtypes_ is None:
                 self._argtypes_ = []
             self._ptr = self._getfuncptr_fromaddress(self._argtypes_, restype)
-            self._check_argtypes_for_fastpath()
             return
 
-
         # A callback into python
         if callable(argument) and not argsl:
             self.callable = argument
@@ -259,7 +257,7 @@
         if (sys.platform == 'win32' and isinstance(argument, (int, long))
             and argsl):
             ffiargs, ffires = self._ffishapes(self._argtypes_, self._restype_)
-            self._com_index =  argument + 0x1000
+            self._com_index = argument + 0x1000
             self.name = argsl.pop(0)
             if argsl:
                 self.paramflags = argsl.pop(0)
@@ -281,6 +279,7 @@
             except SystemExit as e:
                 handle_system_exit(e)
                 raise
+
         return f
 
     def __call__(self, *args, **kwargs):
@@ -317,7 +316,7 @@
             except:
                 exc_info = sys.exc_info()
                 traceback.print_tb(exc_info[2], file=sys.stderr)
-                print >>sys.stderr, "%s: %s" % (exc_info[0].__name__, exc_info[1])
+                print >> sys.stderr, "%s: %s" % (exc_info[0].__name__, exc_info[1])
                 return 0
             if self._restype_ is not None:
                 return res
@@ -328,7 +327,7 @@
             # really slow".  Now we don't worry that much about slowness
             # of ctypes, and it's strange to get warnings for perfectly-
             # legal code.
-            #warnings.warn('C function without declared arguments called',
+            # warnings.warn('C function without declared arguments called',
             #              RuntimeWarning, stacklevel=2)
             argtypes = []
 
@@ -337,7 +336,7 @@
             if not args:
                 raise ValueError(
                     "native COM method call without 'this' parameter"
-                    )
+                )
             thisvalue = args[0]
             thisarg = cast(thisvalue, POINTER(POINTER(c_void_p)))
             keepalives, newargs, argtypes, outargs, errcheckargs = (
@@ -366,7 +365,6 @@
         return tuple(outargs)
 
     def _call_funcptr(self, funcptr, *newargs):
-
         if self._flags_ & _rawffi.FUNCFLAG_USE_ERRNO:
             tmp = _rawffi.get_errno()
             _rawffi.set_errno(get_errno())
@@ -431,7 +429,7 @@
             ffiargs = [argtype.get_ffi_argtype() for argtype in argtypes]
             ffires = restype.get_ffi_argtype()
             return _ffi.FuncPtr.fromaddr(ptr, '', ffiargs, ffires, self._flags_)
-        
+
         cdll = self.dll._handle
         try:
             ffi_argtypes = [argtype.get_ffi_argtype() for argtype in argtypes]
@@ -450,7 +448,7 @@
             # funcname -> _funcname@<n>
             # where n is 0, 4, 8, 12, ..., 128
             for i in range(33):
-                mangled_name = "_%s@%d" % (self.name, i*4)
+                mangled_name = "_%s@%d" % (self.name, i * 4)
                 try:
                     return cdll.getfunc(mangled_name,
                                         ffi_argtypes, ffi_restype,
@@ -492,7 +490,7 @@
         for argtype, arg in zip(argtypes, args):
             param = argtype.from_param(arg)
             _type_ = getattr(argtype, '_type_', None)
-            if _type_ == 'P': # special-case for c_void_p
+            if _type_ == 'P':  # special-case for c_void_p
                 param = param._get_buffer_value()
             elif self._is_primitive(argtype):
                 param = param.value
@@ -668,69 +666,11 @@
             self._needs_free = False
 
 
-def make_fastpath_subclass(CFuncPtr):
-    if CFuncPtr._is_fastpath:
-        return CFuncPtr
-    #
-    try:
-        return make_fastpath_subclass.memo[CFuncPtr]
-    except KeyError:
-        pass
-
-    class CFuncPtrFast(CFuncPtr):
-
-        _is_fastpath = True
-        _slowpath_allowed = True # set to False by tests
-
-        @classmethod
-        def enable_fastpath_maybe(cls, obj):
-            if (obj.callable is None and
-                obj._com_index is None):
-                obj.__class__ = cls
-
-        def __rollback(self):
-            assert self._slowpath_allowed
-            self.__class__ = CFuncPtr
-
-        # disable the fast path if we reset argtypes
-        def _setargtypes(self, argtypes):
-            self.__rollback()
-            self._setargtypes(argtypes)
-        argtypes = property(CFuncPtr._getargtypes, _setargtypes)
-
-        def _setcallable(self, func):
-            self.__rollback()
-            self.callable = func
-        callable = property(lambda x: None, _setcallable)
-
-        def _setcom_index(self, idx):
-            self.__rollback()
-            self._com_index = idx
-        _com_index = property(lambda x: None, _setcom_index)
-
-        def __call__(self, *args):
-            thisarg = None
-            argtypes = self._argtypes_
-            restype = self._restype_
-            funcptr = self._getfuncptr(argtypes, restype, thisarg)
-            try:
-                result = self._call_funcptr(funcptr, *args)
-                result, _ = self._do_errcheck(result, args)
-            except (TypeError, ArgumentError, UnicodeDecodeError):
-                assert self._slowpath_allowed
-                return CFuncPtr.__call__(self, *args)
-            return result
-
-    make_fastpath_subclass.memo[CFuncPtr] = CFuncPtrFast
-    return CFuncPtrFast
-make_fastpath_subclass.memo = {}
-
-
 def handle_system_exit(e):
     # issue #1194: if we get SystemExit here, then exit the interpreter.
     # Highly obscure imho but some people seem to depend on it.
     if sys.flags.inspect:
-        return   # Don't exit if -i flag was given.
+        return  # Don't exit if -i flag was given.
     else:
         code = e.code
         if isinstance(code, int):
diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py
--- a/lib_pypy/_ctypes/structure.py
+++ b/lib_pypy/_ctypes/structure.py
@@ -234,6 +234,9 @@
         if ('_abstract_' in cls.__dict__ or cls is Structure 
                                          or cls is union.Union):
             raise TypeError("abstract class")
+        if hasattr(cls, '_swappedbytes_'):
+            raise NotImplementedError("missing in PyPy: structure/union with "
+                                      "swapped (non-native) byte ordering")
         if hasattr(cls, '_ffistruct_'):
             self.__dict__['_buffer'] = self._ffistruct_(autofree=True)
         return self
diff --git a/lib_pypy/_pypy_winbase_build.py b/lib_pypy/_pypy_winbase_build.py
--- a/lib_pypy/_pypy_winbase_build.py
+++ b/lib_pypy/_pypy_winbase_build.py
@@ -79,10 +79,20 @@
 BOOL WINAPI CreateProcessA(char *, char *, void *,
                            void *, BOOL, DWORD, char *,
                            char *, LPSTARTUPINFO, LPPROCESS_INFORMATION);
+BOOL WINAPI CreateProcessW(wchar_t *, wchar_t *, void *,
+                           void *, BOOL, DWORD, wchar_t *,
+                           wchar_t *, LPSTARTUPINFO, LPPROCESS_INFORMATION);
 DWORD WINAPI WaitForSingleObject(HANDLE, DWORD);
 BOOL WINAPI GetExitCodeProcess(HANDLE, LPDWORD);
 BOOL WINAPI TerminateProcess(HANDLE, UINT);
 HANDLE WINAPI GetStdHandle(DWORD);
+DWORD WINAPI GetModuleFileNameW(HANDLE, wchar_t *, DWORD);
+
+UINT WINAPI SetErrorMode(UINT);
+#define SEM_FAILCRITICALERRORS     0x0001
+#define SEM_NOGPFAULTERRORBOX      0x0002
+#define SEM_NOALIGNMENTFAULTEXCEPT 0x0004
+#define SEM_NOOPENFILEERRORBOX     0x8000
 """)
 
 # --------------------
diff --git a/lib_pypy/_pypy_winbase_cffi.py b/lib_pypy/_pypy_winbase_cffi.py
--- a/lib_pypy/_pypy_winbase_cffi.py
+++ b/lib_pypy/_pypy_winbase_cffi.py
@@ -3,8 +3,8 @@
 
 ffi = _cffi_backend.FFI('_pypy_winbase_cffi',
     _version = 0x2601,
-    _types = b'\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x09\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x19\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x50\x03\x00\x00\x13\x11\x00\x00\x53\x03\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x13\x11\x00\x00\x13\x11\x00\x00\x4F\x03\x00\x00\x4E\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x03\x00\x00\x1F\x11\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x18\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x1F\x11\x00\x00\x0A\x01\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x0D\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x18\x0D\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x18\x0D\x00\x00\x02\x0F\x00\x00\x42\x0D\x00\x00\x06\x01\x00\x00\x00\x0F\x00\x00\x42\x0D\x00\x00\x00\x0F\x00\x00\x42\x0D\x00\x00\x10\x01\x00\x00\x00\x0F\x00\x00\x15\x0D\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x02\x0F\x00\x00\x00\x09\x00\x00\x01\x09\x00\x00\x02\x01\x00\x00\x52\x03\x00\x00\x04\x01\x00\x00\x00\x01',
-    _globals = (b'\x00\x00\x24\x23CloseHandle',0,b'\x00\x00\x1E\x23CreatePipe',0,b'\x00\x00\x12\x23CreateProcessA',0,b'\x00\x00\x2F\x23DuplicateHandle',0,b'\x00\x00\x4C\x23GetCurrentProcess',0,b'\x00\x00\x2B\x23GetExitCodeProcess',0,b'\x00\x00\x49\x23GetStdHandle',0,b'\x00\x00\x3F\x23GetVersion',0,b'\x00\x00\x27\x23TerminateProcess',0,b'\x00\x00\x3B\x23WaitForSingleObject',0,b'\x00\x00\x38\x23_get_osfhandle',0,b'\x00\x00\x10\x23_getch',0,b'\x00\x00\x10\x23_getche',0,b'\x00\x00\x44\x23_getwch',0,b'\x00\x00\x44\x23_getwche',0,b'\x00\x00\x10\x23_kbhit',0,b'\x00\x00\x07\x23_locking',0,b'\x00\x00\x0C\x23_open_osfhandle',0,b'\x00\x00\x00\x23_putch',0,b'\x00\x00\x46\x23_putwch',0,b'\x00\x00\x03\x23_setmode',0,b'\x00\x00\x00\x23_ungetch',0,b'\x00\x00\x41\x23_ungetwch',0),
-    _struct_unions = ((b'\x00\x00\x00\x4E\x00\x00\x00\x02$PROCESS_INFORMATION',b'\x00\x00\x15\x11hProcess',b'\x00\x00\x15\x11hThread',b'\x00\x00\x18\x11dwProcessId',b'\x00\x00\x18\x11dwThreadId'),(b'\x00\x00\x00\x4F\x00\x00\x00\x02$STARTUPINFO',b'\x00\x00\x18\x11cb',b'\x00\x00\x13\x11lpReserved',b'\x00\x00\x13\x11lpDesktop',b'\x00\x00\x13\x11lpTitle',b'\x00\x00\x18\x11dwX',b'\x00\x00\x18\x11dwY',b'\x00\x00\x18\x11dwXSize',b'\x00\x00\x18\x11dwYSize',b'\x00\x00\x18\x11dwXCountChars',b'\x00\x00\x18\x11dwYCountChars',b'\x00\x00\x18\x11dwFillAttribute',b'\x00\x00\x18\x11dwFlags',b'\x00\x00\x42\x11wShowWindow',b'\x00\x00\x42\x11cbReserved2',b'\x00\x00\x51\x11lpReserved2',b'\x00\x00\x15\x11hStdInput',b'\x00\x00\x15\x11hStdOutput',b'\x00\x00\x15\x11hStdError')),
-    _typenames = (b'\x00\x00\x00\x1CLPPROCESS_INFORMATION',b'\x00\x00\x00\x1BLPSTARTUPINFO',b'\x00\x00\x00\x4EPROCESS_INFORMATION',b'\x00\x00\x00\x4FSTARTUPINFO',b'\x00\x00\x00\x42wint_t'),
+    _types = b'\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x09\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x19\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x64\x03\x00\x00\x13\x11\x00\x00\x67\x03\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x13\x11\x00\x00\x13\x11\x00\x00\x63\x03\x00\x00\x62\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x03\x00\x00\x1F\x11\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x18\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x1F\x11\x00\x00\x0A\x01\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x5B\x03\x00\x00\x39\x11\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x39\x11\x00\x00\x39\x11\x00\x00\x1B\x11\x00\x00\x1C\x11\x00\x00\x02\x0F\x00\x00\x0D\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x29\x0D\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x18\x0D\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x18\x0D\x00\x00\x15\x11\x00\x00\x39\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x18\x0D\x00\x00\x02\x0F\x00\x00\x56\x0D\x00\x00\x06\x01\x00\x00\x00\x0F\x00\x00\x56\x0D\x00\x00\x00\x0F\x00\x00\x56\x0D\x00\x00\x10\x01\x00\x00\x00\x0F\x00\x00\x15\x0D\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x02\x0F\x00\x00\x00\x09\x00\x00\x01\x09\x00\x00\x02\x01\x00\x00\x66\x03\x00\x00\x04\x01\x00\x00\x00\x01',
+    _globals = (b'\x00\x00\x24\x23CloseHandle',0,b'\x00\x00\x1E\x23CreatePipe',0,b'\x00\x00\x12\x23CreateProcessA',0,b'\x00\x00\x38\x23CreateProcessW',0,b'\x00\x00\x2F\x23DuplicateHandle',0,b'\x00\x00\x60\x23GetCurrentProcess',0,b'\x00\x00\x2B\x23GetExitCodeProcess',0,b'\x00\x00\x4E\x23GetModuleFileNameW',0,b'\x00\x00\x5D\x23GetStdHandle',0,b'\x00\x00\x53\x23GetVersion',0,b'\xFF\xFF\xFF\x1FSEM_FAILCRITICALERRORS',1,b'\xFF\xFF\xFF\x1FSEM_NOALIGNMENTFAULTEXCEPT',4,b'\xFF\xFF\xFF\x1FSEM_NOGPFAULTERRORBOX',2,b'\xFF\xFF\xFF\x1FSEM_NOOPENFILEERRORBOX',32768,b'\x00\x00\x47\x23SetErrorMode',0,b'\x00\x00\x27\x23TerminateProcess',0,b'\x00\x00\x4A\x23WaitForSingleObject',0,b'\x00\x00\x44\x23_get_osfhandle',0,b'\x00\x00\x10\x23_getch',0,b'\x00\x00\x10\x23_getche',0,b'\x00\x00\x58\x23_getwch',0,b'\x00\x00\x58\x23_getwche',0,b'\x00\x00\x10\x23_kbhit',0,b'\x00\x00\x07\x23_locking',0,b'\x00\x00\x0C\x23_open_osfhandle',0,b'\x00\x00\x00\x23_putch',0,b'\x00\x00\x5A\x23_putwch',0,b'\x00\x00\x03\x23_setmode',0,b'\x00\x00\x00\x23_ungetch',0,b'\x00\x00\x55\x23_ungetwch',0),
+    _struct_unions = ((b'\x00\x00\x00\x62\x00\x00\x00\x02$PROCESS_INFORMATION',b'\x00\x00\x15\x11hProcess',b'\x00\x00\x15\x11hThread',b'\x00\x00\x18\x11dwProcessId',b'\x00\x00\x18\x11dwThreadId'),(b'\x00\x00\x00\x63\x00\x00\x00\x02$STARTUPINFO',b'\x00\x00\x18\x11cb',b'\x00\x00\x13\x11lpReserved',b'\x00\x00\x13\x11lpDesktop',b'\x00\x00\x13\x11lpTitle',b'\x00\x00\x18\x11dwX',b'\x00\x00\x18\x11dwY',b'\x00\x00\x18\x11dwXSize',b'\x00\x00\x18\x11dwYSize',b'\x00\x00\x18\x11dwXCountChars',b'\x00\x00\x18\x11dwYCountChars',b'\x00\x00\x18\x11dwFillAttribute',b'\x00\x00\x18\x11dwFlags',b'\x00\x00\x56\x11wShowWindow',b'\x00\x00\x56\x11cbReserved2',b'\x00\x00\x65\x11lpReserved2',b'\x00\x00\x15\x11hStdInput',b'\x00\x00\x15\x11hStdOutput',b'\x00\x00\x15\x11hStdError')),
+    _typenames = (b'\x00\x00\x00\x1CLPPROCESS_INFORMATION',b'\x00\x00\x00\x1BLPSTARTUPINFO',b'\x00\x00\x00\x62PROCESS_INFORMATION',b'\x00\x00\x00\x63STARTUPINFO',b'\x00\x00\x00\x56wint_t'),
 )
diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -31,10 +31,11 @@
 import weakref
 from threading import _get_ident as _thread_get_ident
 try:
-    from __pypy__ import newlist_hint
+    from __pypy__ import newlist_hint, add_memory_pressure
 except ImportError:
     assert '__pypy__' not in sys.builtin_module_names
     newlist_hint = lambda sizehint: []
+    add_memory_pressure = lambda size: None
 
 if sys.version_info[0] >= 3:
     StandardError = Exception
@@ -150,6 +151,9 @@
 def connect(database, timeout=5.0, detect_types=0, isolation_level="",
                  check_same_thread=True, factory=None, cached_statements=100):
     factory = Connection if not factory else factory
+    # an sqlite3 db seems to be around 100 KiB at least (doesn't matter if
+    # backed by :memory: or a file)
+    add_memory_pressure(100 * 1024)
     return factory(database, timeout, detect_types, isolation_level,
                     check_same_thread, factory, cached_statements)
 
diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -42,8 +42,9 @@
 from rpython.jit.backend import detect_cpu
 try:
     if detect_cpu.autodetect().startswith('x86'):
-        working_modules.add('_vmprof')
-        working_modules.add('faulthandler')
+        if not sys.platform.startswith('openbsd'):
+            working_modules.add('_vmprof')
+            working_modules.add('faulthandler')
 except detect_cpu.ProcessorAutodetectError:
     pass
 
@@ -219,9 +220,6 @@
         BoolOption("withsmalllong", "use a version of 'long' in a C long long",
                    default=False),
 
-        BoolOption("withstrbuf", "use strings optimized for addition (ver 2)",
-                   default=False),
-
         BoolOption("withspecialisedtuple",
                    "use specialised tuples",
                    default=False),
diff --git a/pypy/doc/build.rst b/pypy/doc/build.rst
--- a/pypy/doc/build.rst
+++ b/pypy/doc/build.rst
@@ -79,6 +79,9 @@
 _ssl
     libssl
 
+_vmprof
+    libunwind (optional, loaded dynamically at runtime)
+
 Make sure to have these libraries (with development headers) installed
 before building PyPy, otherwise the resulting binary will not contain
 these modules.  Furthermore, the following libraries should be present
@@ -107,22 +110,22 @@
 
     apt-get install gcc make libffi-dev pkg-config libz-dev libbz2-dev \
     libsqlite3-dev libncurses-dev libexpat1-dev libssl-dev libgdbm-dev \
-    tk-dev libgc-dev \
+    tk-dev libgc-dev python-cffi \
     liblzma-dev  # For lzma on PyPy3.
 
 On Fedora::
 
     dnf install gcc make libffi-devel pkgconfig zlib-devel bzip2-devel \
     sqlite-devel ncurses-devel expat-devel openssl-devel tk-devel \
-    gdbm-devel \
+    gdbm-devel python-cffi\
     xz-devel  # For lzma on PyPy3.
 
 On SLES11::
 
     zypper install gcc make python-devel pkg-config \
     zlib-devel libopenssl-devel libbz2-devel sqlite3-devel \
-    libexpat-devel libffi-devel python-curses \
-    xz-devel  # For lzma on PyPy3.
+    libexpat-devel libffi-devel python-curses python-cffi \
+    xz-devel # For lzma on PyPy3.
     (XXX plus the SLES11 version of libgdbm-dev and tk-dev)
 
 On Mac OS X, most of these build-time dependencies are installed alongside
@@ -185,7 +188,7 @@
 ::
 
     cd pypy/tool/release
-    ./package.py pypy-VER-PLATFORM
+    ./package.py --archive-name=pypy-VER-PLATFORM
 
 This creates a clean and prepared hierarchy, as well as a ``.tar.bz2``
 with the same content; both are found by default in
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
@@ -357,6 +357,24 @@
 
 .. __: https://bitbucket.org/pypy/pypy/issue/1974/different-behaviour-for-collections-of
 
+Performance Differences
+-------------------------
+
+CPython has an optimization that can make repeated string concatenation not
+quadratic. For example, this kind of code runs in O(n) time::
+
+    s = ''
+    for string in mylist:
+        s += string
+
+In PyPy, this code will always have quadratic complexity. Note also, that the
+CPython optimization is brittle and can break by having slight variations in
+your code anyway. So you should anyway replace the code with::
+
+    parts = []
+    for string in mylist:
+        parts.append(string)
+    s = "".join(parts)
 
 Miscellaneous
 -------------
@@ -483,7 +501,14 @@
   the rest is kept.  If you return an unexpected string from
   ``__hex__()`` you get an exception (or a crash before CPython 2.7.13).
 
-* PyPy3: ``__class__`` attritube assignment between heaptypes and non heaptypes.
+* In PyPy, dictionaries passed as ``**kwargs`` can contain only string keys,
+  even for ``dict()`` and ``dict.update()``.  CPython 2.7 allows non-string
+  keys in these two cases (and only there, as far as we know).  E.g. this
+  code produces a ``TypeError``, on CPython 3.x as well as on any PyPy:
+  ``dict(**{1: 2})``.  (Note that ``dict(**d1)`` is equivalent to
+  ``dict(d1)``.)
+
+* PyPy3: ``__class__`` attribute assignment between heaptypes and non heaptypes.
   CPython allows that for module subtypes, but not for e.g. ``int``
   or ``float`` subtypes. Currently PyPy does not support the
   ``__class__`` attribute assignment for any non heaptype subtype.
diff --git a/pypy/doc/index-of-release-notes.rst b/pypy/doc/index-of-release-notes.rst
--- a/pypy/doc/index-of-release-notes.rst
+++ b/pypy/doc/index-of-release-notes.rst
@@ -6,6 +6,7 @@
 
 .. toctree::
 
+   release-v5.7.1.rst
    release-v5.7.0.rst
    release-pypy2.7-v5.6.0.rst
    release-pypy2.7-v5.4.1.rst
@@ -59,6 +60,7 @@
 
 .. toctree::
 
+   release-v5.7.1.rst
    release-v5.7.0.rst
 
 CPython 3.3 compatible versions
diff --git a/pypy/doc/install.rst b/pypy/doc/install.rst
--- a/pypy/doc/install.rst
+++ b/pypy/doc/install.rst
@@ -32,10 +32,10 @@
 
 .. code-block:: console
 
-    $ tar xf pypy-2.1.tar.bz2
-    $ ./pypy-2.1/bin/pypy
-    Python 2.7.3 (480845e6b1dd, Jul 31 2013, 11:05:31)
-    [PyPy 2.1.0 with GCC 4.4.3] on linux2
+    $ tar xf pypy-x.y.z.tar.bz2
+    $ ./pypy-x.y.z/bin/pypy
+    Python 2.7.x (xxxxxxxxxxxx, Date, Time)
+    [PyPy x.y.z with GCC x.y.z] on linux2
     Type "help", "copyright", "credits" or "license" for more information.
     And now for something completely different: ``PyPy is an exciting technology
     that lets you to write fast, portable, multi-platform interpreters with less
@@ -57,6 +57,7 @@
 .. code-block:: console
 
     $ ./pypy-xxx/bin/pypy -m ensurepip
+    $ ./pypy-xxx/bin/pip install -U pip wheel # to upgrade to the latest versions
     $ ./pypy-xxx/bin/pip install pygments  # for example
 
 Third party libraries will be installed in ``pypy-xxx/site-packages``, and
@@ -77,7 +78,17 @@
 	# from the mercurial checkout
 	$ virtualenv -p /path/to/pypy/pypy/translator/goal/pypy-c my-pypy-env
 
-Note that bin/python is now a symlink to bin/pypy.
+	# in any case activate it
+	$ source my-pypy-env/bin/activate
+
+Note that my-pypy-env/bin/python is now a symlink to my-pypy-env/bin/pypy
+so you should be able to run pypy simply by typing::
+
+    $ python
+
+You should still upgrade pip and wheel to the latest versions via::
+
+    $ my-pypy-env/bin/pip install -U pip wheel
 
 .. _pip: http://pypi.python.org/pypi/pip
 .. _ensurepip: https://docs.python.org/2.7/library/ensurepip.html
diff --git a/pypy/doc/release-v5.7.0.rst b/pypy/doc/release-v5.7.0.rst
--- a/pypy/doc/release-v5.7.0.rst
+++ b/pypy/doc/release-v5.7.0.rst
@@ -2,8 +2,11 @@
 PyPy2.7 and PyPy3.5 v5.7 - two in one release
 =============================================
 
-We have released PyPy2.7 v5.7, and a beta-quality PyPy3.5 v5.7 (for
-Linux 64bit only at first).
+The PyPy team is proud to release both PyPy2.7 v5.7 (an interpreter supporting
+Python v2.7 syntax), and a beta-quality PyPy3.5 v5.7 (an interpreter for Python
+v3.5 syntax). The two releases are both based on much the same codebase, thus
+the dual release.  Note that PyPy3.5 supports Linux 64bit only for now. 
+
 This new PyPy2.7 release includes the upstream stdlib version 2.7.13, and
 PyPy3.5 (our first in the 3.5 series) includes the upstream stdlib version
 3.5.3.
@@ -88,14 +91,15 @@
 * New features and cleanups
 
   * update the format of the PYPYLOG file and improvements to vmprof
-  * emit more sysconfig values for downstream cextension packages
+  * emit more sysconfig values for downstream cextension packages including
+    properly setting purelib and platlib to site-packages
   * add ``PyAnySet_Check``, ``PyModule_GetName``, ``PyWeakref_Check*``,
     ``_PyImport_{Acquire,Release}Lock``, ``PyGen_Check*``, ``PyOS_AfterFork``,
   * detect and raise on recreation of a PyPy object from a PyObject during
     tp_dealloc
   * refactor and clean up poor handling of unicode exposed in work on py3.5
   * builtin module cppyy_ supports C++ 11, 14, etc. via cling (reflex has been removed)
-  * adapt ``weakref`` according to CPython issue #19542_, will be in CPython 2.7.14
+  * adapt ``weakref`` according to CPython issue 19542_, will be in CPython 2.7.14
   * support translations with cpyext and the Boehm GC (for special cases like
     RevDB_
   * implement ``StringBuffer.get_raw_address`` for the buffer protocol, it is
@@ -121,16 +125,18 @@
   * disable ``clock_gettime()`` on OS/X, since we support 10.11 and it was only
     added in 10.12
   * support ``HAVE_FSTATVFS`` which was unintentionally always false
-  * fix user-created C-API heaptype, issue #2434_
+  * fix user-created C-API heaptype, issue 2434_
   * fix ``PyDict_Update`` is not actually the same as ``dict.update``
   * assign ``tp_doc`` on ``PyTypeObject`` and tie it to the app-level ``__doc__`` attribute
-    issue #2446_
+    issue 2446_
   * clean up memory leaks around ``PyObject_GetBuffer``, ``PyMemoryView_GET_BUFFER``,
     ``PyMemoryView_FromBuffer``, and ``PyBuffer_Release``
   * improve support for creating C-extension objects from app-level classes,
     filling more slots, especially ``tp_new`` and ``tp_dealloc``
-  * fix for ``ctypes.c_bool`` returning ``bool`` restype, issue #2475_
+  * fix for ``ctypes.c_bool`` returning ``bool`` restype, issue 2475_
   * fix in corner cases with the GIL and C-API functions
+  * allow overriding thread.local.__init__ in a subclass, issue 2501_
+  * allow ``PyClass_New`` to be called with NULL as the first arguemnt, issue 2504_
 
 
 * Performance improvements:
@@ -183,21 +189,19 @@
 * Performance improvements:
 
   * do not create a list whenever ``descr_new`` of a ``bytesobject`` is called
-  * 
-  * 
-  * 
 
 * The following features of Python 3.5 are not implemented yet in PyPy:
 
   * PEP 442: Safe object finalization
   * PEP 489: Multi-phase extension module initialization
-  * XXX what else?
 
 .. _resolved: whatsnew-pypy2-5.7.0.html
 .. _19542: https://bugs.python.org/issue19542
 .. _2434: https://bitbucket.org/pypy/pypy/issues/2434/support-pybind11-in-conjunction-with-pypys
 .. _2446: https://bitbucket.org/pypy/pypy/issues/2446/cpyext-tp_doc-field-not-reflected-on
 .. _2475: https://bitbucket.org/pypy/pypy/issues/2475
+.. _2501: https://bitbucket.org/pypy/pypy/issues/2501
+.. _2504: https://bitbucket.org/pypy/pypy/issues/2504
 .. _RevDB: https://bitbucket.org/pypy/revdb
 .. _cryptography: https://cryptography.io
 .. _cppyy: cppyy.html
diff --git a/pypy/doc/release-v5.7.1.rst b/pypy/doc/release-v5.7.1.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/release-v5.7.1.rst
@@ -0,0 +1,50 @@
+==========
+PyPy 5.7.1
+==========
+
+We have released a bugfix PyPy2.7-v5.7.1 and PyPy3.5-v5.7.1 beta (Linux 64bit),
+due to the following issues:
+
+  * correctly handle an edge case in dict.pop (issue 2508_)
+
+  * fix a regression to correctly handle multiple inheritance in a C-API type
+    where the second base is an app-level class with a ``__new__`` function
+
+  * fix a regression to fill a C-API type's ``tp_getattr`` slot from a
+    ``__getattr__`` method (issue 2523_)
+
+Thanks to those who reported the issues.
+
+.. _2508: https://bitbucket.org/pypy/pypy/issues/2508
+.. _2523: https://bitbucket.org/pypy/pypy/issues/2523
+
+What is PyPy?
+=============
+
+PyPy is a very compliant Python interpreter, almost a drop-in replacement for
+CPython 2.7 and CPython 3.5. It's fast (`PyPy and CPython 2.7.x`_ performance comparison)
+due to its integrated tracing JIT compiler.
+
+We also welcome developers of other `dynamic languages`_ to see what RPython
+can do for them.
+
+The PyPy 2.7 release supports: 
+
+  * **x86** machines on most common operating systems
+    (Linux 32/64 bits, Mac OS X 64 bits, Windows 32 bits, OpenBSD, FreeBSD)
+  
+  * newer **ARM** hardware (ARMv6 or ARMv7, with VFPv3) running Linux,
+  
+  * big- and little-endian variants of **PPC64** running Linux,
+
+  * **s390x** running Linux
+
+.. _`PyPy and CPython 2.7.x`: http://speed.pypy.org
+.. _`dynamic languages`: http://rpython.readthedocs.io/en/latest/examples.html
+
+Please update, and continue to help us make PyPy better.
+
+Cheers
+
+The PyPy Team
+
diff --git a/pypy/doc/test/test_whatsnew.py b/pypy/doc/test/test_whatsnew.py
--- a/pypy/doc/test/test_whatsnew.py
+++ b/pypy/doc/test/test_whatsnew.py
@@ -101,6 +101,8 @@
     assert not not_documented
     if branch == 'default':
         assert not not_merged
+    else:
+        assert branch in documented, 'Please document this branch before merging: %s' % branch
 
 def test_startrev_on_default():
     doc = ROOT.join('pypy', 'doc')
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -2,7 +2,69 @@
 What's new in PyPy2.7 5.8+
 ==========================
 
-.. this is a revision shortly after release-pypy2.7-v5.7
+.. this is a revision shortly after release-pypy2.7-v5.7.0
 .. startrev: 44f31f6dd39f
 
+Add cpyext interfaces for ``PyModule_New``
 
+Correctly handle `dict.pop`` where the ``pop``
+key is not the same type as the ``dict``'s and ``pop``
+is called with a default (will be part of release 5.7.1)
+
+.. branch: issue2522
+
+Fix missing tp_new on w_object called through multiple inheritance
+(will be part of release 5.7.1)
+
+.. branch: lstrip_to_empty_string
+
+.. branch: vmprof-native
+
+PyPy support to profile native frames in vmprof.
+
+.. branch: reusing-r11
+.. branch: branch-prediction
+
+Performance tweaks in the x86 JIT-generated machine code: rarely taken
+blocks are moved off-line.  Also, the temporary register used to contain
+large constants is reused across instructions.
+
+.. branch: vmprof-0.4.4
+
+.. branch: controller-refactor
+
+Refactor rpython.rtyper.controllerentry.
+
+.. branch: PyBuffer-backport
+
+Internal refactoring of buffers and memoryviews. Memoryviews will now be
+accepted in a few more places, e.g. in compile().
+
+.. branch: sthalik/fix-signed-integer-sizes-1494493539409
+
+.. branch: cpyext-obj-stealing
+
+Redo much of the refcount semantics in PyList_{SG}etItem to closer match
+CPython and ensure the same PyObject stored in the list can be later
+retrieved
+
+.. branch: cpyext-recursionlimit
+
+Implement Py_EnterRecursiveCall and associated functions
+
+.. branch: pypy_ctypes_nosegfault_nofastpath
+
+Remove faulty fastpath from ctypes
+
+.. branch: sockopt_zero
+
+Passing a buffersize of 0 to socket.getsockopt
+
+.. branch: better-test-whatsnew
+
+.. branch: faster-rstruct-2
+
+Improve the performance of struct.pack and struct.pack_into by using raw_store
+or gc_store_indexed whenever possible. Moreover, enable the existing
+struct.unpack fast path to all the existing buffer types, whereas previously
+it was enabled only for strings
diff --git a/pypy/doc/windows.rst b/pypy/doc/windows.rst
--- a/pypy/doc/windows.rst
+++ b/pypy/doc/windows.rst
@@ -11,7 +11,7 @@
 
 To build pypy-c you need a working python environment, and a C compiler.
 It is possible to translate with a CPython 2.6 or later, but this is not
-the preferred way, because it will take a lot longer to run – depending
+the preferred way, because it will take a lot longer to run � depending
 on your architecture, between two and three times as long. So head to
 `our downloads`_ and get the latest stable version.
 
@@ -23,11 +23,11 @@
 Installing Visual Compiler v9 (for Python 2.7)
 ----------------------------------------------
 
-This compiler, while the standard one for Python 2.7, is depricated. Microsoft has
+This compiler, while the standard one for Python 2.7, is deprecated. Microsoft has
 made it available as the `Microsoft Visual C++ Compiler for Python 2.7`_ (the link
 was checked in Nov 2016). Note that the compiler suite will be installed in
 ``C:\Users\<user name>\AppData\Local\Programs\Common\Microsoft\Visual C++ for Python``.
-Using a current version of ``setuptools`` will be able to find it there. For
+A current version of ``setuptools`` will be able to find it there. For
 Windows 10, you must right-click the download, and under ``Properties`` ->
 ``Compatibility`` mark it as ``Run run this program in comatibility mode for``
 ``Previous version...``. Also, you must download and install the ``.Net Framework 3.5``,
@@ -40,8 +40,9 @@
 Translating PyPy with Visual Studio
 -----------------------------------
 
-We routinely test translation using Visual Studio 2008, Express
-Edition.  Other configurations may work as well.
+We routinely test translation using v9, also known as Visual Studio 2008.
+Our buildbot is still using the Express Edition, not the compiler noted above.
+Other configurations may work as well.
 
 The translation scripts will set up the appropriate environment variables
 for the compiler, so you do not need to run vcvars before translation.
@@ -117,6 +118,9 @@
 -----------------------------------------------------------
 
 Download the versions of all the external packages from
+https://bitbucket.org/pypy/pypy/downloads/local_5.8.zip
+(for post-5.7.1 builds) with sha256 checksum 
+``fbe769bf3a4ab6f5a8b0a05b61930fc7f37da2a9a85a8f609cf5a9bad06e2554`` or
 https://bitbucket.org/pypy/pypy/downloads/local_2.4.zip
 (for 2.4 release and later) or
 https://bitbucket.org/pypy/pypy/downloads/local.zip
@@ -124,9 +128,9 @@
 Then expand it into the base directory (base_dir) and modify your environment
 to reflect this::
 
-    set PATH=<base_dir>\bin;<base_dir>\tcltk\bin;%PATH%
-    set INCLUDE=<base_dir>\include;<base_dir>\tcltk\include;%INCLUDE%
-    set LIB=<base_dir>\lib;<base_dir>\tcltk\lib;%LIB%
+    set PATH=<base_dir>\bin;%PATH%
+    set INCLUDE=<base_dir>\include;%INCLUDE%
+    set LIB=<base_dir>\lib;%LIB%
 
 Now you should be good to go. If you choose this method, you do not need
 to download/build anything else. 
@@ -173,13 +177,14 @@
 The zlib compression library
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Download http://www.gzip.org/zlib/zlib-1.2.3.tar.gz and extract it in
-the base directory.  Then compile as a static library::
+Download http://www.gzip.org/zlib/zlib-1.2.11.tar.gz and extract it in
+the base directory.  Then compile::
 
-    cd zlib-1.2.3
+    cd zlib-1.2.11
     nmake -f win32\Makefile.msc
     copy zlib.lib <somewhere in LIB>
     copy zlib.h zconf.h <somewhere in INCLUDE>
+    copy zlib1.dll <in PATH> # (needed for tests via ll2ctypes)
 
 
 The bz2 compression library
@@ -198,22 +203,23 @@
 
 PyPy uses cffi to interact with sqlite3.dll. Only the dll is needed, the cffi
 wrapper is compiled when the module is imported for the first time.
-The sqlite3.dll should be version 3.6.21 for CPython2.7 compatablility.
+The sqlite3.dll should be version 3.8.11 for CPython2.7 compatablility.
 
 
 The expat XML parser
 ~~~~~~~~~~~~~~~~~~~~
 
 Download the source code of expat on sourceforge:
-http://sourceforge.net/projects/expat/ and extract it in the base directory.
-Version 2.1.0 is known to pass tests. Then open the project file ``expat.dsw``
+https://github.com/libexpat/libexpat/releases and extract it in the base directory.
+Version 2.1.1 is known to pass tests. Then open the project file ``expat.dsw``
 with Visual Studio; follow the instruction for converting the project files,
 switch to the "Release" configuration, use the ``expat_static`` project,
-reconfigure the runtime for Multi-threaded DLL (/MD) and build.
+reconfigure the runtime for Multi-threaded DLL (/MD) and build. Do the same for
+the ``expat`` project to build the ``expat.dll`` (for tests via ll2ctypes)
 
-Then, copy the file ``win32\bin\release\libexpat.lib`` somewhere in somewhere
-in LIB, and both ``lib\expat.h`` and ``lib\expat_external.h`` somewhere in
-INCLUDE.
+Then, copy the file ``win32\bin\release\libexpat.lib`` into
+LIB, and both ``lib\expat.h`` and ``lib\expat_external.h`` in
+INCLUDE, and ``win32\bin\release\libexpat.dll`` into PATH.
 
 
 The OpenSSL library
@@ -222,16 +228,17 @@
 OpenSSL needs a Perl interpreter to configure its makefile.  You may
 use the one distributed by ActiveState, or the one from cygwin.::
 
-    svn export http://svn.python.org/projects/external/openssl-1.0.1i
-    cd openssl-1.0.1i
+    svn export http://svn.python.org/projects/external/openssl-1.0.2k
+    cd openssl-1.0.2k
     perl Configure VC-WIN32 no-idea no-mdc2
     ms\do_ms.bat
     nmake -f ms\nt.mak install
+    copy out32\*.lib <somewhere in LIB>
+    xcopy /S include\openssl <somewhere in INCLUDE>
 
-Then, copy the files ``out32\*.lib`` somewhere in
-somewhere in LIB, and the entire ``include\openssl`` directory as-is somewhere
-in INCLUDE.
-
+For tests you will also need the dlls::
+    nmake -f ms\ntdll.mak install
+    copy out32dll\*.dll <somewhere in PATH>
 
 TkInter module support
 ~~~~~~~~~~~~~~~~~~~~~~
@@ -241,18 +248,17 @@
 directory found for the release script, create the dlls, libs, headers and
 runtime by running::
 
-	svn export http://svn.python.org/projects/external/tcl-8.5.2.1 tcl85
-	svn export http://svn.python.org/projects/external/tk-8.5.2.0 tk85
-	cd tcl85\win
-	nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=0 INSTALLDIR=..\..\tcltk clean all
-	nmake -f makefile.vc DEBUG=0 INSTALLDIR=..\..\tcltk install
-	cd ..\..\tk85\win
-	nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl85 clean all
-	nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl85 install
-
-Now you should have a tcktk\bin, tcltk\lib, and tcltk\include directory ready
-for use. The release packaging script will pick up the tcltk runtime in the lib
-directory and put it in the archive.
+    svn export http://svn.python.org/projects/external/tcl-8.5.2.1 tcl85
+    svn export http://svn.python.org/projects/external/tk-8.5.2.0 tk85
+    cd tcl85\win
+    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=0 INSTALLDIR=..\..\tcltk clean all
+    nmake -f makefile.vc DEBUG=0 INSTALLDIR=..\..\tcltk install
+    cd ..\..\tk85\win
+    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl85 clean all
+    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl85 install
+    copy ..\..\tcltk\bin\* <somewhere in PATH>
+    copy ..\..\tcltk\lib\*.lib <somewhere in LIB>
+    xcopy /S ..\..\tcltk\include <somewhere in INCLUDE>
 
 The lzma compression library
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -263,6 +269,9 @@
 http://tukaani.org/xz/xz-5.0.5-windows.zip, check the signature
 http://tukaani.org/xz/xz-5.0.5-windows.zip.sig
 
+Then copy the headers to the include directory, rename ``liblzma.a`` to 
+``lzma.lib`` and copy it to the lib directory
+
 
 Using the mingw compiler
 ------------------------
@@ -334,9 +343,9 @@
 integer.  The simplest fix is to make sure that it is so, but it will
 give the following incompatibility between CPython and PyPy on Win64:
 
-CPython: ``sys.maxint == 2**32-1, sys.maxsize == 2**64-1``
+CPython: ``sys.maxint == 2**31-1, sys.maxsize == 2**63-1``
 
-PyPy: ``sys.maxint == sys.maxsize == 2**64-1``
+PyPy: ``sys.maxint == sys.maxsize == 2**63-1``
 
 ...and, correspondingly, PyPy supports ints up to the larger value of
 sys.maxint before they are converted to ``long``.  The first decision
diff --git a/pypy/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py
--- a/pypy/goal/targetpypystandalone.py
+++ b/pypy/goal/targetpypystandalone.py
@@ -264,11 +264,14 @@
                 raise Exception("Cannot use the --output option with PyPy "
                                 "when --shared is on (it is by default). "
                                 "See issue #1971.")
-            if (config.translation.profopt is not None
-                    and not config.translation.noprofopt):
-                raise Exception("Cannot use the --profopt option "
-                                "when --shared is on (it is by default). "
-                                "See issue #2398.")
+
+        # if both profopt and profoptpath are specified then we keep them as they are with no other changes
+        if config.translation.profopt:
+            if config.translation.profoptargs is None:
+                config.translation.profoptargs = "$(RPYDIR)/../lib-python/2.7/test/regrtest.py --pgo -x test_asyncore test_gdb test_multiprocessing test_subprocess || true"
+        elif config.translation.profoptargs is not None:
+            raise Exception("Cannot use --profoptargs without specifying --profopt as well")
+
         if sys.platform == 'win32':
             libdir = thisdir.join('..', '..', 'libs')
             libdir.ensure(dir=1)
@@ -307,6 +310,9 @@
             config.translation.jit = True
 
         if config.translation.sandbox:
+            assert 0, ("--sandbox is not tested nor maintained.  If you "
+                       "really want to try it anyway, remove this line in "
+                       "pypy/goal/targetpypystandalone.py.")
             config.objspace.lonepycfiles = False
 
         if config.objspace.usemodules.cpyext:
diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py
--- a/pypy/interpreter/app_main.py
+++ b/pypy/interpreter/app_main.py
@@ -818,6 +818,11 @@
     executable = sys.pypy_find_executable(executable)
     stdlib_path = sys.pypy_find_stdlib(executable)
     if stdlib_path is None:
+        for lib_path in sys.path:
+            stdlib_path = sys.pypy_find_stdlib(lib_path)
+            if stdlib_path is not None:
+                break
+    if stdlib_path is None:
         print >> sys.stderr, STDLIB_WARNING
     else:
         sys.path[:] = stdlib_path
diff --git a/pypy/interpreter/astcompiler/assemble.py b/pypy/interpreter/astcompiler/assemble.py
--- a/pypy/interpreter/astcompiler/assemble.py
+++ b/pypy/interpreter/astcompiler/assemble.py
@@ -7,6 +7,7 @@
 from pypy.interpreter.astcompiler import ast, misc, symtable
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.pycode import PyCode
+from pypy.interpreter.miscutils import string_sort
 from pypy.tool import stdlib_opcode as ops
 
 
@@ -138,9 +139,12 @@
 
 
 def _make_index_dict_filter(syms, flag):
+    names = syms.keys()
+    string_sort(names)   # return cell vars in alphabetical order
     i = 0
     result = {}
-    for name, scope in syms.iteritems():
+    for name in names:
+        scope = syms[name]
         if scope == flag:
             result[name] = i
             i += 1
@@ -170,6 +174,7 @@
         self.var_names = _list_to_dict(scope.varnames)
         self.cell_vars = _make_index_dict_filter(scope.symbols,
                                                  symtable.SCOPE_CELL)
+        string_sort(scope.free_vars)    # return free vars in alphabetical order
         self.free_vars = _list_to_dict(scope.free_vars, len(self.cell_vars))
         self.w_consts = space.newdict()
         self.argcount = 0
diff --git a/pypy/interpreter/astcompiler/symtable.py b/pypy/interpreter/astcompiler/symtable.py
--- a/pypy/interpreter/astcompiler/symtable.py
+++ b/pypy/interpreter/astcompiler/symtable.py
@@ -36,7 +36,7 @@
         self.roles = {}
         self.varnames = []
         self.children = []
-        self.free_vars = []
+        self.free_vars = []    # a bag of names: the order doesn't matter here
         self.temp_name_counter = 1
         self.has_exec = False
         self.has_free = False
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -9,7 +9,9 @@
 from rpython.rlib.signature import signature
 from rpython.rlib.rarithmetic import r_uint, SHRT_MIN, SHRT_MAX, \
     INT_MIN, INT_MAX, UINT_MAX, USHRT_MAX
+from rpython.rlib.buffer import StringBuffer
 
+from pypy.interpreter.buffer import BufferInterfaceNotFound
 from pypy.interpreter.executioncontext import (ExecutionContext, ActionFlag,
     make_finalizer_queue)
 from pypy.interpreter.error import OperationError, new_exception_class, oefmt
@@ -221,7 +223,8 @@
         if w_impl is not None:
             w_result = space.get_and_call_function(w_impl, self,
                                         space.newint(flags))
-            if space.isinstance_w(w_result, space.w_buffer):
+            if (space.isinstance_w(w_result, space.w_buffer) or
+                    space.isinstance_w(w_result, space.w_memoryview)):
                 return w_result.buffer_w(space, flags)
         raise BufferInterfaceNotFound
 
@@ -233,7 +236,8 @@
         if w_impl is not None:
             w_result = space.get_and_call_function(w_impl, self,
                                         space.newint(space.BUF_FULL_RO))
-            if space.isinstance_w(w_result, space.w_buffer):
+            if (space.isinstance_w(w_result, space.w_buffer) or
+                    space.isinstance_w(w_result, space.w_memoryview)):
                 return w_result.readbuf_w(space)
         raise BufferInterfaceNotFound
 
@@ -245,7 +249,8 @@
         if w_impl is not None:
             w_result = space.get_and_call_function(w_impl, self,
                                         space.newint(space.BUF_FULL))
-            if space.isinstance_w(w_result, space.w_buffer):
+            if (space.isinstance_w(w_result, space.w_buffer) or
+                    space.isinstance_w(w_result, space.w_memoryview)):
                 return w_result.writebuf_w(space)
         raise BufferInterfaceNotFound
 
@@ -254,7 +259,8 @@
         if w_impl is not None:
             w_result = space.get_and_call_function(w_impl, self,
                                         space.newint(space.BUF_FULL_RO))
-            if space.isinstance_w(w_result, space.w_buffer):
+            if (space.isinstance_w(w_result, space.w_buffer) or
+                    space.isinstance_w(w_result, space.w_memoryview)):
                 return w_result.charbuf_w(space)
         raise BufferInterfaceNotFound
 
@@ -392,9 +398,6 @@
 class DescrMismatch(Exception):
     pass
 
-class BufferInterfaceNotFound(Exception):
-    pass
-
 @specialize.memo()
 def wrappable_class_name(Class):
     try:
@@ -1501,18 +1504,28 @@
     def readbuf_w(self, w_obj):
         # Old buffer interface, returns a readonly buffer (PyObject_AsReadBuffer)
         try:
+            return w_obj.buffer_w(self, self.BUF_SIMPLE).as_readbuf()
+        except OperationError:
+            self._getarg_error("convertible to a buffer", w_obj)
+        except BufferInterfaceNotFound:
+            pass
+        try:
             return w_obj.readbuf_w(self)
         except BufferInterfaceNotFound:
-            raise oefmt(self.w_TypeError,
-                        "expected a readable buffer object")
+            self._getarg_error("convertible to a buffer", w_obj)
 
     def writebuf_w(self, w_obj):
         # Old buffer interface, returns a writeable buffer (PyObject_AsWriteBuffer)
         try:
+            return w_obj.buffer_w(self, self.BUF_WRITABLE).as_writebuf()
+        except OperationError:
+            self._getarg_error("read-write buffer", w_obj)
+        except BufferInterfaceNotFound:
+            pass
+        try:
             return w_obj.writebuf_w(self)
         except BufferInterfaceNotFound:
-            raise oefmt(self.w_TypeError,
-                        "expected a writeable buffer object")
+            self._getarg_error("read-write buffer", w_obj)
 
     def charbuf_w(self, w_obj):
         # Old buffer interface, returns a character buffer (PyObject_AsCharBuffer)
@@ -1541,12 +1554,10 @@
             if self.isinstance_w(w_obj, self.w_unicode):
                 return self.str(w_obj).readbuf_w(self)
             try:
-                return w_obj.buffer_w(self, 0)
-            except BufferInterfaceNotFound:
-                pass
-            try:
-                return w_obj.readbuf_w(self)
-            except BufferInterfaceNotFound:
+                return self.readbuf_w(w_obj)
+            except OperationError as e:
+                if not e.match(self, self.w_TypeError):
+                    raise
                 self._getarg_error("string or buffer", w_obj)
         elif code == 's#':
             if self.isinstance_w(w_obj, self.w_bytes):
@@ -1558,16 +1569,7 @@
             except BufferInterfaceNotFound:
                 self._getarg_error("string or read-only buffer", w_obj)
         elif code == 'w*':
-            try:
-                return w_obj.buffer_w(self, self.BUF_WRITABLE)
-            except OperationError:
-                self._getarg_error("read-write buffer", w_obj)
-            except BufferInterfaceNotFound:
-                pass
-            try:
-                return w_obj.writebuf_w(self)
-            except BufferInterfaceNotFound:
-                self._getarg_error("read-write buffer", w_obj)
+            return self.writebuf_w(w_obj)
         elif code == 't#':
             try:
                 return w_obj.charbuf_w(self)
@@ -1654,6 +1656,23 @@
     def fsencode_or_none_w(self, w_obj):
         return None if self.is_none(w_obj) else self.fsencode_w(w_obj)
 
+    def byte_w(self, w_obj):
+        """
+        Convert an index-like object to an interp-level char
+
+        Used for app-level code like "bytearray(b'abc')[0] = 42".
+        """
+        if self.isinstance_w(w_obj, self.w_bytes):
+            string = self.bytes_w(w_obj)
+            if len(string) != 1:
+                raise oefmt(self.w_ValueError, "string must be of size 1")
+            return string[0]
+        value = self.getindex_w(w_obj, None)
+        if not 0 <= value < 256:
+            # this includes the OverflowError in case the long is too large
+            raise oefmt(self.w_ValueError, "byte must be in range(0, 256)")
+        return chr(value)
+
     def int_w(self, w_obj, allow_conversion=True):
         """
         Unwrap an app-level int object into an interpret-level int.
diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py
new file mode 100644
--- /dev/null
+++ b/pypy/interpreter/buffer.py
@@ -0,0 +1,295 @@
+from rpython.rlib.buffer import StringBuffer, SubBuffer
+
+from pypy.interpreter.error import oefmt
+
+class BufferInterfaceNotFound(Exception):
+    pass
+
+
+class BufferView(object):
+    """Abstract base class for buffers."""
+    _attrs_ = ['readonly']
+    _immutable_ = True
+
+    def getlength(self):
+        """Returns the size in bytes (even if getitemsize() > 1)."""
+        raise NotImplementedError
+
+    def as_str(self):
+        "Returns an interp-level string with the whole content of the buffer."
+        return ''.join(self._copy_buffer())
+
+    def getbytes(self, start, size):
+        """Return `size` bytes starting at byte offset `start`.
+
+        This is a low-level operation, it is up to the caller to ensure that
+        the data requested actually correspond to items accessible from the
+        BufferView.
+        Note that `start` may be negative, e.g. if the buffer is reversed.
+        """
+        raise NotImplementedError
+
+    def setbytes(self, start, string):
+        raise NotImplementedError
+
+    def get_raw_address(self):
+        raise ValueError("no raw buffer")
+
+    def as_readbuf(self):
+        # Inefficient. May be overridden.
+        return StringBuffer(self.as_str())
+
+    def as_writebuf(self):
+        """Return a writable Buffer sharing the same data as `self`."""
+        raise BufferInterfaceNotFound
+
+    def getformat(self):
+        raise NotImplementedError
+
+    def getitemsize(self):
+        raise NotImplementedError
+
+    def getndim(self):
+        raise NotImplementedError
+
+    def getshape(self):
+        raise NotImplementedError
+
+    def getstrides(self):
+        raise NotImplementedError
+
+    def releasebuffer(self):
+        pass
+
+    def value_from_bytes(self, space, s):
+        from pypy.module.struct.formatiterator import UnpackFormatIterator
+        buf = StringBuffer(s)
+        fmtiter = UnpackFormatIterator(space, buf)
+        fmtiter.interpret(self.getformat())
+        return fmtiter.result_w[0]
+
+    def _copy_buffer(self):
+        if self.getndim() == 0:
+            itemsize = self.getitemsize()
+            return [self.getbytes(0, itemsize)]
+        data = []
+        self._copy_rec(0, data, 0)
+        return data
+
+    def _copy_rec(self, idim, data, off):
+        shapes = self.getshape()
+        shape = shapes[idim]
+        strides = self.getstrides()
+
+        if self.getndim() - 1 == idim:
+            self._copy_base(data, off)
+            return
+
+        for i in range(shape):
+            self._copy_rec(idim + 1, data, off)
+            off += strides[idim]
+
+    def _copy_base(self, data, off):
+        shapes = self.getshape()
+        step = shapes[0]
+        strides = self.getstrides()
+        itemsize = self.getitemsize()
+        bytesize = self.getlength()
+        copiedbytes = 0
+        for i in range(step):
+            bytes = self.getbytes(off, itemsize)
+            data.append(bytes)
+            copiedbytes += len(bytes)
+            off += strides[0]
+            # do notcopy data if the sub buffer is out of bounds
+            if copiedbytes >= bytesize:
+                break
+
+    def get_offset(self, space, dim, index):
+        "Convert index at dimension `dim` into a byte offset"
+        shape = self.getshape()
+        nitems = shape[dim]
+        if index < 0:
+            index += nitems
+        if index < 0 or index >= nitems:
+            raise oefmt(space.w_IndexError,
+                "index out of bounds on dimension %d", dim + 1)
+        # TODO suboffsets?
+        strides = self.getstrides()
+        return strides[dim] * index
+
+    def w_getitem(self, space, idx):
+        offset = self.get_offset(space, 0, idx)
+        itemsize = self.getitemsize()
+        # TODO: this probably isn't very fast
+        data = self.getbytes(offset, itemsize)
+        return space.newbytes(data)
+
+    def new_slice(self, start, step, slicelength):
+        return BufferSlice(self, start, step, slicelength)
+
+    def w_tolist(self, space):
+        dim = self.getndim()
+        if dim == 0:
+            raise NotImplementedError
+        elif dim == 1:
+            n = self.getshape()[0]
+            values_w = [space.ord(self.w_getitem(space, i)) for i in range(n)]
+            return space.newlist(values_w)
+        else:
+            return self._tolist_rec(space, 0, 0)
+
+    def _tolist_rec(self, space, start, idim):
+        strides = self.getstrides()
+        shape = self.getshape()
+        #
+        dim = idim + 1
+        stride = strides[idim]
+        itemsize = self.getitemsize()
+        dimshape = shape[idim]
+        #
+        if dim >= self.getndim():
+            bytecount = (stride * dimshape)
+            values_w = [
+                self.value_from_bytes(space, self.getbytes(pos, itemsize))
+                for pos in range(start, start + bytecount, stride)]
+            return space.newlist(values_w)
+
+        items = [None] * dimshape
+        for i in range(dimshape):
+            item = self._tolist_rec(space, start, idim + 1)
+            items[i] = item
+            start += stride
+
+        return space.newlist(items)
+
+    def wrap(self, space):
+        return space.newmemoryview(self)
+
+
+class SimpleView(BufferView):
+    _attrs_ = ['readonly', 'data']
+    _immutable_ = True
+
+    def __init__(self, data):
+        self.data = data
+        self.readonly = self.data.readonly
+
+    def getlength(self):
+        return self.data.getlength()
+
+    def as_str(self):
+        return self.data.as_str()
+
+    def getbytes(self, start, size):
+        return self.data[start:start + size]
+
+    def setbytes(self, offset, s):
+        self.data.setslice(offset, s)
+
+    def get_raw_address(self):
+        return self.data.get_raw_address()
+
+    def as_readbuf(self):
+        return self.data
+
+    def as_writebuf(self):
+        assert not self.data.readonly
+        return self.data
+
+    def getformat(self):
+        return 'B'
+
+    def getitemsize(self):
+        return 1
+
+    def getndim(self):
+        return 1
+
+    def getshape(self):
+        return [self.getlength()]
+
+    def getstrides(self):
+        return [1]
+
+    def get_offset(self, space, dim, index):
+        "Convert index at dimension `dim` into a byte offset"
+        assert dim == 0
+        nitems = self.getlength()
+        if index < 0:
+            index += nitems
+        if index < 0 or index >= nitems:
+            raise oefmt(space.w_IndexError,
+                "index out of bounds on dimension %d", dim + 1)
+        return index
+
+    def w_getitem(self, space, idx):
+        idx = self.get_offset(space, 0, idx)
+        ch = self.data[idx]
+        return space.newbytes(ch)
+
+    def new_slice(self, start, step, slicelength):
+        if step == 1:
+            return SimpleView(SubBuffer(self.data, start, slicelength))
+        else:
+            return BufferSlice(self, start, step, slicelength)
+
+
+class BufferSlice(BufferView):
+    _immutable_ = True
+    _attrs_ = ['parent', 'readonly', 'shape', 'strides', 'start', 'step']
+
+    def __init__(self, parent, start, step, length):
+        self.parent = parent
+        self.readonly = self.parent.readonly
+        self.strides = parent.getstrides()[:]
+        self.start = start
+        self.step = step
+        self.strides[0] *= step
+        self.shape = parent.getshape()[:]
+        self.shape[0] = length
+
+    def getlength(self):
+        return self.shape[0] * self.getitemsize()
+
+    def getbytes(self, start, size):
+        offset = self.start * self.parent.getstrides()[0]
+        return self.parent.getbytes(offset + start, size)
+
+    def setbytes(self, start, string):
+        if len(string) == 0:
+            return        # otherwise, adding self.offset might make 'start'
+                          # out of bounds
+        offset = self.start * self.parent.getstrides()[0]
+        self.parent.setbytes(offset + start, string)
+
+    def get_raw_address(self):
+        from rpython.rtyper.lltypesystem import rffi
+        offset = self.start * self.parent.getstrides()[0]
+        return rffi.ptradd(self.parent.get_raw_address(), offset)
+
+    def getformat(self):
+        return self.parent.getformat()
+
+    def getitemsize(self):
+        return self.parent.getitemsize()
+
+    def getndim(self):
+        return self.parent.getndim()
+
+    def getshape(self):
+        return self.shape
+
+    def getstrides(self):
+        return self.strides
+
+    def parent_index(self, idx):
+        return self.start + self.step * idx
+
+    def w_getitem(self, space, idx):
+        return self.parent.w_getitem(space, self.parent_index(idx))
+
+    def new_slice(self, start, step, slicelength):
+        real_start = start + self.start
+        real_step = self.step * step
+        return BufferSlice(self.parent, real_start, real_step, slicelength)
diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py
--- a/pypy/interpreter/miscutils.py
+++ b/pypy/interpreter/miscutils.py
@@ -2,6 +2,9 @@
 Miscellaneous utilities.
 """
 
+from rpython.rlib.listsort import make_timsort_class
+
+
 class ThreadLocals:
     """Pseudo thread-local storage, for 'space.threadlocals'.
     This is not really thread-local at all; the intention is that the PyPy
@@ -53,3 +56,15 @@
             def set(self, key, value):
                 self._dict[key] = value
         return FakeWeakValueDict()
+
+
+_StringBaseTimSort = make_timsort_class()
+
+class StringSort(_StringBaseTimSort):
+    def lt(self, a, b):
+        return a < b
+
+def string_sort(lst):
+    """Sort a (resizable) list of strings."""
+    sorter = StringSort(lst, len(lst))
+    sorter.sort()
diff --git a/pypy/interpreter/pyparser/future.py b/pypy/interpreter/pyparser/future.py
--- a/pypy/interpreter/pyparser/future.py
+++ b/pypy/interpreter/pyparser/future.py
@@ -78,6 +78,7 @@
     from pypy.interpreter.pyparser import pygram
     it = TokenIterator(tokens)
     result = 0
+    last_position = (0, 0)
     #
     # The only things that can precede a future statement are another
     # future statement and a doc string (only one).  This is a very
@@ -92,6 +93,11 @@
            it.skip_name("__future__") and
            it.skip_name("import")):
         it.skip(pygram.tokens.LPAR)    # optionally
+        # return in 'last_position' any line-column pair that points
+        # somewhere inside the last __future__ import statement
+        # (at the start would be fine too, but it's easier to grab a
+        # random position inside)
+        last_position = (it.tok[2], it.tok[3])
         result |= future_flags.get_compiler_feature(it.next_feature_name())
         while it.skip(pygram.tokens.COMMA):
             result |= future_flags.get_compiler_feature(it.next_feature_name())
@@ -99,5 +105,4 @@
         it.skip(pygram.tokens.SEMI)    # optionally
         it.skip_newlines()
 
-    position = (it.tok[2], it.tok[3])
-    return result, position
+    return result, last_position
diff --git a/pypy/interpreter/pyparser/test/test_future.py b/pypy/interpreter/pyparser/test/test_future.py
--- a/pypy/interpreter/pyparser/test/test_future.py
+++ b/pypy/interpreter/pyparser/test/test_future.py
@@ -2,10 +2,9 @@
 from pypy.interpreter.pyparser import future, pytokenizer
 from pypy.tool import stdlib___future__ as fut
 
-def run(s, expected_last_future=None):
+def run(s, expected_last_future=(0, 0)):
     source_lines = s.splitlines(True)
     tokens = pytokenizer.generate_tokens(source_lines, 0)
-    expected_last_future = expected_last_future or tokens[-1][2:4]
     #
     flags, last_future_import = future.add_future_flags(
         future.futureFlags_2_7, tokens)
@@ -14,7 +13,7 @@
 
 def test_docstring():
     s = '"Docstring\\" "\nfrom  __future__ import division\n'
-    f = run(s)
+    f = run(s, (2, 24))
     assert f == fut.CO_FUTURE_DIVISION
 
 def test_comment():
@@ -45,167 +44,167 @@
 
 def test_from():
     s = 'from  __future__ import division\n'
-    f = run(s)
+    f = run(s, (1, 24))
     assert f == fut.CO_FUTURE_DIVISION
 
 def test_froms():
     s = 'from  __future__ import division, generators, with_statement\n'
-    f = run(s)
+    f = run(s, (1, 24))
     assert f == (fut.CO_FUTURE_DIVISION |
                  fut.CO_GENERATOR_ALLOWED |
                  fut.CO_FUTURE_WITH_STATEMENT)
 
 def test_from_as():
     s = 'from  __future__ import division as b\n'
-    f = run(s)
+    f = run(s, (1, 24))
     assert f == fut.CO_FUTURE_DIVISION
     
 def test_froms_as():
     s = 'from  __future__ import division as b, generators as c\n'
-    f = run(s)
+    f = run(s, (1, 24))
     assert f == (fut.CO_FUTURE_DIVISION |
                  fut.CO_GENERATOR_ALLOWED)
 
 def test_from_paren():
     s = 'from  __future__ import (division)\n'
-    f = run(s)
+    f = run(s, (1, 25))
     assert f == fut.CO_FUTURE_DIVISION
 
 def test_froms_paren():
     s = 'from  __future__ import (division, generators)\n'
-    f = run(s)
+    f = run(s, (1, 25))
     assert f == (fut.CO_FUTURE_DIVISION |
                  fut.CO_GENERATOR_ALLOWED)
 
 def test_froms_paren_as():
     s = 'from  __future__ import (division as b, generators,)\n'
-    f = run(s)
+    f = run(s, (1, 25))
     assert f == (fut.CO_FUTURE_DIVISION |
                  fut.CO_GENERATOR_ALLOWED)
 
 def test_paren_with_newline():
     s = 'from __future__ import (division,\nabsolute_import)\n'
-    f = run(s)
+    f = run(s, (1, 24))
     assert f == (fut.CO_FUTURE_DIVISION | fut.CO_FUTURE_ABSOLUTE_IMPORT)
 
 def test_paren_with_newline_2():
     s = 'from __future__ import (\ndivision,\nabsolute_import)\n'
-    f = run(s)
+    f = run(s, (2, 0))
     assert f == (fut.CO_FUTURE_DIVISION | fut.CO_FUTURE_ABSOLUTE_IMPORT)
 
 def test_multiline():
     s = '"abc" #def\n  #ghi\nfrom  __future__ import (division as b, generators,)\nfrom __future__ import with_statement\n'
-    f = run(s)
+    f = run(s, (4, 23))
     assert f == (fut.CO_FUTURE_DIVISION |
                  fut.CO_GENERATOR_ALLOWED |
                  fut.CO_FUTURE_WITH_STATEMENT)
 
 def test_windows_style_lineendings():
     s = '"abc" #def\r\n  #ghi\r\nfrom  __future__ import (division as b, generators,)\r\nfrom __future__ import with_statement\r\n'
-    f = run(s)
+    f = run(s, (4, 23))
     assert f == (fut.CO_FUTURE_DIVISION |
                  fut.CO_GENERATOR_ALLOWED |
                  fut.CO_FUTURE_WITH_STATEMENT)
 
 def test_mac_style_lineendings():
     s = '"abc" #def\r  #ghi\rfrom  __future__ import (division as b, generators,)\rfrom __future__ import with_statement\r'
-    f = run(s)
+    f = run(s, (4, 23))
     assert f == (fut.CO_FUTURE_DIVISION |
                  fut.CO_GENERATOR_ALLOWED |
                  fut.CO_FUTURE_WITH_STATEMENT)
 
 def test_semicolon():
     s = '"abc" #def\n  #ghi\nfrom  __future__ import (division as b, generators,);  from __future__ import with_statement\n'
-    f = run(s)
+    f = run(s, (3, 78))
     assert f == (fut.CO_FUTURE_DIVISION |
                  fut.CO_GENERATOR_ALLOWED |
                  fut.CO_FUTURE_WITH_STATEMENT)
 
 def test_semicolon_2():
     s = 'from  __future__ import division; from foo import bar'
-    f = run(s, expected_last_future=(1, 39))
+    f = run(s, expected_last_future=(1, 24))
     assert f == fut.CO_FUTURE_DIVISION
 
 def test_full_chain():
     s = '"abc" #def\n  #ghi\nfrom  __future__ import (division as b, generators,);  from __future__ import with_statement\n'
-    f = run(s)
+    f = run(s, (3, 78))
     assert f == (fut.CO_FUTURE_DIVISION |
                  fut.CO_GENERATOR_ALLOWED |
                  fut.CO_FUTURE_WITH_STATEMENT)
 
 def test_intervening_code():
     s = 'from  __future__ import (division as b, generators,)\nfrom sys import modules\nfrom __future__ import with_statement\n'
-    f = run(s, expected_last_future=(2, 5))
+    f = run(s, expected_last_future=(1, 25))
     assert f == (fut.CO_FUTURE_DIVISION | fut.CO_GENERATOR_ALLOWED)
 
 def test_nonexisting():
     s = 'from  __future__ import non_existing_feature\n'
-    f = run(s)
+    f = run(s, (1, 24))
     assert f == 0
 
 def test_nonexisting_2():
     s = 'from  __future__ import non_existing_feature, with_statement\n'
-    f = run(s)
+    f = run(s, (1, 24))
     assert f == fut.CO_FUTURE_WITH_STATEMENT
 
 def test_from_import_abs_import():
     s = 'from  __future__ import absolute_import\n'
-    f = run(s)
+    f = run(s, (1, 24))
     assert f == fut.CO_FUTURE_ABSOLUTE_IMPORT
 
 def test_raw_doc():
     s = 'r"Doc"\nfrom __future__ import with_statement\n'
-    f = run(s)
+    f = run(s, (2, 23))
     assert f == fut.CO_FUTURE_WITH_STATEMENT
 
 def test_unicode_doc():
     s = 'u"Doc"\nfrom __future__ import with_statement\n'
-    f = run(s)
+    f = run(s, (2, 23))
     assert f == fut.CO_FUTURE_WITH_STATEMENT
 
 def test_raw_unicode_doc():
     s = 'ru"Doc"\nfrom __future__ import with_statement\n'
-    f = run(s)
+    f = run(s, (2, 23))
     assert f == fut.CO_FUTURE_WITH_STATEMENT
 
 def test_continuation_line():
     s = "\\\nfrom __future__ import with_statement\n"
-    f = run(s)
+    f = run(s, (2, 23))
     assert f == fut.CO_FUTURE_WITH_STATEMENT
 
 def test_continuation_lines():
     s = "\\\n  \t\\\nfrom __future__ import with_statement\n"
-    f = run(s)
+    f = run(s, (3, 23))
     assert f == fut.CO_FUTURE_WITH_STATEMENT
 
 def test_lots_of_continuation_lines():
     s = "\\\n\\\n\\\n\\\n\\\n\\\n\nfrom __future__ import with_statement\n"
-    f = run(s)
+    f = run(s, (8, 23))
     assert f == fut.CO_FUTURE_WITH_STATEMENT
 
 def test_continuation_lines_raise():
     s = "   \\\n  \t\\\nfrom __future__ import with_statement\n"
-    f = run(s, expected_last_future=(1, 0))
+    f = run(s)
     assert f == 0     # because of the INDENT
 
 def test_continuation_lines_in_docstring_single_quoted():
     s = '"\\\n\\\n\\\n\\\n\\\n\\\n"\nfrom  __future__ import division\n'
-    f = run(s)
+    f = run(s, (8, 24))
     assert f == fut.CO_FUTURE_DIVISION
 
 def test_continuation_lines_in_docstring_triple_quoted():
     s = '"""\\\n\\\n\\\n\\\n\\\n\\\n"""\nfrom  __future__ import division\n'
-    f = run(s)
+    f = run(s, (8, 24))
     assert f == fut.CO_FUTURE_DIVISION
 
 def test_blank_lines():
     s = ('\n\t\n\nfrom __future__ import with_statement'
          '  \n  \n  \nfrom __future__ import division')
-    f = run(s)
+    f = run(s, (7, 23))
     assert f == fut.CO_FUTURE_WITH_STATEMENT | fut.CO_FUTURE_DIVISION
 
 def test_dummy_semicolons():
     s = ('from __future__ import division;\n'
          'from __future__ import with_statement;')
-    f = run(s)
+    f = run(s, (2, 23))
     assert f == fut.CO_FUTURE_DIVISION | fut.CO_FUTURE_WITH_STATEMENT
diff --git a/pypy/interpreter/test/test_compiler.py b/pypy/interpreter/test/test_compiler.py
--- a/pypy/interpreter/test/test_compiler.py
+++ b/pypy/interpreter/test/test_compiler.py
@@ -787,6 +787,32 @@
         else:
             assert l1 == l2 == l3 == l4 == [1, 3, 2, 4]
 
+    def test_freevars_order(self):
+        # co_cellvars and co_freevars are guaranteed to appear in
+        # alphabetical order.  See CPython Issue #15368 (which does
+        # not come with tests).
+        source = """if 1:
+        def f1(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15):
+            def g1():
+                return (x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15)
+            return g1
+        def f2(x15,x14,x13,x12,x11,x10,x9,x8,x7,x6,x5,x4,x3,x2,x1):
+            def g2():
+                return (x15,x14,x13,x12,x11,x10,x9,x8,x7,x6,x5,x4,x3,x2,x1)
+            return g2
+        c1 = f1(*range(15)).__code__.co_freevars
+        c2 = f2(*range(15)).__code__.co_freevars
+        r1 = f1.__code__.co_cellvars
+        r2 = f2.__code__.co_cellvars
+        """
+        d = {}
+        exec(source, d)
+        assert d['c1'] == d['c2']
+        # the test above is important for a few bytecode hacks,
+        # but actually we get them in alphabetical order, so check that:
+        assert d['c1'] == tuple(sorted(d['c1']))
+        assert d['r1'] == d['r2'] == d['c1']
+
 
 ##class TestPythonAstCompiler(BaseTestCompiler):
 ##    def setup_method(self, method):
diff --git a/pypy/interpreter/test/test_syntax.py b/pypy/interpreter/test/test_syntax.py
--- a/pypy/interpreter/test/test_syntax.py
+++ b/pypy/interpreter/test/test_syntax.py
@@ -366,6 +366,15 @@
         assert isinstance(ns["b"], str)
         assert isinstance(ns["c"], str)
 
+    def test_both_futures_with_semicolon(self):
+        # Issue #2526: a corner case which crashes only if the file
+        # contains *nothing more* than two __future__ imports separated
+        # by a semicolon.
+        s = """
+from __future__ import unicode_literals; from __future__ import print_function
+"""
+        exec s in {}
+
 
 class AppTestComprehensions:
 
diff --git a/pypy/module/__builtin__/app_functional.py b/pypy/module/__builtin__/app_functional.py
--- a/pypy/module/__builtin__/app_functional.py
+++ b/pypy/module/__builtin__/app_functional.py
@@ -2,7 +2,6 @@
 Plain Python definition of the builtin functions oriented towards
 functional programming.
 """
-from __future__ import with_statement
 import operator
 from __pypy__ import resizelist_hint, newlist_hint
 from __pypy__ import specialized_zip_2_lists
diff --git a/pypy/module/__builtin__/compiling.py b/pypy/module/__builtin__/compiling.py
--- a/pypy/module/__builtin__/compiling.py
+++ b/pypy/module/__builtin__/compiling.py
@@ -38,6 +38,8 @@
                     "compile() arg 3 must be 'exec', 'eval' or 'single'")
 
     if space.isinstance_w(w_source, space.gettypeobject(ast.W_AST.typedef)):
+        if flags & consts.PyCF_ONLY_AST:
+            return w_source
         ast_node = ast.mod.from_object(space, w_source)
         return ec.compiler.compile_ast(ast_node, filename, mode, flags)
 
diff --git a/pypy/module/__builtin__/test/test_compile.py b/pypy/module/__builtin__/test/test_compile.py
--- a/pypy/module/__builtin__/test/test_compile.py


More information about the pypy-commit mailing list