[Python-checkins] r45625 - in python/trunk/Lib/ctypes: __init__.py _loader.py test/test_bitfields.py test/test_byteswap.py test/test_callbacks.py test/test_cast.py test/test_cfuncs.py test/test_checkretval.py test/test_find.py test/test_funcptr.py test/test_functions.py test/test_libc.py test/test_loading.py test/test_pointers.py test/test_posix.py test/test_prototypes.py test/test_refcounts.py test/test_returnfuncptrs.py test/test_slicing.py test/test_stringptr.py test/test_unicode.py test/test_values.py test/test_win32.py util.py

thomas.heller python-checkins at python.org
Fri Apr 21 18:51:05 CEST 2006


Author: thomas.heller
Date: Fri Apr 21 18:51:04 2006
New Revision: 45625

Added:
   python/trunk/Lib/ctypes/test/test_find.py
   python/trunk/Lib/ctypes/util.py
Removed:
   python/trunk/Lib/ctypes/_loader.py
   python/trunk/Lib/ctypes/test/test_posix.py
Modified:
   python/trunk/Lib/ctypes/__init__.py
   python/trunk/Lib/ctypes/test/test_bitfields.py
   python/trunk/Lib/ctypes/test/test_byteswap.py
   python/trunk/Lib/ctypes/test/test_callbacks.py
   python/trunk/Lib/ctypes/test/test_cast.py
   python/trunk/Lib/ctypes/test/test_cfuncs.py
   python/trunk/Lib/ctypes/test/test_checkretval.py
   python/trunk/Lib/ctypes/test/test_funcptr.py
   python/trunk/Lib/ctypes/test/test_functions.py
   python/trunk/Lib/ctypes/test/test_libc.py
   python/trunk/Lib/ctypes/test/test_loading.py
   python/trunk/Lib/ctypes/test/test_pointers.py
   python/trunk/Lib/ctypes/test/test_prototypes.py
   python/trunk/Lib/ctypes/test/test_refcounts.py
   python/trunk/Lib/ctypes/test/test_returnfuncptrs.py
   python/trunk/Lib/ctypes/test/test_slicing.py
   python/trunk/Lib/ctypes/test/test_stringptr.py
   python/trunk/Lib/ctypes/test/test_unicode.py
   python/trunk/Lib/ctypes/test/test_values.py
   python/trunk/Lib/ctypes/test/test_win32.py
Log:
Merge in changes from ctypes 0.9.9.6 upstream version.

Modified: python/trunk/Lib/ctypes/__init__.py
==============================================================================
--- python/trunk/Lib/ctypes/__init__.py	(original)
+++ python/trunk/Lib/ctypes/__init__.py	Fri Apr 21 18:51:04 2006
@@ -3,7 +3,7 @@
 import os as _os, sys as _sys
 from itertools import chain as _chain
 
-__version__ = "0.9.9.4"
+__version__ = "0.9.9.6"
 
 from _ctypes import Union, Structure, Array
 from _ctypes import _Pointer
@@ -23,8 +23,6 @@
 from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL, \
      FUNCFLAG_PYTHONAPI as _FUNCFLAG_PYTHONAPI
 
-from ctypes._loader import LibraryLoader
-
 """
 WINOLEAPI -> HRESULT
 WINOLEAPI_(type)
@@ -72,9 +70,11 @@
     The function prototype can be called in three ways to create a
     callable object:
 
-    prototype(funct) - returns a C callable function calling funct
-    prototype(vtbl_index, method_name[, paramflags]) - a Python callable that calls a COM method
-    prototype(funct_name, dll[, paramflags]) - a Python callable that calls an exported function in a dll
+    prototype(integer address) -> foreign function
+    prototype(callable) -> create and return a C callable function from callable
+    prototype(integer index, method name[, paramflags]) -> foreign function calling a COM method
+    prototype((ordinal number, dll object)[, paramflags]) -> foreign function exported by ordinal
+    prototype((function name, dll object)[, paramflags]) -> foreign function exported by name
     """
     try:
         return _c_functype_cache[(restype, argtypes)]
@@ -352,6 +352,23 @@
             _flags_ = _FUNCFLAG_STDCALL
             _restype_ = HRESULT
 
+class LibraryLoader(object):
+    def __init__(self, dlltype):
+        self._dlltype = dlltype
+
+    def __getattr__(self, name):
+        if name[0] == '_':
+            raise AttributeError(name)
+        dll = self._dlltype(name)
+        setattr(self, name, dll)
+        return dll
+
+    def __getitem__(self, name):
+        return getattr(self, name)
+
+    def LoadLibrary(self, name):
+        return self._dlltype(name)
+
 cdll = LibraryLoader(CDLL)
 pydll = LibraryLoader(PyDLL)
 
@@ -402,7 +419,12 @@
         _restype_ = restype
         _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
     return CFunctionType
-cast = PYFUNCTYPE(py_object, c_void_p, py_object)(_cast_addr)
+_cast = PYFUNCTYPE(py_object, c_void_p, py_object)(_cast_addr)
+
+def cast(obj, typ):
+    result = _cast(obj, typ)
+    result.__keepref = obj
+    return result
 
 _string_at = CFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr)
 def string_at(ptr, size=0):

