| """ |
| A testcase which accesses *values* in a dll. |
| """ |
| |
| import unittest |
| from ctypes import * |
| |
| import _ctypes_test |
| |
| class ValuesTestCase(unittest.TestCase): |
| |
| def test_an_integer(self): |
| ctdll = CDLL(_ctypes_test.__file__) |
| an_integer = c_int.in_dll(ctdll, "an_integer") |
| x = an_integer.value |
| self.assertEqual(x, ctdll.get_an_integer()) |
| an_integer.value *= 2 |
| self.assertEqual(x*2, ctdll.get_an_integer()) |
| |
| def test_undefined(self): |
| ctdll = CDLL(_ctypes_test.__file__) |
| self.assertRaises(ValueError, c_int.in_dll, ctdll, "Undefined_Symbol") |
| |
| class Win_ValuesTestCase(unittest.TestCase): |
| """This test only works when python itself is a dll/shared library""" |
| |
| def test_optimizeflag(self): |
| # This test accesses the Py_OptimizeFlag intger, which is |
| # exported by the Python dll. |
| |
| # It's value is set depending on the -O and -OO flags: |
| # if not given, it is 0 and __debug__ is 1. |
| # If -O is given, the flag is 1, for -OO it is 2. |
| # docstrings are also removed in the latter case. |
| opt = c_int.in_dll(pydll, "Py_OptimizeFlag").value |
| if __debug__: |
| self.assertEqual(opt, 0) |
| elif ValuesTestCase.__doc__ is not None: |
| self.assertEqual(opt, 1) |
| else: |
| self.assertEqual(opt, 2) |
| |
| def test_frozentable(self): |
| # Python exports a PyImport_FrozenModules symbol. This is a |
| # pointer to an array of struct _frozen entries. The end of the |
| # array is marked by an entry containing a NULL name and zero |
| # size. |
| |
| # In standard Python, this table contains a __hello__ |
| # module, and a __phello__ package containing a spam |
| # module. |
| class struct_frozen(Structure): |
| _fields_ = [("name", c_char_p), |
| ("code", POINTER(c_ubyte)), |
| ("size", c_int)] |
| FrozenTable = POINTER(struct_frozen) |
| |
| ft = FrozenTable.in_dll(pydll, "PyImport_FrozenModules") |
| # ft is a pointer to the struct_frozen entries: |
| items = [] |
| for entry in ft: |
| # This is dangerous. We *can* iterate over a pointer, but |
| # the loop will not terminate (maybe with an access |
| # violation;-) because the pointer instance has no size. |
| if entry.name is None: |
| break |
| items.append((entry.name, entry.size)) |
| import sys |
| if sys.version_info[:2] >= (2, 3): |
| expected = [("__hello__", 104), ("__phello__", -104), ("__phello__.spam", 104)] |
| else: |
| expected = [("__hello__", 100), ("__phello__", -100), ("__phello__.spam", 100)] |
| self.assertEqual(items, expected) |
| |
| from ctypes import _pointer_type_cache |
| del _pointer_type_cache[struct_frozen] |
| |
| def test_undefined(self): |
| self.assertRaises(ValueError, c_int.in_dll, pydll, "Undefined_Symbol") |
| |
| if __name__ == '__main__': |
| unittest.main() |