[pypy-commit] pypy py3.6: merge py3.5 into branch

mattip pypy.commits at gmail.com
Sun Nov 18 03:57:39 EST 2018


Author: Matti Picus <matti.picus at gmail.com>
Branch: py3.6
Changeset: r95329:18106031c176
Date: 2018-11-17 23:33 -0800
http://bitbucket.org/pypy/pypy/changeset/18106031c176/

Log:	merge py3.5 into branch

diff too long, truncating to 2000 out of 2161 lines

diff --git a/lib-python/3/distutils/sysconfig_pypy.py b/lib-python/3/distutils/sysconfig_pypy.py
--- a/lib-python/3/distutils/sysconfig_pypy.py
+++ b/lib-python/3/distutils/sysconfig_pypy.py
@@ -8,11 +8,9 @@
 available.
 """
 
-__revision__ = "$Id: sysconfig.py 85358 2010-10-10 09:54:59Z antoine.pitrou $"
-
 import sys
 import os
-import imp
+import imp, _imp
 
 from distutils.errors import DistutilsPlatformError
 
@@ -71,9 +69,17 @@
 def _init_nt():
     """Initialize the module as appropriate for NT"""
     g = {}
+    # set basic install directories
+    g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
+    g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
+
+    # XXX hmmm.. a normal install puts include files here
+    g['INCLUDEPY'] = get_python_inc(plat_specific=0)
+
+    g['EXT_SUFFIX'] = _imp.extension_suffixes()[0]
     g['EXE'] = ".exe"
-    g['SO'] = ".pyd"
-    g['SOABI'] = g['SO'].rsplit('.')[0]   # xxx?
+    g['VERSION'] = get_python_version().replace(".", "")
+    g['BINDIR'] = os.path.dirname(os.path.abspath(sys.executable))
 
     global _config_vars
     _config_vars = g
diff --git a/lib_pypy/_cffi_ssl/_stdssl/__init__.py b/lib_pypy/_cffi_ssl/_stdssl/__init__.py
--- a/lib_pypy/_cffi_ssl/_stdssl/__init__.py
+++ b/lib_pypy/_cffi_ssl/_stdssl/__init__.py
@@ -190,7 +190,7 @@
     # Prefer poll, if available, since you can poll() any fd
     # which can't be done with select().
     if HAVE_POLL:
-        p.register(sock.fileno(), POLLOUT | POLLIN)
+        p.register(sock.fileno(), POLLOUT if writing else POLLIN)
 
         rc = len(p.poll(timeout * 1000.0))
     else:
diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py
--- a/lib_pypy/pyrepl/unix_console.py
+++ b/lib_pypy/pyrepl/unix_console.py
@@ -27,6 +27,12 @@
 from .console import Console, Event
 from .unix_eventqueue import EventQueue
 from .trace import trace
+try:
+    from __pypy__ import pyos_inputhook
+except ImportError:
+    def pyos_inputhook():
+        pass
+
 
 class InvalidTerminal(RuntimeError):
     pass
@@ -76,8 +82,8 @@
             pass
         def register(self, fd, flag):
             self.fd = fd
-        def poll(self, timeout=None):
-            r,w,e = select.select([self.fd],[],[],timeout)
+        def poll(self):   # note: a 'timeout' argument would be *milliseconds*
+            r,w,e = select.select([self.fd],[],[])
             return r
 
 POLLIN = getattr(select, "POLLIN", None)
@@ -407,6 +413,7 @@
     def get_event(self, block=1):
         while self.event_queue.empty():
             while 1: # All hail Unix!
+                pyos_inputhook()
                 try:
                     self.push_char(os.read(self.input_fd, 1))
                 except (IOError, OSError) as err:
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
@@ -42,3 +42,16 @@
 .. branch: py3.6-wordcode
 
 implement new wordcode instruction encoding on the 3.6 branch
+
+.. branch: socket_default_timeout_blockingness
+
+Backport CPython fix for possible shell injection issue in `distutils.spawn`,
+https://bugs.python.org/issue34540
+
+.. branch: cffi_dlopen_unicode
+
+Enable use of unicode file names in `dlopen`
+
+.. branch: rlock-in-rpython
+
+Backport CPython fix for `thread.RLock` 
diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py
--- a/pypy/module/__pypy__/__init__.py
+++ b/pypy/module/__pypy__/__init__.py
@@ -110,6 +110,7 @@
         'stack_almost_full'         : 'interp_magic.stack_almost_full',
         'fsencode'                  : 'interp_magic.fsencode',
         'fsdecode'                  : 'interp_magic.fsdecode',
+        'pyos_inputhook'            : 'interp_magic.pyos_inputhook',
     }
 
     submodules = {
diff --git a/pypy/module/__pypy__/interp_magic.py b/pypy/module/__pypy__/interp_magic.py
--- a/pypy/module/__pypy__/interp_magic.py
+++ b/pypy/module/__pypy__/interp_magic.py
@@ -209,3 +209,13 @@
 def revdb_stop(space):
     from pypy.interpreter.reverse_debugging import stop_point
     stop_point()
+
+def pyos_inputhook(space):
+    """Call PyOS_InputHook() from the CPython C API."""
+    if not space.config.objspace.usemodules.cpyext:
+        return
+    w_modules = space.sys.get('modules')
+    if space.finditem_str(w_modules, 'cpyext') is None:
+        return      # cpyext not imported yet, ignore
+    from pypy.module.cpyext.api import invoke_pyos_inputhook
+    invoke_pyos_inputhook(space)
diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py
--- a/pypy/module/_cffi_backend/cdataobj.py
+++ b/pypy/module/_cffi_backend/cdataobj.py
@@ -79,13 +79,6 @@
             w_result = self.ctype.cast_to_int(ptr)
         return w_result
 
-    def long(self, space):
-        w_result = self.int(space)
-        space = self.space
-        if space.is_w(space.type(w_result), space.w_int):
-            w_result = space.newlong(space.int_w(w_result))
-        return w_result
-
     def float(self):
         with self as ptr:
             w_result = self.ctype.float(ptr)
@@ -664,7 +657,6 @@
     __repr__ = interp2app(W_CData.repr),
     __bool__ = interp2app(W_CData.bool),
     __int__ = interp2app(W_CData.int),
-    __long__ = interp2app(W_CData.long),
     __float__ = interp2app(W_CData.float),
     __complex__ = interp2app(W_CData.complex),
     __len__ = interp2app(W_CData.len),
diff --git a/pypy/module/_cffi_backend/cdlopen.py b/pypy/module/_cffi_backend/cdlopen.py
--- a/pypy/module/_cffi_backend/cdlopen.py
+++ b/pypy/module/_cffi_backend/cdlopen.py
@@ -1,31 +1,24 @@
 from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
 from rpython.rlib.objectmodel import specialize, we_are_translated
-from rpython.rlib.rdynload import DLLHANDLE, dlopen, dlsym, dlclose, DLOpenError
+from rpython.rlib.rdynload import DLLHANDLE, dlsym, dlclose
 
 from pypy.interpreter.error import oefmt
-from pypy.module._rawffi.interp_rawffi import wrap_dlopenerror
 
 from pypy.module._cffi_backend.parse_c_type import (
     _CFFI_OPCODE_T, GLOBAL_S, CDL_INTCONST_S, STRUCT_UNION_S, FIELD_S,
     ENUM_S, TYPENAME_S, ll_set_cdl_realize_global_int)
 from pypy.module._cffi_backend.realize_c_type import getop
 from pypy.module._cffi_backend.lib_obj import W_LibObject
-from pypy.module._cffi_backend import cffi_opcode, cffi1_module
-
+from pypy.module._cffi_backend import cffi_opcode, cffi1_module, misc
 
 class W_DlOpenLibObject(W_LibObject):
 
-    def __init__(self, ffi, filename, flags):
-        with rffi.scoped_str2charp(filename) as ll_libname:
-            if filename is None:
-                filename = "<None>"
-            try:
-                handle = dlopen(ll_libname, flags)
-            except DLOpenError as e:
-                raise wrap_dlopenerror(ffi.space, e, filename)
-        W_LibObject.__init__(self, ffi, filename)
+    def __init__(self, ffi, w_filename, flags):
+        space = ffi.space
+        fname, handle = misc.dlopen_w(space, w_filename, flags)
+        W_LibObject.__init__(self, ffi, fname)
         self.libhandle = handle
-        self.register_finalizer(ffi.space)
+        self.register_finalizer(space)
 
     def _finalize_(self):
         h = self.libhandle
diff --git a/pypy/module/_cffi_backend/embedding.py b/pypy/module/_cffi_backend/embedding.py
--- a/pypy/module/_cffi_backend/embedding.py
+++ b/pypy/module/_cffi_backend/embedding.py
@@ -95,7 +95,9 @@
 if os.name == 'nt':
 
     do_includes = r"""
+#ifndef _WIN32_WINNT
 #define _WIN32_WINNT 0x0501
+#endif
 #include <windows.h>
 
 static void _cffi_init(void);
diff --git a/pypy/module/_cffi_backend/ffi_obj.py b/pypy/module/_cffi_backend/ffi_obj.py
--- a/pypy/module/_cffi_backend/ffi_obj.py
+++ b/pypy/module/_cffi_backend/ffi_obj.py
@@ -572,8 +572,8 @@
         return self.ffi_type(w_arg, ACCEPT_STRING | ACCEPT_CDATA)
 
 
-    @unwrap_spec(filename="fsencode_or_none", flags=int)
-    def descr_dlopen(self, filename, flags=0):
+    @unwrap_spec(flags=int)
+    def descr_dlopen(self, w_filename, flags=0):
         """\
 Load and return a dynamic library identified by 'name'.  The standard
 C library can be loaded by passing None.
@@ -584,7 +584,7 @@
 first access."""
         #
         from pypy.module._cffi_backend import cdlopen