Deleted: /python/trunk/Lib/ctypes/_loader.py
==============================================================================
--- /python/trunk/Lib/ctypes/_loader.py	Fri Apr 21 18:51:04 2006
+++ (empty file)
@@ -1,262 +0,0 @@
-import sys, os
-import ctypes
-
-if os.name in ("nt", "ce"):
-    from _ctypes import LoadLibrary as dlopen
-else:
-    from _ctypes import dlopen
-from _ctypes import RTLD_LOCAL, RTLD_GLOBAL
-
-# _findLib(name) returns an iterable of possible names for a library.
-if os.name in ("nt", "ce"):
-    def _findLib(name):
-        return [name]
-
-if os.name == "posix" and sys.platform == "darwin":
-    from ctypes.macholib.dyld import dyld_find as _dyld_find
-    def _findLib(name):
-        possible = ['lib%s.dylib' % name,
-                    '%s.dylib' % name,
-                    '%s.framework/%s' % (name, name)]
-        for name in possible:
-            try:
-                return [_dyld_find(name)]
-            except ValueError:
-                continue
-        return []
-
-elif os.name == "posix":
-    # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump
-    import re, tempfile
-
-    def _findLib_gcc(name):
-        expr = '[^\(\)\s]*lib%s\.[^\(\)\s]*' % name
-        cmd = 'if type gcc &>/dev/null; then CC=gcc; else CC=cc; fi;' \
-              '$CC -Wl,-t -o /dev/null 2>&1 -l' + name
-        try:
-            fdout, outfile =  tempfile.mkstemp()
-            fd = os.popen(cmd)
-            trace = fd.read()
-            err = fd.close()
-        finally:
-            try:
-                os.unlink(outfile)
-            except OSError, e:
-                if e.errno != errno.ENOENT:
-                    raise
-        res = re.search(expr, trace)
-        if not res:
-            return None
-        return res.group(0)
-
-    def _findLib_ld(name):
-        expr = '/[^\(\)\s]*lib%s\.[^\(\)\s]*' % name
-        res = re.search(expr, os.popen('/sbin/ldconfig -p 2>/dev/null').read())
-        if not res:
-            cmd = 'ldd %s 2>/dev/null' % sys.executable
-            res = re.search(expr, os.popen(cmd).read())
-            if not res:
-                return None
-        return res.group(0)
-
-    def _get_soname(f):
-        cmd = "objdump -p -j .dynamic 2>/dev/null " + f
-        res = re.search(r'\sSONAME\s+([^\s]+)', os.popen(cmd).read())
-        if not res:
-            return f
-        return res.group(1)
-
-    def _findLib(name):
-        lib = _findLib_ld(name)
-        if not lib:
-            lib = _findLib_gcc(name)
-            if not lib:
-                return [name]
-        return [_get_soname(lib)]
-
-class LibraryLoader(object):
-    """Loader for shared libraries.
-
-    Shared libraries are accessed when compiling/linking a program,
-    and when the program is run.  The purpose of the 'find' method is
-    to locate a library similar to what the compiler does (on machines
-    with several versions of a shared library the most recent should
-    be loaded), while 'load' acts like when the program is run, and
-    uses the runtime loader directly.  'load_version' works like
-    'load' but tries to be platform independend (for cases where this
-    makes sense).  Loading via attribute access is a shorthand
-    notation especially useful for interactive use."""
-
-
-    def __init__(self, dlltype, mode=RTLD_LOCAL):
-        """Create a library loader instance which loads libraries by
-        creating an instance of 'dlltype'.  'mode' can be RTLD_LOCAL
-        or RTLD_GLOBAL, it is ignored on Windows.
-        """
-        self._dlltype = dlltype
-        self._mode = mode
-
-    def load(self, libname, mode=None):
-        """Load and return the library with the given libname.  On
-        most systems 'libname' is the filename of the shared library;
-        when it's not a pathname it will be searched in a system
-        dependend list of locations (on many systems additional search
-        paths can be specified by an environment variable).  Sometimes
-        the extension (like '.dll' on Windows) can be omitted.
-
-        'mode' allows to override the default flags specified in the
-        constructor, it is ignored on Windows.
-        """
-        if mode is None:
-            mode = self._mode
-        return self._load(libname, mode)
-
-    def load_library(self, libname, mode=None):
-        """Load and return the library with the given libname.  This
-        method passes the specified 'libname' directly to the
-        platform's library loading function (dlopen, or LoadLibrary).
-
-        'mode' allows to override the default flags specified in the
-        constructor, it is ignored on Windows.
-        """
-        if mode is None:
-            mode = self._mode
-        return self._dlltype(libname, mode)
-
-    # alias name for backwards compatiblity
-    LoadLibrary = load_library
-
-    # Helpers for load and load_version - assembles a filename from name and filename
-    if os.name in ("nt", "ce"):
-        # Windows (XXX what about cygwin?)
-        def _plat_load_version(self, name, version, mode):
-            # not sure if this makes sense
-            if version is not None:
-                return self.load(name + version, mode)
-            return self.load(name, mode)
-
-        _load = load_library
-
-    elif os.name == "posix" and sys.platform == "darwin":
-        # Mac OS X
-        def _plat_load_version(self, name, version, mode):
-            if version:
-                return self.load("lib%s.%s.dylib" % (name, version), mode)
-            return self.load("lib%s.dylib" % name, mode)
-
-        def _load(self, libname, mode):
-            # _dyld_find raises ValueError, convert this into OSError
-            try:
-                pathname = _dyld_find(libname)
-            except ValueError:
-                raise OSError("Library %s could not be found" % libname)
-            return self.load_library(pathname, mode)
-
-    elif os.name == "posix":
-        # Posix
-        def _plat_load_version(self, name, version, mode):
-            if version:
-                return self.load("lib%s.so.%s" % (name, version), mode)
-            return self.load("lib%s.so" % name, mode)
-
-        _load = load_library
-
-    else:
-        # Others, TBD
-        def _plat_load_version(self, name, version, mode=None):
-            return self.load(name, mode)
-
-        _load = load_library
-
-    def load_version(self, name, version=None, mode=None):
-        """Build a (system dependend) filename from 'name' and
-        'version', then load and return it.  'name' is the library
-        name without any prefix like 'lib' and suffix like '.so' or
-        '.dylib'.  This method should be used if a library is
-        available on different platforms, using the particular naming
-        convention of each platform.
-
-        'mode' allows to override the default flags specified in the
-        constructor, it is ignored on Windows.
-        """
-        return self._plat_load_version(name, version, mode)
-
-    def find(self, name, mode=None):
-        """Try to find a library, load and return it.  'name' is the
-        library name without any prefix like 'lib', suffix like '.so',
-        '.dylib' or version number (this is the form used for the
-        posix linker option '-l').
-
-        'mode' allows to override the default flags specified in the
-        constructor, it is ignored on Windows.
-
-        On windows, this method does the same as the 'load' method.
-
-        On other platforms, this function might call other programs
-        like the compiler to find the library.  When using ctypes to
-        write a shared library wrapping, consider using .load() or
-        .load_version() instead.
-        """
-        for libname in _findLib(name):
-            try:
-                return self.load(libname, mode)
-            except OSError:
-                continue
-        raise OSError("Library %r not found" % name)
-
-    def __getattr__(self, name):
-        """Load a library via attribute access.  Calls
-        .load_version().  The result is cached."""
-        if name.startswith("_"):
-            raise AttributeError(name)
-        dll = self.load_version(name)
-        setattr(self, name, dll)
-        return dll
-
-################################################################
-# test code
-
-class CDLL(object):
-    def __init__(self, name, mode):
-        self._handle = dlopen(name, mode)
-        self._name = name
-
-    def __repr__(self):
-        return "<%s '%s', handle %x at %x>" % \
-               (self.__class__.__name__, self._name,
-                (self._handle & (sys.maxint*2 + 1)),
-                id(self))
-
-cdll = LibraryLoader(CDLL)
-
-def test():
-    if os.name == "nt":
-        print cdll.msvcrt
-        print cdll.load("msvcrt")
-        # load_version looks more like an artefact:
-        print cdll.load_version("msvcr", "t")
-        print cdll.find("msvcrt")
-
-    if os.name == "posix":
-        # find and load_version
-        print cdll.find("m")
-        print cdll.find("c")
-        print cdll.load_version("crypto", "0.9.7")
-
-        # getattr
-        print cdll.m
-        print cdll.bz2
-
-        # load
-        if sys.platform == "darwin":
-            print cdll.load("libm.dylib")
-            print cdll.load("libcrypto.dylib")
-            print cdll.load("libSystem.dylib")
-            print cdll.load("System.framework/System")
-        else:
-            print cdll.load("libm.so")
-            print cdll.load("libcrypt.so")
-            print cdll.find("crypt")
-
-if __name__ == "__main__":
-    test()

