[pypy-svn] r72375 - in pypy/trunk/pypy: module/_rawffi module/_rawffi/test rlib rlib/test

arigo at codespeak.net arigo at codespeak.net
Thu Mar 18 15:40:33 CET 2010


Author: arigo
Date: Thu Mar 18 15:40:31 2010
New Revision: 72375

Modified:
   pypy/trunk/pypy/module/_rawffi/interp_rawffi.py
   pypy/trunk/pypy/module/_rawffi/test/test__rawffi.py
   pypy/trunk/pypy/rlib/libffi.py
   pypy/trunk/pypy/rlib/test/test_libffi.py
Log:
Fix an issue with CDLL() not reporting errors on top of PyPy.
Done with a custom DLOpenError exception at interp-level.


Modified: pypy/trunk/pypy/module/_rawffi/interp_rawffi.py
==============================================================================
--- pypy/trunk/pypy/module/_rawffi/interp_rawffi.py	(original)
+++ pypy/trunk/pypy/module/_rawffi/interp_rawffi.py	Thu Mar 18 15:40:31 2010
@@ -144,7 +144,11 @@
 
 class W_CDLL(Wrappable):
     def __init__(self, space, name):
-        self.cdll = CDLL(name)
+        try:
+            self.cdll = CDLL(name)
+        except DLOpenError, e:
+            raise operationerrfmt(space.w_OSError, '%s: %s', name,
+                                  e.msg or 'unspecified error')
         self.name = name
         self.w_cache = space.newdict()
         self.space = space

Modified: pypy/trunk/pypy/module/_rawffi/test/test__rawffi.py
==============================================================================
--- pypy/trunk/pypy/module/_rawffi/test/test__rawffi.py	(original)
+++ pypy/trunk/pypy/module/_rawffi/test/test__rawffi.py	Thu Mar 18 15:40:31 2010
@@ -188,6 +188,16 @@
         import _rawffi
         _rawffi.CDLL(self.libc_name)
 
+    def test_libload_fail(self):
+        import _rawffi
+        try:
+            _rawffi.CDLL("xxxxx_this_name_does_not_exist_xxxxx")
+        except OSError, e:
+            print e
+            assert str(e).startswith("xxxxx_this_name_does_not_exist_xxxxx: ")
+        else:
+            raise AssertionError("did not fail??")
+
     def test_libc_load(self):
         import _rawffi
         _rawffi.get_libc()

Modified: pypy/trunk/pypy/rlib/libffi.py
==============================================================================
--- pypy/trunk/pypy/rlib/libffi.py	(original)
+++ pypy/trunk/pypy/rlib/libffi.py	Thu Mar 18 15:40:31 2010
@@ -15,10 +15,6 @@
 import sys
 import ctypes.util
 
-DEBUG = False # writes dlerror() messages to stderr
-# XXX this need solving rather than hacking. We need to raise something else
-#     than OSError, something capable of delivering a message
-
 from pypy.translator.platform import platform
 
 # maaaybe isinstance here would be better. Think
@@ -218,6 +214,13 @@
 def winexternal(name, args, result):
     return rffi.llexternal(name, args, result, compilation_info=eci, calling_conv='win')
 
+class DLOpenError(Exception):
+    def __init__(self, msg):
+        self.msg = msg
+    def __str__(self):
+        return repr(self.msg)
+
+
 if not _WIN32:
     c_dlopen = external('dlopen', [rffi.CCHARP, rffi.INT], rffi.VOIDP)
     c_dlclose = external('dlclose', [rffi.VOIDP], rffi.INT)
@@ -248,12 +251,7 @@
         res = c_dlopen(name, rffi.cast(rffi.INT, mode))
         if not res:
             err = dlerror()
-            # because the message would be lost in a translated program (OSError only has an errno),
-            # we offer a way to write it to stderr
-            if DEBUG:
-                import os
-                os.write(2, err)
-            raise OSError(-1, err)
+            raise DLOpenError(err)
         return res
 
     dlclose = c_dlclose
@@ -284,8 +282,8 @@
     def dlopen(name):
         res = rwin32.LoadLibrary(name)
         if not res:
-            # XXX format error message
-            raise WindowsError(2, rwin32.GetLastError())
+            err = rwin32.GetLastError()
+            raise DLOpenError(rwin32.FormatError(err))
         return res
 
     def dlclose(handle):
@@ -626,6 +624,7 @@
 
 class CDLL:
     def __init__(self, libname, unload_on_finalization=True):
+        """Load the library, or raises DLOpenError."""
         self.unload_on_finalization = unload_on_finalization
         self.lib = lltype.nullptr(rffi.CCHARP.TO)
         ll_libname = rffi.str2charp(libname)

Modified: pypy/trunk/pypy/rlib/test/test_libffi.py
==============================================================================
--- pypy/trunk/pypy/rlib/test/test_libffi.py	(original)
+++ pypy/trunk/pypy/rlib/test/test_libffi.py	Thu Mar 18 15:40:31 2010
@@ -24,7 +24,7 @@
         ALLOCATED.clear()
 
     def test_dlopen(self):
-        py.test.raises(OSError, "dlopen(rffi.str2charp('xxxxxxxxxxxx'))")
+        py.test.raises(DLOpenError, "dlopen(rffi.str2charp('xxxxxxxxxxxx'))")
         assert dlopen(rffi.str2charp(get_libc_name()))
         
     def get_libc(self):



More information about the Pypy-commit mailing list