-        return cdlopen.W_DlOpenLibObject(self, filename, flags)
+        return cdlopen.W_DlOpenLibObject(self, w_filename, flags)
 
 
     def descr_dlclose(self, w_lib):
diff --git a/pypy/module/_cffi_backend/libraryobj.py b/pypy/module/_cffi_backend/libraryobj.py
--- a/pypy/module/_cffi_backend/libraryobj.py
+++ b/pypy/module/_cffi_backend/libraryobj.py
@@ -4,28 +4,21 @@
 from pypy.interpreter.error import oefmt
 from pypy.interpreter.gateway import interp2app, unwrap_spec
 from pypy.interpreter.typedef import TypeDef
-from pypy.module._rawffi.interp_rawffi import wrap_dlopenerror
 
 from rpython.rtyper.lltypesystem import rffi
-from rpython.rlib.rdynload import DLLHANDLE, dlopen, dlsym, dlclose, DLOpenError
+from rpython.rlib.rdynload import DLLHANDLE, dlsym, dlclose
 
 from pypy.module._cffi_backend.cdataobj import W_CData
 from pypy.module._cffi_backend.ctypeobj import W_CType
+from pypy.module._cffi_backend import misc
 
 
 class W_Library(W_Root):
     _immutable_ = True
 
-    def __init__(self, space, filename, flags):
+    def __init__(self, space, w_filename, flags):
         self.space = space
-        with rffi.scoped_str2charp(filename) as ll_libname:
-            if filename is None:
-                filename = "<None>"
-            try:
-                self.handle = dlopen(ll_libname, flags)
-            except DLOpenError as e:
-                raise wrap_dlopenerror(space, e, filename)
-        self.name = filename
+        self.name, self.handle = misc.dlopen_w(space, w_filename, flags)
         self.register_finalizer(space)
 
     def _finalize_(self):
@@ -104,7 +97,7 @@
 W_Library.typedef.acceptable_as_base_class = False
 
 
- at unwrap_spec(filename="fsencode_or_none", flags=int)
-def load_library(space, filename, flags=0):
-    lib = W_Library(space, filename, flags)
+ at unwrap_spec(flags=int)
+def load_library(space, w_filename, flags=0):
+    lib = W_Library(space, w_filename, flags)
     return lib
diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py
--- a/pypy/module/_cffi_backend/misc.py
+++ b/pypy/module/_cffi_backend/misc.py
@@ -1,14 +1,24 @@
 from __future__ import with_statement
+import sys
 
 from pypy.interpreter.error import OperationError, oefmt
+from pypy.module._rawffi.interp_rawffi import wrap_dlopenerror
 
 from rpython.rlib import jit
 from rpython.rlib.objectmodel import specialize, we_are_translated
 from rpython.rlib.rarithmetic import r_uint, r_ulonglong
 from rpython.rlib.unroll import unrolling_iterable
+from rpython.rlib.rdynload import dlopen, DLOpenError
+from rpython.rlib.nonconst import NonConstant
 from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
 from rpython.translator.tool.cbuild import ExternalCompilationInfo
 
+if sys.platform == 'win32':
+    from rpython.rlib.rdynload import dlopenU
+    WIN32 = True
+else:
+    WIN32 = False
+
 
 # ____________________________________________________________
 
@@ -202,6 +212,9 @@
     else:
         if strict and value < 0:
             raise OperationError(space.w_OverflowError, space.newtext(neg_msg))
+        if not we_are_translated():
+            if isinstance(value, NonConstant):   # hack for test_ztranslation
+                return r_uint(0)
         return r_uint(value)
     # note that if not 'strict', then space.int() will round down floats
     bigint = space.bigint_w(space.int(w_ob), allow_conversion=False)
@@ -389,3 +402,28 @@
     ptr = rffi.cast(rffi.FLOATP, source)
     for i in range(len(float_list)):
         float_list[i] = rffi.cast(lltype.Float, ptr[i])
+
+# ____________________________________________________________
+
+def dlopen_w(space, w_filename, flags):
+    if WIN32 and space.isinstance_w(w_filename, space.w_unicode):
+        fname = space.text_w(space.repr(w_filename))
+        unicode_name = space.unicode_w(w_filename)
+        with rffi.scoped_unicode2wcharp(unicode_name) as ll_libname:
+            try:
+                handle = dlopenU(ll_libname, flags)
+            except DLOpenError as e:
+                raise wrap_dlopenerror(space, e, fname)
+    else:
+        if space.is_none(w_filename):
+            fname = None
+        else:
+            fname = space.fsencode_w(w_filename)
+        with rffi.scoped_str2charp(fname) as ll_libname:
+            if fname is None:
+                fname = "<None>"
+            try:
+                handle = dlopen(ll_libname, flags)
+            except DLOpenError as e:
+                raise wrap_dlopenerror(space, e, fname)
+    return fname, handle
diff --git a/pypy/module/_cffi_backend/test/test_re_python.py b/pypy/module/_cffi_backend/test/test_re_python.py
--- a/pypy/module/_cffi_backend/test/test_re_python.py
+++ b/pypy/module/_cffi_backend/test/test_re_python.py
@@ -1,8 +1,13 @@
 import py
+import sys, shutil, os
 from rpython.tool.udir import udir
 from pypy.interpreter.gateway import interp2app
 from pypy.module._cffi_backend.newtype import _clean_cache
 
+if sys.platform == 'win32':
+    WIN32 = True
+else:
+    WIN32 = False
 
 class AppTestRecompilerPython:
     spaceconfig = dict(usemodules=['_cffi_backend'])
@@ -40,6 +45,18 @@
                             'globalconst42', 'globalconsthello'])
         outputfilename = ffiplatform.compile(str(tmpdir), ext)
         cls.w_extmod = space.wrap(outputfilename)
+        if WIN32:
+            unicode_name = u'load\u03betest.dll'
+        else:
+            unicode_name = u'load_caf\xe9' + os.path.splitext(outputfilename)[1]
+            try:
+                unicode_name.encode(sys.getfilesystemencoding())
+            except UnicodeEncodeError:
+                unicode_name = None    # skip test_dlopen_unicode
+        if unicode_name is not None:
+            outputfileUname = os.path.join(unicode(udir), unicode_name)
+            shutil.copyfile(outputfilename, outputfileUname)
+            cls.w_extmodU = space.wrap(outputfileUname)
         #mod.tmpdir = tmpdir
         #
         ffi = FFI()
@@ -108,6 +125,16 @@
         assert lib.add42(-10) == 32
         assert type(lib.add42) is _cffi_backend.FFI.CData
 
+    def test_dlopen_unicode(self):
+        if not getattr(self, 'extmodU', None):
+            skip("no unicode file name")
+        import _cffi_backend, sys
+        sys.pypy_initfsencoding()   # initialize space.sys.filesystemencoding
+        self.fix_path()
+        from re_python_pysrc import ffi
+        lib = ffi.dlopen(self.extmodU)
+        assert lib.add42(-10) == 32
+
     def test_dlclose(self):
         import _cffi_backend
         self.fix_path()
diff --git a/pypy/module/_codecs/test/test_codecs.py b/pypy/module/_codecs/test/test_codecs.py
--- a/pypy/module/_codecs/test/test_codecs.py
+++ b/pypy/module/_codecs/test/test_codecs.py
@@ -761,6 +761,26 @@
         assert b"\\u3042\u3xxx".decode("unicode-escape", "test.handler1") == \
             u"\u3042[<92><117><51>]xxx"
 
+    def test_unicode_internal_error_handler_infinite_loop(self):
+        import codecs
+        class MyException(Exception):
+            pass
+        seen = [0]
+        def handler_unicodeinternal(exc):
+            if not isinstance(exc, UnicodeDecodeError):
+                raise TypeError("don't know how to handle %r" % exc)
+            seen[0] += 1
+            if seen[0] == 20:   # stop the 20th time this is called
+                raise MyException
+            return (u"\x01", 4)   # 4 < len(input), so will try and fail again
+        codecs.register_error("test.inf", handler_unicodeinternal)
+        try:
+            b"\x00\x00\x00\x00\x00".decode("unicode-internal", "test.inf")
+        except MyException:
+            pass
+        else:
+            raise AssertionError("should have gone into infinite loop")
+
     def test_encode_error_bad_handler(self):
         import codecs
         codecs.register_error("test.bad_handler", lambda e: (repl, 1))
diff --git a/pypy/module/_cppyy/capi/loadable_capi.py b/pypy/module/_cppyy/capi/loadable_capi.py
--- a/pypy/module/_cppyy/capi/loadable_capi.py
+++ b/pypy/module/_cppyy/capi/loadable_capi.py
@@ -308,10 +308,10 @@
         dldflags = rdynload.RTLD_LOCAL | rdynload.RTLD_LAZY
         if os.environ.get('CPPYY_BACKEND_LIBRARY'):
             libname = os.environ['CPPYY_BACKEND_LIBRARY']
-            state.backend = W_Library(space, libname, dldflags)
+            state.backend = W_Library(space, space.newtext(libname), dldflags)
         else:
             # try usual lookups
-            state.backend = W_Library(space, backend_library, dldflags)
+            state.backend = W_Library(space, space.newtext(backend_library), dldflags)
 
         if state.backend:
             # fix constants
diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py
--- a/pypy/module/_io/interp_fileio.py
+++ b/pypy/module/_io/interp_fileio.py
@@ -197,12 +197,11 @@
                             wrap_oserror2(space, e, w_name,
                                           exception_name='w_IOError',
                                           eintr_retry=True)
-                    if not rposix._WIN32:
-                        try:
-                            _open_inhcache.set_non_inheritable(self.fd)
-                        except OSError as e:
-                            raise wrap_oserror2(space, e, w_name,
-                                                eintr_retry=False)
+                    try:
+                         _open_inhcache.set_non_inheritable(self.fd)
+                    except OSError as e:
+                        raise wrap_oserror2(space, e, w_name,
+                                            eintr_retry=False)
                 else:
                     w_fd = space.call_function(w_opener, w_name,
                                                space.newint(flags))
