| Jeremy Hylton | 6642653 | 2001-10-15 21:38:56 +0000 | [diff] [blame] | 1 | import unittest | 
| Guido van Rossum | 3b0a329 | 2002-08-09 16:38:32 +0000 | [diff] [blame] | 2 | from test.test_support import TestFailed, have_unicode, TESTFN | 
| Tim Peters | e089c68 | 2001-04-10 03:41:41 +0000 | [diff] [blame] | 3 |  | 
| Jeremy Hylton | 6642653 | 2001-10-15 21:38:56 +0000 | [diff] [blame] | 4 | class C: | 
 | 5 |     def __cmp__(self, other): | 
 | 6 |         return cmp(self.__dict__, other.__dict__) | 
 | 7 |  | 
 | 8 | import __main__ | 
 | 9 | __main__.C = C | 
 | 10 | C.__module__ = "__main__" | 
 | 11 |  | 
 | 12 | class myint(int): | 
 | 13 |     def __init__(self, x): | 
 | 14 |         self.str = str(x) | 
 | 15 |  | 
 | 16 | class initarg(C): | 
| Guido van Rossum | 1444f67 | 2001-12-19 16:38:29 +0000 | [diff] [blame] | 17 |  | 
 | 18 |     __safe_for_unpickling__ = 1 | 
 | 19 |  | 
| Jeremy Hylton | 6642653 | 2001-10-15 21:38:56 +0000 | [diff] [blame] | 20 |     def __init__(self, a, b): | 
 | 21 |         self.a = a | 
 | 22 |         self.b = b | 
 | 23 |  | 
 | 24 |     def __getinitargs__(self): | 
 | 25 |         return self.a, self.b | 
 | 26 |  | 
| Guido van Rossum | 04a8661 | 2001-12-19 16:58:54 +0000 | [diff] [blame] | 27 | class metaclass(type): | 
 | 28 |     pass | 
 | 29 |  | 
 | 30 | class use_metaclass(object): | 
 | 31 |     __metaclass__ = metaclass | 
 | 32 |  | 
| Jeremy Hylton | 6642653 | 2001-10-15 21:38:56 +0000 | [diff] [blame] | 33 | # break into multiple strings to avoid confusing font-lock-mode | 
| Tim Peters | 461922a | 2001-04-09 20:07:05 +0000 | [diff] [blame] | 34 | DATA = """(lp1 | 
| Tim Peters | e935816 | 2001-01-22 22:05:20 +0000 | [diff] [blame] | 35 | I0 | 
 | 36 | aL1L | 
| Tim Peters | 461922a | 2001-04-09 20:07:05 +0000 | [diff] [blame] | 37 | aF2 | 
| Tim Peters | e935816 | 2001-01-22 22:05:20 +0000 | [diff] [blame] | 38 | ac__builtin__ | 
 | 39 | complex | 
| Tim Peters | 461922a | 2001-04-09 20:07:05 +0000 | [diff] [blame] | 40 | p2 | 
 | 41 | """ + \ | 
 | 42 | """(F3 | 
 | 43 | F0 | 
 | 44 | tRp3 | 
 | 45 | aI1 | 
 | 46 | aI-1 | 
 | 47 | aI255 | 
 | 48 | aI-255 | 
 | 49 | aI-256 | 
 | 50 | aI65535 | 
 | 51 | aI-65535 | 
 | 52 | aI-65536 | 
 | 53 | aI2147483647 | 
 | 54 | aI-2147483647 | 
 | 55 | aI-2147483648 | 
 | 56 | a""" + \ | 
 | 57 | """(S'abc' | 
| Tim Peters | e935816 | 2001-01-22 22:05:20 +0000 | [diff] [blame] | 58 | p4 | 
 | 59 | g4 | 
| Tim Peters | 461922a | 2001-04-09 20:07:05 +0000 | [diff] [blame] | 60 | """ + \ | 
| Guido van Rossum | 42f92da | 2001-04-16 00:28:21 +0000 | [diff] [blame] | 61 | """(i__main__ | 
| Tim Peters | e935816 | 2001-01-22 22:05:20 +0000 | [diff] [blame] | 62 | C | 
 | 63 | p5 | 
| Tim Peters | 461922a | 2001-04-09 20:07:05 +0000 | [diff] [blame] | 64 | """ + \ | 
| Tim Peters | e935816 | 2001-01-22 22:05:20 +0000 | [diff] [blame] | 65 | """(dp6 | 
 | 66 | S'foo' | 
 | 67 | p7 | 
 | 68 | I1 | 
 | 69 | sS'bar' | 
 | 70 | p8 | 
 | 71 | I2 | 
 | 72 | sbg5 | 
 | 73 | tp9 | 
 | 74 | ag9 | 
 | 75 | aI5 | 
 | 76 | a. | 
 | 77 | """ | 
 | 78 |  | 
