Home | History | Annotate | Download | only in test
      1 import unittest
      2 import pickle
      3 from ctypes import *
      4 import _ctypes_test
      5 dll = CDLL(_ctypes_test.__file__)
      6 
      7 class X(Structure):
      8     _fields_ = [("a", c_int), ("b", c_double)]
      9     init_called = 0
     10     def __init__(self, *args, **kw):
     11         X.init_called += 1
     12         self.x = 42
     13 
     14 class Y(X):
     15     _fields_ = [("str", c_char_p)]
     16 
     17 class PickleTest(unittest.TestCase):
     18     def dumps(self, item):
     19         return pickle.dumps(item)
     20 
     21     def loads(self, item):
     22         return pickle.loads(item)
     23 
     24     def test_simple(self):
     25         for src in [
     26             c_int(42),
     27             c_double(3.14),
     28             ]:
     29             dst = self.loads(self.dumps(src))
     30             self.assertEqual(src.__dict__, dst.__dict__)
     31             self.assertEqual(memoryview(src).tobytes(),
     32                                  memoryview(dst).tobytes())
     33 
     34     def test_struct(self):
     35         X.init_called = 0
     36 
     37         x = X()
     38         x.a = 42
     39         self.assertEqual(X.init_called, 1)
     40 
     41         y = self.loads(self.dumps(x))
     42 
     43         # loads must NOT call __init__
     44         self.assertEqual(X.init_called, 1)
     45 
     46         # ctypes instances are identical when the instance __dict__
     47         # and the memory buffer are identical
     48         self.assertEqual(y.__dict__, x.__dict__)
     49         self.assertEqual(memoryview(y).tobytes(),
     50                              memoryview(x).tobytes())
     51 
     52     def test_unpickable(self):
     53         # ctypes objects that are pointers or contain pointers are
     54         # unpickable.
     55         self.assertRaises(ValueError, lambda: self.dumps(Y()))
     56 
     57         prototype = CFUNCTYPE(c_int)
     58 
     59         for item in [
     60             c_char_p(),
     61             c_wchar_p(),
     62             c_void_p(),
     63             pointer(c_int(42)),
     64             dll._testfunc_p_p,
     65             prototype(lambda: 42),
     66             ]:
     67             self.assertRaises(ValueError, lambda: self.dumps(item))
     68 
     69     def test_wchar(self):
     70         pickle.dumps(c_char("x"))
     71         # Issue 5049
     72         pickle.dumps(c_wchar(u"x"))
     73 
     74 class PickleTest_1(PickleTest):
     75     def dumps(self, item):
     76         return pickle.dumps(item, 1)
     77 
     78 class PickleTest_2(PickleTest):
     79     def dumps(self, item):
     80         return pickle.dumps(item, 2)
     81 
     82 if __name__ == "__main__":
     83     unittest.main()
     84