Modified: python/trunk/Lib/ctypes/test/test_bitfields.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_bitfields.py	(original)
+++ python/trunk/Lib/ctypes/test/test_bitfields.py	Fri Apr 21 18:51:04 2006
@@ -24,7 +24,7 @@
                 ("R", c_short, 6),
                 ("S", c_short, 7)]
 
-func = cdll.load(_ctypes_test.__file__).unpack_bitfields
+func = CDLL(_ctypes_test.__file__).unpack_bitfields
 func.argtypes = POINTER(BITS), c_char
 
 ##for n in "ABCDEFGHIMNOPQRS":

Modified: python/trunk/Lib/ctypes/test/test_byteswap.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_byteswap.py	(original)
+++ python/trunk/Lib/ctypes/test/test_byteswap.py	Fri Apr 21 18:51:04 2006
@@ -15,7 +15,7 @@
 
 class Test(unittest.TestCase):
     def X_test(self):
-        print sys.byteorder
+        print >> sys.stderr,  sys.byteorder
         for i in range(32):
             bits = BITS()
             setattr(bits, "i%s" % i, 1)

Modified: python/trunk/Lib/ctypes/test/test_callbacks.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_callbacks.py	(original)
+++ python/trunk/Lib/ctypes/test/test_callbacks.py	Fri Apr 21 18:51:04 2006
@@ -115,7 +115,7 @@
 
     def test_integrate(self):
         # Derived from some then non-working code, posted by David Foster
