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

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

#countcontent
1n/afrom ctypes import *
2n/aimport unittest
3n/aimport struct
4n/a
5n/adef valid_ranges(*types):
6n/a # given a sequence of numeric types, collect their _type_
7n/a # attribute, which is a single format character compatible with
8n/a # the struct module, use the struct module to calculate the
9n/a # minimum and maximum value allowed for this format.
10n/a # Returns a list of (min, max) values.
11n/a result = []
12n/a for t in types:
13n/a fmt = t._type_
14n/a size = struct.calcsize(fmt)
15n/a a = struct.unpack(fmt, (b"\x00"*32)[:size])[0]
16n/a b = struct.unpack(fmt, (b"\xFF"*32)[:size])[0]
17n/a c = struct.unpack(fmt, (b"\x7F"+b"\x00"*32)[:size])[0]
18n/a d = struct.unpack(fmt, (b"\x80"+b"\xFF"*32)[:size])[0]
19n/a result.append((min(a, b, c, d), max(a, b, c, d)))
20n/a return result
21n/a
22n/aArgType = type(byref(c_int(0)))
23n/a
24n/aunsigned_types = [c_ubyte, c_ushort, c_uint, c_ulong]
25n/asigned_types = [c_byte, c_short, c_int, c_long, c_longlong]
26n/a
27n/abool_types = []
28n/a
29n/afloat_types = [c_double, c_float]
30n/a
31n/atry:
32n/a c_ulonglong
33n/a c_longlong
34n/aexcept NameError:
35n/a pass
36n/aelse:
37n/a unsigned_types.append(c_ulonglong)
38n/a signed_types.append(c_longlong)
39n/a
40n/atry:
41n/a c_bool
42n/aexcept NameError:
43n/a pass
44n/aelse:
45n/a bool_types.append(c_bool)
46n/a
47n/aunsigned_ranges = valid_ranges(*unsigned_types)
48n/asigned_ranges = valid_ranges(*signed_types)
49n/abool_values = [True, False, 0, 1, -1, 5000, 'test', [], [1]]
50n/a
51n/a################################################################
52n/a
53n/aclass NumberTestCase(unittest.TestCase):
54n/a
55n/a def test_default_init(self):
56n/a # default values are set to zero
57n/a for t in signed_types + unsigned_types + float_types:
58n/a self.assertEqual(t().value, 0)
59n/a
60n/a def test_unsigned_values(self):
61n/a # the value given to the constructor is available
62n/a # as the 'value' attribute
63n/a for t, (l, h) in zip(unsigned_types, unsigned_ranges):
64n/a self.assertEqual(t(l).value, l)
65n/a self.assertEqual(t(h).value, h)
66n/a
67n/a def test_signed_values(self):
68n/a # see above
69n/a for t, (l, h) in zip(signed_types, signed_ranges):
70n/a self.assertEqual(t(l).value, l)
71n/a self.assertEqual(t(h).value, h)
72n/a
73n/a def test_bool_values(self):
74n/a from operator import truth
75n/a for t, v in zip(bool_types, bool_values):
76n/a self.assertEqual(t(v).value, truth(v))
77n/a
78n/a def test_typeerror(self):
79n/a # Only numbers are allowed in the constructor,
80n/a # otherwise TypeError is raised
81n/a for t in signed_types + unsigned_types + float_types:
82n/a self.assertRaises(TypeError, t, "")
83n/a self.assertRaises(TypeError, t, None)
84n/a
85n/a @unittest.skip('test disabled')
86n/a def test_valid_ranges(self):
87n/a # invalid values of the correct type
88n/a # raise ValueError (not OverflowError)
89n/a for t, (l, h) in zip(unsigned_types, unsigned_ranges):
90n/a self.assertRaises(ValueError, t, l-1)
91n/a self.assertRaises(ValueError, t, h+1)
92n/a
93n/a def test_from_param(self):
94n/a # the from_param class method attribute always
95n/a # returns PyCArgObject instances
96n/a for t in signed_types + unsigned_types + float_types:
97n/a self.assertEqual(ArgType, type(t.from_param(0)))
98n/a
99n/a def test_byref(self):
100n/a # calling byref returns also a PyCArgObject instance
101n/a for t in signed_types + unsigned_types + float_types + bool_types:
102n/a parm = byref(t())
103n/a self.assertEqual(ArgType, type(parm))
104n/a
105n/a
106n/a def test_floats(self):
107n/a # c_float and c_double can be created from
108n/a # Python int and float
109n/a class FloatLike(object):
110n/a def __float__(self):
111n/a return 2.0
112n/a f = FloatLike()
113n/a for t in float_types:
114n/a self.assertEqual(t(2.0).value, 2.0)
115n/a self.assertEqual(t(2).value, 2.0)
116n/a self.assertEqual(t(2).value, 2.0)
117n/a self.assertEqual(t(f).value, 2.0)
118n/a
119n/a def test_integers(self):
120n/a class FloatLike(object):
121n/a def __float__(self):
122n/a return 2.0
123n/a f = FloatLike()
124n/a class IntLike(object):
125n/a def __int__(self):
126n/a return 2
127n/a i = IntLike()
128n/a # integers cannot be constructed from floats,
129n/a # but from integer-like objects
130n/a for t in signed_types + unsigned_types:
131n/a self.assertRaises(TypeError, t, 3.14)
132n/a self.assertRaises(TypeError, t, f)
133n/a self.assertEqual(t(i).value, 2)
134n/a
135n/a def test_sizes(self):
136n/a for t in signed_types + unsigned_types + float_types + bool_types:
137n/a try:
138n/a size = struct.calcsize(t._type_)
139n/a except struct.error:
140n/a continue
141n/a # sizeof of the type...
142n/a self.assertEqual(sizeof(t), size)
143n/a # and sizeof of an instance
144n/a self.assertEqual(sizeof(t()), size)
145n/a
146n/a def test_alignments(self):
147n/a for t in signed_types + unsigned_types + float_types:
148n/a code = t._type_ # the typecode
149n/a align = struct.calcsize("c%c" % code) - struct.calcsize(code)
150n/a
151n/a # alignment of the type...
152n/a self.assertEqual((code, alignment(t)),
153n/a (code, align))
154n/a # and alignment of an instance
155n/a self.assertEqual((code, alignment(t())),
156n/a (code, align))
157n/a
158n/a def test_int_from_address(self):
159n/a from array import array
160n/a for t in signed_types + unsigned_types:
161n/a # the array module doesn't support all format codes
162n/a # (no 'q' or 'Q')
163n/a try:
164n/a array(t._type_)
165n/a except ValueError:
166n/a continue
167n/a a = array(t._type_, [100])
168n/a
169n/a # v now is an integer at an 'external' memory location
170n/a v = t.from_address(a.buffer_info()[0])
171n/a self.assertEqual(v.value, a[0])
172n/a self.assertEqual(type(v), t)
173n/a
174n/a # changing the value at the memory location changes v's value also
175n/a a[0] = 42
176n/a self.assertEqual(v.value, a[0])
177n/a
178n/a
179n/a def test_float_from_address(self):
180n/a from array import array
181n/a for t in float_types:
182n/a a = array(t._type_, [3.14])
183n/a v = t.from_address(a.buffer_info()[0])
184n/a self.assertEqual(v.value, a[0])
185n/a self.assertIs(type(v), t)
186n/a a[0] = 2.3456e17
187n/a self.assertEqual(v.value, a[0])
188n/a self.assertIs(type(v), t)
189n/a
190n/a def test_char_from_address(self):
191n/a from ctypes import c_char
192n/a from array import array
193n/a
194n/a a = array('b', [0])
195n/a a[0] = ord('x')
196n/a v = c_char.from_address(a.buffer_info()[0])
197n/a self.assertEqual(v.value, b'x')
198n/a self.assertIs(type(v), c_char)
199n/a
200n/a a[0] = ord('?')
201n/a self.assertEqual(v.value, b'?')
202n/a
203n/a # array does not support c_bool / 't'
204n/a @unittest.skip('test disabled')
205n/a def test_bool_from_address(self):
206n/a from ctypes import c_bool
207n/a from array import array
208n/a a = array(c_bool._type_, [True])
209n/a v = t.from_address(a.buffer_info()[0])
210n/a self.assertEqual(v.value, a[0])
211n/a self.assertEqual(type(v) is t)
212n/a a[0] = False
213n/a self.assertEqual(v.value, a[0])
214n/a self.assertEqual(type(v) is t)
215n/a
216n/a def test_init(self):
217n/a # c_int() can be initialized from Python's int, and c_int.
218n/a # Not from c_long or so, which seems strange, abc should
219n/a # probably be changed:
220n/a self.assertRaises(TypeError, c_int, c_long(42))
221n/a
222n/a def test_float_overflow(self):
223n/a import sys
224n/a big_int = int(sys.float_info.max) * 2
225n/a for t in float_types + [c_longdouble]:
226n/a self.assertRaises(OverflowError, t, big_int)
227n/a if (hasattr(t, "__ctype_be__")):
228n/a self.assertRaises(OverflowError, t.__ctype_be__, big_int)
229n/a if (hasattr(t, "__ctype_le__")):
230n/a self.assertRaises(OverflowError, t.__ctype_le__, big_int)
231n/a
232n/a @unittest.skip('test disabled')
233n/a def test_perf(self):
234n/a check_perf()
235n/a
236n/afrom ctypes import _SimpleCData
237n/aclass c_int_S(_SimpleCData):
238n/a _type_ = "i"
239n/a __slots__ = []
240n/a
241n/adef run_test(rep, msg, func, arg=None):
242n/a## items = [None] * rep
243n/a items = range(rep)
244n/a from time import clock
245n/a if arg is not None:
246n/a start = clock()
247n/a for i in items:
248n/a func(arg); func(arg); func(arg); func(arg); func(arg)
249n/a stop = clock()
250n/a else:
251n/a start = clock()
252n/a for i in items:
253n/a func(); func(); func(); func(); func()
254n/a stop = clock()
255n/a print("%15s: %.2f us" % (msg, ((stop-start)*1e6/5/rep)))
256n/a
257n/adef check_perf():
258n/a # Construct 5 objects
259n/a from ctypes import c_int
260n/a
261n/a REP = 200000
262n/a
263n/a run_test(REP, "int()", int)
264n/a run_test(REP, "int(999)", int)
265n/a run_test(REP, "c_int()", c_int)
266n/a run_test(REP, "c_int(999)", c_int)
267n/a run_test(REP, "c_int_S()", c_int_S)
268n/a run_test(REP, "c_int_S(999)", c_int_S)
269n/a
270n/a# Python 2.3 -OO, win2k, P4 700 MHz:
271n/a#
272n/a# int(): 0.87 us
273n/a# int(999): 0.87 us
274n/a# c_int(): 3.35 us
275n/a# c_int(999): 3.34 us
276n/a# c_int_S(): 3.23 us
277n/a# c_int_S(999): 3.24 us
278n/a
279n/a# Python 2.2 -OO, win2k, P4 700 MHz:
280n/a#
281n/a# int(): 0.89 us
282n/a# int(999): 0.89 us
283n/a# c_int(): 9.99 us
284n/a# c_int(999): 10.02 us
285n/a# c_int_S(): 9.87 us
286n/a# c_int_S(999): 9.85 us
287n/a
288n/aif __name__ == '__main__':
289n/a## check_perf()
290n/a unittest.main()