@@ -226,6 +225,7 @@
                             raise wrap_oserror2(space, e, w_name,
                                                 eintr_retry=False)
 
+
             try:
                 st = os.fstat(self.fd)
             except OSError as e:
diff --git a/pypy/module/_io/test/test_bufferedio.py b/pypy/module/_io/test/test_bufferedio.py
--- a/pypy/module/_io/test/test_bufferedio.py
+++ b/pypy/module/_io/test/test_bufferedio.py
@@ -169,12 +169,12 @@
             #
             exc = raises(TypeError, readinto, u"hello")
             msg = str(exc.value)
-            print(msg)
+            # print(msg)
             assert " read-write b" in msg and msg.endswith(", not str")
             #
             exc = raises(TypeError, readinto, memoryview(b"hello"))
             msg = str(exc.value)
-            print(msg)
+            # print(msg)
             assert " read-write b" in msg and msg.endswith(", not memoryview")
             #
             f.close()
diff --git a/pypy/module/_io/test/test_bytesio.py b/pypy/module/_io/test/test_bytesio.py
--- a/pypy/module/_io/test/test_bytesio.py
+++ b/pypy/module/_io/test/test_bytesio.py
@@ -111,12 +111,12 @@
             #
             exc = raises(TypeError, readinto, u"hello")
             msg = str(exc.value)
-            print(msg)
+            # print(msg)
             assert " read-write b" in msg and msg.endswith(", not str")
             #
             exc = raises(TypeError, readinto, memoryview(b"hello"))
             msg = str(exc.value)
-            print(msg)
+            # print(msg)
             assert " read-write b" in msg and msg.endswith(", not memoryview")
             #
             b.close()
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
@@ -173,12 +173,12 @@
         #
         exc = raises(TypeError, f.readinto, u"hello")
         msg = str(exc.value)
-        print(msg)
+        # print(msg)
         assert " read-write b" in msg and msg.endswith(", not str")
         #
         exc = raises(TypeError, f.readinto, memoryview(b"hello"))
         msg = str(exc.value)
-        print(msg)
+        # print(msg)
         assert " read-write b" in msg and msg.endswith(", not memoryview")
         #
         f.close()
@@ -288,31 +288,34 @@
         raises(FileExistsError, _io.FileIO, filename, 'x')
 
     def test_non_inheritable(self):
-        import _io, posix
+        import _io
+        os = self.posix
         f = _io.FileIO(self.tmpfile, 'r')
-        assert posix.get_inheritable(f.fileno()) == False
+        assert os.get_inheritable(f.fileno()) == False
         f.close()
 
     def test_FileIO_fd_does_not_change_inheritable(self):
-        import _io, posix
-        fd1, fd2 = posix.pipe()
-        posix.set_inheritable(fd1, True)
-        posix.set_inheritable(fd2, False)
+        import _io
+        os = self.posix
+        fd1, fd2 = os.pipe()
+        os.set_inheritable(fd1, True)
+        os.set_inheritable(fd2, False)
         f1 = _io.FileIO(fd1, 'r')
         f2 = _io.FileIO(fd2, 'w')
-        assert posix.get_inheritable(fd1) == True
-        assert posix.get_inheritable(fd2) == False
+        assert os.get_inheritable(fd1) == True
+        assert os.get_inheritable(fd2) == False
         f1.close()
         f2.close()
 
     def test_close_upon_reinit(self):
-        import _io, posix
+        import _io
+        os = self.posix
         f = _io.FileIO(self.tmpfile, 'r')
         fd1 = f.fileno()
         f.__init__(self.tmpfile, 'w')
         fd2 = f.fileno()
         if fd1 != fd2:
-            raises(OSError, posix.close, fd1)
+            raises(OSError, os.close, fd1)
 
     def test_opener_negative(self):
         import _io
diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py
--- a/pypy/module/array/interp_array.py
+++ b/pypy/module/array/interp_array.py
@@ -179,6 +179,10 @@
             lltype.free(self._buffer, flavor='raw')
 
     def setlen(self, size, zero=False, overallocate=True):
+        if self._buffer:
+            delta_memory_pressure = -self.allocated * self.itemsize
+        else:
+            delta_memory_pressure = 0
         if size > 0:
             if size > self.allocated or size < self.allocated / 2:
                 if overallocate:
@@ -191,14 +195,13 @@
                     some = 0
                 self.allocated = size + some
                 byte_size = self.allocated * self.itemsize
+                delta_memory_pressure += byte_size
                 if zero:
                     new_buffer = lltype.malloc(
-                        rffi.CCHARP.TO, byte_size, flavor='raw',
-                        add_memory_pressure=True, zero=True)
+                        rffi.CCHARP.TO, byte_size, flavor='raw', zero=True)
                 else:
                     new_buffer = lltype.malloc(
-                        rffi.CCHARP.TO, byte_size, flavor='raw',
-                        add_memory_pressure=True)
+                        rffi.CCHARP.TO, byte_size, flavor='raw')
                     copy_bytes = min(size, self.len) * self.itemsize
                     rffi.c_memcpy(rffi.cast(rffi.VOIDP, new_buffer),
                                   rffi.cast(rffi.VOIDP, self._buffer),
@@ -215,6 +218,11 @@
             lltype.free(self._buffer, flavor='raw')
         self._buffer = new_buffer
         self.len = size
+        # adds the difference between the old and the new raw-malloced
+        # size.  If setlen() is called a lot on the same array object,
+        # it is important to take into account the fact that we also do
+        # lltype.free() above.
+        rgc.add_memory_pressure(delta_memory_pressure)
 
     def _fromiterable(self, w_seq):
         # used by fromsequence().
@@ -259,8 +267,10 @@
             return None
         oldbuffer = self._buffer
         self._buffer = lltype.malloc(rffi.CCHARP.TO,
-            (self.len - (j - i)) * self.itemsize, flavor='raw',
-            add_memory_pressure=True)
+            (self.len - (j - i)) * self.itemsize, flavor='raw')
+        # Issue #2913: don't pass add_memory_pressure here, otherwise
+        # memory pressure grows but actual raw memory usage doesn't---we
+        # are freeing the old buffer at the end of this function.
         if i:
             rffi.c_memcpy(
                 rffi.cast(rffi.VOIDP, self._buffer),
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
@@ -93,8 +93,11 @@
 
 if sys.platform == 'win32':
     dash = '_'
+    WIN32 = True
 else:
     dash = ''
+    WIN32 = False
+
 
 def fclose(fp):
     try:
@@ -610,13 +613,9 @@
     'PyObject_CallMethod', 'PyObject_CallFunctionObjArgs', 'PyObject_CallMethodObjArgs',
     '_PyObject_CallFunction_SizeT', '_PyObject_CallMethod_SizeT',
 
-    'PyObject_GetBuffer', 'PyBuffer_Release',
+    'PyObject_DelItemString', 'PyObject_GetBuffer', 'PyBuffer_Release',
     '_Py_setfilesystemdefaultencoding',
 
-    'PyCObject_FromVoidPtr', 'PyCObject_FromVoidPtrAndDesc', 'PyCObject_AsVoidPtr',
-    'PyCObject_GetDesc', 'PyCObject_Import', 'PyCObject_SetVoidPtr',
-    'PyCObject_Type', '_Py_get_cobject_type',
-
     'PyCapsule_New', 'PyCapsule_IsValid', 'PyCapsule_GetPointer',
     'PyCapsule_GetName', 'PyCapsule_GetDestructor', 'PyCapsule_GetContext',
     'PyCapsule_SetPointer', 'PyCapsule_SetName', 'PyCapsule_SetDestructor',
@@ -648,6 +647,7 @@
     'Py_FrozenFlag', 'Py_TabcheckFlag', 'Py_UnicodeFlag', 'Py_IgnoreEnvironmentFlag',
     'Py_DivisionWarningFlag', 'Py_DontWriteBytecodeFlag', 'Py_NoUserSiteDirectory',
     '_Py_QnewFlag', 'Py_Py3kWarningFlag', 'Py_HashRandomizationFlag', '_Py_PackageContext',
+    'PyOS_InputHook',
 
     'PyMem_RawMalloc', 'PyMem_RawCalloc', 'PyMem_RawRealloc', 'PyMem_RawFree',
     'PyMem_Malloc', 'PyMem_Calloc', 'PyMem_Realloc', 'PyMem_Free',
@@ -672,7 +672,7 @@
     'PyObject*', 'space.w_None', header=pypy_decl)
 register_global('_Py_TrueStruct',
     'PyObject*', 'space.w_True', header=pypy_decl)