-        dll = cdll.load(_ctypes_test.__file__)
+        dll = CDLL(_ctypes_test.__file__)
 
         # The function prototype called by 'integrate': double func(double);
         CALLBACK = CFUNCTYPE(c_double, c_double)

Modified: python/trunk/Lib/ctypes/test/test_cast.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_cast.py	(original)
+++ python/trunk/Lib/ctypes/test/test_cast.py	Fri Apr 21 18:51:04 2006
@@ -23,33 +23,24 @@
     def test_address2pointer(self):
         array = (c_int * 3)(42, 17, 2)
 
-        # on AMD64, sizeof(int) == 4 and sizeof(void *) == 8.
-        # By default, cast would convert a Python int (or long) into
-        # a C int, which would be too short to represent a pointer
-        # on this platform.
-
-        # So we have to wrap the address into a c_void_p for this to work.
-        #
-        # XXX Better would be to hide the differences in the cast function.
         address = addressof(array)
         ptr = cast(c_void_p(address), POINTER(c_int))
         self.failUnlessEqual([ptr[i] for i in range(3)], [42, 17, 2])
 
+        ptr = cast(address, POINTER(c_int))
+        self.failUnlessEqual([ptr[i] for i in range(3)], [42, 17, 2])
+
 
     def test_ptr2array(self):
         array = (c_int * 3)(42, 17, 2)
 
-##        # Hm, already tested above.
-##        ptr = cast(array, POINTER(c_int))
-##        self.failUnlessEqual([ptr[i] for i in range(3)], [42, 17, 2])
-
-#        print cast(addressof(array), c_int * 3)[:]
-##        ptr = cast(addressof(ptr)
-
-##        print ptr[0], ptr[1], ptr[2]
-##        ptr = POINTER(c_int).from_address(addressof(array))
-##        # XXX this crashes:
-##        print ptr[0], ptr[1], ptr[2]
+        from sys import getrefcount
+
+        before = getrefcount(array)
+        ptr = cast(array, POINTER(c_int))
+        self.failUnlessEqual(getrefcount(array), before + 1)
+        del ptr
+        self.failUnlessEqual(getrefcount(array), before)
 
 if __name__ == "__main__":
     unittest.main()

Modified: python/trunk/Lib/ctypes/test/test_cfuncs.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_cfuncs.py	(original)
+++ python/trunk/Lib/ctypes/test/test_cfuncs.py	Fri Apr 21 18:51:04 2006
@@ -7,7 +7,7 @@
 import _ctypes_test
 
 class CFunctions(unittest.TestCase):
-    _dll = cdll.load(_ctypes_test.__file__)
+    _dll = CDLL(_ctypes_test.__file__)
 
     def S(self):
         return c_longlong.in_dll(self._dll, "last_tf_arg_s").value

Modified: python/trunk/Lib/ctypes/test/test_checkretval.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_checkretval.py	(original)
+++ python/trunk/Lib/ctypes/test/test_checkretval.py	Fri Apr 21 18:51:04 2006
@@ -14,7 +14,7 @@
     def test_checkretval(self):
 
         import _ctypes_test
-        dll = cdll.load(_ctypes_test.__file__)
+        dll = CDLL(_ctypes_test.__file__)
         self.failUnlessEqual(42, dll._testfunc_p_p(42))
 
         dll._testfunc_p_p.restype = CHECKED