| Tim Peters | 461922a | 2001-04-09 20:07:05 +0000 | [diff] [blame] | 79 | BINDATA = ']q\x01(K\x00L1L\nG@\x00\x00\x00\x00\x00\x00\x00' + \ | 
 | 80 |           'c__builtin__\ncomplex\nq\x02(G@\x08\x00\x00\x00\x00\x00' + \ | 
 | 81 |           '\x00G\x00\x00\x00\x00\x00\x00\x00\x00tRq\x03K\x01J\xff\xff' + \ | 
 | 82 |           '\xff\xffK\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xff' + \ | 
 | 83 |           'J\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00' + \ | 
| Guido van Rossum | 42f92da | 2001-04-16 00:28:21 +0000 | [diff] [blame] | 84 |           '\x00\x80J\x00\x00\x00\x80(U\x03abcq\x04h\x04(c__main__\n' + \ | 
| Tim Peters | 461922a | 2001-04-09 20:07:05 +0000 | [diff] [blame] | 85 |           'C\nq\x05oq\x06}q\x07(U\x03fooq\x08K\x01U\x03barq\tK\x02ubh' + \ | 
 | 86 |           '\x06tq\nh\nK\x05e.' | 
| Tim Peters | e0c446b | 2001-10-18 21:57:37 +0000 | [diff] [blame] | 87 |  | 
| Jeremy Hylton | 6642653 | 2001-10-15 21:38:56 +0000 | [diff] [blame] | 88 | def create_data(): | 
| Tim Peters | e935816 | 2001-01-22 22:05:20 +0000 | [diff] [blame] | 89 |     c = C() | 
 | 90 |     c.foo = 1 | 
 | 91 |     c.bar = 2 | 
 | 92 |     x = [0, 1L, 2.0, 3.0+0j] | 
| Tim Peters | 461922a | 2001-04-09 20:07:05 +0000 | [diff] [blame] | 93 |     # Append some integer test cases at cPickle.c's internal size | 
 | 94 |     # cutoffs. | 
 | 95 |     uint1max = 0xff | 
 | 96 |     uint2max = 0xffff | 
 | 97 |     int4max = 0x7fffffff | 
 | 98 |     x.extend([1, -1, | 
 | 99 |               uint1max, -uint1max, -uint1max-1, | 
 | 100 |               uint2max, -uint2max, -uint2max-1, | 
 | 101 |                int4max,  -int4max,  -int4max-1]) | 
| Tim Peters | e935816 | 2001-01-22 22:05:20 +0000 | [diff] [blame] | 102 |     y = ('abc', 'abc', c, c) | 
 | 103 |     x.append(y) | 
 | 104 |     x.append(y) | 
 | 105 |     x.append(5) | 
| Jeremy Hylton | 6642653 | 2001-10-15 21:38:56 +0000 | [diff] [blame] | 106 |     return x | 
| Tim Peters | c58440f | 2001-04-09 17:16:31 +0000 | [diff] [blame] | 107 |  | 
| Jeremy Hylton | 6642653 | 2001-10-15 21:38:56 +0000 | [diff] [blame] | 108 | class AbstractPickleTests(unittest.TestCase): | 
| Tim Peters | c58440f | 2001-04-09 17:16:31 +0000 | [diff] [blame] | 109 |  | 
| Jeremy Hylton | 6642653 | 2001-10-15 21:38:56 +0000 | [diff] [blame] | 110 |     _testdata = create_data() | 
| Tim Peters | c58440f | 2001-04-09 17:16:31 +0000 | [diff] [blame] | 111 |  | 
| Jeremy Hylton | 6642653 | 2001-10-15 21:38:56 +0000 | [diff] [blame] | 112 |     def setUp(self): | 
 | 113 |         # subclass must define self.dumps, self.loads, self.error | 
