Thomas Heller | 13394e9 | 2008-02-13 20:40:44 +0000 | [diff] [blame] | 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)) |
Benjamin Peterson | c9c0f20 | 2009-06-30 23:06:06 +0000 | [diff] [blame] | 30 | self.assertEqual(src.__dict__, dst.__dict__) |
| 31 | self.assertEqual(memoryview(src).tobytes(), |
Thomas Heller | 13394e9 | 2008-02-13 20:40:44 +0000 | [diff] [blame] | 32 | memoryview(dst).tobytes()) |
| 33 | |
| 34 | def test_struct(self): |
| 35 | X.init_called = 0 |
| 36 | |
| 37 | x = X() |
| 38 | x.a = 42 |
Benjamin Peterson | c9c0f20 | 2009-06-30 23:06:06 +0000 | [diff] [blame] | 39 | self.assertEqual(X.init_called, 1) |
Thomas Heller | 13394e9 | 2008-02-13 20:40:44 +0000 | [diff] [blame] | 40 | |
| 41 | y = self.loads(self.dumps(x)) |
| 42 | |
| 43 | # loads must NOT call __init__ |
Benjamin Peterson | c9c0f20 | 2009-06-30 23:06:06 +0000 | [diff] [blame] | 44 | self.assertEqual(X.init_called, 1) |
Thomas Heller | 13394e9 | 2008-02-13 20:40:44 +0000 | [diff] [blame] | 45 | |
| 46 | # ctypes instances are identical when the instance __dict__ |
| 47 | # and the memory buffer are identical |
Benjamin Peterson | c9c0f20 | 2009-06-30 23:06:06 +0000 | [diff] [blame] | 48 | self.assertEqual(y.__dict__, x.__dict__) |
| 49 | self.assertEqual(memoryview(y).tobytes(), |
Thomas Heller | 13394e9 | 2008-02-13 20:40:44 +0000 | [diff] [blame] | 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 | |
Thomas Heller | c9baac8 | 2009-04-24 20:05:20 +0000 | [diff] [blame] | 69 | def test_wchar(self): |
| 70 | pickle.dumps(c_char(b"x")) |
| 71 | # Issue 5049 |
| 72 | pickle.dumps(c_wchar("x")) |
| 73 | |
Thomas Heller | 13394e9 | 2008-02-13 20:40:44 +0000 | [diff] [blame] | 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() |