Author: Armin Rigo <ar...@tunes.org>
Branch: py3.5
Changeset: r95227:115a0ddc5b54
Date: 2018-10-20 14:48 +0200
http://bitbucket.org/pypy/pypy/changeset/115a0ddc5b54/

Log:    hg merge default

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/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
 
 
-@unwrap_spec(filename="fsencode_or_none", flags=int)
-def load_library(space, filename, flags=0):
-    lib = W_Library(space, filename, flags)
+@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,15 +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
+
 
 # ____________________________________________________________
 
@@ -393,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/_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/rpython/rlib/rdynload.py b/rpython/rlib/rdynload.py
--- a/rpython/rlib/rdynload.py
+++ b/rpython/rlib/rdynload.py
@@ -242,6 +242,16 @@
             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:
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to