| Tim Peters | e935816 | 2001-01-22 22:05:20 +0000 | [diff] [blame] | 114 |         pass | 
| Tim Peters | c58440f | 2001-04-09 17:16:31 +0000 | [diff] [blame] | 115 |  | 
| Jeremy Hylton | 6642653 | 2001-10-15 21:38:56 +0000 | [diff] [blame] | 116 |     def test_misc(self): | 
 | 117 |         # test various datatypes not tested by testdata | 
 | 118 |         x = myint(4) | 
 | 119 |         s = self.dumps(x) | 
 | 120 |         y = self.loads(s) | 
 | 121 |         self.assertEqual(x, y) | 
| Tim Peters | e935816 | 2001-01-22 22:05:20 +0000 | [diff] [blame] | 122 |  | 
| Jeremy Hylton | 6642653 | 2001-10-15 21:38:56 +0000 | [diff] [blame] | 123 |         x = (1, ()) | 
 | 124 |         s = self.dumps(x) | 
 | 125 |         y = self.loads(s) | 
 | 126 |         self.assertEqual(x, y) | 
| Tim Peters | e935816 | 2001-01-22 22:05:20 +0000 | [diff] [blame] | 127 |  | 
| Jeremy Hylton | 6642653 | 2001-10-15 21:38:56 +0000 | [diff] [blame] | 128 |         x = initarg(1, x) | 
 | 129 |         s = self.dumps(x) | 
 | 130 |         y = self.loads(s) | 
 | 131 |         self.assertEqual(x, y) | 