Added: python/trunk/Lib/ctypes/test/test_find.py
==============================================================================
--- (empty file)
+++ python/trunk/Lib/ctypes/test/test_find.py	Fri Apr 21 18:51:04 2006
@@ -0,0 +1,90 @@
+import unittest
+import os, sys
+from ctypes import *
+from ctypes.util import find_library
+from ctypes.test import is_resource_enabled
+
+if sys.platform == "win32":
+    lib_gl = find_library("OpenGL32")
+    lib_glu = find_library("Glu32")
+    lib_glut = find_library("glut32")
+    lib_gle = None
+elif sys.platform == "darwin":
+    lib_gl = lib_glu = find_library("OpenGL")
+    lib_glut = find_library("GLUT")
+    lib_gle = None
+else:
+    lib_gl = find_library("GL")
+    lib_glu = find_library("GLU")
+    lib_glut = find_library("glut")
+    lib_gle = find_library("gle")
+
+## print, for debugging
+if is_resource_enabled("printing"):
+    if lib_gl or lib_glu or lib_glut or lib_gle:
+        print "OpenGL libraries:"
+        for item in (("GL", lib_gl),
+                     ("GLU", lib_glu),
+                     ("glut", lib_glut),
+                     ("gle", lib_gle)):
+            print "\t", item
+
+
+# On some systems, loading the OpenGL libraries needs the RTLD_GLOBAL mode.
+class Test_OpenGL_libs(unittest.TestCase):
+    def setUp(self):
+        self.gl = self.glu = self.gle = self.glut = None
+        if lib_gl:
+            self.gl = CDLL(lib_gl, mode=RTLD_GLOBAL)
+        if lib_glu:
+            self.glu = CDLL(lib_glu, RTLD_GLOBAL)
+        if lib_glut:
+            self.glut = CDLL(lib_glut)
+        if lib_gle:
+            self.gle = CDLL(lib_gle)
+
+    if lib_gl:
+        def test_gl(self):
+            if self.gl:
+                self.gl.glClearIndex
+
+    if lib_glu:
+        def test_glu(self):
+            if self.glu:
+                self.glu.gluBeginCurve
+
+    if lib_glut:
+        def test_glut(self):
+            if self.glut:
+                self.glut.glutWireTetrahedron
+
+    if lib_gle:
+        def test_gle(self):
+            if self.gle:
+                self.gle.gleGetJoinStyle
+
+##if os.name == "posix" and sys.platform != "darwin":
+
+##    # On platforms where the default shared library suffix is '.so',
+##    # at least some libraries can be loaded as attributes of the cdll
+##    # object, since ctypes now tries loading the lib again
+##    # with '.so' appended of the first try fails.
+##    #
+##    # Won't work for libc, unfortunately.  OTOH, it isn't
+##    # needed for libc since this is already mapped into the current
+##    # process (?)
+##    #
+##    # On MAC OSX, it won't work either, because dlopen() needs a full path,
+##    # and the default suffix is either none or '.dylib'.
+
+##    class LoadLibs(unittest.TestCase):
+##        def test_libm(self):
+##            import math
+##            libm = cdll.libm
+##            sqrt = libm.sqrt
+##            sqrt.argtypes = (c_double,)
+##            sqrt.restype = c_double
+##            self.failUnlessEqual(sqrt(2), math.sqrt(2))
+
+if __name__ == "__main__":
+    unittest.main()

Modified: python/trunk/Lib/ctypes/test/test_funcptr.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_funcptr.py	(original)
+++ python/trunk/Lib/ctypes/test/test_funcptr.py	Fri Apr 21 18:51:04 2006
@@ -8,7 +8,7 @@
     WINFUNCTYPE = CFUNCTYPE
 
 import _ctypes_test
-lib = cdll.load(_ctypes_test.__file__)
+lib = CDLL(_ctypes_test.__file__)
 
 class CFuncPtrTestCase(unittest.TestCase):
     def test_basic(self):

Modified: python/trunk/Lib/ctypes/test/test_functions.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_functions.py	(original)
+++ python/trunk/Lib/ctypes/test/test_functions.py	Fri Apr 21 18:51:04 2006
@@ -15,9 +15,9 @@
     WINFUNCTYPE = CFUNCTYPE
 
 import _ctypes_test
-dll = cdll.load(_ctypes_test.__file__)
+dll = CDLL(_ctypes_test.__file__)
 if sys.platform == "win32":
-    windll = windll.load(_ctypes_test.__file__)
+    windll = WinDLL(_ctypes_test.__file__)
 
 class POINT(Structure):
     _fields_ = [("x", c_int), ("y", c_int)]

Modified: python/trunk/Lib/ctypes/test/test_libc.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_libc.py	(original)
+++ python/trunk/Lib/ctypes/test/test_libc.py	Fri Apr 21 18:51:04 2006
@@ -4,7 +4,7 @@
 from ctypes import *
 import _ctypes_test
 
-lib = cdll.load(_ctypes_test.__file__)
+lib = CDLL(_ctypes_test.__file__)
 
 class LibTest(unittest.TestCase):
     def test_sqrt(self):

Modified: python/trunk/Lib/ctypes/test/test_loading.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_loading.py	(original)
+++ python/trunk/Lib/ctypes/test/test_loading.py	Fri Apr 21 18:51:04 2006
@@ -1,6 +1,8 @@
 from ctypes import *
 import sys, unittest
 import os, StringIO
+from ctypes.util import find_library
+from ctypes.test import is_resource_enabled
 
 libc_name = None
 if os.name == "nt":
@@ -18,39 +20,49 @@
                 libc_name = line.split()[4]
             else:
                 libc_name = line.split()[2]
-##            print "libc_name is", libc_name
             break
 
+if is_resource_enabled("printing"):
+    print "libc_name is", libc_name
+
 class LoaderTest(unittest.TestCase):
 
     unknowndll = "xxrandomnamexx"
 
     if libc_name is not None:
         def test_load(self):
-            cdll.load(libc_name)
-            cdll.load(os.path.basename(libc_name))
-            self.assertRaises(OSError, cdll.load, self.unknowndll)
+            CDLL(libc_name)
+            CDLL(os.path.basename(libc_name))
+            self.assertRaises(OSError, CDLL, self.unknowndll)
 
     if libc_name is not None and os.path.basename(libc_name) == "libc.so.6":
         def test_load_version(self):
-            cdll.load_version("c", "6")
+            cdll.LoadLibrary("libc.so.6")
             # linux uses version, libc 9 should not exist
