[pypy-commit] pypy default: hg merge cffi_dlopen_unicode
arigo
pypy.commits at gmail.com
Sat Oct 20 08:48:49 EDT 2018
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r95225:6b5c9e6f9782
Date: 2018-10-20 14:01 +0200
http://bitbucket.org/pypy/pypy/changeset/6b5c9e6f9782/
Log: hg merge cffi_dlopen_unicode
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
- 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,23 @@
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.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
+
# ____________________________________________________________
@@ -383,3 +392,30 @@
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
+ elif space.isinstance_w(w_filename, space.w_unicode):
+ fname = space.fsencode_w(w_filename)
+ else:
+ fname = space.text_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,15 @@
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
+ 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:
More information about the pypy-commit
mailing list