| Tim Peters | e935816 | 2001-01-22 22:05:20 +0000 | [diff] [blame] | 132 |  | 
| Jeremy Hylton | 6642653 | 2001-10-15 21:38:56 +0000 | [diff] [blame] | 133 |         # XXX test __reduce__ protocol? | 
 | 134 |  | 
 | 135 |     def test_identity(self): | 
 | 136 |         s = self.dumps(self._testdata) | 
 | 137 |         x = self.loads(s) | 
 | 138 |         self.assertEqual(x, self._testdata) | 
 | 139 |  | 
 | 140 |     def test_constant(self): | 
 | 141 |         x = self.loads(DATA) | 
 | 142 |         self.assertEqual(x, self._testdata) | 
 | 143 |         x = self.loads(BINDATA) | 
 | 144 |         self.assertEqual(x, self._testdata) | 
 | 145 |  | 
 | 146 |     def test_binary(self): | 
 | 147 |         s = self.dumps(self._testdata, 1) | 
 | 148 |         x = self.loads(s) | 
 | 149 |         self.assertEqual(x, self._testdata) | 
 | 150 |  | 
 | 151 |     def test_recursive_list(self): | 
 | 152 |         l = [] | 
 | 153 |         l.append(l) | 
 | 154 |         s = self.dumps(l) | 
 | 155 |         x = self.loads(s) | 
 | 156 |         self.assertEqual(x, l) | 
 | 157 |         self.assertEqual(x, x[0]) | 
 | 158 |         self.assertEqual(id(x), id(x[0])) | 
 | 159 |  | 
 | 160 |     def test_recursive_dict(self): | 
 | 161 |         d = {} | 
 | 162 |         d[1] = d | 
 | 163 |         s = self.dumps(d) | 
 | 164 |         x = self.loads(s) | 
 | 165 |         self.assertEqual(x, d) | 
 | 166 |         self.assertEqual(x[1], x) | 
 | 167 |         self.assertEqual(id(x[1]), id(x)) | 
 | 168 |  | 
 | 169 |     def test_recursive_inst(self): | 
 | 170 |         i = C() | 
 | 171 |         i.attr = i | 
 | 172 |         s = self.dumps(i) | 
 | 173 |         x = self.loads(s) | 
 | 174 |         self.assertEqual(x, i) | 
 | 175 |         self.assertEqual(x.attr, x) | 
 | 176 |         self.assertEqual(id(x.attr), id(x)) | 
 | 177 |  | 
 | 178 |     def test_recursive_multi(self): | 
 | 179 |         l = [] | 
 | 180 |         d = {1:l} | 
 | 181 |         i = C() | 
 | 182 |         i.attr = d | 
 | 183 |         l.append(i) | 
 | 184 |         s = self.dumps(l) | 
 | 185 |         x = self.loads(s) | 
 | 186 |         self.assertEqual(x, l) | 
 | 187 |         self.assertEqual(x[0], i) | 
 | 188 |         self.assertEqual(x[0].attr, d) | 
 | 189 |         self.assertEqual(x[0].attr[1], x) | 
 | 190 |         self.assertEqual(x[0].attr[1][0], i) | 
 | 191 |         self.assertEqual(x[0].attr[1][0].attr, d) | 
 | 192 |  | 
 | 193 |     def test_garyp(self): | 
 | 194 |         self.assertRaises(self.error, self.loads, 'garyp') | 
 | 195 |  | 
 | 196 |     def test_insecure_strings(self): | 
 | 197 |         insecure = ["abc", "2 + 2", # not quoted | 
| Martin v. Löwis | 8a8da79 | 2002-08-14 07:46:28 +0000 | [diff] [blame] | 198 |                     #"'abc' + 'def'", # not a single quoted string | 
| Jeremy Hylton | 6642653 | 2001-10-15 21:38:56 +0000 | [diff] [blame] | 199 |                     "'abc", # quote is not closed | 
 | 200 |                     "'abc\"", # open quote and close quote don't match | 
 | 201 |                     "'abc'   ?", # junk after close quote | 
| Martin v. Löwis | eb3f00a | 2002-08-14 08:22:50 +0000 | [diff] [blame] | 202 |                     "'\\'", # trailing backslash | 
| Jeremy Hylton | 6642653 | 2001-10-15 21:38:56 +0000 | [diff] [blame] | 203 |                     # some tests of the quoting rules | 
| Martin v. Löwis | 8a8da79 | 2002-08-14 07:46:28 +0000 | [diff] [blame] | 204 |                     #"'abc\"\''", | 
 | 205 |                     #"'\\\\a\'\'\'\\\'\\\\\''", | 
| Jeremy Hylton | 6642653 | 2001-10-15 21:38:56 +0000 | [diff] [blame] | 206 |                     ] | 
 | 207 |         for s in insecure: | 
 | 208 |             buf = "S" + s + "\012p0\012." | 
 | 209 |             self.assertRaises(ValueError, self.loads, buf) | 
 | 210 |  | 
| Martin v. Löwis | 339d0f7 | 2001-08-17 18:39:25 +0000 | [diff] [blame] | 211 |     if have_unicode: | 
| Jeremy Hylton | 6642653 | 2001-10-15 21:38:56 +0000 | [diff] [blame] | 212 |         def test_unicode(self): | 
 | 213 |             endcases = [unicode(''), unicode('<\\u>'), unicode('<\\\u1234>'), | 
 | 214 |                         unicode('<\n>'),  unicode('<\\>')] | 
 | 215 |             for u in endcases: | 
 | 216 |                 p = self.dumps(u) | 
 | 217 |                 u2 = self.loads(p) | 
 | 218 |                 self.assertEqual(u2, u) | 
| Tim Peters | e089c68 | 2001-04-10 03:41:41 +0000 | [diff] [blame] | 219 |  | 
| Jeremy Hylton | 6642653 | 2001-10-15 21:38:56 +0000 | [diff] [blame] | 220 |     def test_ints(self): | 
 | 221 |         import sys | 
 | 222 |         n = sys.maxint | 
 | 223 |         while n: | 
 | 224 |             for expected in (-n, n): | 
 | 225 |                 s = self.dumps(expected) | 
 | 226 |                 n2 = self.loads(s) | 
 | 227 |                 self.assertEqual(expected, n2) | 
 | 228 |             n = n >> 1 | 
