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

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

#countcontent
1n/afrom ctypes import *
2n/afrom ctypes.test import need_symbol
3n/aimport unittest
4n/a
5n/a# IMPORTANT INFO:
6n/a#
7n/a# Consider this call:
8n/a# func.restype = c_char_p
9n/a# func(c_char_p("123"))
10n/a# It returns
11n/a# "123"
12n/a#
13n/a# WHY IS THIS SO?
14n/a#
15n/a# argument tuple (c_char_p("123"), ) is destroyed after the function
16n/a# func is called, but NOT before the result is actually built.
17n/a#
18n/a# If the arglist would be destroyed BEFORE the result has been built,
19n/a# the c_char_p("123") object would already have a zero refcount,
20n/a# and the pointer passed to (and returned by) the function would
21n/a# probably point to deallocated space.
22n/a#
23n/a# In this case, there would have to be an additional reference to the argument...
24n/a
25n/aimport _ctypes_test
26n/atestdll = CDLL(_ctypes_test.__file__)
27n/a
28n/a# Return machine address `a` as a (possibly long) non-negative integer.
29n/a# Starting with Python 2.5, id(anything) is always non-negative, and
30n/a# the ctypes addressof() inherits that via PyLong_FromVoidPtr().
31n/adef positive_address(a):
32n/a if a >= 0:
33n/a return a
34n/a # View the bits in `a` as unsigned instead.
35n/a import struct
36n/a num_bits = struct.calcsize("P") * 8 # num bits in native machine address
37n/a a += 1 << num_bits
38n/a assert a >= 0
39n/a return a
40n/a
41n/adef c_wbuffer(init):
42n/a n = len(init) + 1
43n/a return (c_wchar * n)(*init)
44n/a
45n/aclass CharPointersTestCase(unittest.TestCase):
46n/a
47n/a def setUp(self):
48n/a func = testdll._testfunc_p_p
49n/a func.restype = c_long
50n/a func.argtypes = None
51n/a
52n/a def test_paramflags(self):
53n/a # function returns c_void_p result,
54n/a # and has a required parameter named 'input'
55n/a prototype = CFUNCTYPE(c_void_p, c_void_p)
56n/a func = prototype(("_testfunc_p_p", testdll),
57n/a ((1, "input"),))
58n/a
59n/a try:
60n/a func()
61n/a except TypeError as details:
62n/a self.assertEqual(str(details), "required argument 'input' missing")
63n/a else:
64n/a self.fail("TypeError not raised")
65n/a
66n/a self.assertEqual(func(None), None)
67n/a self.assertEqual(func(input=None), None)
68n/a
69n/a
70n/a def test_int_pointer_arg(self):
71n/a func = testdll._testfunc_p_p
72n/a if sizeof(c_longlong) == sizeof(c_void_p):
73n/a func.restype = c_longlong
74n/a else:
75n/a func.restype = c_long
76n/a self.assertEqual(0, func(0))
77n/a
78n/a ci = c_int(0)
79n/a
80n/a func.argtypes = POINTER(c_int),
81n/a self.assertEqual(positive_address(addressof(ci)),
82n/a positive_address(func(byref(ci))))
83n/a
84n/a func.argtypes = c_char_p,
85n/a self.assertRaises(ArgumentError, func, byref(ci))
86n/a
87n/a func.argtypes = POINTER(c_short),
88n/a self.assertRaises(ArgumentError, func, byref(ci))
89n/a
90n/a func.argtypes = POINTER(c_double),
91n/a self.assertRaises(ArgumentError, func, byref(ci))
92n/a
93n/a def test_POINTER_c_char_arg(self):
94n/a func = testdll._testfunc_p_p
95n/a func.restype = c_char_p
96n/a func.argtypes = POINTER(c_char),
97n/a
98n/a self.assertEqual(None, func(None))
99n/a self.assertEqual(b"123", func(b"123"))
100n/a self.assertEqual(None, func(c_char_p(None)))
101n/a self.assertEqual(b"123", func(c_char_p(b"123")))
102n/a
103n/a self.assertEqual(b"123", func(c_buffer(b"123")))
104n/a ca = c_char(b"a")
105n/a self.assertEqual(ord(b"a"), func(pointer(ca))[0])
106n/a self.assertEqual(ord(b"a"), func(byref(ca))[0])
107n/a
108n/a def test_c_char_p_arg(self):
109n/a func = testdll._testfunc_p_p
110n/a func.restype = c_char_p
111n/a func.argtypes = c_char_p,
112n/a
113n/a self.assertEqual(None, func(None))
114n/a self.assertEqual(b"123", func(b"123"))
115n/a self.assertEqual(None, func(c_char_p(None)))
116n/a self.assertEqual(b"123", func(c_char_p(b"123")))
117n/a
118n/a self.assertEqual(b"123", func(c_buffer(b"123")))
119n/a ca = c_char(b"a")
120n/a self.assertEqual(ord(b"a"), func(pointer(ca))[0])
121n/a self.assertEqual(ord(b"a"), func(byref(ca))[0])
122n/a
123n/a def test_c_void_p_arg(self):
124n/a func = testdll._testfunc_p_p
125n/a func.restype = c_char_p
126n/a func.argtypes = c_void_p,
127n/a
128n/a self.assertEqual(None, func(None))
129n/a self.assertEqual(b"123", func(b"123"))
130n/a self.assertEqual(b"123", func(c_char_p(b"123")))
131n/a self.assertEqual(None, func(c_char_p(None)))
132n/a
133n/a self.assertEqual(b"123", func(c_buffer(b"123")))
134n/a ca = c_char(b"a")
135n/a self.assertEqual(ord(b"a"), func(pointer(ca))[0])
136n/a self.assertEqual(ord(b"a"), func(byref(ca))[0])
137n/a
138n/a func(byref(c_int()))
139n/a func(pointer(c_int()))
140n/a func((c_int * 3)())
141n/a
142n/a @need_symbol('c_wchar_p')
143n/a def test_c_void_p_arg_with_c_wchar_p(self):
144n/a func = testdll._testfunc_p_p
145n/a func.restype = c_wchar_p
146n/a func.argtypes = c_void_p,
147n/a
148n/a self.assertEqual(None, func(c_wchar_p(None)))
149n/a self.assertEqual("123", func(c_wchar_p("123")))
150n/a
151n/a def test_instance(self):
152n/a func = testdll._testfunc_p_p
153n/a func.restype = c_void_p
154n/a
155n/a class X:
156n/a _as_parameter_ = None
157n/a
158n/a func.argtypes = c_void_p,
159n/a self.assertEqual(None, func(X()))
160n/a
161n/a func.argtypes = None
162n/a self.assertEqual(None, func(X()))
163n/a
164n/a@need_symbol('c_wchar')
165n/aclass WCharPointersTestCase(unittest.TestCase):
166n/a
167n/a def setUp(self):
168n/a func = testdll._testfunc_p_p
169n/a func.restype = c_int
170n/a func.argtypes = None
171n/a
172n/a
173n/a def test_POINTER_c_wchar_arg(self):
174n/a func = testdll._testfunc_p_p
175n/a func.restype = c_wchar_p
176n/a func.argtypes = POINTER(c_wchar),
177n/a
178n/a self.assertEqual(None, func(None))
179n/a self.assertEqual("123", func("123"))
180n/a self.assertEqual(None, func(c_wchar_p(None)))
181n/a self.assertEqual("123", func(c_wchar_p("123")))
182n/a
183n/a self.assertEqual("123", func(c_wbuffer("123")))
184n/a ca = c_wchar("a")
185n/a self.assertEqual("a", func(pointer(ca))[0])
186n/a self.assertEqual("a", func(byref(ca))[0])
187n/a
188n/a def test_c_wchar_p_arg(self):
189n/a func = testdll._testfunc_p_p
190n/a func.restype = c_wchar_p
191n/a func.argtypes = c_wchar_p,
192n/a
193n/a c_wchar_p.from_param("123")
194n/a
195n/a self.assertEqual(None, func(None))
196n/a self.assertEqual("123", func("123"))
197n/a self.assertEqual(None, func(c_wchar_p(None)))
198n/a self.assertEqual("123", func(c_wchar_p("123")))
199n/a
200n/a # XXX Currently, these raise TypeErrors, although they shouldn't:
201n/a self.assertEqual("123", func(c_wbuffer("123")))
202n/a ca = c_wchar("a")
203n/a self.assertEqual("a", func(pointer(ca))[0])
204n/a self.assertEqual("a", func(byref(ca))[0])
205n/a
206n/aclass ArrayTest(unittest.TestCase):
207n/a def test(self):
208n/a func = testdll._testfunc_ai8
209n/a func.restype = POINTER(c_int)
210n/a func.argtypes = c_int * 8,
211n/a
212n/a func((c_int * 8)(1, 2, 3, 4, 5, 6, 7, 8))
213n/a
214n/a # This did crash before:
215n/a
216n/a def func(): pass
217n/a CFUNCTYPE(None, c_int * 3)(func)
218n/a
219n/a################################################################
220n/a
221n/aif __name__ == '__main__':
222n/a unittest.main()