[pypy-svn] r50356 - pypy/branch/applevel-ctypes2/pypy/lib/app_test/ctypes
fijal at codespeak.net
fijal at codespeak.net
Sat Jan 5 16:51:25 CET 2008
Author: fijal
Date: Sat Jan 5 16:51:25 2008
New Revision: 50356
Added:
pypy/branch/applevel-ctypes2/pypy/lib/app_test/ctypes/test_numbers.py (contents, props changed)
Log:
Add ported test_numbers
Added: pypy/branch/applevel-ctypes2/pypy/lib/app_test/ctypes/test_numbers.py
==============================================================================
--- (empty file)
+++ pypy/branch/applevel-ctypes2/pypy/lib/app_test/ctypes/test_numbers.py Sat Jan 5 16:51:25 2008
@@ -0,0 +1,176 @@
+from ctypes import *
+import unittest
+import sys, struct
+
+def valid_ranges(*types):
+ # given a sequence of numeric types, collect their _type_
+ # attribute, which is a single format character compatible with
+ # the struct module, use the struct module to calculate the
+ # minimum and maximum value allowed for this format.
+ # Returns a list of (min, max) values.
+ result = []
+ for t in types:
+ fmt = t._type_
+ size = struct.calcsize(fmt)
+ a = struct.unpack(fmt, ("\x00"*32)[:size])[0]
+ b = struct.unpack(fmt, ("\xFF"*32)[:size])[0]
+ c = struct.unpack(fmt, ("\x7F"+"\x00"*32)[:size])[0]
+ d = struct.unpack(fmt, ("\x80"+"\xFF"*32)[:size])[0]
+ result.append((min(a, b, c, d), max(a, b, c, d)))
+ return result
+
+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]
+
+float_types = [c_double, c_float]
+
+try:
+ c_ulonglong
+ c_longlong
+except NameError:
+ pass
+else:
+ unsigned_types.append(c_ulonglong)
+ signed_types.append(c_longlong)
+
+unsigned_ranges = valid_ranges(*unsigned_types)
+signed_ranges = valid_ranges(*signed_types)
+
+################################################################
+
+class TestNumber:
+ def test_default_init(self):
+ # default values are set to zero
+ for t in signed_types + unsigned_types + float_types:
+ assert t().value == 0
+
+ def test_unsigned_values(self):
+ # the value given to the constructor is available
+ # as the 'value' attribute
+ for t, (l, h) in zip(unsigned_types, unsigned_ranges):
+ assert t(l).value == l
+ assert t(h).value == h
+
+ def test_signed_values(self):
+ # see above
+ for t, (l, h) in zip(signed_types, signed_ranges):
+ assert t(l).value == l
+ assert t(h).value == h
+
+ def test_typeerror(self):
+ # Only numbers are allowed in the contructor,
+ # otherwise TypeError is raised
+ for t in signed_types + unsigned_types + float_types:
+ raises(TypeError, t, "")
+ raises(TypeError, t, None)
+
+## def test_valid_ranges(self):
+## # invalid values of the correct type
+## # raise ValueError (not OverflowError)
+## for t, (l, h) in zip(unsigned_types, unsigned_ranges):
+## self.assertRaises(ValueError, t, l-1)
+## self.assertRaises(ValueError, t, h+1)
+
+ def test_from_param(self):
+ # the from_param class method attribute always
+ # returns PyCArgObject instances
+ for t in signed_types + unsigned_types + float_types:
+ assert ArgType == type(t.from_param(0))
+
+ def test_byref(self):
+ # calling byref returns also a PyCArgObject instance
+ for t in signed_types + unsigned_types + float_types:
+ parm = byref(t())
+ assert ArgType == type(parm)
+
+
+ def test_floats(self):
+ # c_float and c_double can be created from
+ # Python int, long and float
+ for t in float_types:
+ assert t(2.0).value == 2.0
+ assert t(2).value == 2.0
+ assert t(2L).value == 2.0
+
+ def test_integers(self):
+ # integers cannot be constructed from floats
+ for t in signed_types + unsigned_types:
+ raises(TypeError, t, 3.14)
+
+ def test_sizes(self):
+ for t in signed_types + unsigned_types + float_types:
+ size = struct.calcsize(t._type_)
+ # sizeof of the type...
+ assert sizeof(t) == size
+ # and sizeof of an instance
+ assert sizeof(t()) == size
+
+ def test_alignments(self):
+ for t in signed_types + unsigned_types + float_types:
+ code = t._type_ # the typecode
+ align = struct.calcsize("c%c" % code) - struct.calcsize(code)
+
+ # alignment of the type...
+ assert (code, alignment(t)) == (code, align)
+ # and alignment of an instance
+ assert (code, alignment(t())) == (code, align)
+
+ def test_int_from_address(self):
+ from array import array
+ for t in signed_types + unsigned_types:
+ # the array module doesn't suppport all format codes
+ # (no 'q' or 'Q')
+ try:
+ array(t._type_)
+ except ValueError:
+ continue
+ a = array(t._type_, [100])
+
+ # v now is an integer at an 'external' memory location
+ v = t.from_address(a.buffer_info()[0])
+ assert v.value == a[0]
+ assert type(v) == t
+
+ # changing the value at the memory location changes v's value also
+ a[0] = 42
+ assert v.value == a[0]
+
+
+ def test_float_from_address(self):
+ from array import array
+ for t in float_types:
+ a = array(t._type_, [3.14])
+ v = t.from_address(a.buffer_info()[0])
+ assert v.value == a[0]
+ assert type(v) is t
+ a[0] = 2.3456e17
+ assert v.value == a[0]
+ assert type(v) is t
+
+ def test_char_from_address(self):
+ from ctypes import c_char
+ from array import array
+
+ a = array('c', 'x')
+ v = c_char.from_address(a.buffer_info()[0])
+ assert v.value == a[0]
+ assert type(v) is c_char
+
+ a[0] = '?'
+ assert v.value == a[0]
+
+ 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
+ # probably be changed:
+ raises(TypeError, c_int, c_long(42))
+
+## def test_perf(self):
+## check_perf()
+
+from ctypes import _SimpleCData
+class c_int_S(_SimpleCData):
+ _type_ = "i"
+ __slots__ = []
More information about the Pypy-commit
mailing list