summaryrefslogtreecommitdiff
path: root/Lib/ctypes/test
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/ctypes/test')
-rw-r--r--Lib/ctypes/test/test_byteswap.py70
-rw-r--r--Lib/ctypes/test/test_cfuncs.py2
-rw-r--r--Lib/ctypes/test/test_keeprefs.py5
-rw-r--r--Lib/ctypes/test/test_loading.py80
-rw-r--r--Lib/ctypes/test/test_pointers.py12
-rw-r--r--Lib/ctypes/test/test_posix.py6
-rw-r--r--Lib/ctypes/test/test_prototypes.py16
-rw-r--r--Lib/ctypes/test/test_random_things.py10
-rw-r--r--Lib/ctypes/test/test_sizes.py3
-rw-r--r--Lib/ctypes/test/test_unaligned_structures.py45
10 files changed, 209 insertions, 40 deletions
diff --git a/Lib/ctypes/test/test_byteswap.py b/Lib/ctypes/test/test_byteswap.py
index 1b31f90229..d0ada40229 100644
--- a/Lib/ctypes/test/test_byteswap.py
+++ b/Lib/ctypes/test/test_byteswap.py
@@ -149,7 +149,7 @@ class Test(unittest.TestCase):
self.failUnless(c_char.__ctype_le__ is c_char)
self.failUnless(c_char.__ctype_be__ is c_char)
- def test_struct_fields(self):
+ def test_struct_fields_1(self):
if sys.byteorder == "little":
base = BigEndianStructure
else:
@@ -198,17 +198,20 @@ class Test(unittest.TestCase):
pass
self.assertRaises(TypeError, setattr, S, "_fields_", [("s", T)])
- # crashes on solaris with a core dump.
- def X_test_struct_fields(self):
+ def test_struct_fields_2(self):
+ # standard packing in struct uses no alignment.
+ # So, we have to align using pad bytes.
+ #
+ # Unaligned accesses will crash Python (on those platforms that
+ # don't allow it, like sparc solaris).
if sys.byteorder == "little":
base = BigEndianStructure
- fmt = ">bhid"
+ fmt = ">bxhid"
else:
base = LittleEndianStructure
- fmt = "<bhid"
+ fmt = "<bxhid"
class S(base):
- _pack_ = 1 # struct with '<' or '>' uses standard alignment.
_fields_ = [("b", c_byte),
("h", c_short),
("i", c_int),
@@ -218,5 +221,60 @@ class Test(unittest.TestCase):
s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14)
self.failUnlessEqual(bin(s1), bin(s2))
+ def test_unaligned_nonnative_struct_fields(self):
+ if sys.byteorder == "little":
+ base = BigEndianStructure
+ fmt = ">b h xi xd"
+ else:
+ base = LittleEndianStructure
+ fmt = "<b h xi xd"
+
+ class S(base):
+ _pack_ = 1
+ _fields_ = [("b", c_byte),
+
+ ("h", c_short),
+
+ ("_1", c_byte),
+ ("i", c_int),
+
+ ("_2", c_byte),
+ ("d", c_double)]
+
+ s1 = S()
+ s1.b = 0x12
+ s1.h = 0x1234
+ s1.i = 0x12345678
+ s1.d = 3.14
+ s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14)
+ self.failUnlessEqual(bin(s1), bin(s2))
+
+ def test_unaligned_native_struct_fields(self):
+ if sys.byteorder == "little":
+ fmt = "<b h xi xd"
+ else:
+ base = LittleEndianStructure
+ fmt = ">b h xi xd"
+
+ class S(Structure):
+ _pack_ = 1
+ _fields_ = [("b", c_byte),
+
+ ("h", c_short),
+
+ ("_1", c_byte),
+ ("i", c_int),
+
+ ("_2", c_byte),
+ ("d", c_double)]
+
+ s1 = S()
+ s1.b = 0x12
+ s1.h = 0x1234
+ s1.i = 0x12345678
+ s1.d = 3.14
+ s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14)
+ self.failUnlessEqual(bin(s1), bin(s2))
+
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/ctypes/test/test_cfuncs.py b/Lib/ctypes/test/test_cfuncs.py
index 7c2b28be7c..6e0798d1f4 100644
--- a/Lib/ctypes/test/test_cfuncs.py
+++ b/Lib/ctypes/test/test_cfuncs.py
@@ -179,7 +179,7 @@ else:
def __getattr__(self, name):
if name[:2] == '__' and name[-2:] == '__':
raise AttributeError, name
- func = self._FuncPtr("s_" + name, self)
+ func = self._FuncPtr(("s_" + name, self))
setattr(self, name, func)
return func
diff --git a/Lib/ctypes/test/test_keeprefs.py b/Lib/ctypes/test/test_keeprefs.py
index 39e70e335c..7318f290e6 100644
--- a/Lib/ctypes/test/test_keeprefs.py
+++ b/Lib/ctypes/test/test_keeprefs.py
@@ -140,5 +140,10 @@ class PointerToStructure(unittest.TestCase):
r.a[0].x = 42
r.a[0].y = 99
+ # to avoid leaking when tests are run several times
+ # clean up the types left in the cache.
+ from ctypes import _pointer_type_cache
+ del _pointer_type_cache[POINT]
+
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/ctypes/test/test_loading.py b/Lib/ctypes/test/test_loading.py
index 80564b8295..4558417518 100644
--- a/Lib/ctypes/test/test_loading.py
+++ b/Lib/ctypes/test/test_loading.py
@@ -2,40 +2,72 @@ from ctypes import *
import sys, unittest
import os, StringIO
+libc_name = None
+if os.name == "nt":
+ libc_name = "msvcrt"
+elif os.name == "ce":
+ libc_name = "coredll"
+elif sys.platform == "darwin":
+ libc_name = "libc.dylib"
+elif sys.platform == "cygwin":
+ libc_name = "cygwin1.dll"
+else:
+ for line in os.popen("ldd %s" % sys.executable):
+ if "libc.so" in line:
+ if sys.platform == "openbsd3":
+ libc_name = line.split()[4]
+ else:
+ libc_name = line.split()[2]
+## print "libc_name is", libc_name
+ break
+
class LoaderTest(unittest.TestCase):
unknowndll = "xxrandomnamexx"
- def test_load(self):
- if os.name == "nt":
- name = "msvcrt"
- elif os.name == "ce":
- name = "coredll"
- elif sys.platform == "darwin":
- name = "libc.dylib"
- elif sys.platform.startswith("freebsd"):
- name = "libc.so"
- elif sys.platform == "sunos5":
- name = "libc.so"
- else:
- name = "libc.so.6"
- cdll.load(name)
- self.assertRaises(OSError, cdll.load, self.unknowndll)
-
- def test_load_version(self):
- version = "6"
- name = "c"
- if sys.platform == "linux2":
- cdll.load_version(name, version)
+ 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)
+
+ 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")
# linux uses version, libc 9 should not exist
- self.assertRaises(OSError, cdll.load_version, name, "9")
- self.assertRaises(OSError, cdll.load_version, self.unknowndll, "")
+ self.assertRaises(OSError, cdll.load_version, "c", "9")
+ self.assertRaises(OSError, cdll.load_version, self.unknowndll, "")
- if os.name == "posix" and sys.platform != "sunos5":
def test_find(self):
name = "c"
cdll.find(name)
self.assertRaises(OSError, cdll.find, self.unknowndll)
+ if os.name in ("nt", "ce"):
+ def test_load_library(self):
+ if os.name == "nt":
+ windll.load_library("kernel32").GetModuleHandleW
+ windll.LoadLibrary("kernel32").GetModuleHandleW
+ WinDLL("kernel32").GetModuleHandleW
+ elif os.name == "ce":
+ windll.load_library("coredll").GetModuleHandleW
+ windll.LoadLibrary("coredll").GetModuleHandleW
+ WinDLL("coredll").GetModuleHandleW
+
+ def test_load_ordinal_functions(self):
+ import _ctypes_test
+ dll = WinDLL(_ctypes_test.__file__)
+ # We load the same function both via ordinal and name
+ func_ord = dll[2]
+ func_name = dll.GetString
+ # addressof gets the address where the function pointer is stored
+ a_ord = addressof(func_ord)
+ a_name = addressof(func_name)
+ f_ord_addr = c_void_p.from_address(a_ord).value
+ f_name_addr = c_void_p.from_address(a_name).value
+ self.failUnlessEqual(hex(f_ord_addr), hex(f_name_addr))
+
+ self.failUnlessRaises(AttributeError, dll.__getitem__, 1234)
+
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/ctypes/test/test_pointers.py b/Lib/ctypes/test/test_pointers.py
index 6172abb1f6..3a324a67c3 100644
--- a/Lib/ctypes/test/test_pointers.py
+++ b/Lib/ctypes/test/test_pointers.py
@@ -166,6 +166,18 @@ class PointersTestCase(unittest.TestCase):
result = func( byref(argc), argv )
assert result == 'world', result
+ def test_bug_1467852(self):
+ # http://sourceforge.net/tracker/?func=detail&atid=532154&aid=1467852&group_id=71702
+ x = c_int(5)
+ dummy = []
+ for i in range(32000):
+ dummy.append(c_int(i))
+ y = c_int(6)
+ p = pointer(x)
+ pp = pointer(p)
+ q = pointer(y)
+ pp[0] = q # <==
+ self.failUnlessEqual(p[0], 6)
if __name__ == '__main__':
unittest.main()
diff --git a/Lib/ctypes/test/test_posix.py b/Lib/ctypes/test/test_posix.py
index 2b4fdff17a..fe0a40a1ae 100644
--- a/Lib/ctypes/test/test_posix.py
+++ b/Lib/ctypes/test/test_posix.py
@@ -8,8 +8,10 @@ if os.name == "posix" and sys.platform == "linux2":
class TestRTLD_GLOBAL(unittest.TestCase):
def test_GL(self):
- cdll.load('libGL.so', mode=RTLD_GLOBAL)
- cdll.load('libGLU.so')
+ 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":
diff --git a/Lib/ctypes/test/test_prototypes.py b/Lib/ctypes/test/test_prototypes.py
index 2c3d75b522..47f5da1091 100644
--- a/Lib/ctypes/test/test_prototypes.py
+++ b/Lib/ctypes/test/test_prototypes.py
@@ -24,6 +24,19 @@ import unittest
import _ctypes_test
testdll = cdll.load(_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
+# the ctypes addressof() inherits that via PyLong_FromVoidPtr().
+def positive_address(a):
+ if a >= 0:
+ return a
+ # View the bits in `a` as unsigned instead.
+ import struct
+ num_bits = struct.calcsize("P") * 8 # num bits in native machine address
+ a += 1L << num_bits
+ assert a >= 0
+ return a
+
def c_wbuffer(init):
n = len(init) + 1
return (c_wchar * n)(*init)
@@ -43,7 +56,8 @@ class CharPointersTestCase(unittest.TestCase):
ci = c_int(0)
func.argtypes = POINTER(c_int),
- self.failUnlessEqual(addressof(ci), func(byref(ci)))
+ self.failUnlessEqual(positive_address(addressof(ci)),
+ positive_address(func(byref(ci))))
func.argtypes = c_char_p,
self.assertRaises(ArgumentError, func, byref(ci))
diff --git a/Lib/ctypes/test/test_random_things.py b/Lib/ctypes/test/test_random_things.py
index cd50ca8981..78a665bc5f 100644
--- a/Lib/ctypes/test/test_random_things.py
+++ b/Lib/ctypes/test/test_random_things.py
@@ -51,16 +51,14 @@ class CallbackTracbackTestCase(unittest.TestCase):
def test_IntegerDivisionError(self):
cb = CFUNCTYPE(c_int, c_int)(callback_func)
out = self.capture_stderr(cb, 0)
- self.failUnlessEqual(out.splitlines()[-1],
- "ZeroDivisionError: "
- "integer division or modulo by zero")
+ self.failUnlessEqual(out.splitlines()[-1][:19],
+ "ZeroDivisionError: ")
def test_FloatDivisionError(self):
cb = CFUNCTYPE(c_int, c_double)(callback_func)
out = self.capture_stderr(cb, 0.0)
- self.failUnlessEqual(out.splitlines()[-1],
- "ZeroDivisionError: "
- "float division")
+ self.failUnlessEqual(out.splitlines()[-1][:19],
+ "ZeroDivisionError: ")
def test_TypeErrorDivisionError(self):
cb = CFUNCTYPE(c_int, c_char_p)(callback_func)
diff --git a/Lib/ctypes/test/test_sizes.py b/Lib/ctypes/test/test_sizes.py
index 6fb9ca0377..208c00efcb 100644
--- a/Lib/ctypes/test/test_sizes.py
+++ b/Lib/ctypes/test/test_sizes.py
@@ -20,5 +20,8 @@ class SizesTestCase(unittest.TestCase):
self.failUnlessEqual(8, sizeof(c_int64))
self.failUnlessEqual(8, sizeof(c_uint64))
+ def test_size_t(self):
+ self.failUnlessEqual(sizeof(c_void_p), sizeof(c_size_t))
+
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/ctypes/test/test_unaligned_structures.py b/Lib/ctypes/test/test_unaligned_structures.py
new file mode 100644
index 0000000000..89343ba48e
--- /dev/null
+++ b/Lib/ctypes/test/test_unaligned_structures.py
@@ -0,0 +1,45 @@
+import sys, unittest
+from ctypes import *
+
+structures = []
+byteswapped_structures = []
+
+
+if sys.byteorder == "little":
+ SwappedStructure = BigEndianStructure
+else:
+ SwappedStructure = LittleEndianStructure
+
+for typ in [c_short, c_int, c_long, c_longlong,
+ c_float, c_double,
+ c_ushort, c_uint, c_ulong, c_ulonglong]:
+ class X(Structure):
+ _pack_ = 1
+ _fields_ = [("pad", c_byte),
+ ("value", typ)]
+ class Y(SwappedStructure):
+ _pack_ = 1
+ _fields_ = [("pad", c_byte),
+ ("value", typ)]
+ structures.append(X)
+ byteswapped_structures.append(Y)
+
+class TestStructures(unittest.TestCase):
+ def test_native(self):
+ for typ in structures:
+## print typ.value
+ self.failUnlessEqual(typ.value.offset, 1)
+ o = typ()
+ o.value = 4
+ self.failUnlessEqual(o.value, 4)
+
+ def test_swapped(self):
+ for typ in byteswapped_structures:
+## print >> sys.stderr, typ.value
+ self.failUnlessEqual(typ.value.offset, 1)
+ o = typ()
+ o.value = 4
+ self.failUnlessEqual(o.value, 4)
+
+if __name__ == '__main__':
+ unittest.main()