blob: 4cbfd4ba4b5b86edba8fed97ef988178f0c66b94 [file] [log] [blame]
Dan Albert287553d2017-02-16 10:47:51 -08001"""
2A testcase which accesses *values* in a dll.
3"""
4
5import unittest
6from ctypes import *
7
8import _ctypes_test
9
10class ValuesTestCase(unittest.TestCase):
11
12 def test_an_integer(self):
13 ctdll = CDLL(_ctypes_test.__file__)
14 an_integer = c_int.in_dll(ctdll, "an_integer")
15 x = an_integer.value
16 self.assertEqual(x, ctdll.get_an_integer())
17 an_integer.value *= 2
18 self.assertEqual(x*2, ctdll.get_an_integer())
19
20 def test_undefined(self):
21 ctdll = CDLL(_ctypes_test.__file__)
22 self.assertRaises(ValueError, c_int.in_dll, ctdll, "Undefined_Symbol")
23
24 class Win_ValuesTestCase(unittest.TestCase):
25 """This test only works when python itself is a dll/shared library"""
26
27 def test_optimizeflag(self):
28 # This test accesses the Py_OptimizeFlag intger, which is
29 # exported by the Python dll.
30
31 # It's value is set depending on the -O and -OO flags:
32 # if not given, it is 0 and __debug__ is 1.
33 # If -O is given, the flag is 1, for -OO it is 2.
34 # docstrings are also removed in the latter case.
35 opt = c_int.in_dll(pydll, "Py_OptimizeFlag").value
36 if __debug__:
37 self.assertEqual(opt, 0)
38 elif ValuesTestCase.__doc__ is not None:
39 self.assertEqual(opt, 1)
40 else:
41 self.assertEqual(opt, 2)
42
43 def test_frozentable(self):
44 # Python exports a PyImport_FrozenModules symbol. This is a
45 # pointer to an array of struct _frozen entries. The end of the
46 # array is marked by an entry containing a NULL name and zero
47 # size.
48
49 # In standard Python, this table contains a __hello__
50 # module, and a __phello__ package containing a spam
51 # module.
52 class struct_frozen(Structure):
53 _fields_ = [("name", c_char_p),
54 ("code", POINTER(c_ubyte)),
55 ("size", c_int)]
56 FrozenTable = POINTER(struct_frozen)
57
58 ft = FrozenTable.in_dll(pydll, "PyImport_FrozenModules")
59 # ft is a pointer to the struct_frozen entries:
60 items = []
61 for entry in ft:
62 # This is dangerous. We *can* iterate over a pointer, but
63 # the loop will not terminate (maybe with an access
64 # violation;-) because the pointer instance has no size.
65 if entry.name is None:
66 break
67 items.append((entry.name, entry.size))
68 import sys
69 if sys.version_info[:2] >= (2, 3):
70 expected = [("__hello__", 104), ("__phello__", -104), ("__phello__.spam", 104)]
71 else:
72 expected = [("__hello__", 100), ("__phello__", -100), ("__phello__.spam", 100)]
73 self.assertEqual(items, expected)
74
75 from ctypes import _pointer_type_cache
76 del _pointer_type_cache[struct_frozen]
77
78 def test_undefined(self):
79 self.assertRaises(ValueError, c_int.in_dll, pydll, "Undefined_Symbol")
80
81if __name__ == '__main__':
82 unittest.main()