-            self.assertRaises(OSError, cdll.load_version, "c", "9")
-            self.assertRaises(OSError, cdll.load_version, self.unknowndll, "")
+            self.assertRaises(OSError, cdll.LoadLibrary, "libc.so.9")
+            self.assertRaises(OSError, cdll.LoadLibrary, self.unknowndll)
 
-        def test_find(self):
-            name = "c"
-            cdll.find(name)
-            self.assertRaises(OSError, cdll.find, self.unknowndll)
+    def test_find(self):
+        for name in ("c", "m"):
+            lib = find_library(name)
+            if lib:
+                cdll.LoadLibrary(lib)
+                CDLL(lib)
 
     if os.name in ("nt", "ce"):
         def test_load_library(self):
+            if is_resource_enabled("printing"):
+                print find_library("kernel32")
+                print find_library("user32")
+
             if os.name == "nt":
-                windll.load_library("kernel32").GetModuleHandleW
+                windll.kernel32.GetModuleHandleW
+                windll["kernel32"].GetModuleHandleW
                 windll.LoadLibrary("kernel32").GetModuleHandleW
                 WinDLL("kernel32").GetModuleHandleW
             elif os.name == "ce":
-                windll.load_library("coredll").GetModuleHandleW
+                windll.coredll.GetModuleHandleW
+                windll["coredll"].GetModuleHandleW
                 windll.LoadLibrary("coredll").GetModuleHandleW
                 WinDLL("coredll").GetModuleHandleW
 

Modified: python/trunk/Lib/ctypes/test/test_pointers.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_pointers.py	(original)
+++ python/trunk/Lib/ctypes/test/test_pointers.py	Fri Apr 21 18:51:04 2006
@@ -20,7 +20,7 @@
         self.failUnlessRaises(TypeError, A, c_ulong(33))
 
     def test_pass_pointers(self):
-        dll = cdll.load(_ctypes_test.__file__)
+        dll = CDLL(_ctypes_test.__file__)
         func = dll._testfunc_p_p
         func.restype = c_long
 
@@ -35,7 +35,7 @@
         self.failUnlessEqual(res[0], 12345678)
 
     def test_change_pointers(self):
-        dll = cdll.load(_ctypes_test.__file__)
+        dll = CDLL(_ctypes_test.__file__)
         func = dll._testfunc_p_p
 
         i = c_int(87654)
@@ -70,7 +70,7 @@
             return 0
         callback = PROTOTYPE(func)
 
-        dll = cdll.load(_ctypes_test.__file__)
+        dll = CDLL(_ctypes_test.__file__)
         # This function expects a function pointer,
         # and calls this with an integer pointer as parameter.
         # The int pointer points to a table containing the numbers 1..10
@@ -156,7 +156,7 @@
 
     def test_charpp( self ):
         """Test that a character pointer-to-pointer is correctly passed"""
-        dll = cdll.load(_ctypes_test.__file__)
+        dll = CDLL(_ctypes_test.__file__)
         func = dll._testfunc_c_p_p
         func.restype = c_char_p
         argv = (c_char_p * 2)()

Deleted: /python/trunk/Lib/ctypes/test/test_posix.py
==============================================================================
--- /python/trunk/Lib/ctypes/test/test_posix.py	Fri Apr 21 18:51:04 2006
+++ (empty file)
@@ -1,40 +0,0 @@
-import unittest, os, sys
-from ctypes import *
-
-if os.name == "posix" and sys.platform == "linux2":
-    # I don't really know on which platforms this works,
-    # later it should use the find_library stuff to avoid
-    # hardcoding the names.
-
-    class TestRTLD_GLOBAL(unittest.TestCase):
-        def test_GL(self):
-            if os.path.exists('/usr/lib/libGL.so'):
-                cdll.load('libGL.so', mode=RTLD_GLOBAL)
-            if os.path.exists('/usr/lib/libGLU.so'):
-                cdll.load('libGLU.so')
-
-##if os.name == "posix" and sys.platform != "darwin":
-
-##    # On platforms where the default shared library suffix is '.so',
-##    # at least some libraries can be loaded as attributes of the cdll
-##    # object, since ctypes now tries loading the lib again
-##    # with '.so' appended of the first try fails.
-##    #
-##    # Won't work for libc, unfortunately.  OTOH, it isn't
-##    # needed for libc since this is already mapped into the current
-##    # process (?)
-##    #
-##    # On MAC OSX, it won't work either, because dlopen() needs a full path,
-##    # and the default suffix is either none or '.dylib'.
-
-##    class LoadLibs(unittest.TestCase):
-##        def test_libm(self):
-##            import math
-##            libm = cdll.libm
-##            sqrt = libm.sqrt
-##            sqrt.argtypes = (c_double,)
-##            sqrt.restype = c_double
-##            self.failUnlessEqual(sqrt(2), math.sqrt(2))
-
-if __name__ == "__main__":
-    unittest.main()

Modified: python/trunk/Lib/ctypes/test/test_prototypes.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_prototypes.py	(original)
+++ python/trunk/Lib/ctypes/test/test_prototypes.py	Fri Apr 21 18:51:04 2006
@@ -22,7 +22,7 @@
 # In this case, there would have to be an additional reference to the argument...
 
 import _ctypes_test
