[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