PageRenderTime 10ms CodeModel.GetById 2ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 0ms

/Lib/ctypes/test/test_random_things.py

http://unladen-swallow.googlecode.com/
Python | 75 lines | 49 code | 13 blank | 13 comment | 2 complexity | a474060652a00805e90717efa70a2e72 MD5 | raw file
 1from ctypes import *
 2import unittest, sys
 3
 4def callback_func(arg):
 5    42 / arg
 6    raise ValueError(arg)
 7
 8if sys.platform == "win32":
 9
10    class call_function_TestCase(unittest.TestCase):
11        # _ctypes.call_function is deprecated and private, but used by
12        # Gary Bishp's readline module.  If we have it, we must test it as well.
13
14        def test(self):
15            from _ctypes import call_function
16            windll.kernel32.LoadLibraryA.restype = c_void_p
17            windll.kernel32.GetProcAddress.argtypes = c_void_p, c_char_p
18            windll.kernel32.GetProcAddress.restype = c_void_p
19
20            hdll = windll.kernel32.LoadLibraryA("kernel32")
21            funcaddr = windll.kernel32.GetProcAddress(hdll, "GetModuleHandleA")
22
23            self.failUnlessEqual(call_function(funcaddr, (None,)),
24                                 windll.kernel32.GetModuleHandleA(None))
25
26class CallbackTracbackTestCase(unittest.TestCase):
27    # When an exception is raised in a ctypes callback function, the C
28    # code prints a traceback.
29    #
30    # This test makes sure the exception types *and* the exception
31    # value is printed correctly.
32    #
33    # Changed in 0.9.3: No longer is '(in callback)' prepended to the
34    # error message - instead a additional frame for the C code is
35    # created, then a full traceback printed.  When SystemExit is
36    # raised in a callback function, the interpreter exits.
37
38    def capture_stderr(self, func, *args, **kw):
39        # helper - call function 'func', and return the captured stderr
40        import StringIO
41        old_stderr = sys.stderr
42        logger = sys.stderr = StringIO.StringIO()
43        try:
44            func(*args, **kw)
45        finally:
46            sys.stderr = old_stderr
47        return logger.getvalue()
48
49    def test_ValueError(self):
50        cb = CFUNCTYPE(c_int, c_int)(callback_func)
51        out = self.capture_stderr(cb, 42)
52        self.failUnlessEqual(out.splitlines()[-1],
53                             "ValueError: 42")
54
55    def test_IntegerDivisionError(self):
56        cb = CFUNCTYPE(c_int, c_int)(callback_func)
57        out = self.capture_stderr(cb, 0)
58        self.failUnlessEqual(out.splitlines()[-1][:19],
59                             "ZeroDivisionError: ")
60
61    def test_FloatDivisionError(self):
62        cb = CFUNCTYPE(c_int, c_double)(callback_func)
63        out = self.capture_stderr(cb, 0.0)
64        self.failUnlessEqual(out.splitlines()[-1][:19],
65                             "ZeroDivisionError: ")
66
67    def test_TypeErrorDivisionError(self):
68        cb = CFUNCTYPE(c_int, c_char_p)(callback_func)
69        out = self.capture_stderr(cb, "spam")
70        self.failUnlessEqual(out.splitlines()[-1],
71                             "TypeError: "
72                             "unsupported operand type(s) for /: 'int' and 'str'")
73
74if __name__ == '__main__':
75    unittest.main()