-testdll = cdll.load(_ctypes_test.__file__)
+testdll = CDLL(_ctypes_test.__file__)
 
 # Return machine address `a` as a (possibly long) non-negative integer.
 # Starting with Python 2.5, id(anything) is always non-negative, and

Modified: python/trunk/Lib/ctypes/test/test_refcounts.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_refcounts.py	(original)
+++ python/trunk/Lib/ctypes/test/test_refcounts.py	Fri Apr 21 18:51:04 2006
@@ -6,7 +6,7 @@
 OtherCallback = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_ulonglong)
 
 import _ctypes_test
-dll = ctypes.cdll.load(_ctypes_test.__file__)
+dll = ctypes.CDLL(_ctypes_test.__file__)
 
 class RefcountTestCase(unittest.TestCase):
 

Modified: python/trunk/Lib/ctypes/test/test_returnfuncptrs.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_returnfuncptrs.py	(original)
+++ python/trunk/Lib/ctypes/test/test_returnfuncptrs.py	Fri Apr 21 18:51:04 2006
@@ -8,7 +8,7 @@
     def test_with_prototype(self):
         # The _ctypes_test shared lib/dll exports quite some functions for testing.
         # The get_strchr function returns a *pointer* to the C strchr function.
-        dll = cdll.load(_ctypes_test.__file__)
+        dll = CDLL(_ctypes_test.__file__)
         get_strchr = dll.get_strchr
         get_strchr.restype = CFUNCTYPE(c_char_p, c_char_p, c_char)
         strchr = get_strchr()
@@ -18,7 +18,7 @@
         self.assertRaises(TypeError, strchr, "abcdef")
 
     def test_without_prototype(self):
-        dll = cdll.load(_ctypes_test.__file__)
+        dll = CDLL(_ctypes_test.__file__)
         get_strchr = dll.get_strchr
         # the default 'c_int' would not work on systems where sizeof(int) != sizeof(void *)
         get_strchr.restype = c_void_p

Modified: python/trunk/Lib/ctypes/test/test_slicing.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_slicing.py	(original)
+++ python/trunk/Lib/ctypes/test/test_slicing.py	Fri Apr 21 18:51:04 2006
@@ -37,7 +37,7 @@
     def test_char_ptr(self):
         s = "abcdefghijklmnopqrstuvwxyz\0"
 
-        dll = cdll.load(_ctypes_test.__file__)
+        dll = CDLL(_ctypes_test.__file__)
         dll.my_strdup.restype = POINTER(c_char)
         res = dll.my_strdup(s)
         self.failUnlessEqual(res[:len(s)], s)
@@ -65,7 +65,7 @@
         def test_wchar_ptr(self):
             s = u"abcdefghijklmnopqrstuvwxyz\0"
 
-            dll = cdll.load(_ctypes_test.__file__)
+            dll = CDLL(_ctypes_test.__file__)
             dll.my_wcsdup.restype = POINTER(c_wchar)
             dll.my_wcsdup.argtypes = POINTER(c_wchar),
             res = dll.my_wcsdup(s)

Modified: python/trunk/Lib/ctypes/test/test_stringptr.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_stringptr.py	(original)
+++ python/trunk/Lib/ctypes/test/test_stringptr.py	Fri Apr 21 18:51:04 2006
@@ -3,7 +3,7 @@
 
 import _ctypes_test
 
-lib = cdll.load(_ctypes_test.__file__)
+lib = CDLL(_ctypes_test.__file__)
 
 class StringPtrTestCase(unittest.TestCase):
 

Modified: python/trunk/Lib/ctypes/test/test_unicode.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_unicode.py	(original)
+++ python/trunk/Lib/ctypes/test/test_unicode.py	Fri Apr 21 18:51:04 2006
@@ -8,7 +8,7 @@
     pass
 else:
     import _ctypes_test
-    dll = ctypes.cdll.load(_ctypes_test.__file__)
+    dll = ctypes.CDLL(_ctypes_test.__file__)
     wcslen = dll.my_wcslen
     wcslen.argtypes = [ctypes.c_wchar_p]
 
@@ -66,7 +66,7 @@
             self.failUnlessEqual(buf[:], u"ab\0\0\0\0")
 
     import _ctypes_test
-    func = ctypes.cdll.load(_ctypes_test.__file__)._testfunc_p_p
+    func = ctypes.CDLL(_ctypes_test.__file__)._testfunc_p_p
 
     class StringTestCase(UnicodeTestCase):
         def setUp(self):

Modified: python/trunk/Lib/ctypes/test/test_values.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_values.py	(original)
+++ python/trunk/Lib/ctypes/test/test_values.py	Fri Apr 21 18:51:04 2006
@@ -10,7 +10,7 @@
 class ValuesTestCase(unittest.TestCase):
 
     def test_an_integer(self):
-        ctdll = cdll.load(_ctypes_test.__file__)
+        ctdll = CDLL(_ctypes_test.__file__)
         an_integer = c_int.in_dll(ctdll, "an_integer")
         x = an_integer.value
         self.failUnlessEqual(x, ctdll.get_an_integer())
