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

mattip pypy.commits at gmail.com
Fri Oct 12 09:03:09 EDT 2018


Author: Matti Picus <matti.picus at gmail.com>
Branch: unicode-utf8-py3
Changeset: r95210:07afb9936e34
Date: 2018-10-12 15:56 +0300
http://bitbucket.org/pypy/pypy/changeset/07afb9936e34/

Log:	merge py3.5 into branch

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
@@ -186,7 +186,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/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/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/misc.py b/pypy/module/_cffi_backend/misc.py
--- a/pypy/module/_cffi_backend/misc.py
+++ b/pypy/module/_cffi_backend/misc.py
@@ -6,6 +6,7 @@
 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.nonconst import NonConstant
 from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
 from rpython.translator.tool.cbuild import ExternalCompilationInfo
 
@@ -202,6 +203,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)
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
@@ -772,6 +772,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/_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
@@ -196,12 +196,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))
@@ -225,6 +224,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_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
@@ -279,31 +279,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/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',
@@ -672,7 +671,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 +715,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 +1120,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 +1130,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"
@@ -1495,7 +1490,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 +1543,6 @@
 
     if sys.platform == 'win32':
         get_pythonapi_source = '''
-        #include <windows.h>
         RPY_EXTERN
         HANDLE pypy_get_pythonapi_handle() {
             MEMORY_BASIC_INFORMATION  mi;
@@ -1563,6 +1556,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 +1669,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:
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/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/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_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/sys/initpath.py b/pypy/module/sys/initpath.py
--- a/pypy/module/sys/initpath.py
+++ b/pypy/module/sys/initpath.py
@@ -231,7 +231,9 @@
 if os.name == 'nt':
 
     _source_code = r"""
+#ifndef _WIN32_WINNT
 #define _WIN32_WINNT 0x0501
+#endif
 #include <windows.h>
 #include <stdio.h>
 
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,15 @@
             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 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
@@ -1777,8 +1777,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]
diff --git a/rpython/rlib/test/loadtest/loadtest1.dll b/rpython/rlib/test/loadtest/loadtest1.dll
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..cb83854875c876717371bdf90488eed9c6571f03
GIT binary patch

[cut]

diff --git a/rpython/rlib/test/test_rposix.py b/rpython/rlib/test/test_rposix.py
--- a/rpython/rlib/test/test_rposix.py
+++ b/rpython/rlib/test/test_rposix.py
@@ -83,6 +83,14 @@
         # the most intriguing failure of ntpath.py should not repeat, here:
         assert not data.endswith(stuff)
 
+    @win_only
+    def test__getfullpathname_long(self):
+        stuff = "C:" + "\\abcd" * 100
+        py.test.raises(WindowsError, rposix.getfullpathname, stuff)
+        ustuff = u"C:" + u"\\abcd" * 100
+        res = rposix.getfullpathname(ustuff)
+        assert res == ustuff
+
     def test_getcwd(self):
         assert rposix.getcwd() == os.getcwd()
 
diff --git a/rpython/rlib/test/test_rwin32.py b/rpython/rlib/test/test_rwin32.py
--- a/rpython/rlib/test/test_rwin32.py
+++ b/rpython/rlib/test/test_rwin32.py
@@ -6,6 +6,44 @@
 from rpython.rlib import rwin32
 from rpython.tool.udir import udir
 
+loadtest_dir = os.path.dirname(__file__) + '/loadtest'
+test1 = os.path.abspath(loadtest_dir + '/loadtest1.dll')
+test0 = os.path.abspath(loadtest_dir + '/loadtest0.dll')
+
+if not os.path.exists(test1) or not os.path.exists(test0):
+    # This is how the files, which are checked into the repo, were created
+    from rpython.translator.tool.cbuild import ExternalCompilationInfo
+    from rpython.translator.platform import platform
+    from rpython.translator import cdir
+    if not os.path.exists(loadtest_dir):
+        os.mkdir(loadtest_dir)
+    c_file = udir.ensure("test_rwin32", dir=1).join("test0.c")
+    c_file.write(py.code.Source('''
+    #include "src/precommondefs.h"
+    RPY_EXPORTED
+    int internal_sum(int a, int b) {
+        return a + b;
+    }
+    '''))
+    eci = ExternalCompilationInfo(include_dirs=[cdir])
+    lib_name = str(platform.compile([c_file], eci, test0[:-4],
+                   standalone=False))
+    assert os.path.abspath(lib_name) == os.path.abspath(test0)
+
+    c_file = udir.ensure("test_rwin32", dir=1).join("test1.c")
+    c_file.write(py.code.Source('''
+    #include "src/precommondefs.h"
+    int internal_sum(int a, int b);
+    RPY_EXPORTED
+    int sum(int a, int b) {
+        return internal_sum(a, b);
+    }
+    '''))
+    eci = ExternalCompilationInfo(include_dirs=[cdir], 
+                        libraries=[loadtest_dir + '/loadtest0'])
+    lib_name = str(platform.compile([c_file], eci, test1[:-4],
+                   standalone=False, ))
+    assert os.path.abspath(lib_name) == os.path.abspath(test1)
 
 def test_get_osfhandle():
     fid = open(str(udir.join('validate_test.txt')), 'w')
@@ -28,13 +66,13 @@
                          "import time;"
                          "time.sleep(10)",
                          ],
-                        ) 
+                        )
     print proc.pid
     handle = rwin32.OpenProcess(rwin32.PROCESS_ALL_ACCESS, False, proc.pid)
     assert rwin32.TerminateProcess(handle, signal.SIGTERM) == 1
     rwin32.CloseHandle(handle)
     assert proc.wait() == signal.SIGTERM
- 
+
 @py.test.mark.dont_track_allocations('putenv intentionally keeps strings alive')
 def test_wenviron():
     name, value = u'PYPY_TEST_日本', u'foobar日本'
@@ -55,3 +93,48 @@
     msg = rwin32.FormatErrorW(34)
     assert type(msg) is unicode
     assert u'%2' in msg
+
+def test_loadlibraryA():
+    # test0 can be loaded alone, but test1 requires the modified search path
+    hdll = rwin32.LoadLibrary(test0)
+    assert hdll
+    faddr = rwin32.GetProcAddress(hdll, 'internal_sum')
+    assert faddr
+    assert rwin32.FreeLibrary(hdll)
+
+    hdll = rwin32.LoadLibrary(test1)
+    assert not hdll
+
+    assert os.path.exists(test1)
+
+    hdll = rwin32.LoadLibraryExA(test1)
+    assert hdll
+    faddr = rwin32.GetProcAddress(hdll, 'sum')
+    assert faddr
+    assert rwin32.FreeLibrary(hdll)
+
+def test_loadlibraryW():
+    # test0 can be loaded alone, but test1 requires the modified search path
+    hdll = rwin32.LoadLibraryW(unicode(test0))
+    assert hdll
+    faddr = rwin32.GetProcAddress(hdll, 'internal_sum')
+    assert faddr
+    assert rwin32.FreeLibrary(hdll)
+
+    hdll = rwin32.LoadLibraryW(unicode(test1))
+    assert not hdll
+
+    assert os.path.exists(unicode(test1))
+
+    hdll = rwin32.LoadLibraryExW(unicode(test1))
+    assert hdll
+    faddr = rwin32.GetProcAddress(hdll, 'sum')
+    assert faddr
+    assert rwin32.FreeLibrary(hdll)
+
+def test_loadlibrary_unicode():
+    import shutil
+    test0u = unicode(udir.join(u'load\u03betest.dll'))
+    shutil.copyfile(test0, test0u)
+    hdll = rwin32.LoadLibraryW(test0u)
+    assert hdll


More information about the pypy-commit mailing list