| Tim Peters | 19ef62d | 2001-08-28 22:21:18 +0000 | [diff] [blame] | 229 |  | 
| Jeremy Hylton | 6642653 | 2001-10-15 21:38:56 +0000 | [diff] [blame] | 230 |     def test_maxint64(self): | 
 | 231 |         maxint64 = (1L << 63) - 1 | 
 | 232 |         data = 'I' + str(maxint64) + '\n.' | 
 | 233 |         got = self.loads(data) | 
 | 234 |         self.assertEqual(got, maxint64) | 
 | 235 |  | 
 | 236 |         # Try too with a bogus literal. | 
 | 237 |         data = 'I' + str(maxint64) + 'JUNK\n.' | 
 | 238 |         self.assertRaises(ValueError, self.loads, data) | 
 | 239 |  | 
 | 240 |     def test_reduce(self): | 
| Tim Peters | 19ef62d | 2001-08-28 22:21:18 +0000 | [diff] [blame] | 241 |         pass | 
| Jeremy Hylton | 6642653 | 2001-10-15 21:38:56 +0000 | [diff] [blame] | 242 |  | 
 | 243 |     def test_getinitargs(self): | 
 | 244 |         pass | 
 | 245 |  | 
| Guido van Rossum | 04a8661 | 2001-12-19 16:58:54 +0000 | [diff] [blame] | 246 |     def test_metaclass(self): | 
 | 247 |         a = use_metaclass() | 
 | 248 |         s = self.dumps(a) | 
 | 249 |         b = self.loads(s) | 
 | 250 |         self.assertEqual(a.__class__, b.__class__) | 
 | 251 |  | 
| Michael W. Hudson | 7bb466a | 2002-03-05 13:27:58 +0000 | [diff] [blame] | 252 |     def test_structseq(self): | 
 | 253 |         import time | 
 | 254 |         t = time.localtime() | 
 | 255 |         s = self.dumps(t) | 
 | 256 |         u = self.loads(s) | 
| Tim Peters | 863ac44 | 2002-04-16 01:38:40 +0000 | [diff] [blame] | 257 |         self.assertEqual(t, u) | 
| Michael W. Hudson | 0e02530 | 2002-03-06 17:11:18 +0000 | [diff] [blame] | 258 |         import os | 
 | 259 |         if hasattr(os, "stat"): | 
 | 260 |             t = os.stat(os.curdir) | 
 | 261 |             s = self.dumps(t) | 
 | 262 |             u = self.loads(s) | 
 | 263 |             self.assertEqual(t, u) | 
 | 264 |         if hasattr(os, "statvfs"): | 
 | 265 |             t = os.statvfs(os.curdir) | 
 | 266 |             s = self.dumps(t) | 
 | 267 |             u = self.loads(s) | 
 | 268 |             self.assertEqual(t, u) | 
| Michael W. Hudson | 7bb466a | 2002-03-05 13:27:58 +0000 | [diff] [blame] | 269 |  | 
| Guido van Rossum | d6c9e63 | 2003-01-28 03:49:52 +0000 | [diff] [blame] | 270 |     # Tests for protocol 2 | 
 | 271 |  | 
 | 272 |     def test_long1(self): | 
 | 273 |         x = 12345678910111213141516178920L | 
 | 274 |         s = self.dumps(x, 2) | 
 | 275 |         y = self.loads(s) | 
 | 276 |         self.assertEqual(x, y) | 
 | 277 |  | 
 | 278 |     def test_long4(self): | 
 | 279 |         x = 12345678910111213141516178920L << (256*8) | 
 | 280 |         s = self.dumps(x, 2) | 
 | 281 |         y = self.loads(s) | 
 | 282 |         self.assertEqual(x, y) | 
 | 283 |  | 