@@ -18,7 +18,7 @@
         self.failUnlessEqual(x*2, ctdll.get_an_integer())
 
     def test_undefined(self):
-        ctdll = cdll.load(_ctypes_test.__file__)
+        ctdll = CDLL(_ctypes_test.__file__)
         self.assertRaises(ValueError, c_int.in_dll, ctdll, "Undefined_Symbol")
 
     class Win_ValuesTestCase(unittest.TestCase):

Modified: python/trunk/Lib/ctypes/test/test_win32.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_win32.py	(original)
+++ python/trunk/Lib/ctypes/test/test_win32.py	Fri Apr 21 18:51:04 2006
@@ -54,7 +54,7 @@
                         ("right", c_long),
                         ("bottom", c_long)]
 
-        dll = cdll.load(_ctypes_test.__file__)
+        dll = CDLL(_ctypes_test.__file__)
 
         pt = POINT(10, 10)
         rect = RECT(0, 0, 20, 20)

Added: python/trunk/Lib/ctypes/util.py
==============================================================================
--- (empty file)
+++ python/trunk/Lib/ctypes/util.py	Fri Apr 21 18:51:04 2006
@@ -0,0 +1,122 @@
+import sys, os
+import ctypes
+
+# find_library(name) returns the pathname of a library, or None.
+if os.name == "nt":
+    def find_library(name):
+        # See MSDN for the REAL search order.
+        for directory in os.environ['PATH'].split(os.pathsep):
+            fname = os.path.join(directory, name)
+            if os.path.exists(fname):
+                return fname
+            if fname.lower().endswith(".dll"):
+                continue
+            fname = fname + ".dll"
+            if os.path.exists(fname):
+                return fname
+        return None
+
+if os.name == "ce":
+    # search path according to MSDN:
+    # - absolute path specified by filename
+    # - The .exe launch directory
+    # - the Windows directory
+    # - ROM dll files (where are they?)
+    # - OEM specified search path: HKLM\Loader\SystemPath
+    def find_library(name):
+        return name
+
+if os.name == "posix" and sys.platform == "darwin":
+    from ctypes.macholib.dyld import dyld_find as _dyld_find
+    def find_library(name):
+        possible = ['lib%s.dylib' % name,
+                    '%s.dylib' % name,
+                    '%s.framework/%s' % (name, name)]
+        for name in possible:
+            try:
+                return _dyld_find(name)
+            except ValueError:
+                continue
+        return None
+
+elif os.name == "posix":
+    # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump
+    import re, tempfile
+
+    def _findLib_gcc(name):
+        expr = '[^\(\)\s]*lib%s\.[^\(\)\s]*' % name
+        cmd = 'if type gcc &>/dev/null; then CC=gcc; else CC=cc; fi;' \
+              '$CC -Wl,-t -o /dev/null 2>&1 -l' + name
+        try:
+            fdout, outfile =  tempfile.mkstemp()
+            fd = os.popen(cmd)
+            trace = fd.read()
+            err = fd.close()
+        finally:
+            try:
+                os.unlink(outfile)
+            except OSError, e:
+                if e.errno != errno.ENOENT:
+                    raise
+        res = re.search(expr, trace)
+        if not res:
+            return None
+        return res.group(0)
+
+    def _findLib_ld(name):
+        expr = '/[^\(\)\s]*lib%s\.[^\(\)\s]*' % name
+        res = re.search(expr, os.popen('/sbin/ldconfig -p 2>/dev/null').read())
+        if not res:
+            # Hm, this works only for libs needed by the python executable.
+            cmd = 'ldd %s 2>/dev/null' % sys.executable
+            res = re.search(expr, os.popen(cmd).read())
+            if not res:
+                return None
+        return res.group(0)
+
+    def _get_soname(f):
+        cmd = "objdump -p -j .dynamic 2>/dev/null " + f
+        res = re.search(r'\sSONAME\s+([^\s]+)', os.popen(cmd).read())
+        if not res:
+            return None
+        return res.group(1)
+
+    def find_library(name):
+        lib = _findLib_ld(name) or _findLib_gcc(name)
+        if not lib:
+            return None
+        return _get_soname(lib)
+
+################################################################
+# test code
+
+def test():
+    from ctypes import cdll
+    if os.name == "nt":
+        print cdll.msvcrt
+        print cdll.load("msvcrt")
+        print find_library("msvcrt")
+
+    if os.name == "posix":
+        # find and load_version
+        print find_library("m")
+        print find_library("c")
+        print find_library("bz2")
+
+        # getattr
+##        print cdll.m
+##        print cdll.bz2
+
+        # load
+        if sys.platform == "darwin":
+            print cdll.LoadLibrary("libm.dylib")
+            print cdll.LoadLibrary("libcrypto.dylib")
+            print cdll.LoadLibrary("libSystem.dylib")
+            print cdll.LoadLibrary("System.framework/System")
+        else:
+            print cdll.LoadLibrary("libm.so")
+            print cdll.LoadLibrary("libcrypt.so")
+            print find_library("crypt")
+
+if __name__ == "__main__":
+    test()


More information about the Python-checkins mailing list