ยปCore Development>Code coverage>Lib/ctypes/test/test_funcptr.py

Python code coverage for Lib/ctypes/test/test_funcptr.py

#countcontent
1n/aimport unittest
2n/afrom ctypes import *
3n/a
4n/atry:
5n/a WINFUNCTYPE
6n/aexcept NameError:
7n/a # fake to enable this test on Linux
8n/a WINFUNCTYPE = CFUNCTYPE
9n/a
10n/aimport _ctypes_test
11n/alib = CDLL(_ctypes_test.__file__)
12n/a
13n/aclass CFuncPtrTestCase(unittest.TestCase):
14n/a def test_basic(self):
15n/a X = WINFUNCTYPE(c_int, c_int, c_int)
16n/a
17n/a def func(*args):
18n/a return len(args)
19n/a
20n/a x = X(func)
21n/a self.assertEqual(x.restype, c_int)
22n/a self.assertEqual(x.argtypes, (c_int, c_int))
23n/a self.assertEqual(sizeof(x), sizeof(c_voidp))
24n/a self.assertEqual(sizeof(X), sizeof(c_voidp))
25n/a
26n/a def test_first(self):
27n/a StdCallback = WINFUNCTYPE(c_int, c_int, c_int)
28n/a CdeclCallback = CFUNCTYPE(c_int, c_int, c_int)
29n/a
30n/a def func(a, b):
31n/a return a + b
32n/a
33n/a s = StdCallback(func)
34n/a c = CdeclCallback(func)
35n/a
36n/a self.assertEqual(s(1, 2), 3)
37n/a self.assertEqual(c(1, 2), 3)
38n/a # The following no longer raises a TypeError - it is now
39n/a # possible, as in C, to call cdecl functions with more parameters.
40n/a #self.assertRaises(TypeError, c, 1, 2, 3)
41n/a self.assertEqual(c(1, 2, 3, 4, 5, 6), 3)
42n/a if not WINFUNCTYPE is CFUNCTYPE:
43n/a self.assertRaises(TypeError, s, 1, 2, 3)
44n/a
45n/a def test_structures(self):
46n/a WNDPROC = WINFUNCTYPE(c_long, c_int, c_int, c_int, c_int)
47n/a
48n/a def wndproc(hwnd, msg, wParam, lParam):
49n/a return hwnd + msg + wParam + lParam
50n/a
51n/a HINSTANCE = c_int
52n/a HICON = c_int
53n/a HCURSOR = c_int
54n/a LPCTSTR = c_char_p
55n/a
56n/a class WNDCLASS(Structure):
57n/a _fields_ = [("style", c_uint),
58n/a ("lpfnWndProc", WNDPROC),
59n/a ("cbClsExtra", c_int),
60n/a ("cbWndExtra", c_int),
61n/a ("hInstance", HINSTANCE),
62n/a ("hIcon", HICON),
63n/a ("hCursor", HCURSOR),
64n/a ("lpszMenuName", LPCTSTR),
65n/a ("lpszClassName", LPCTSTR)]
66n/a
67n/a wndclass = WNDCLASS()
68n/a wndclass.lpfnWndProc = WNDPROC(wndproc)
69n/a
70n/a WNDPROC_2 = WINFUNCTYPE(c_long, c_int, c_int, c_int, c_int)
71n/a
72n/a # This is no longer true, now that WINFUNCTYPE caches created types internally.
73n/a ## # CFuncPtr subclasses are compared by identity, so this raises a TypeError:
74n/a ## self.assertRaises(TypeError, setattr, wndclass,
75n/a ## "lpfnWndProc", WNDPROC_2(wndproc))
76n/a # instead:
77n/a
78n/a self.assertIs(WNDPROC, WNDPROC_2)
79n/a # 'wndclass.lpfnWndProc' leaks 94 references. Why?
80n/a self.assertEqual(wndclass.lpfnWndProc(1, 2, 3, 4), 10)
81n/a
82n/a
83n/a f = wndclass.lpfnWndProc
84n/a
85n/a del wndclass
86n/a del wndproc
87n/a
88n/a self.assertEqual(f(10, 11, 12, 13), 46)
89n/a
90n/a def test_dllfunctions(self):
91n/a
92n/a def NoNullHandle(value):
93n/a if not value:
94n/a raise WinError()
95n/a return value
96n/a
97n/a strchr = lib.my_strchr
98n/a strchr.restype = c_char_p
99n/a strchr.argtypes = (c_char_p, c_char)
100n/a self.assertEqual(strchr(b"abcdefghi", b"b"), b"bcdefghi")
101n/a self.assertEqual(strchr(b"abcdefghi", b"x"), None)
102n/a
103n/a
104n/a strtok = lib.my_strtok
105n/a strtok.restype = c_char_p
106n/a # Neither of this does work: strtok changes the buffer it is passed
107n/a## strtok.argtypes = (c_char_p, c_char_p)
108n/a## strtok.argtypes = (c_string, c_char_p)
109n/a
110n/a def c_string(init):
111n/a size = len(init) + 1
112n/a return (c_char*size)(*init)
113n/a
114n/a s = b"a\nb\nc"
115n/a b = c_string(s)
116n/a
117n/a## b = (c_char * (len(s)+1))()
118n/a## b.value = s
119n/a
120n/a## b = c_string(s)
121n/a self.assertEqual(strtok(b, b"\n"), b"a")
122n/a self.assertEqual(strtok(None, b"\n"), b"b")
123n/a self.assertEqual(strtok(None, b"\n"), b"c")
124n/a self.assertEqual(strtok(None, b"\n"), None)
125n/a
126n/aif __name__ == '__main__':
127n/a unittest.main()