| Guido van Rossum | 44f0ea5 | 2003-01-28 04:14:51 +0000 | [diff] [blame] | 284 |     def test_short_tuples(self): | 
 | 285 |         a = () | 
| Guido van Rossum | 025bc2f | 2003-01-28 04:20:02 +0000 | [diff] [blame^] | 286 |         b = (1,) | 
 | 287 |         c = (1, 2) | 
 | 288 |         d = (1, 2, 3) | 
 | 289 |         e = (1, 2, 3, 4) | 
| Guido van Rossum | 44f0ea5 | 2003-01-28 04:14:51 +0000 | [diff] [blame] | 290 |         for proto in 0, 1, 2: | 
 | 291 |             for x in a, b, c, d, e: | 
 | 292 |                 s = self.dumps(x, proto) | 
 | 293 |                 y = self.loads(s) | 
 | 294 |                 self.assertEqual(x, y, (proto, x, s, y)) | 
 | 295 |  | 
| Jeremy Hylton | 6642653 | 2001-10-15 21:38:56 +0000 | [diff] [blame] | 296 | class AbstractPickleModuleTests(unittest.TestCase): | 
 | 297 |  | 
 | 298 |     def test_dump_closed_file(self): | 
| Guido van Rossum | 3b0a329 | 2002-08-09 16:38:32 +0000 | [diff] [blame] | 299 |         import os | 
 | 300 |         f = open(TESTFN, "w") | 
 | 301 |         try: | 
 | 302 |             f.close() | 
 | 303 |             self.assertRaises(ValueError, self.module.dump, 123, f) | 
 | 304 |         finally: | 
 | 305 |             os.remove(TESTFN) | 
| Jeremy Hylton | 6642653 | 2001-10-15 21:38:56 +0000 | [diff] [blame] | 306 |  | 
 | 307 |     def test_load_closed_file(self): | 
| Guido van Rossum | 3b0a329 | 2002-08-09 16:38:32 +0000 | [diff] [blame] | 308 |         import os | 
 | 309 |         f = open(TESTFN, "w") | 
 | 310 |         try: | 
 | 311 |             f.close() | 
 | 312 |             self.assertRaises(ValueError, self.module.dump, 123, f) | 
 | 313 |         finally: | 
 | 314 |             os.remove(TESTFN) | 
| Jeremy Hylton | 4c8be85 | 2002-11-13 22:10:47 +0000 | [diff] [blame] | 315 |  | 
 | 316 | class AbstractPersistentPicklerTests(unittest.TestCase): | 
 | 317 |  | 
 | 318 |     # This class defines persistent_id() and persistent_load() | 
 | 319 |     # functions that should be used by the pickler.  All even integers | 
 | 320 |     # are pickled using persistent ids. | 
 | 321 |  | 
 | 322 |     def persistent_id(self, object): | 
 | 323 |         if isinstance(object, int) and object % 2 == 0: | 
 | 324 |             self.id_count += 1 | 
 | 325 |             return str(object) | 
 | 326 |         else: | 
 | 327 |             return None | 
 | 328 |  | 
 | 329 |     def persistent_load(self, oid): | 
 | 330 |         self.load_count += 1 | 
 | 331 |         object = int(oid) | 
 | 332 |         assert object % 2 == 0 | 
 | 333 |         return object | 
 | 334 |  | 
 | 335 |     def test_persistence(self): | 
 | 336 |         self.id_count = 0 | 
 | 337 |         self.load_count = 0 | 
 | 338 |         L = range(10) | 
 | 339 |         self.assertEqual(self.loads(self.dumps(L)), L) | 
 | 340 |         self.assertEqual(self.id_count, 5) | 
 | 341 |         self.assertEqual(self.load_count, 5) | 
 | 342 |  | 
 | 343 |     def test_bin_persistence(self): | 
 | 344 |         self.id_count = 0 | 
 | 345 |         self.load_count = 0 | 
 | 346 |         L = range(10) | 
 | 347 |         self.assertEqual(self.loads(self.dumps(L, 1)), L) | 
 | 348 |         self.assertEqual(self.id_count, 5) | 
 | 349 |         self.assertEqual(self.load_count, 5) |