diff options
Diffstat (limited to 'Lib/ctypes')
-rw-r--r-- | Lib/ctypes/__init__.py | 7 | ||||
-rw-r--r-- | Lib/ctypes/test/test_functions.py | 14 | ||||
-rw-r--r-- | Lib/ctypes/test/test_memfunctions.py | 2 | ||||
-rw-r--r-- | Lib/ctypes/test/test_numbers.py | 31 | ||||
-rw-r--r-- | Lib/ctypes/test/test_repr.py | 2 |
5 files changed, 50 insertions, 6 deletions
diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py index e2ea426..bd9b66e 100644 --- a/Lib/ctypes/__init__.py +++ b/Lib/ctypes/__init__.py @@ -233,6 +233,9 @@ class c_void_p(_SimpleCData): c_voidp = c_void_p # backwards compatibility (to a bug) _check_size(c_void_p) +class c_bool(_SimpleCData): + _type_ = "t" + # This cache maps types to pointers to them. _pointer_type_cache = {} @@ -480,7 +483,7 @@ def cast(obj, typ): return _cast(obj, obj, typ) _string_at = CFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr) -def string_at(ptr, size=0): +def string_at(ptr, size=-1): """string_at(addr[, size]) -> string Return the string at addr.""" @@ -492,7 +495,7 @@ except ImportError: pass else: _wstring_at = CFUNCTYPE(py_object, c_void_p, c_int)(_wstring_at_addr) - def wstring_at(ptr, size=0): + def wstring_at(ptr, size=-1): """wstring_at(addr[, size]) -> string Return the string at addr.""" diff --git a/Lib/ctypes/test/test_functions.py b/Lib/ctypes/test/test_functions.py index e907e21..40892b9 100644 --- a/Lib/ctypes/test/test_functions.py +++ b/Lib/ctypes/test/test_functions.py @@ -21,7 +21,9 @@ if sys.platform == "win32": class POINT(Structure): _fields_ = [("x", c_int), ("y", c_int)] - +class RECT(Structure): + _fields_ = [("left", c_int), ("top", c_int), + ("right", c_int), ("bottom", c_int)] class FunctionTestCase(unittest.TestCase): def test_mro(self): @@ -379,5 +381,15 @@ class FunctionTestCase(unittest.TestCase): self.failUnlessEqual((s8i.a, s8i.b, s8i.c, s8i.d, s8i.e, s8i.f, s8i.g, s8i.h), (9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9)) + def test_sf1651235(self): + # see http://www.python.org/sf/1651235 + + proto = CFUNCTYPE(c_int, RECT, POINT) + def callback(*args): + return 0 + + callback = proto(callback) + self.failUnlessRaises(ArgumentError, lambda: callback((1, 2, 3, 4), POINT())) + if __name__ == '__main__': unittest.main() diff --git a/Lib/ctypes/test/test_memfunctions.py b/Lib/ctypes/test/test_memfunctions.py index fbae2ce..aef7a73 100644 --- a/Lib/ctypes/test/test_memfunctions.py +++ b/Lib/ctypes/test/test_memfunctions.py @@ -14,6 +14,7 @@ class MemFunctionsTest(unittest.TestCase): self.failUnlessEqual(string_at(result), "Hello, World") self.failUnlessEqual(string_at(result, 5), "Hello") self.failUnlessEqual(string_at(result, 16), "Hello, World\0\0\0\0") + self.failUnlessEqual(string_at(result, 0), "") def test_memset(self): a = create_string_buffer(1000000) @@ -54,6 +55,7 @@ class MemFunctionsTest(unittest.TestCase): self.failUnlessEqual(wstring_at(a), "Hello, World") self.failUnlessEqual(wstring_at(a, 5), "Hello") self.failUnlessEqual(wstring_at(a, 16), "Hello, World\0\0\0\0") + self.failUnlessEqual(wstring_at(a, 0), "") if __name__ == "__main__": unittest.main() diff --git a/Lib/ctypes/test/test_numbers.py b/Lib/ctypes/test/test_numbers.py index 2c5a990..eaabc7c 100644 --- a/Lib/ctypes/test/test_numbers.py +++ b/Lib/ctypes/test/test_numbers.py @@ -24,6 +24,8 @@ ArgType = type(byref(c_int(0))) unsigned_types = [c_ubyte, c_ushort, c_uint, c_ulong] signed_types = [c_byte, c_short, c_int, c_long, c_longlong] +bool_types = [] + float_types = [c_double, c_float] try: @@ -35,8 +37,16 @@ else: unsigned_types.append(c_ulonglong) signed_types.append(c_longlong) +try: + c_bool +except NameError: + pass +else: + bool_types.append(c_bool) + unsigned_ranges = valid_ranges(*unsigned_types) signed_ranges = valid_ranges(*signed_types) +bool_values = [True, False, 0, 1, -1, 5000, 'test', [], [1]] ################################################################ @@ -60,6 +70,11 @@ class NumberTestCase(unittest.TestCase): self.failUnlessEqual(t(l).value, l) self.failUnlessEqual(t(h).value, h) + def test_bool_values(self): + from operator import truth + for t, v in zip(bool_types, bool_values): + self.failUnlessEqual(t(v).value, truth(v)) + def test_typeerror(self): # Only numbers are allowed in the contructor, # otherwise TypeError is raised @@ -82,7 +97,7 @@ class NumberTestCase(unittest.TestCase): def test_byref(self): # calling byref returns also a PyCArgObject instance - for t in signed_types + unsigned_types + float_types: + for t in signed_types + unsigned_types + float_types + bool_types: parm = byref(t()) self.failUnlessEqual(ArgType, type(parm)) @@ -101,7 +116,7 @@ class NumberTestCase(unittest.TestCase): self.assertRaises(TypeError, t, 3.14) def test_sizes(self): - for t in signed_types + unsigned_types + float_types: + for t in signed_types + unsigned_types + float_types + bool_types: size = struct.calcsize(t._type_) # sizeof of the type... self.failUnlessEqual(sizeof(t), size) @@ -164,6 +179,18 @@ class NumberTestCase(unittest.TestCase): a[0] = '?' self.failUnlessEqual(v.value, a[0]) + # array does not support c_bool / 't' + # def test_bool_from_address(self): + # from ctypes import c_bool + # from array import array + # a = array(c_bool._type_, [True]) + # v = t.from_address(a.buffer_info()[0]) + # self.failUnlessEqual(v.value, a[0]) + # self.failUnlessEqual(type(v) is t) + # a[0] = False + # self.failUnlessEqual(v.value, a[0]) + # self.failUnlessEqual(type(v) is t) + def test_init(self): # c_int() can be initialized from Python's int, and c_int. # Not from c_long or so, which seems strange, abd should diff --git a/Lib/ctypes/test/test_repr.py b/Lib/ctypes/test/test_repr.py index 1044f67..f6f9366 100644 --- a/Lib/ctypes/test/test_repr.py +++ b/Lib/ctypes/test/test_repr.py @@ -4,7 +4,7 @@ import unittest subclasses = [] for base in [c_byte, c_short, c_int, c_long, c_longlong, c_ubyte, c_ushort, c_uint, c_ulong, c_ulonglong, - c_float, c_double]: + c_float, c_double, c_bool]: class X(base): pass subclasses.append(X) |