/Lib/ctypes/test/test_pickling.py

http://unladen-swallow.googlecode.com/ · Python · 83 lines · 60 code · 17 blank · 6 comment · 3 complexity · 2ee9e3d1f2da369718143c2162a0623f MD5 · raw file

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