Home | History | Annotate | Download | only in test
      1 """
      2 A testcase which accesses *values* in a dll.
      3 """
      4 
      5 import unittest
      6 from ctypes import *
      7 
      8 import _ctypes_test
      9 
     10 class 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 
     81 if __name__ == '__main__':
     82     unittest.main()
     83