-register_global('_Py_ZeroStruct',
+register_global('_Py_FalseStruct',
     'PyObject*', 'space.w_False', header=pypy_decl)
 register_global('_Py_NotImplementedStruct',
     'PyObject*', 'space.w_NotImplemented', header=pypy_decl)
@@ -716,8 +716,8 @@
         "PyByteArray_Type": "space.w_bytearray",
         "PyMemoryView_Type": "space.w_memoryview",
         "PyBaseObject_Type": "space.w_object",
-        'PyNone_Type': 'space.type(space.w_None)',
-        'PyNotImplemented_Type': 'space.type(space.w_NotImplemented)',
+        '_PyNone_Type': 'space.type(space.w_None)',
+        '_PyNotImplemented_Type': 'space.type(space.w_NotImplemented)',
         'PyCell_Type': 'space.gettypeobject(Cell.typedef)',
         'PyModule_Type': 'space.gettypeobject(Module.typedef)',
         'PyProperty_Type': 'space.gettypeobject(W_Property.typedef)',
@@ -1121,9 +1121,6 @@
     # of the cpyext module.  The C functions are called with no wrapper,
     # but must not do anything like calling back PyType_Ready().  We
     # use them just to get a pointer to the PyTypeObjects defined in C.
-    get_cobject_type = rffi.llexternal('_%s_get_cobject_type' % prefix,
-                                       [], PyTypeObjectPtr,
-                                       compilation_info=eci, _nowrapper=True)
     get_capsule_type = rffi.llexternal('_%s_get_capsule_type' % prefix,
                                        [], PyTypeObjectPtr,
                                        compilation_info=eci, _nowrapper=True)
@@ -1134,7 +1131,6 @@
     def init_types(space):
         from pypy.module.cpyext.typeobject import py_type_ready
         from pypy.module.sys.interp_encoding import getfilesystemencoding
-        py_type_ready(space, get_cobject_type())
         py_type_ready(space, get_capsule_type())
         s = space.text_w(getfilesystemencoding(space))
         setdefenc(rffi.str2charp(s, track_allocation=False))  # "leaks"
@@ -1188,6 +1184,10 @@
     state.C._PyPy_object_dealloc = rffi.llexternal(
         '_PyPy_object_dealloc', [PyObject], lltype.Void,
         compilation_info=eci, _nowrapper=True)
+    FUNCPTR = lltype.Ptr(lltype.FuncType([], rffi.INT))
+    state.C.get_pyos_inputhook = rffi.llexternal(
+        '_PyPy_get_PyOS_InputHook', [], FUNCPTR,
+        compilation_info=eci, _nowrapper=True)
 
 
 def init_function(func):
@@ -1495,7 +1495,6 @@
                          source_dir / "pythonrun.c",
                          source_dir / "sysmodule.c",
                          source_dir / "complexobject.c",
-                         source_dir / "cobject.c",
                          source_dir / "structseq.c",
                          source_dir / "capsule.c",
                          source_dir / "pysignals.c",
@@ -1549,7 +1548,6 @@
 
     if sys.platform == 'win32':
         get_pythonapi_source = '''
-        #include <windows.h>
         RPY_EXTERN
         HANDLE pypy_get_pythonapi_handle() {
             MEMORY_BASIC_INFORMATION  mi;
@@ -1563,6 +1561,9 @@
         }
         '''
         separate_module_sources.append(get_pythonapi_source)
+        kwds['post_include_bits'] = ['#include <windows.h>',
+                            'RPY_EXTERN HANDLE pypy_get_pythonapi_handle();',
+                                    ]
 
     eci = ExternalCompilationInfo(
         include_dirs=include_dirs,
@@ -1673,7 +1674,11 @@
     try:
         ll_libname = rffi.str2charp(path)
         try:
-            dll = rdynload.dlopen(ll_libname, space.sys.dlopenflags)
+            if WIN32:
+                # Allow other DLLs in the same directory with "path"
+                dll = rdynload.dlopenex(ll_libname)
+            else:
+                dll = rdynload.dlopen(ll_libname, space.sys.dlopenflags)
         finally:
             lltype.free(ll_libname, flavor='raw')
     except rdynload.DLOpenError as e:
@@ -1789,6 +1794,12 @@
             return
         return exec_def(space, w_mod, mod_as_pyobj)
 
+def invoke_pyos_inputhook(space):
+    state = space.fromcache(State)
+    c_inputhook = state.C.get_pyos_inputhook()
+    if c_inputhook:
+        generic_cpy_call(space, c_inputhook)
+
 @specialize.ll()
 def generic_cpy_call(space, func, *args):
     FT = lltype.typeOf(func).TO
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
@@ -9,6 +9,7 @@
 from pypy.module.cpyext.pyobject import PyObject
 from pypy.module.cpyext.pyerrors import PyErr_SetFromErrno
 from pypy.module.cpyext.funcobject import PyCodeObject
+from pypy.module.cpyext.frameobject import PyFrameObject
 from pypy.module.__builtin__ import compiling
 
 PyCompilerFlags = cpython_struct(
@@ -58,6 +59,11 @@
         return None
     return caller.get_w_globals()    # borrowed ref
 
+ at cpython_api([], PyFrameObject, error=CANNOT_FAIL, result_borrowed=True)
+def PyEval_GetFrame(space):
+    caller = space.getexecutioncontext().gettopframe_nohidden()
+    return caller    # borrowed ref, may be null
+
 @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
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
@@ -123,7 +123,6 @@
 #include "memoryobject.h"
 #include "eval.h"
 #include "pymem.h"
-#include "pycobject.h"
 #include "pycapsule.h"
 #include "bytesobject.h"
 #include "sliceobject.h"
diff --git a/pypy/module/cpyext/include/abstract.h b/pypy/module/cpyext/include/abstract.h
--- a/pypy/module/cpyext/include/abstract.h
+++ b/pypy/module/cpyext/include/abstract.h
@@ -4,6 +4,15 @@
 extern "C" {
 #endif
 
+     PyAPI_FUNC(int) PyObject_DelItemString(PyObject *o, char *key);
+
+       /*
+     Remove the mapping for object, key, from the object *o.
+     Returns -1 on failure.  This is equivalent to
+     the Python statement: del o[key].
+       */
+
+
     /* new buffer API */
 
 #define PyObject_CheckBuffer(obj) \
@@ -27,6 +36,27 @@
     /* Releases a Py_buffer obtained from getbuffer ParseTuple's s*.
     */
 
+/*  Mapping protocol:*/
+
+     /* implemented as a macro:
+
+     int PyMapping_DelItemString(PyObject *o, char *key);
+
+     Remove the mapping for object, key, from the object *o.
+     Returns -1 on failure.  This is equivalent to
+     the Python statement: del o[key].
+       */
+#define PyMapping_DelItemString(O,K) PyObject_DelItemString((O),(K))
+
+     /* implemented as a macro:
+
+     int PyMapping_DelItem(PyObject *o, PyObject *key);
+
+     Remove the mapping for object, key, from the object *o.
+     Returns -1 on failure.  This is equivalent to
+     the Python statement: del o[key].
+       */
+#define PyMapping_DelItem(O,K) PyObject_DelItem((O),(K))
 
 #ifdef __cplusplus
 }
diff --git a/pypy/module/cpyext/include/boolobject.h b/pypy/module/cpyext/include/boolobject.h
--- a/pypy/module/cpyext/include/boolobject.h
+++ b/pypy/module/cpyext/include/boolobject.h
@@ -1,5 +1,4 @@
-
-/* Bool object interface */
+/* Boolean object interface */
 
 #ifndef Py_BOOLOBJECT_H
 #define Py_BOOLOBJECT_H
@@ -7,15 +6,19 @@
 extern "C" {
 #endif
 
-#define Py_False ((PyObject *) &_Py_ZeroStruct)
+#define PyBool_Check(x) (Py_TYPE(x) == &PyBool_Type)
+
+/* Py_False and Py_True are the only two bools in existence.
+Don't forget to apply Py_INCREF() when returning either!!! */
+
+/* Use these macros */
+#define Py_False ((PyObject *) &_Py_FalseStruct)
 #define Py_True ((PyObject *) &_Py_TrueStruct)
 
 /* Macros for returning Py_True or Py_False, respectively */
 #define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True
 #define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False
 
-#define PyBool_Check(op) ((op)->ob_type == &PyBool_Type)
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/pypy/module/cpyext/include/pycobject.h b/pypy/module/cpyext/include/pycobject.h
deleted file mode 100644
--- a/pypy/module/cpyext/include/pycobject.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef Py_COBJECT_H
-#define Py_COBJECT_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-PyAPI_DATA(PyTypeObject) PyCObject_Type;
-
-#define PyCObject_Check(op) ((op)->ob_type == &PyCObject_Type)
-
-/* Create a PyCObject from a pointer to a C object and an optional
-   destructor function.  If the second argument is non-null, then it
-   will be called with the first argument if and when the PyCObject is
-   destroyed.
-
-*/
-PyAPI_FUNC(PyObject *) PyCObject_FromVoidPtr(
-	void *cobj, void (*destruct)(void*));
-
-
-/* Create a PyCObject from a pointer to a C object, a description object,
-   and an optional destructor function.  If the third argument is non-null,
-   then it will be called with the first and second arguments if and when 
-   the PyCObject is destroyed.
-*/
-PyAPI_FUNC(PyObject *) PyCObject_FromVoidPtrAndDesc(
-	void *cobj, void *desc, void (*destruct)(void*,void*));
-
-/* Retrieve a pointer to a C object from a PyCObject. */
-PyAPI_FUNC(void *) PyCObject_AsVoidPtr(PyObject *);
-
-/* Retrieve a pointer to a description object from a PyCObject. */
-PyAPI_FUNC(void *) PyCObject_GetDesc(PyObject *);
-
-/* Import a pointer to a C object from a module using a PyCObject. */
-PyAPI_FUNC(void *) PyCObject_Import(const char *module_name, const char *cobject_name);
-
-/* Modify a C object. Fails (==0) if object has a destructor. */
-PyAPI_FUNC(int) PyCObject_SetVoidPtr(PyObject *self, void *cobj);
-
-
-#if (PY_VERSION_HEX >= 0x02060000 || defined(Py_BUILD_CORE))
-typedef struct {
-    PyObject_HEAD
-    void *cobject;
-    void *desc;
-    void (*destructor)(void *);
-} PyCObject;
-#endif
-
-PyAPI_FUNC(PyTypeObject *) _Py_get_cobject_type(void);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* !Py_COBJECT_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
@@ -41,6 +41,11 @@
 
 #define Py_CompileString(str, filename, start) Py_CompileStringFlags(str, filename, start, NULL)
 
+/* Stuff with no proper home (yet) */
+PyAPI_DATA(int) (*PyOS_InputHook)(void);
+typedef int (*_pypy_pyos_inputhook)(void);
+PyAPI_FUNC(_pypy_pyos_inputhook) _PyPy_get_PyOS_InputHook(void);
+
 #ifdef __cplusplus
 }
 #endif
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
@@ -41,19 +41,6 @@
     w_mode = space.newtext(rffi.charp2str(mode))
     return space.call_method(space.builtin, 'open', w_filename, w_mode)
 
- at cpython_api([FILEP, CONST_STRING, CONST_STRING, rffi.VOIDP], PyObject)
-def PyFile_FromFile(space, fp, name, mode, close):
-    """Create a new PyFileObject from the already-open standard C file
-    pointer, fp.  The function close will be called when the file should be
-    closed.  Return NULL on failure."""
-    raise NotImplementedError
-
- at cpython_api([PyObject, rffi.INT_real], lltype.Void)
-def PyFile_SetBufSize(space, w_file, n):
-    """Available on systems with setvbuf() only.  This should only be called
-    immediately after file object creation."""
-    raise NotImplementedError
-
 @cpython_api([CONST_STRING, PyObject], rffi.INT_real, error=-1)
 def PyFile_WriteString(space, s, w_p):
     """Write string s to file object p.  Return 0 on success or -1 on
@@ -75,9 +62,3 @@
         w_str = space.repr(w_obj)
     space.call_method(w_p, "write", w_str)
     return 0
-
- at cpython_api([PyObject], PyObject)
-def PyFile_Name(space, w_p):
-    """Return the name of the file specified by p as a string object."""
-    w_name = space.getattr(w_p, space.newtext("name"))
-    return w_name     # borrowed ref, should be a W_StringObject from the file
diff --git a/pypy/module/cpyext/src/abstract.c b/pypy/module/cpyext/src/abstract.c
--- a/pypy/module/cpyext/src/abstract.c
+++ b/pypy/module/cpyext/src/abstract.c
@@ -23,6 +23,23 @@
 /* Operations on any object */
 
 int
+PyObject_DelItemString(PyObject *o, char *key)
+{
+    PyObject *okey;
+    int ret;
+
+    if (o == NULL || key == NULL) {
+        null_error();
+        return -1;
+    }
+    okey = PyUnicode_FromString(key);
+    if (okey == NULL)
+        return -1;
+    ret = PyObject_DelItem(o, okey);
+    Py_DECREF(okey);
+    return ret;
+}
+int
 PyObject_CheckReadBuffer(PyObject *obj)
 {
     PyBufferProcs *pb = obj->ob_type->tp_as_buffer;
@@ -96,6 +113,20 @@
     return 0;
 }
 
+/* Buffer C-API for Python 3.0 */
+
+int
+PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags)
+{
+    if (!PyObject_CheckBuffer(obj)) {
+        PyErr_Format(PyExc_TypeError,
+                     "'%100s' does not have the buffer interface",
+                     Py_TYPE(obj)->tp_name);
+        return -1;
+    }
+    return (*(obj->ob_type->tp_as_buffer->bf_getbuffer))(obj, view, flags);
+}
+
 void*
 PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices)
 {
@@ -111,6 +142,7 @@
     return (void*)pointer;
 }
 
+
 void
 _Py_add_one_to_index_F(int nd, Py_ssize_t *index, const Py_ssize_t *shape)
 {
@@ -253,19 +285,6 @@
 
 
 
-/* Buffer C-API for Python 3.0 */
-
-int
-PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags)
-{
-    if (!PyObject_CheckBuffer(obj)) {
-        PyErr_Format(PyExc_TypeError,
-                     "'%100s' does not have the buffer interface",
-                     Py_TYPE(obj)->tp_name);
-        return -1;
-    }
-    return (*(obj->ob_type->tp_as_buffer->bf_getbuffer))(obj, view, flags);
-}
 
 void
 PyBuffer_Release(Py_buffer *view)
@@ -427,6 +446,7 @@
     return retval;
 }
 
+
 static PyObject *
 objargs_mktuple(va_list va)
 {
diff --git a/pypy/module/cpyext/src/cobject.c b/pypy/module/cpyext/src/cobject.c
deleted file mode 100644
--- a/pypy/module/cpyext/src/cobject.c
+++ /dev/null
@@ -1,162 +0,0 @@
-
-/* Wrap void* pointers to be passed between C modules */
-
-#include "Python.h"
-
-
-/* Declarations for objects of type PyCObject */
-
-typedef void (*destructor1)(void *);
-typedef void (*destructor2)(void *, void*);
-
-PyObject *
-PyCObject_FromVoidPtr(void *cobj, void (*destr)(void *))
-{
-    PyCObject *self;
-
-    self = PyObject_NEW(PyCObject, &PyCObject_Type);
-    if (self == NULL)
-        return NULL;
-    self->cobject=cobj;
-    self->destructor=destr;
-    self->desc=NULL;
-
-    return (PyObject *)self;
-}
-
-PyObject *
-PyCObject_FromVoidPtrAndDesc(void *cobj, void *desc,
-                             void (*destr)(void *, void *))
-{
-    PyCObject *self;
-
-    if (!desc) {
-        PyErr_SetString(PyExc_TypeError,
-                        "PyCObject_FromVoidPtrAndDesc called with null"
-                        " description");
-        return NULL;
-    }
-    self = PyObject_NEW(PyCObject, &PyCObject_Type);
-    if (self == NULL)
-        return NULL;
-    self->cobject = cobj;
-    self->destructor = (destructor1)destr;
-    self->desc = desc;
-
-    return (PyObject *)self;
-}
-
-void *
-PyCObject_AsVoidPtr(PyObject *self)
-{
-    if (self) {
-        if (PyCapsule_CheckExact(self)) {
-            const char *name = PyCapsule_GetName(self);
-            return (void *)PyCapsule_GetPointer(self, name);
-        }
-        if (self->ob_type == &PyCObject_Type)
-            return ((PyCObject *)self)->cobject;
-        PyErr_SetString(PyExc_TypeError,
-                        "PyCObject_AsVoidPtr with non-C-object");
-    }
-    if (!PyErr_Occurred())
-        PyErr_SetString(PyExc_TypeError,
-                        "PyCObject_AsVoidPtr called with null pointer");
-    return NULL;
-}
-
-void *
-PyCObject_GetDesc(PyObject *self)
-{
-    if (self) {
-        if (self->ob_type == &PyCObject_Type)
-            return ((PyCObject *)self)->desc;
-        PyErr_SetString(PyExc_TypeError,
-                        "PyCObject_GetDesc with non-C-object");
-    }
-    if (!PyErr_Occurred())
-        PyErr_SetString(PyExc_TypeError,
-                        "PyCObject_GetDesc called with null pointer");
-    return NULL;
-}
-
-void *
-PyCObject_Import(const char *module_name, const char *name)
-{
-    PyObject *m, *c;
-    void *r = NULL;
-
-    if ((m = PyImport_ImportModule(module_name))) {
-        if ((c = PyObject_GetAttrString(m,name))) {
-            r = PyCObject_AsVoidPtr(c);
-            Py_DECREF(c);
-	}
-        Py_DECREF(m);
-    }
-    return r;
-}
-
-int
-PyCObject_SetVoidPtr(PyObject *self, void *cobj)
-{
-    PyCObject* cself = (PyCObject*)self;
-    if (cself == NULL || !PyCObject_Check(cself) ||
-	cself->destructor != NULL) {
-	PyErr_SetString(PyExc_TypeError, 
-			"Invalid call to PyCObject_SetVoidPtr");
-	return 0;
-    }
-    cself->cobject = cobj;
-    return 1;
-}
-
-static void
-PyCObject_dealloc(PyCObject *self)
-{
-    if (self->destructor) {
-        if(self->desc)
-            ((destructor2)(self->destructor))(self->cobject, self->desc);
-        else
-            (self->destructor)(self->cobject);
-    }
-    PyObject_DEL(self);
-}
-
-
-PyDoc_STRVAR(PyCObject_Type__doc__,
-"C objects to be exported from one extension module to another\n\
-\n\
-C objects are used for communication between extension modules.  They\n\
-provide a way for an extension module to export a C interface to other\n\
-extension modules, so that extension modules can use the Python import\n\
-mechanism to link to one another.");
-
-PyTypeObject PyCObject_Type = {
-    PyVarObject_HEAD_INIT(NULL, 0)
-    "PyCObject",		/*tp_name*/
-    sizeof(PyCObject),		/*tp_basicsize*/
-    0,				/*tp_itemsize*/
-    /* methods */
-    (destructor)PyCObject_dealloc, /*tp_dealloc*/
-    0,				/*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*/
-    PyCObject_Type__doc__	/*tp_doc*/
-};
-
-PyTypeObject *_Py_get_cobject_type(void)
-{
-    return &PyCObject_Type;
-}
diff --git a/pypy/module/cpyext/src/missing.c b/pypy/module/cpyext/src/missing.c
--- a/pypy/module/cpyext/src/missing.c
+++ b/pypy/module/cpyext/src/missing.c
@@ -31,3 +31,7 @@
 void _Py_setfilesystemdefaultencoding(const char *enc) {
     Py_FileSystemDefaultEncoding = enc;
 }
+int (*PyOS_InputHook)(void) = 0;  /* only ever filled in by C extensions */
+PyAPI_FUNC(_pypy_pyos_inputhook) _PyPy_get_PyOS_InputHook(void) {
+    return PyOS_InputHook;
+}
diff --git a/pypy/module/cpyext/stubs-find-implemented.py b/pypy/module/cpyext/stubs-find-implemented.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/stubs-find-implemented.py
@@ -0,0 +1,21 @@
+import re
+import os
+
+
+for line in open('stubs.py'):
+    if not line.strip():
+        continue
+    if line.startswith('    '):
+        continue
+    if line.startswith('#'):
+        continue
+    if line.startswith('@cpython_api'):
+        continue
+    if line.endswith(' = rffi.VOIDP\n'):
+        continue
+
+    #print line.rstrip()
+    m = re.match(r"def ([\w\d_]+)[(]", line)
+    assert m, line
+    funcname = m.group(1)
+    os.system('grep -w %s [a-r]*.py s[a-s]*.py str*.py stubsa*.py sy*.py [t-z]*.py' % funcname)
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,29 +1,10 @@
-from pypy.module.cpyext.api import (
-    cpython_api, PyObject, PyObjectP, CANNOT_FAIL
-    )
-from pypy.module.cpyext.complexobject import Py_complex_ptr as Py_complex
-from rpython.rtyper.lltypesystem import rffi, lltype
+#----this file is not imported, only here for reference----
 
-CWCHARPP = lltype.Ptr(lltype.Array(rffi.CWCHARP, hints={'nolength': True}))
-
-# we don't really care
-PyTypeObjectPtr = rffi.VOIDP
-Py_ssize_t = rffi.SSIZE_T
-PyModuleDef = rffi.VOIDP
-PyMethodDef = rffi.VOIDP
-PyGetSetDef = rffi.VOIDP
-PyMemberDef = rffi.VOIDP
-va_list = rffi.VOIDP
-wrapperbase = rffi.VOIDP
-FILE = rffi.VOIDP
-PyFrameObject = rffi.VOIDP
-_inittab = rffi.VOIDP
-PyThreadState = rffi.VOIDP
-PyInterpreterState = rffi.VOIDP
-Py_UNICODE = lltype.UniChar
-PyCompilerFlags = rffi.VOIDP
-struct_node = rffi.VOIDP
-Py_tracefunc = rffi.VOIDP
+#from pypy.module.cpyext.api import (
+#    cpython_api, PyObject, PyObjectP, CANNOT_FAIL
+#    )
+#from pypy.module.cpyext.complexobject import Py_complex_ptr as Py_complex
+#from rpython.rtyper.lltypesystem import rffi, lltype
 
 
 @cpython_api([rffi.CCHARP], Py_ssize_t, error=-1)
@@ -228,39 +209,6 @@
     this method returns zero and sets errno to EDOM."""
     raise NotImplementedError
 
- at cpython_api([rffi.DOUBLE, lltype.Char, rffi.INT_real, rffi.INT_real, rffi.INTP], rffi.CCHARP)
-def PyOS_double_to_string(space, val, format_code, precision, flags, ptype):
-    """Convert a double val to a string using supplied
-    format_code, precision, and flags.
-
-    format_code must be one of 'e', 'E', 'f', 'F',
-    'g', 'G' or 'r'.  For 'r', the supplied precision
-    must be 0 and is ignored.  The 'r' format code specifies the
-    standard repr() format.
-
-    flags can be zero or more of the values Py_DTSF_SIGN,
-    Py_DTSF_ADD_DOT_0, or Py_DTSF_ALT, or-ed together:
-
-    Py_DTSF_SIGN means to always precede the returned string with a sign
-    character, even if val is non-negative.
-
-    Py_DTSF_ADD_DOT_0 means to ensure that the returned string will not look
-    like an integer.
-
-    Py_DTSF_ALT means to apply "alternate" formatting rules.  See the
-    documentation for the PyOS_snprintf() '#' specifier for
-    details.
-
-    If ptype is non-NULL, then the value it points to will be set to one of
-    Py_DTST_FINITE, Py_DTST_INFINITE, or Py_DTST_NAN, signifying that
-    val is a finite number, an infinite number, or not a number, respectively.
-
-    The return value is a pointer to buffer with the converted string or
-    NULL if the conversion failed. The caller is responsible for freeing the
-    returned string by calling PyMem_Free().
-    """
-    raise NotImplementedError
-
 @cpython_api([rffi.CCHARP, rffi.CCHARP], rffi.CCHARP)
 def PyOS_stricmp(space, s1, s2):
     """Case insensitive comparison of strings. The function works almost
@@ -275,24 +223,6 @@
     """
     raise NotImplementedError
 
- at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
-def PyTZInfo_Check(space, ob):
-    """Return true if ob is of type PyDateTime_TZInfoType or a subtype of
-    PyDateTime_TZInfoType.  ob must not be NULL.
-    """
-    raise NotImplementedError
-
- at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
-def PyTZInfo_CheckExact(space, ob):
-    """Return true if ob is of type PyDateTime_TZInfoType. ob must not be
-    NULL.
-    """
-    raise NotImplementedError
-
- at cpython_api([PyTypeObjectPtr, PyGetSetDef], PyObject)
-def PyDescr_NewGetSet(space, type, getset):
-    raise NotImplementedError
-
 @cpython_api([PyTypeObjectPtr, PyMemberDef], PyObject)
 def PyDescr_NewMember(space, type, meth):
     raise NotImplementedError
@@ -483,31 +413,6 @@
     0 on success, -1 on failure."""
     raise NotImplementedError
 
- at cpython_api([PyObject], rffi.INT_real, error=-1)
-def Py_ReprEnter(space, object):
-    """Called at the beginning of the tp_repr implementation to
-    detect cycles.
-
-    If the object has already been processed, the function returns a
-    positive integer.  In that case the tp_repr implementation
-    should return a string object indicating a cycle.  As examples,
-    dict objects return {...} and list objects
-    return [...].
-
-    The function will return a negative integer if the recursion limit
-    is reached.  In that case the tp_repr implementation should
-    typically return NULL.
-
-    Otherwise, the function returns zero and the tp_repr
-    implementation can continue normally."""
-    raise NotImplementedError
-
- at cpython_api([PyObject], lltype.Void)
-def Py_ReprLeave(space, object):
-    """Ends a Py_ReprEnter().  Must be called once for each
-    invocation of Py_ReprEnter() that returns zero."""
-    raise NotImplementedError
-
 @cpython_api([rffi.INT_real, rffi.CCHARP, rffi.CCHARP, rffi.INT_real, rffi.CCHARP, rffi.CCHARP, rffi.CCHARP, rffi.INT_real], PyObject)
 def PyFile_FromFd(space, fd, name, mode, buffering, encoding, errors, newline, closefd):
     """Create a Python file object from the file descriptor of an already
@@ -1295,39 +1200,6 @@
     """
     raise NotImplementedError
 
- at cpython_api([PyObject], rffi.VOIDP)
-def PyModule_GetState(space, module):
-    """Return the "state" of the module, that is, a pointer to the block of memory
-    allocated at module creation time, or NULL.  See
-    PyModuleDef.m_size."""
-    raise NotImplementedError
-
- at cpython_api([PyObject], PyModuleDef)
-def PyModule_GetDef(space, module):
-    """Return a pointer to the PyModuleDef struct from which the module was
-    created, or NULL if the module wasn't created with
-    PyModule_Create()."""
-    raise NotImplementedError
-
-
- at cpython_api([PyModuleDef], PyObject)
-def PyModule_Create(space, module):
-    """Create a new module object, given the definition in module.  This behaves
-    like PyModule_Create2() with module_api_version set to
-    PYTHON_API_VERSION."""
-    raise NotImplementedError
-
-
- at cpython_api([PyModuleDef, rffi.INT_real], PyObject)
-def PyModule_Create2(space, module, module_api_version):
-    """Create a new module object, given the definition in module, assuming the
-    API version module_api_version.  If that version does not match the version
-    of the running interpreter, a RuntimeWarning is emitted.
-
-    Most uses of this function should be using PyModule_Create()
-    instead; only use this if you are sure you need it."""
-    raise NotImplementedError
-
 @cpython_api([PyObject, rffi.INT_real], PyObject)
 def PyNumber_ToBase(space, n, base):
     """Returns the integer n converted to base base as a string.  The base
@@ -1337,23 +1209,6 @@
     PyNumber_Index() first."""
     raise NotImplementedError
 
- at cpython_api([PyObject], PyObject)
-def PyObject_Bytes(space, o):
-    """
-    Compute a bytes representation of object o.  NULL is returned on
-    failure and a bytes object on success.  This is equivalent to the Python
-    expression bytes(o), when o is not an integer.  Unlike bytes(o),
-    a TypeError is raised when o is an integer instead of a zero-initialized
-    bytes object."""
-    raise NotImplementedError
-
- at cpython_api([], PyFrameObject)
-def PyEval_GetFrame(space):
-    """Return the current thread state's frame, which is NULL if no frame is
-    currently executing."""
-    raise NotImplementedError
-    borrow_from()
-
 @cpython_api([PyFrameObject], rffi.INT_real, error=-1)
 def PyFrame_GetLineNumber(space, frame):
     """Return the line number that frame is currently executing."""
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
@@ -510,3 +510,15 @@
             assert run_async(list1()) == ([], [0, 1, 2])
             assert run_async(list2()) == ([], [0, 1, 2])
             """
+
+    def test_getframe(self):
+        import sys
+        module = self.import_extension('foo', [
+            ("getframe1", "METH_NOARGS",
+             """
+                PyFrameObject *x = PyEval_GetFrame();
+                Py_INCREF(x);
+                return (PyObject *)x;
+             """),], prologue="#include <frameobject.h>\n")
+        res = module.getframe1()
+        assert res is sys._getframe(0)
diff --git a/pypy/module/cpyext/test/test_misc.py b/pypy/module/cpyext/test/test_misc.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/test/test_misc.py
@@ -0,0 +1,35 @@
+from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
+
+
+class AppTestMisc(AppTestCpythonExtensionBase):
+
+    def test_pyos_inputhook(self):
+        module = self.import_extension('foo', [
+               ("set_pyos_inputhook", "METH_NOARGS",
+                '''
+                    PyOS_InputHook = &my_callback;
+                    Py_RETURN_NONE;
+                '''),
+                ("fetch_value", "METH_NOARGS",
+                '''
+                    return PyLong_FromLong(my_flag);
+                '''),
+            ], prologue='''
+            static long my_flag = 0;
+            static int my_callback(void) { return ++my_flag; }
+            ''')
+
+        try:
+            import __pypy__
+        except ImportError:
+            skip("only runs on top of pypy")
+        assert module.fetch_value() == 0
+        __pypy__.pyos_inputhook()
+        assert module.fetch_value() == 0
+        module.set_pyos_inputhook()       # <= set
+        assert module.fetch_value() == 0
+        __pypy__.pyos_inputhook()
+        assert module.fetch_value() == 1
+        __pypy__.pyos_inputhook()
+        assert module.fetch_value() == 2
+        assert module.fetch_value() == 2
diff --git a/pypy/module/cpyext/test/test_pycobject.py b/pypy/module/cpyext/test/test_pycobject.py
deleted file mode 100644
--- a/pypy/module/cpyext/test/test_pycobject.py
+++ /dev/null
@@ -1,30 +0,0 @@
-import py
-from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
-
-class AppTestStringObject(AppTestCpythonExtensionBase):
-    def test_pycobject_import(self):
-        module = self.import_extension('foo', [
-            ("set_ptr", "METH_O",
-             """
-                 PyObject *pointer, *module;
-                 void *ptr = PyLong_AsVoidPtr(args);
-                 if (PyErr_Occurred()) return NULL;
-                 pointer = PyCObject_FromVoidPtr(ptr, NULL);
-                 if (PyErr_Occurred()) return NULL;
-                 module = PyImport_ImportModule("foo");
-                 PyModule_AddObject(module, "_ptr", pointer);
-                 Py_DECREF(module);
-                 if (PyErr_Occurred()) return NULL;
-                 Py_RETURN_NONE;
-             """),
-            ("get_ptr", "METH_NOARGS",
-             """
-                 void *ptr = PyCObject_Import("foo", "_ptr");
-                 if (PyErr_Occurred()) return NULL;
-                 return PyLong_FromVoidPtr(ptr);
-             """)])
-        module.set_ptr(1234)
-        assert "PyCObject object" in str(module._ptr)
-        import gc; gc.collect()
-        assert module.get_ptr() == 1234
-        del module._ptr
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
@@ -48,17 +48,6 @@
 
         space.call_method(w_file, "close")
 
-    def test_file_name(self, space, api):
-        name = str(udir / "_test_file")
-        with rffi.scoped_str2charp(name) as filename:
-            with rffi.scoped_str2charp("wb") as mode:
-                w_file = api.PyFile_FromString(filename, mode)
-        assert space.str_w(api.PyFile_Name(w_file)) == name
-
-    @pytest.mark.xfail
-    def test_file_setbufsize(self, space, api):
-        api.PyFile_SetBufSize()
-
     def test_file_writestring(self, space, api, capfd):
         w_stdout = space.sys.get("stdout")
         with rffi.scoped_str2charp("test\n") as s:
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
@@ -677,13 +677,15 @@
     def test_decode_null_encoding(self, space):
         null_charp = lltype.nullptr(rffi.CCHARP.TO)
         u_text = u'abcdefg'
-        s_text = space.str_w(PyUnicode_AsEncodedString(space, space.wrap(u_text), null_charp, null_charp))
+        s_text = space.bytes_w(PyUnicode_AsEncodedString(space, space.wrap(u_text), null_charp, null_charp))
         b_text = rffi.str2charp(s_text)
         assert space.unicode_w(PyUnicode_Decode(
             space, b_text, len(s_text), null_charp, null_charp)) == u_text
         with raises_w(space, TypeError):
             PyUnicode_FromEncodedObject(
                 space, space.wrap(u_text), null_charp, None)
+        assert space.unicode_w(PyUnicode_FromEncodedObject(
+            space, space.newbytes(s_text), null_charp, None)) == u_text
         rffi.free_charp(b_text)
 
     def test_mbcs(self, space):
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
@@ -486,11 +486,16 @@
     in the unicode() built-in function.  The codec to be used is looked up
     using the Python codec registry.  Return NULL if an exception was raised by
     the codec."""
-    if not encoding:
-        # This tracks CPython 2.7, in CPython 3.4 'utf-8' is hardcoded instead
-        encoding = PyUnicode_GetDefaultEncoding(space)
-    w_str = space.newbytes(rffi.charpsize2str(s, size))
-    w_encoding = space.newtext(rffi.charp2str(encoding))
+    return _pyunicode_decode(space, rffi.charpsize2str(s, size),
+                             encoding, errors)
+
+def _pyunicode_decode(space, s, encoding, errors):
+    if encoding:
+        w_encoding = space.newtext(rffi.charp2str(encoding))
+    else:
+        # python 3.4 changed to this from defaultencoding
+        w_encoding = space.newtext('utf-8')
+    w_str = space.newbytes(s)
     if errors:
         w_errors = space.newtext(rffi.charp2str(errors))
     else:
@@ -525,28 +530,12 @@
 
     All other objects, including Unicode objects, cause a TypeError to be
     set."""
-    if not encoding:
-        raise oefmt(space.w_TypeError, "decoding Unicode is not supported")
-    w_encoding = space.newtext(rffi.charp2str(encoding))
-    if errors:
-        w_errors = space.newtext(rffi.charp2str(errors))
-    else:
-        w_errors = None
-
-    # - unicode is disallowed
-    # - raise TypeError for non-string types
     if space.isinstance_w(w_obj, space.w_unicode):
-        w_meth = None
-    else:
-        try:
-            w_meth = space.getattr(w_obj, space.newtext('decode'))
-        except OperationError as e:
-            if not e.match(space, space.w_AttributeError):
-                raise
-            w_meth = None
-    if w_meth is None:
-        raise oefmt(space.w_TypeError, "decoding Unicode is not supported")
-    return space.call_function(w_meth, w_encoding, w_errors)
+        raise oefmt(space.w_TypeError, "decoding str is not supported")
+    if space.isinstance_w(w_obj, space.w_bytearray):   # Python 2.x specific
+        raise oefmt(space.w_TypeError, "decoding bytearray is not supported")
+    s = space.charbuf_w(w_obj)
+    return _pyunicode_decode(space, s, encoding, errors)
 
 
 @cpython_api([PyObject, PyObjectP], rffi.INT_real, error=0)
diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py
--- a/pypy/module/posix/test/test_posix2.py
+++ b/pypy/module/posix/test/test_posix2.py
@@ -232,9 +232,9 @@
     def test_pickle(self):
         import pickle, os
         st = self.posix.stat(os.curdir)
-        print(type(st).__module__)
+        # print(type(st).__module__)
         s = pickle.dumps(st)
-        print(repr(s))
+        # print(repr(s))
         new = pickle.loads(s)
         assert new == st
         assert type(new) is type(st)
@@ -578,6 +578,12 @@
             res = fp.read()
             assert res == '1\n'
 
+    if sys.platform == "win32":
+        # using startfile in app_startfile creates global state
+        test_popen.dont_track_allocations = True
+        test_popen_with.dont_track_allocations = True
+        test_popen_child_fds.dont_track_allocations = True
+
     if hasattr(__import__(os.name), '_getfullpathname'):
         def test__getfullpathname(self):
             # nt specific
diff --git a/pypy/module/pwd/interp_pwd.py b/pypy/module/pwd/interp_pwd.py
--- a/pypy/module/pwd/interp_pwd.py
+++ b/pypy/module/pwd/interp_pwd.py
@@ -37,7 +37,8 @@
 passwd_p = lltype.Ptr(config['passwd'])
 
 def external(name, args, result, **kwargs):
-    return rffi.llexternal(name, args, result, compilation_info=eci, **kwargs)
+    return rffi.llexternal(name, args, result, compilation_info=eci,
+                           releasegil=False, **kwargs)
 
 c_getpwuid = external("getpwuid", [uid_t], passwd_p)
 c_getpwnam = external("getpwnam", [rffi.CCHARP], passwd_p)
diff --git a/pypy/module/sys/initpath.py b/pypy/module/sys/initpath.py
--- a/pypy/module/sys/initpath.py
+++ b/pypy/module/sys/initpath.py
@@ -231,11 +231,13 @@
 if os.name == 'nt':
 
     _source_code = r"""
+#ifndef _WIN32_WINNT
 #define _WIN32_WINNT 0x0501
+#endif
 #include <windows.h>
 #include <stdio.h>
+#include <stdlib.h>
 
-RPY_EXPORTED
 char *_pypy_init_home(void)
 {
     HMODULE hModule = 0;
@@ -271,7 +273,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-RPY_EXPORTED
 char *_pypy_init_home(void)
 {
     Dl_info info;
@@ -289,11 +290,27 @@
 }
 """
 
+_source_code += """
+inline
+void _pypy_init_free(char *p)
+{
+    free(p);
+}
+"""
+
+if we_are_translated():
+   post_include_bits = []
+else:
+    # for tests 
+    post_include_bits=['RPY_EXPORTED char *_pypy_init_home(void);',
+                       'RPY_EXPORTED void _pypy_init_free(char*);',
+                      ]
+
 _eci = ExternalCompilationInfo(separate_module_sources=[_source_code],
-    post_include_bits=['RPY_EXPORTED char *_pypy_init_home(void);'])
+                               post_include_bits=post_include_bits)
 _eci = _eci.merge(rdynload.eci)
 
 pypy_init_home = rffi.llexternal("_pypy_init_home", [], rffi.CCHARP,
                                  _nowrapper=True, compilation_info=_eci)
-pypy_init_free = rffi.llexternal("free", [rffi.CCHARP], lltype.Void,
+pypy_init_free = rffi.llexternal("_pypy_init_free", [rffi.CCHARP], lltype.Void,
                                  _nowrapper=True, compilation_info=_eci)
diff --git a/pypy/module/thread/os_lock.py b/pypy/module/thread/os_lock.py
--- a/pypy/module/thread/os_lock.py
+++ b/pypy/module/thread/os_lock.py
@@ -49,7 +49,8 @@
             # Run signal handlers if we were interrupted
             space.getexecutioncontext().checksignals()
             if microseconds >= 0:
-                microseconds = r_longlong(endtime - (time.time() * 1e6))
+                microseconds = r_longlong((endtime - (time.time() * 1e6))
+                                          + 0.999)
                 # Check for negative values, since those mean block
                 # forever
                 if microseconds <= 0:
@@ -247,7 +248,7 @@
                         "cannot release un-acquired lock")
         self.rlock_count -= 1
         if self.rlock_count == 0:
-            self.rlock_owner == 0
+            self.rlock_owner = 0
             self.lock.release()
 
     def is_owned_w(self, space):
diff --git a/pypy/module/thread/test/test_lock.py b/pypy/module/thread/test/test_lock.py
--- a/pypy/module/thread/test/test_lock.py
+++ b/pypy/module/thread/test/test_lock.py
@@ -306,6 +306,9 @@
         finally:
             signal.signal(signal.SIGALRM, oldalrm)
 
+
+class AppTestLockRepr(GenericTestThread):
+
     def test_lock_repr(self):
         import _thread
         lock = _thread.allocate_lock()
diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py
--- a/rpython/rlib/jit.py
+++ b/rpython/rlib/jit.py
@@ -151,7 +151,7 @@
     if getattr(func, '_elidable_function_', False):
         raise TypeError("it does not make sense for %s to be both elidable and unroll_safe" % func)
     if not getattr(func, '_jit_look_inside_', True):
-        raise TypeError("it does not make sense for %s to be both elidable and dont_look_inside" % func)
+        raise TypeError("it does not make sense for %s to be both unroll_safe and dont_look_inside" % func)
     func._jit_unroll_safe_ = True
     return func
 
diff --git a/rpython/rlib/rdynload.py b/rpython/rlib/rdynload.py
--- a/rpython/rlib/rdynload.py
+++ b/rpython/rlib/rdynload.py
@@ -233,6 +233,25 @@
             raise DLOpenError(ustr.encode('utf-8'))
         return res
 
+    def dlopenex(name):
+        res = rwin32.LoadLibraryExA(name)
+        if not res:
+            err = rwin32.GetLastError_saved()
+            ustr = rwin32.FormatErrorW(err)
+            # DLOpenError unicode msg breaks translation of cpyext create_extension_module
+            raise DLOpenError(ustr.encode('utf-8'))
+        return res
+
+    def dlopenU(name, mode=-1):
+        # mode is unused on windows, but a consistant signature
+        res = rwin32.LoadLibraryW(name)
+        if not res:
+            err = rwin32.GetLastError_saved()
+            ustr = rwin32.FormatErrorW(err)
+            # DLOpenError unicode msg breaks translation of cpyext create_extension_module
+            raise DLOpenError(ustr.encode('utf-8'))
+        return res
+
     def dlclose(handle):
         res = rwin32.FreeLibrary(handle)
         if res:
diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py
--- a/rpython/rlib/rmmap.py
+++ b/rpython/rlib/rmmap.py
@@ -835,7 +835,7 @@
         # assume -1 and 0 both mean invalid file descriptor
         # to 'anonymously' map memory.
         if fileno != -1 and fileno != 0:
-            fh = rwin32.get_osfhandle(fileno)
+            fh = rffi.cast(HANDLE, rwin32.get_osfhandle(fileno))
             # Win9x appears to need us seeked to zero
             # SEEK_SET = 0
             # libc._lseek(fileno, 0, SEEK_SET)
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -137,7 +137,10 @@
         RPY_EXTERN void exit_suppress_iph(void* handle) {};
         #endif
     ''',]
-    post_include_bits=['RPY_EXTERN int _PyVerify_fd(int);']
+    post_include_bits=['RPY_EXTERN int _PyVerify_fd(int);',
+                       'RPY_EXTERN void* enter_suppress_iph();',
+                       'RPY_EXTERN void exit_suppress_iph(void* handle);',
+                      ]
 else:
     separate_module_sources = []
     post_include_bits = []
@@ -235,7 +238,8 @@
             rthread.tlfield_rpy_errno.setraw(_get_errno())
             # ^^^ keep fork() up-to-date too, below
 if _WIN32:
-    includes = ['io.h', 'sys/utime.h', 'sys/types.h', 'process.h', 'time.h']
+    includes = ['io.h', 'sys/utime.h', 'sys/types.h', 'process.h', 'time.h',
+                'direct.h']
     libraries = []
 else:
     if sys.platform.startswith(('darwin', 'netbsd', 'openbsd')):
@@ -730,16 +734,21 @@
     length = rwin32.MAX_PATH + 1
     traits = _preferred_traits(path)
     win32traits = make_win32_traits(traits)
-    with traits.scoped_alloc_buffer(length) as buf:
-        res = win32traits.GetFullPathName(
-            traits.as_str0(path), rffi.cast(rwin32.DWORD, length),
-            buf.raw, lltype.nullptr(win32traits.LPSTRP.TO))
-        if res == 0:
-            raise rwin32.lastSavedWindowsError("_getfullpathname failed")
-        result = buf.str(intmask(res))
-        assert result is not None
-        result = rstring.assert_str0(result)
-        return result
+    while True:      # should run the loop body maximum twice
+        with traits.scoped_alloc_buffer(length) as buf:
+            res = win32traits.GetFullPathName(
+                traits.as_str0(path), rffi.cast(rwin32.DWORD, length),
+                buf.raw, lltype.nullptr(win32traits.LPSTRP.TO))
+            res = intmask(res)
+            if res == 0:
+                raise rwin32.lastSavedWindowsError("_getfullpathname failed")
+            if res >= length:
+                length = res + 1
+                continue
+            result = buf.str(res)
+            assert result is not None
+            result = rstring.assert_str0(result)
+            return result
 
 c_getcwd = external(UNDERSCORE_ON_WIN32 + 'getcwd',
                     [rffi.CCHARP, rffi.SIZE_T], rffi.CCHARP,
diff --git a/rpython/rlib/runicode.py b/rpython/rlib/runicode.py
--- a/rpython/rlib/runicode.py
+++ b/rpython/rlib/runicode.py
@@ -1775,8 +1775,6 @@
                                     "truncated input",
                                     s, pos, size)
             result.append(res)
-            if pos > size - unicode_bytes:
-                break
             continue
         t = r_uint(0)
         h = 0
diff --git a/rpython/rlib/rwin32.py b/rpython/rlib/rwin32.py
--- a/rpython/rlib/rwin32.py
+++ b/rpython/rlib/rwin32.py
@@ -20,7 +20,7 @@
 
 if WIN32:
     eci = ExternalCompilationInfo(
-        includes = ['windows.h', 'stdio.h', 'stdlib.h'],
+        includes = ['windows.h', 'stdio.h', 'stdlib.h', 'io.h'],
         libraries = ['kernel32'],
         )
 else:
@@ -113,6 +113,7 @@
                        MB_ERR_INVALID_CHARS ERROR_NO_UNICODE_TRANSLATION
                        WC_NO_BEST_FIT_CHARS STD_INPUT_HANDLE STD_OUTPUT_HANDLE
                        STD_ERROR_HANDLE HANDLE_FLAG_INHERIT FILE_TYPE_CHAR
+                       LOAD_WITH_ALTERED_SEARCH_PATH
                     """
         from rpython.translator.platform import host_factory
         static_platform = host_factory()
@@ -195,12 +196,28 @@
     GetModuleHandle = winexternal('GetModuleHandleA', [rffi.CCHARP], HMODULE)
     LoadLibrary = winexternal('LoadLibraryA', [rffi.CCHARP], HMODULE,
                               save_err=rffi.RFFI_SAVE_LASTERROR)
+    def wrap_loadlibraryex(func):
+        def loadlibrary(name, flags=LOAD_WITH_ALTERED_SEARCH_PATH):
+            # Requires a full path name with '/' -> '\\'
+            return func(name, NULL_HANDLE, flags)
+        return loadlibrary
+
+    _LoadLibraryExA = winexternal('LoadLibraryExA',
+                                [rffi.CCHARP, HANDLE, DWORD], HMODULE,
+                                save_err=rffi.RFFI_SAVE_LASTERROR)
+    LoadLibraryExA = wrap_loadlibraryex(_LoadLibraryExA)
+    LoadLibraryW = winexternal('LoadLibraryW', [rffi.CWCHARP], HMODULE,
+                              save_err=rffi.RFFI_SAVE_LASTERROR)
+    _LoadLibraryExW = winexternal('LoadLibraryExW',
+                                [rffi.CWCHARP, HANDLE, DWORD], HMODULE,
+                                save_err=rffi.RFFI_SAVE_LASTERROR)
+    LoadLibraryExW = wrap_loadlibraryex(_LoadLibraryExW)
     GetProcAddress = winexternal('GetProcAddress',
                                  [HMODULE, rffi.CCHARP],
                                  rffi.VOIDP)
     FreeLibrary = winexternal('FreeLibrary', [HMODULE], BOOL, releasegil=False)
 
-    LocalFree = winexternal('LocalFree', [HLOCAL], DWORD)
+    LocalFree = winexternal('LocalFree', [HLOCAL], HLOCAL)
     CloseHandle = winexternal('CloseHandle', [HANDLE], BOOL, releasegil=False,
                               save_err=rffi.RFFI_SAVE_LASTERROR)
     CloseHandle_no_err = winexternal('CloseHandle', [HANDLE], BOOL,
@@ -215,12 +232,12 @@
         [DWORD, rffi.VOIDP, DWORD, DWORD, rffi.CWCHARP, DWORD, rffi.VOIDP],
         DWORD)
 
-    _get_osfhandle = rffi.llexternal('_get_osfhandle', [rffi.INT], HANDLE)
+    _get_osfhandle = rffi.llexternal('_get_osfhandle', [rffi.INT], rffi.INTP)
 
     def get_osfhandle(fd):
         from rpython.rlib.rposix import FdValidator
         with FdValidator(fd):
-            handle = _get_osfhandle(fd)
+            handle = rffi.cast(HANDLE, _get_osfhandle(fd))
         if handle == INVALID_HANDLE_VALUE:
             raise WindowsError(ERROR_INVALID_HANDLE, "Invalid file handle")
         return handle
diff --git a/rpython/rlib/test/loadtest/loadtest0.dll b/rpython/rlib/test/loadtest/loadtest0.dll
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9bdcc33a1902f8e989d349c49c2cc08e633aa32b
GIT binary patch

[cut]


More information about the pypy-commit mailing list