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