[pypy-svn] pypy fast-forward: Add support for dlopen(None).

amauryfa commits-noreply at bitbucket.org
Sun Dec 26 23:00:43 CET 2010


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: fast-forward
Changeset: r40234:53dafaa08b2f
Date: 2010-12-26 23:04 +0100
http://bitbucket.org/pypy/pypy/changeset/53dafaa08b2f/

Log:	Add support for dlopen(None). This should fix ctypes which was
	broken in the ff branch on Unix.

diff --git a/pypy/module/_rawffi/interp_rawffi.py b/pypy/module/_rawffi/interp_rawffi.py
--- a/pypy/module/_rawffi/interp_rawffi.py
+++ b/pypy/module/_rawffi/interp_rawffi.py
@@ -214,7 +214,7 @@
     except OSError, e:
         raise wrap_oserror(space, e)
     return space.wrap(W_CDLL(space, name, cdll))
-descr_new_cdll.unwrap_spec = [ObjSpace, W_Root, str]
+descr_new_cdll.unwrap_spec = [ObjSpace, W_Root, 'str_or_None']
 
 W_CDLL.typedef = TypeDef(
     'CDLL',

diff --git a/pypy/rpython/lltypesystem/rffi.py b/pypy/rpython/lltypesystem/rffi.py
--- a/pypy/rpython/lltypesystem/rffi.py
+++ b/pypy/rpython/lltypesystem/rffi.py
@@ -929,20 +929,28 @@
 
 class scoped_str2charp:
     def __init__(self, value):
-        self.buf = str2charp(value)
+        if value is not None:
+            self.buf = str2charp(value)
+        else:
+            self.buf = lltype.nullptr(CCHARP.TO)
     def __enter__(self):
         return self.buf
     def __exit__(self, *args):
-        free_charp(self.buf)
+        if self.buf:
+            free_charp(self.buf)
 
 
 class scoped_unicode2wcharp:
     def __init__(self, value):
-        self.buf = unicode2wcharp(value)
+        if value is not None:
+            self.buf = unicode2wcharp(value)
+        else:
+            self.buf = lltype.nullptr(CWCHARP.TO)
     def __enter__(self):
         return self.buf
     def __exit__(self, *args):
-        free_wcharp(self.buf)
+        if self.buf:
+            free_wcharp(self.buf)
 
 
 class scoped_nonmovingbuffer:

diff --git a/lib_pypy/_ctypes/dll.py b/lib_pypy/_ctypes/dll.py
--- a/lib_pypy/_ctypes/dll.py
+++ b/lib_pypy/_ctypes/dll.py
@@ -2,7 +2,4 @@
 
 def dlopen(name, mode):
     # XXX mode is ignored
-    if name is None:
-        # XXX this should return *all* loaded libs, dlopen(NULL).
-        raise NotImplementedError("dlopen(None)")
     return _rawffi.CDLL(name)

diff --git a/pypy/module/_rawffi/test/test__rawffi.py b/pypy/module/_rawffi/test/test__rawffi.py
--- a/pypy/module/_rawffi/test/test__rawffi.py
+++ b/pypy/module/_rawffi/test/test__rawffi.py
@@ -223,6 +223,16 @@
         else:
             raise AssertionError("did not fail??")
 
+    def test_libload_None(self):
+        if self.iswin32:
+            skip("unix specific")
+        import _rawffi
+        # this should return *all* loaded libs, dlopen(NULL)
+        dll = _rawffi.CDLL(None)
+        # Assume CPython, or PyPy compiled with cpyext
+        res = dll.ptr('Py_IsInitialized', [], 'l')()
+        assert res[0] == 1
+
     def test_libc_load(self):
         import _rawffi
         _rawffi.get_libc()

diff --git a/pypy/rlib/clibffi.py b/pypy/rlib/clibffi.py
--- a/pypy/rlib/clibffi.py
+++ b/pypy/rlib/clibffi.py
@@ -587,11 +587,8 @@
     def __init__(self, libname):
         """Load the library, or raises DLOpenError."""
         RawCDLL.__init__(self, rffi.cast(DLLHANDLE, -1))
-        ll_libname = rffi.str2charp(libname)
-        try:
+        with rffi.scoped_str2charp(libname) as ll_libname:
             self.lib = dlopen(ll_libname)
-        finally:
-            lltype.free(ll_libname, flavor='raw')
 
     def __del__(self):
         if self.lib != rffi.cast(DLLHANDLE, -1):


More information about the Pypy-commit mailing list