»Core Development>Code coverage>Lib/test/pickletester.py

Python code coverage for Lib/test/pickletester.py

#countcontent
1n/aimport collections
2n/aimport copyreg
3n/aimport dbm
4n/aimport io
5n/aimport functools
6n/aimport pickle
7n/aimport pickletools
8n/aimport struct
9n/aimport sys
10n/aimport unittest
11n/aimport weakref
12n/afrom http.cookies import SimpleCookie
13n/a
14n/afrom test import support
15n/afrom test.support import (
16n/a TestFailed, TESTFN, run_with_locale, no_tracing,
17n/a _2G, _4G, bigmemtest,
18n/a )
19n/a
20n/afrom pickle import bytes_types
21n/a
22n/arequires_32b = unittest.skipUnless(sys.maxsize < 2**32,
23n/a "test is only meaningful on 32-bit builds")
24n/a
25n/a# Tests that try a number of pickle protocols should have a
26n/a# for proto in protocols:
27n/a# kind of outer loop.
28n/aprotocols = range(pickle.HIGHEST_PROTOCOL + 1)
29n/a
30n/a
31n/a# Return True if opcode code appears in the pickle, else False.
32n/adef opcode_in_pickle(code, pickle):
33n/a for op, dummy, dummy in pickletools.genops(pickle):
34n/a if op.code == code.decode("latin-1"):
35n/a return True
36n/a return False
37n/a
38n/a# Return the number of times opcode code appears in pickle.
39n/adef count_opcode(code, pickle):
40n/a n = 0
41n/a for op, dummy, dummy in pickletools.genops(pickle):
42n/a if op.code == code.decode("latin-1"):
43n/a n += 1
44n/a return n
45n/a
46n/a
47n/aclass UnseekableIO(io.BytesIO):
48n/a def peek(self, *args):
49n/a raise NotImplementedError
50n/a
51n/a def seekable(self):
52n/a return False
53n/a
54n/a def seek(self, *args):
55n/a raise io.UnsupportedOperation
56n/a
57n/a def tell(self):
58n/a raise io.UnsupportedOperation
59n/a
60n/a
61n/a# We can't very well test the extension registry without putting known stuff
62n/a# in it, but we have to be careful to restore its original state. Code
63n/a# should do this:
64n/a#
65n/a# e = ExtensionSaver(extension_code)
66n/a# try:
67n/a# fiddle w/ the extension registry's stuff for extension_code
68n/a# finally:
69n/a# e.restore()
70n/a
71n/aclass ExtensionSaver:
72n/a # Remember current registration for code (if any), and remove it (if
73n/a # there is one).
74n/a def __init__(self, code):
75n/a self.code = code
76n/a if code in copyreg._inverted_registry:
77n/a self.pair = copyreg._inverted_registry[code]
78n/a copyreg.remove_extension(self.pair[0], self.pair[1], code)
79n/a else:
80n/a self.pair = None
81n/a
82n/a # Restore previous registration for code.
83n/a def restore(self):
84n/a code = self.code
85n/a curpair = copyreg._inverted_registry.get(code)
86n/a if curpair is not None:
87n/a copyreg.remove_extension(curpair[0], curpair[1], code)
88n/a pair = self.pair
89n/a if pair is not None:
90n/a copyreg.add_extension(pair[0], pair[1], code)
91n/a
92n/aclass C:
93n/a def __eq__(self, other):
94n/a return self.__dict__ == other.__dict__
95n/a
96n/aclass D(C):
97n/a def __init__(self, arg):
98n/a pass
99n/a
100n/aclass E(C):
101n/a def __getinitargs__(self):
102n/a return ()
103n/a
104n/aclass H(object):
105n/a pass
106n/a
107n/a# Hashable mutable key
108n/aclass K(object):
109n/a def __init__(self, value):
110n/a self.value = value
111n/a
112n/a def __reduce__(self):
113n/a # Shouldn't support the recursion itself
114n/a return K, (self.value,)
115n/a
116n/aimport __main__
117n/a__main__.C = C
118n/aC.__module__ = "__main__"
119n/a__main__.D = D
120n/aD.__module__ = "__main__"
121n/a__main__.E = E
122n/aE.__module__ = "__main__"
123n/a__main__.H = H
124n/aH.__module__ = "__main__"
125n/a__main__.K = K
126n/aK.__module__ = "__main__"
127n/a
128n/aclass myint(int):
129n/a def __init__(self, x):
130n/a self.str = str(x)
131n/a
132n/aclass initarg(C):
133n/a
134n/a def __init__(self, a, b):
135n/a self.a = a
136n/a self.b = b
137n/a
138n/a def __getinitargs__(self):
139n/a return self.a, self.b
140n/a
141n/aclass metaclass(type):
142n/a pass
143n/a
144n/aclass use_metaclass(object, metaclass=metaclass):
145n/a pass
146n/a
147n/aclass pickling_metaclass(type):
148n/a def __eq__(self, other):
149n/a return (type(self) == type(other) and
150n/a self.reduce_args == other.reduce_args)
151n/a
152n/a def __reduce__(self):
153n/a return (create_dynamic_class, self.reduce_args)
154n/a
155n/adef create_dynamic_class(name, bases):
156n/a result = pickling_metaclass(name, bases, dict())
157n/a result.reduce_args = (name, bases)
158n/a return result
159n/a
160n/a# DATA0 .. DATA4 are the pickles we expect under the various protocols, for
161n/a# the object returned by create_data().
162n/a
163n/aDATA0 = (
164n/a b'(lp0\nL0L\naL1L\naF2.0\n'
165n/a b'ac__builtin__\ncomple'
166n/a b'x\np1\n(F3.0\nF0.0\ntp2\n'
167n/a b'Rp3\naL1L\naL-1L\naL255'
168n/a b'L\naL-255L\naL-256L\naL'
169n/a b'65535L\naL-65535L\naL-'
170n/a b'65536L\naL2147483647L'
171n/a b'\naL-2147483647L\naL-2'
172n/a b'147483648L\na(Vabc\np4'
173n/a b'\ng4\nccopy_reg\n_recon'
174n/a b'structor\np5\n(c__main'
175n/a b'__\nC\np6\nc__builtin__'
176n/a b'\nobject\np7\nNtp8\nRp9\n'
177n/a b'(dp10\nVfoo\np11\nL1L\ns'
178n/a b'Vbar\np12\nL2L\nsbg9\ntp'
179n/a b'13\nag13\naL5L\na.'
180n/a)
181n/a
182n/a# Disassembly of DATA0
183n/aDATA0_DIS = """\
184n/a 0: ( MARK
185n/a 1: l LIST (MARK at 0)
186n/a 2: p PUT 0
187n/a 5: L LONG 0
188n/a 9: a APPEND
189n/a 10: L LONG 1
190n/a 14: a APPEND
191n/a 15: F FLOAT 2.0
192n/a 20: a APPEND
193n/a 21: c GLOBAL '__builtin__ complex'
194n/a 42: p PUT 1
195n/a 45: ( MARK
196n/a 46: F FLOAT 3.0
197n/a 51: F FLOAT 0.0
198n/a 56: t TUPLE (MARK at 45)
199n/a 57: p PUT 2
200n/a 60: R REDUCE
201n/a 61: p PUT 3
202n/a 64: a APPEND
203n/a 65: L LONG 1
204n/a 69: a APPEND
205n/a 70: L LONG -1
206n/a 75: a APPEND
207n/a 76: L LONG 255
208n/a 82: a APPEND
209n/a 83: L LONG -255
210n/a 90: a APPEND
211n/a 91: L LONG -256
212n/a 98: a APPEND
213n/a 99: L LONG 65535
214n/a 107: a APPEND
215n/a 108: L LONG -65535
216n/a 117: a APPEND
217n/a 118: L LONG -65536
218n/a 127: a APPEND
219n/a 128: L LONG 2147483647
220n/a 141: a APPEND
221n/a 142: L LONG -2147483647
222n/a 156: a APPEND
223n/a 157: L LONG -2147483648
224n/a 171: a APPEND
225n/a 172: ( MARK
226n/a 173: V UNICODE 'abc'
227n/a 178: p PUT 4
228n/a 181: g GET 4
229n/a 184: c GLOBAL 'copy_reg _reconstructor'
230n/a 209: p PUT 5
231n/a 212: ( MARK
232n/a 213: c GLOBAL '__main__ C'
233n/a 225: p PUT 6
234n/a 228: c GLOBAL '__builtin__ object'
235n/a 248: p PUT 7
236n/a 251: N NONE
237n/a 252: t TUPLE (MARK at 212)
238n/a 253: p PUT 8
239n/a 256: R REDUCE
240n/a 257: p PUT 9
241n/a 260: ( MARK
242n/a 261: d DICT (MARK at 260)
243n/a 262: p PUT 10
244n/a 266: V UNICODE 'foo'
245n/a 271: p PUT 11
246n/a 275: L LONG 1
247n/a 279: s SETITEM
248n/a 280: V UNICODE 'bar'
249n/a 285: p PUT 12
250n/a 289: L LONG 2
251n/a 293: s SETITEM
252n/a 294: b BUILD
253n/a 295: g GET 9
254n/a 298: t TUPLE (MARK at 172)
255n/a 299: p PUT 13
256n/a 303: a APPEND
257n/a 304: g GET 13
258n/a 308: a APPEND
259n/a 309: L LONG 5
260n/a 313: a APPEND
261n/a 314: . STOP
262n/ahighest protocol among opcodes = 0
263n/a"""
264n/a
265n/aDATA1 = (
266n/a b']q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c__'
267n/a b'builtin__\ncomplex\nq\x01'
268n/a b'(G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00t'
269n/a b'q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ'
270n/a b'\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff'
271n/a b'\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00ab'
272n/a b'cq\x04h\x04ccopy_reg\n_reco'
273n/a b'nstructor\nq\x05(c__main'
274n/a b'__\nC\nq\x06c__builtin__\n'
275n/a b'object\nq\x07Ntq\x08Rq\t}q\n('
276n/a b'X\x03\x00\x00\x00fooq\x0bK\x01X\x03\x00\x00\x00bar'
277n/a b'q\x0cK\x02ubh\ttq\rh\rK\x05e.'
278n/a)
279n/a
280n/a# Disassembly of DATA1
281n/aDATA1_DIS = """\
282n/a 0: ] EMPTY_LIST
283n/a 1: q BINPUT 0
284n/a 3: ( MARK
285n/a 4: K BININT1 0
286n/a 6: K BININT1 1
287n/a 8: G BINFLOAT 2.0
288n/a 17: c GLOBAL '__builtin__ complex'
289n/a 38: q BINPUT 1
290n/a 40: ( MARK
291n/a 41: G BINFLOAT 3.0
292n/a 50: G BINFLOAT 0.0
293n/a 59: t TUPLE (MARK at 40)
294n/a 60: q BINPUT 2
295n/a 62: R REDUCE
296n/a 63: q BINPUT 3
297n/a 65: K BININT1 1
298n/a 67: J BININT -1
299n/a 72: K BININT1 255
300n/a 74: J BININT -255
301n/a 79: J BININT -256
302n/a 84: M BININT2 65535
303n/a 87: J BININT -65535
304n/a 92: J BININT -65536
305n/a 97: J BININT 2147483647
306n/a 102: J BININT -2147483647
307n/a 107: J BININT -2147483648
308n/a 112: ( MARK
309n/a 113: X BINUNICODE 'abc'
310n/a 121: q BINPUT 4
311n/a 123: h BINGET 4
312n/a 125: c GLOBAL 'copy_reg _reconstructor'
313n/a 150: q BINPUT 5
314n/a 152: ( MARK
315n/a 153: c GLOBAL '__main__ C'
316n/a 165: q BINPUT 6
317n/a 167: c GLOBAL '__builtin__ object'
318n/a 187: q BINPUT 7
319n/a 189: N NONE
320n/a 190: t TUPLE (MARK at 152)
321n/a 191: q BINPUT 8
322n/a 193: R REDUCE
323n/a 194: q BINPUT 9
324n/a 196: } EMPTY_DICT
325n/a 197: q BINPUT 10
326n/a 199: ( MARK
327n/a 200: X BINUNICODE 'foo'
328n/a 208: q BINPUT 11
329n/a 210: K BININT1 1
330n/a 212: X BINUNICODE 'bar'
331n/a 220: q BINPUT 12
332n/a 222: K BININT1 2
333n/a 224: u SETITEMS (MARK at 199)
334n/a 225: b BUILD
335n/a 226: h BINGET 9
336n/a 228: t TUPLE (MARK at 112)
337n/a 229: q BINPUT 13
338n/a 231: h BINGET 13
339n/a 233: K BININT1 5
340n/a 235: e APPENDS (MARK at 3)
341n/a 236: . STOP
342n/ahighest protocol among opcodes = 1
343n/a"""
344n/a
345n/aDATA2 = (
346n/a b'\x80\x02]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
347n/a b'__builtin__\ncomplex\n'
348n/a b'q\x01G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00'
349n/a b'\x86q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xff'
350n/a b'J\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff'
351n/a b'\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00a'
352n/a b'bcq\x04h\x04c__main__\nC\nq\x05'
353n/a b')\x81q\x06}q\x07(X\x03\x00\x00\x00fooq\x08K\x01'
354n/a b'X\x03\x00\x00\x00barq\tK\x02ubh\x06tq\nh'
355n/a b'\nK\x05e.'
356n/a)
357n/a
358n/a# Disassembly of DATA2
359n/aDATA2_DIS = """\
360n/a 0: \x80 PROTO 2
361n/a 2: ] EMPTY_LIST
362n/a 3: q BINPUT 0
363n/a 5: ( MARK
364n/a 6: K BININT1 0
365n/a 8: K BININT1 1
366n/a 10: G BINFLOAT 2.0
367n/a 19: c GLOBAL '__builtin__ complex'
368n/a 40: q BINPUT 1
369n/a 42: G BINFLOAT 3.0
370n/a 51: G BINFLOAT 0.0
371n/a 60: \x86 TUPLE2
372n/a 61: q BINPUT 2
373n/a 63: R REDUCE
374n/a 64: q BINPUT 3
375n/a 66: K BININT1 1
376n/a 68: J BININT -1
377n/a 73: K BININT1 255
378n/a 75: J BININT -255
379n/a 80: J BININT -256
380n/a 85: M BININT2 65535
381n/a 88: J BININT -65535
382n/a 93: J BININT -65536
383n/a 98: J BININT 2147483647
384n/a 103: J BININT -2147483647
385n/a 108: J BININT -2147483648
386n/a 113: ( MARK
387n/a 114: X BINUNICODE 'abc'
388n/a 122: q BINPUT 4
389n/a 124: h BINGET 4
390n/a 126: c GLOBAL '__main__ C'
391n/a 138: q BINPUT 5
392n/a 140: ) EMPTY_TUPLE
393n/a 141: \x81 NEWOBJ
394n/a 142: q BINPUT 6
395n/a 144: } EMPTY_DICT
396n/a 145: q BINPUT 7
397n/a 147: ( MARK
398n/a 148: X BINUNICODE 'foo'
399n/a 156: q BINPUT 8
400n/a 158: K BININT1 1
401n/a 160: X BINUNICODE 'bar'
402n/a 168: q BINPUT 9
403n/a 170: K BININT1 2
404n/a 172: u SETITEMS (MARK at 147)
405n/a 173: b BUILD
406n/a 174: h BINGET 6
407n/a 176: t TUPLE (MARK at 113)
408n/a 177: q BINPUT 10
409n/a 179: h BINGET 10
410n/a 181: K BININT1 5
411n/a 183: e APPENDS (MARK at 5)
412n/a 184: . STOP
413n/ahighest protocol among opcodes = 2
414n/a"""
415n/a
416n/aDATA3 = (
417n/a b'\x80\x03]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
418n/a b'builtins\ncomplex\nq\x01G'
419n/a b'@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00\x86q\x02'
420n/a b'Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ\x00\xff'
421n/a b'\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff\xff\x7f'
422n/a b'J\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00abcq'
423n/a b'\x04h\x04c__main__\nC\nq\x05)\x81q'
424n/a b'\x06}q\x07(X\x03\x00\x00\x00barq\x08K\x02X\x03\x00'
425n/a b'\x00\x00fooq\tK\x01ubh\x06tq\nh\nK\x05'
426n/a b'e.'
427n/a)
428n/a
429n/a# Disassembly of DATA3
430n/aDATA3_DIS = """\
431n/a 0: \x80 PROTO 3
432n/a 2: ] EMPTY_LIST
433n/a 3: q BINPUT 0
434n/a 5: ( MARK
435n/a 6: K BININT1 0
436n/a 8: K BININT1 1
437n/a 10: G BINFLOAT 2.0
438n/a 19: c GLOBAL 'builtins complex'
439n/a 37: q BINPUT 1
440n/a 39: G BINFLOAT 3.0
441n/a 48: G BINFLOAT 0.0
442n/a 57: \x86 TUPLE2
443n/a 58: q BINPUT 2
444n/a 60: R REDUCE
445n/a 61: q BINPUT 3
446n/a 63: K BININT1 1
447n/a 65: J BININT -1
448n/a 70: K BININT1 255
449n/a 72: J BININT -255
450n/a 77: J BININT -256
451n/a 82: M BININT2 65535
452n/a 85: J BININT -65535
453n/a 90: J BININT -65536
454n/a 95: J BININT 2147483647
455n/a 100: J BININT -2147483647
456n/a 105: J BININT -2147483648
457n/a 110: ( MARK
458n/a 111: X BINUNICODE 'abc'
459n/a 119: q BINPUT 4
460n/a 121: h BINGET 4
461n/a 123: c GLOBAL '__main__ C'
462n/a 135: q BINPUT 5
463n/a 137: ) EMPTY_TUPLE
464n/a 138: \x81 NEWOBJ
465n/a 139: q BINPUT 6
466n/a 141: } EMPTY_DICT
467n/a 142: q BINPUT 7
468n/a 144: ( MARK
469n/a 145: X BINUNICODE 'bar'
470n/a 153: q BINPUT 8
471n/a 155: K BININT1 2
472n/a 157: X BINUNICODE 'foo'
473n/a 165: q BINPUT 9
474n/a 167: K BININT1 1
475n/a 169: u SETITEMS (MARK at 144)
476n/a 170: b BUILD
477n/a 171: h BINGET 6
478n/a 173: t TUPLE (MARK at 110)
479n/a 174: q BINPUT 10
480n/a 176: h BINGET 10
481n/a 178: K BININT1 5
482n/a 180: e APPENDS (MARK at 5)
483n/a 181: . STOP
484n/ahighest protocol among opcodes = 2
485n/a"""
486n/a
487n/aDATA4 = (
488n/a b'\x80\x04\x95\xa8\x00\x00\x00\x00\x00\x00\x00]\x94(K\x00K\x01G@'
489n/a b'\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x07'
490n/a b'complex\x94\x93\x94G@\x08\x00\x00\x00\x00\x00\x00G'
491n/a b'\x00\x00\x00\x00\x00\x00\x00\x00\x86\x94R\x94K\x01J\xff\xff\xff\xffK'
492n/a b'\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ'
493n/a b'\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80('
494n/a b'\x8c\x03abc\x94h\x06\x8c\x08__main__\x94\x8c'
495n/a b'\x01C\x94\x93\x94)\x81\x94}\x94(\x8c\x03bar\x94K\x02\x8c'
496n/a b'\x03foo\x94K\x01ubh\nt\x94h\x0eK\x05e.'
497n/a)
498n/a
499n/a# Disassembly of DATA4
500n/aDATA4_DIS = """\
501n/a 0: \x80 PROTO 4
502n/a 2: \x95 FRAME 168
503n/a 11: ] EMPTY_LIST
504n/a 12: \x94 MEMOIZE
505n/a 13: ( MARK
506n/a 14: K BININT1 0
507n/a 16: K BININT1 1
508n/a 18: G BINFLOAT 2.0
509n/a 27: \x8c SHORT_BINUNICODE 'builtins'
510n/a 37: \x94 MEMOIZE
511n/a 38: \x8c SHORT_BINUNICODE 'complex'
512n/a 47: \x94 MEMOIZE
513n/a 48: \x93 STACK_GLOBAL
514n/a 49: \x94 MEMOIZE
515n/a 50: G BINFLOAT 3.0
516n/a 59: G BINFLOAT 0.0
517n/a 68: \x86 TUPLE2
518n/a 69: \x94 MEMOIZE
519n/a 70: R REDUCE
520n/a 71: \x94 MEMOIZE
521n/a 72: K BININT1 1
522n/a 74: J BININT -1
523n/a 79: K BININT1 255
524n/a 81: J BININT -255
525n/a 86: J BININT -256
526n/a 91: M BININT2 65535
527n/a 94: J BININT -65535
528n/a 99: J BININT -65536
529n/a 104: J BININT 2147483647
530n/a 109: J BININT -2147483647
531n/a 114: J BININT -2147483648
532n/a 119: ( MARK
533n/a 120: \x8c SHORT_BINUNICODE 'abc'
534n/a 125: \x94 MEMOIZE
535n/a 126: h BINGET 6
536n/a 128: \x8c SHORT_BINUNICODE '__main__'
537n/a 138: \x94 MEMOIZE
538n/a 139: \x8c SHORT_BINUNICODE 'C'
539n/a 142: \x94 MEMOIZE
540n/a 143: \x93 STACK_GLOBAL
541n/a 144: \x94 MEMOIZE
542n/a 145: ) EMPTY_TUPLE
543n/a 146: \x81 NEWOBJ
544n/a 147: \x94 MEMOIZE
545n/a 148: } EMPTY_DICT
546n/a 149: \x94 MEMOIZE
547n/a 150: ( MARK
548n/a 151: \x8c SHORT_BINUNICODE 'bar'
549n/a 156: \x94 MEMOIZE
550n/a 157: K BININT1 2
551n/a 159: \x8c SHORT_BINUNICODE 'foo'
552n/a 164: \x94 MEMOIZE
553n/a 165: K BININT1 1
554n/a 167: u SETITEMS (MARK at 150)
555n/a 168: b BUILD
556n/a 169: h BINGET 10
557n/a 171: t TUPLE (MARK at 119)
558n/a 172: \x94 MEMOIZE
559n/a 173: h BINGET 14
560n/a 175: K BININT1 5
561n/a 177: e APPENDS (MARK at 13)
562n/a 178: . STOP
563n/ahighest protocol among opcodes = 4
564n/a"""
565n/a
566n/a# set([1,2]) pickled from 2.x with protocol 2
567n/aDATA_SET = b'\x80\x02c__builtin__\nset\nq\x00]q\x01(K\x01K\x02e\x85q\x02Rq\x03.'
568n/a
569n/a# xrange(5) pickled from 2.x with protocol 2
570n/aDATA_XRANGE = b'\x80\x02c__builtin__\nxrange\nq\x00K\x00K\x05K\x01\x87q\x01Rq\x02.'
571n/a
572n/a# a SimpleCookie() object pickled from 2.x with protocol 2
573n/aDATA_COOKIE = (b'\x80\x02cCookie\nSimpleCookie\nq\x00)\x81q\x01U\x03key'
574n/a b'q\x02cCookie\nMorsel\nq\x03)\x81q\x04(U\x07commentq\x05U'
575n/a b'\x00q\x06U\x06domainq\x07h\x06U\x06secureq\x08h\x06U\x07'
576n/a b'expiresq\th\x06U\x07max-ageq\nh\x06U\x07versionq\x0bh\x06U'
577n/a b'\x04pathq\x0ch\x06U\x08httponlyq\rh\x06u}q\x0e(U\x0b'
578n/a b'coded_valueq\x0fU\x05valueq\x10h\x10h\x10h\x02h\x02ubs}q\x11b.')
579n/a
580n/a# set([3]) pickled from 2.x with protocol 2
581n/aDATA_SET2 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01K\x03a\x85q\x02Rq\x03.'
582n/a
583n/apython2_exceptions_without_args = (
584n/a ArithmeticError,
585n/a AssertionError,
586n/a AttributeError,
587n/a BaseException,
588n/a BufferError,
589n/a BytesWarning,
590n/a DeprecationWarning,
591n/a EOFError,
592n/a EnvironmentError,
593n/a Exception,
594n/a FloatingPointError,
595n/a FutureWarning,
596n/a GeneratorExit,
597n/a IOError,
598n/a ImportError,
599n/a ImportWarning,
600n/a IndentationError,
601n/a IndexError,
602n/a KeyError,
603n/a KeyboardInterrupt,
604n/a LookupError,
605n/a MemoryError,
606n/a NameError,
607n/a NotImplementedError,
608n/a OSError,
609n/a OverflowError,
610n/a PendingDeprecationWarning,
611n/a ReferenceError,
612n/a RuntimeError,
613n/a RuntimeWarning,
614n/a # StandardError is gone in Python 3, we map it to Exception
615n/a StopIteration,
616n/a SyntaxError,
617n/a SyntaxWarning,
618n/a SystemError,
619n/a SystemExit,
620n/a TabError,
621n/a TypeError,
622n/a UnboundLocalError,
623n/a UnicodeError,
624n/a UnicodeWarning,
625n/a UserWarning,
626n/a ValueError,
627n/a Warning,
628n/a ZeroDivisionError,
629n/a)
630n/a
631n/aexception_pickle = b'\x80\x02cexceptions\n?\nq\x00)Rq\x01.'
632n/a
633n/a# UnicodeEncodeError object pickled from 2.x with protocol 2
634n/aDATA_UEERR = (b'\x80\x02cexceptions\nUnicodeEncodeError\n'
635n/a b'q\x00(U\x05asciiq\x01X\x03\x00\x00\x00fooq\x02K\x00K\x01'
636n/a b'U\x03badq\x03tq\x04Rq\x05.')
637n/a
638n/a
639n/adef create_data():
640n/a c = C()
641n/a c.foo = 1
642n/a c.bar = 2
643n/a x = [0, 1, 2.0, 3.0+0j]
644n/a # Append some integer test cases at cPickle.c's internal size
645n/a # cutoffs.
646n/a uint1max = 0xff
647n/a uint2max = 0xffff
648n/a int4max = 0x7fffffff
649n/a x.extend([1, -1,
650n/a uint1max, -uint1max, -uint1max-1,
651n/a uint2max, -uint2max, -uint2max-1,
652n/a int4max, -int4max, -int4max-1])
653n/a y = ('abc', 'abc', c, c)
654n/a x.append(y)
655n/a x.append(y)
656n/a x.append(5)
657n/a return x
658n/a
659n/a
660n/aclass AbstractUnpickleTests(unittest.TestCase):
661n/a # Subclass must define self.loads.
662n/a
663n/a _testdata = create_data()
664n/a
665n/a def assert_is_copy(self, obj, objcopy, msg=None):
666n/a """Utility method to verify if two objects are copies of each others.
667n/a """
668n/a if msg is None:
669n/a msg = "{!r} is not a copy of {!r}".format(obj, objcopy)
670n/a self.assertEqual(obj, objcopy, msg=msg)
671n/a self.assertIs(type(obj), type(objcopy), msg=msg)
672n/a if hasattr(obj, '__dict__'):
673n/a self.assertDictEqual(obj.__dict__, objcopy.__dict__, msg=msg)
674n/a self.assertIsNot(obj.__dict__, objcopy.__dict__, msg=msg)
675n/a if hasattr(obj, '__slots__'):
676n/a self.assertListEqual(obj.__slots__, objcopy.__slots__, msg=msg)
677n/a for slot in obj.__slots__:
678n/a self.assertEqual(
679n/a hasattr(obj, slot), hasattr(objcopy, slot), msg=msg)
680n/a self.assertEqual(getattr(obj, slot, None),
681n/a getattr(objcopy, slot, None), msg=msg)
682n/a
683n/a def check_unpickling_error(self, errors, data):
684n/a with self.subTest(data=data), \
685n/a self.assertRaises(errors):
686n/a try:
687n/a self.loads(data)
688n/a except BaseException as exc:
689n/a if support.verbose > 1:
690n/a print('%-32r - %s: %s' %
691n/a (data, exc.__class__.__name__, exc))
692n/a raise
693n/a
694n/a def test_load_from_data0(self):
695n/a self.assert_is_copy(self._testdata, self.loads(DATA0))
696n/a
697n/a def test_load_from_data1(self):
698n/a self.assert_is_copy(self._testdata, self.loads(DATA1))
699n/a
700n/a def test_load_from_data2(self):
701n/a self.assert_is_copy(self._testdata, self.loads(DATA2))
702n/a
703n/a def test_load_from_data3(self):
704n/a self.assert_is_copy(self._testdata, self.loads(DATA3))
705n/a
706n/a def test_load_from_data4(self):
707n/a self.assert_is_copy(self._testdata, self.loads(DATA4))
708n/a
709n/a def test_load_classic_instance(self):
710n/a # See issue5180. Test loading 2.x pickles that
711n/a # contain an instance of old style class.
712n/a for X, args in [(C, ()), (D, ('x',)), (E, ())]:
713n/a xname = X.__name__.encode('ascii')
714n/a # Protocol 0 (text mode pickle):
715n/a """
716n/a 0: ( MARK
717n/a 1: i INST '__main__ X' (MARK at 0)
718n/a 13: p PUT 0
719n/a 16: ( MARK
720n/a 17: d DICT (MARK at 16)
721n/a 18: p PUT 1
722n/a 21: b BUILD
723n/a 22: . STOP
724n/a """
725n/a pickle0 = (b"(i__main__\n"
726n/a b"X\n"
727n/a b"p0\n"
728n/a b"(dp1\nb.").replace(b'X', xname)
729n/a self.assert_is_copy(X(*args), self.loads(pickle0))
730n/a
731n/a # Protocol 1 (binary mode pickle)
732n/a """
733n/a 0: ( MARK
734n/a 1: c GLOBAL '__main__ X'
735n/a 13: q BINPUT 0
736n/a 15: o OBJ (MARK at 0)
737n/a 16: q BINPUT 1
738n/a 18: } EMPTY_DICT
739n/a 19: q BINPUT 2
740n/a 21: b BUILD
741n/a 22: . STOP
742n/a """
743n/a pickle1 = (b'(c__main__\n'
744n/a b'X\n'
745n/a b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
746n/a self.assert_is_copy(X(*args), self.loads(pickle1))
747n/a
748n/a # Protocol 2 (pickle2 = b'\x80\x02' + pickle1)
749n/a """
750n/a 0: \x80 PROTO 2
751n/a 2: ( MARK
752n/a 3: c GLOBAL '__main__ X'
753n/a 15: q BINPUT 0
754n/a 17: o OBJ (MARK at 2)
755n/a 18: q BINPUT 1
756n/a 20: } EMPTY_DICT
757n/a 21: q BINPUT 2
758n/a 23: b BUILD
759n/a 24: . STOP
760n/a """
761n/a pickle2 = (b'\x80\x02(c__main__\n'
762n/a b'X\n'
763n/a b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
764n/a self.assert_is_copy(X(*args), self.loads(pickle2))
765n/a
766n/a def test_maxint64(self):
767n/a maxint64 = (1 << 63) - 1
768n/a data = b'I' + str(maxint64).encode("ascii") + b'\n.'
769n/a got = self.loads(data)
770n/a self.assert_is_copy(maxint64, got)
771n/a
772n/a # Try too with a bogus literal.
773n/a data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.'
774n/a self.check_unpickling_error(ValueError, data)
775n/a
776n/a def test_unpickle_from_2x(self):
777n/a # Unpickle non-trivial data from Python 2.x.
778n/a loaded = self.loads(DATA_SET)
779n/a self.assertEqual(loaded, set([1, 2]))
780n/a loaded = self.loads(DATA_XRANGE)
781n/a self.assertEqual(type(loaded), type(range(0)))
782n/a self.assertEqual(list(loaded), list(range(5)))
783n/a loaded = self.loads(DATA_COOKIE)
784n/a self.assertEqual(type(loaded), SimpleCookie)
785n/a self.assertEqual(list(loaded.keys()), ["key"])
786n/a self.assertEqual(loaded["key"].value, "value")
787n/a
788n/a # Exception objects without arguments pickled from 2.x with protocol 2
789n/a for exc in python2_exceptions_without_args:
790n/a data = exception_pickle.replace(b'?', exc.__name__.encode("ascii"))
791n/a loaded = self.loads(data)
792n/a self.assertIs(type(loaded), exc)
793n/a
794n/a # StandardError is mapped to Exception, test that separately
795n/a loaded = self.loads(exception_pickle.replace(b'?', b'StandardError'))
796n/a self.assertIs(type(loaded), Exception)
797n/a
798n/a loaded = self.loads(DATA_UEERR)
799n/a self.assertIs(type(loaded), UnicodeEncodeError)
800n/a self.assertEqual(loaded.object, "foo")
801n/a self.assertEqual(loaded.encoding, "ascii")
802n/a self.assertEqual(loaded.start, 0)
803n/a self.assertEqual(loaded.end, 1)
804n/a self.assertEqual(loaded.reason, "bad")
805n/a
806n/a def test_load_python2_str_as_bytes(self):
807n/a # From Python 2: pickle.dumps('a\x00\xa0', protocol=0)
808n/a self.assertEqual(self.loads(b"S'a\\x00\\xa0'\n.",
809n/a encoding="bytes"), b'a\x00\xa0')
810n/a # From Python 2: pickle.dumps('a\x00\xa0', protocol=1)
811n/a self.assertEqual(self.loads(b'U\x03a\x00\xa0.',
812n/a encoding="bytes"), b'a\x00\xa0')
813n/a # From Python 2: pickle.dumps('a\x00\xa0', protocol=2)
814n/a self.assertEqual(self.loads(b'\x80\x02U\x03a\x00\xa0.',
815n/a encoding="bytes"), b'a\x00\xa0')
816n/a
817n/a def test_load_python2_unicode_as_str(self):
818n/a # From Python 2: pickle.dumps(u'Ï€', protocol=0)
819n/a self.assertEqual(self.loads(b'V\\u03c0\n.',
820n/a encoding='bytes'), 'Ï€')
821n/a # From Python 2: pickle.dumps(u'Ï€', protocol=1)
822n/a self.assertEqual(self.loads(b'X\x02\x00\x00\x00\xcf\x80.',
823n/a encoding="bytes"), 'Ï€')
824n/a # From Python 2: pickle.dumps(u'Ï€', protocol=2)
825n/a self.assertEqual(self.loads(b'\x80\x02X\x02\x00\x00\x00\xcf\x80.',
826n/a encoding="bytes"), 'Ï€')
827n/a
828n/a def test_load_long_python2_str_as_bytes(self):
829n/a # From Python 2: pickle.dumps('x' * 300, protocol=1)
830n/a self.assertEqual(self.loads(pickle.BINSTRING +
831n/a struct.pack("<I", 300) +
832n/a b'x' * 300 + pickle.STOP,
833n/a encoding='bytes'), b'x' * 300)
834n/a
835n/a def test_constants(self):
836n/a self.assertIsNone(self.loads(b'N.'))
837n/a self.assertIs(self.loads(b'\x88.'), True)
838n/a self.assertIs(self.loads(b'\x89.'), False)
839n/a self.assertIs(self.loads(b'I01\n.'), True)
840n/a self.assertIs(self.loads(b'I00\n.'), False)
841n/a
842n/a def test_empty_bytestring(self):
843n/a # issue 11286
844n/a empty = self.loads(b'\x80\x03U\x00q\x00.', encoding='koi8-r')
845n/a self.assertEqual(empty, '')
846n/a
847n/a def test_short_binbytes(self):
848n/a dumped = b'\x80\x03C\x04\xe2\x82\xac\x00.'
849n/a self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00')
850n/a
851n/a def test_binbytes(self):
852n/a dumped = b'\x80\x03B\x04\x00\x00\x00\xe2\x82\xac\x00.'
853n/a self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00')
854n/a
855n/a @requires_32b
856n/a def test_negative_32b_binbytes(self):
857n/a # On 32-bit builds, a BINBYTES of 2**31 or more is refused
858n/a dumped = b'\x80\x03B\xff\xff\xff\xffxyzq\x00.'
859n/a self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
860n/a dumped)
861n/a
862n/a @requires_32b
863n/a def test_negative_32b_binunicode(self):
864n/a # On 32-bit builds, a BINUNICODE of 2**31 or more is refused
865n/a dumped = b'\x80\x03X\xff\xff\xff\xffxyzq\x00.'
866n/a self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
867n/a dumped)
868n/a
869n/a def test_short_binunicode(self):
870n/a dumped = b'\x80\x04\x8c\x04\xe2\x82\xac\x00.'
871n/a self.assertEqual(self.loads(dumped), '\u20ac\x00')
872n/a
873n/a def test_misc_get(self):
874n/a self.check_unpickling_error(KeyError, b'g0\np0')
875n/a self.assert_is_copy([(100,), (100,)],
876n/a self.loads(b'((Kdtp0\nh\x00l.))'))
877n/a
878n/a def test_binbytes8(self):
879n/a dumped = b'\x80\x04\x8e\4\0\0\0\0\0\0\0\xe2\x82\xac\x00.'
880n/a self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00')
881n/a
882n/a def test_binunicode8(self):
883n/a dumped = b'\x80\x04\x8d\4\0\0\0\0\0\0\0\xe2\x82\xac\x00.'
884n/a self.assertEqual(self.loads(dumped), '\u20ac\x00')
885n/a
886n/a @requires_32b
887n/a def test_large_32b_binbytes8(self):
888n/a dumped = b'\x80\x04\x8e\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.'
889n/a self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
890n/a dumped)
891n/a
892n/a @requires_32b
893n/a def test_large_32b_binunicode8(self):
894n/a dumped = b'\x80\x04\x8d\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.'
895n/a self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
896n/a dumped)
897n/a
898n/a def test_get(self):
899n/a pickled = b'((lp100000\ng100000\nt.'
900n/a unpickled = self.loads(pickled)
901n/a self.assertEqual(unpickled, ([],)*2)
902n/a self.assertIs(unpickled[0], unpickled[1])
903n/a
904n/a def test_binget(self):
905n/a pickled = b'(]q\xffh\xfft.'
906n/a unpickled = self.loads(pickled)
907n/a self.assertEqual(unpickled, ([],)*2)
908n/a self.assertIs(unpickled[0], unpickled[1])
909n/a
910n/a def test_long_binget(self):
911n/a pickled = b'(]r\x00\x00\x01\x00j\x00\x00\x01\x00t.'
912n/a unpickled = self.loads(pickled)
913n/a self.assertEqual(unpickled, ([],)*2)
914n/a self.assertIs(unpickled[0], unpickled[1])
915n/a
916n/a def test_dup(self):
917n/a pickled = b'((l2t.'
918n/a unpickled = self.loads(pickled)
919n/a self.assertEqual(unpickled, ([],)*2)
920n/a self.assertIs(unpickled[0], unpickled[1])
921n/a
922n/a def test_negative_put(self):
923n/a # Issue #12847
924n/a dumped = b'Va\np-1\n.'
925n/a self.check_unpickling_error(ValueError, dumped)
926n/a
927n/a @requires_32b
928n/a def test_negative_32b_binput(self):
929n/a # Issue #12847
930n/a dumped = b'\x80\x03X\x01\x00\x00\x00ar\xff\xff\xff\xff.'
931n/a self.check_unpickling_error(ValueError, dumped)
932n/a
933n/a def test_badly_escaped_string(self):
934n/a self.check_unpickling_error(ValueError, b"S'\\'\n.")
935n/a
936n/a def test_badly_quoted_string(self):
937n/a # Issue #17710
938n/a badpickles = [b"S'\n.",
939n/a b'S"\n.',
940n/a b'S\' \n.',
941n/a b'S" \n.',
942n/a b'S\'"\n.',
943n/a b'S"\'\n.',
944n/a b"S' ' \n.",
945n/a b'S" " \n.',
946n/a b"S ''\n.",
947n/a b'S ""\n.',
948n/a b'S \n.',
949n/a b'S\n.',
950n/a b'S.']
951n/a for p in badpickles:
952n/a self.check_unpickling_error(pickle.UnpicklingError, p)
953n/a
954n/a def test_correctly_quoted_string(self):
955n/a goodpickles = [(b"S''\n.", ''),
956n/a (b'S""\n.', ''),
957n/a (b'S"\\n"\n.', '\n'),
958n/a (b"S'\\n'\n.", '\n')]
959n/a for p, expected in goodpickles:
960n/a self.assertEqual(self.loads(p), expected)
961n/a
962n/a def test_frame_readline(self):
963n/a pickled = b'\x80\x04\x95\x05\x00\x00\x00\x00\x00\x00\x00I42\n.'
964n/a # 0: \x80 PROTO 4
965n/a # 2: \x95 FRAME 5
966n/a # 11: I INT 42
967n/a # 15: . STOP
968n/a self.assertEqual(self.loads(pickled), 42)
969n/a
970n/a def test_compat_unpickle(self):
971n/a # xrange(1, 7)
972n/a pickled = b'\x80\x02c__builtin__\nxrange\nK\x01K\x07K\x01\x87R.'
973n/a unpickled = self.loads(pickled)
974n/a self.assertIs(type(unpickled), range)
975n/a self.assertEqual(unpickled, range(1, 7))
976n/a self.assertEqual(list(unpickled), [1, 2, 3, 4, 5, 6])
977n/a # reduce
978n/a pickled = b'\x80\x02c__builtin__\nreduce\n.'
979n/a self.assertIs(self.loads(pickled), functools.reduce)
980n/a # whichdb.whichdb
981n/a pickled = b'\x80\x02cwhichdb\nwhichdb\n.'
982n/a self.assertIs(self.loads(pickled), dbm.whichdb)
983n/a # Exception(), StandardError()
984n/a for name in (b'Exception', b'StandardError'):
985n/a pickled = (b'\x80\x02cexceptions\n' + name + b'\nU\x03ugh\x85R.')
986n/a unpickled = self.loads(pickled)
987n/a self.assertIs(type(unpickled), Exception)
988n/a self.assertEqual(str(unpickled), 'ugh')
989n/a # UserDict.UserDict({1: 2}), UserDict.IterableUserDict({1: 2})
990n/a for name in (b'UserDict', b'IterableUserDict'):
991n/a pickled = (b'\x80\x02(cUserDict\n' + name +
992n/a b'\no}U\x04data}K\x01K\x02ssb.')
993n/a unpickled = self.loads(pickled)
994n/a self.assertIs(type(unpickled), collections.UserDict)
995n/a self.assertEqual(unpickled, collections.UserDict({1: 2}))
996n/a
997n/a def test_bad_stack(self):
998n/a badpickles = [
999n/a b'.', # STOP
1000n/a b'0', # POP
1001n/a b'1', # POP_MARK
1002n/a b'2', # DUP
1003n/a b'(2',
1004n/a b'R', # REDUCE
1005n/a b')R',
1006n/a b'a', # APPEND
1007n/a b'Na',
1008n/a b'b', # BUILD
1009n/a b'Nb',
1010n/a b'd', # DICT
1011n/a b'e', # APPENDS
1012n/a b'(e',
1013n/a b'ibuiltins\nlist\n', # INST
1014n/a b'l', # LIST
1015n/a b'o', # OBJ
1016n/a b'(o',
1017n/a b'p1\n', # PUT
1018n/a b'q\x00', # BINPUT
1019n/a b'r\x00\x00\x00\x00', # LONG_BINPUT
1020n/a b's', # SETITEM
1021n/a b'Ns',
1022n/a b'NNs',
1023n/a b't', # TUPLE
1024n/a b'u', # SETITEMS
1025n/a b'(u',
1026n/a b'}(Nu',
1027n/a b'\x81', # NEWOBJ
1028n/a b')\x81',
1029n/a b'\x85', # TUPLE1
1030n/a b'\x86', # TUPLE2
1031n/a b'N\x86',
1032n/a b'\x87', # TUPLE3
1033n/a b'N\x87',
1034n/a b'NN\x87',
1035n/a b'\x90', # ADDITEMS
1036n/a b'(\x90',
1037n/a b'\x91', # FROZENSET
1038n/a b'\x92', # NEWOBJ_EX
1039n/a b')}\x92',
1040n/a b'\x93', # STACK_GLOBAL
1041n/a b'Vlist\n\x93',
1042n/a b'\x94', # MEMOIZE
1043n/a ]
1044n/a for p in badpickles:
1045n/a self.check_unpickling_error(self.bad_stack_errors, p)
1046n/a
1047n/a def test_bad_mark(self):
1048n/a badpickles = [
1049n/a b'N(.', # STOP
1050n/a b'N(2', # DUP
1051n/a b'cbuiltins\nlist\n)(R', # REDUCE
1052n/a b'cbuiltins\nlist\n()R',
1053n/a b']N(a', # APPEND
1054n/a # BUILD
1055n/a b'cbuiltins\nValueError\n)R}(b',
1056n/a b'cbuiltins\nValueError\n)R(}b',
1057n/a b'(Nd', # DICT
1058n/a b'N(p1\n', # PUT
1059n/a b'N(q\x00', # BINPUT
1060n/a b'N(r\x00\x00\x00\x00', # LONG_BINPUT
1061n/a b'}NN(s', # SETITEM
1062n/a b'}N(Ns',
1063n/a b'}(NNs',
1064n/a b'}((u', # SETITEMS
1065n/a b'cbuiltins\nlist\n)(\x81', # NEWOBJ
1066n/a b'cbuiltins\nlist\n()\x81',
1067n/a b'N(\x85', # TUPLE1
1068n/a b'NN(\x86', # TUPLE2
1069n/a b'N(N\x86',
1070n/a b'NNN(\x87', # TUPLE3
1071n/a b'NN(N\x87',
1072n/a b'N(NN\x87',
1073n/a b']((\x90', # ADDITEMS
1074n/a # NEWOBJ_EX
1075n/a b'cbuiltins\nlist\n)}(\x92',
1076n/a b'cbuiltins\nlist\n)(}\x92',
1077n/a b'cbuiltins\nlist\n()}\x92',
1078n/a # STACK_GLOBAL
1079n/a b'Vbuiltins\n(Vlist\n\x93',
1080n/a b'Vbuiltins\nVlist\n(\x93',
1081n/a b'N(\x94', # MEMOIZE
1082n/a ]
1083n/a for p in badpickles:
1084n/a self.check_unpickling_error(self.bad_stack_errors, p)
1085n/a
1086n/a def test_truncated_data(self):
1087n/a self.check_unpickling_error(EOFError, b'')
1088n/a self.check_unpickling_error(EOFError, b'N')
1089n/a badpickles = [
1090n/a b'B', # BINBYTES
1091n/a b'B\x03\x00\x00',
1092n/a b'B\x03\x00\x00\x00',
1093n/a b'B\x03\x00\x00\x00ab',
1094n/a b'C', # SHORT_BINBYTES
1095n/a b'C\x03',
1096n/a b'C\x03ab',
1097n/a b'F', # FLOAT
1098n/a b'F0.0',
1099n/a b'F0.00',
1100n/a b'G', # BINFLOAT
1101n/a b'G\x00\x00\x00\x00\x00\x00\x00',
1102n/a b'I', # INT
1103n/a b'I0',
1104n/a b'J', # BININT
1105n/a b'J\x00\x00\x00',
1106n/a b'K', # BININT1
1107n/a b'L', # LONG
1108n/a b'L0',
1109n/a b'L10',
1110n/a b'L0L',
1111n/a b'L10L',
1112n/a b'M', # BININT2
1113n/a b'M\x00',
1114n/a # b'P', # PERSID
1115n/a # b'Pabc',
1116n/a b'S', # STRING
1117n/a b"S'abc'",
1118n/a b'T', # BINSTRING
1119n/a b'T\x03\x00\x00',
1120n/a b'T\x03\x00\x00\x00',
1121n/a b'T\x03\x00\x00\x00ab',
1122n/a b'U', # SHORT_BINSTRING
1123n/a b'U\x03',
1124n/a b'U\x03ab',
1125n/a b'V', # UNICODE
1126n/a b'Vabc',
1127n/a b'X', # BINUNICODE
1128n/a b'X\x03\x00\x00',
1129n/a b'X\x03\x00\x00\x00',
1130n/a b'X\x03\x00\x00\x00ab',
1131n/a b'(c', # GLOBAL
1132n/a b'(cbuiltins',
1133n/a b'(cbuiltins\n',
1134n/a b'(cbuiltins\nlist',
1135n/a b'Ng', # GET
1136n/a b'Ng0',
1137n/a b'(i', # INST
1138n/a b'(ibuiltins',
1139n/a b'(ibuiltins\n',
1140n/a b'(ibuiltins\nlist',
1141n/a b'Nh', # BINGET
1142n/a b'Nj', # LONG_BINGET
1143n/a b'Nj\x00\x00\x00',
1144n/a b'Np', # PUT
1145n/a b'Np0',
1146n/a b'Nq', # BINPUT
1147n/a b'Nr', # LONG_BINPUT
1148n/a b'Nr\x00\x00\x00',
1149n/a b'\x80', # PROTO
1150n/a b'\x82', # EXT1
1151n/a b'\x83', # EXT2
1152n/a b'\x84\x01',
1153n/a b'\x84', # EXT4
1154n/a b'\x84\x01\x00\x00',
1155n/a b'\x8a', # LONG1
1156n/a b'\x8b', # LONG4
1157n/a b'\x8b\x00\x00\x00',
1158n/a b'\x8c', # SHORT_BINUNICODE
1159n/a b'\x8c\x03',
1160n/a b'\x8c\x03ab',
1161n/a b'\x8d', # BINUNICODE8
1162n/a b'\x8d\x03\x00\x00\x00\x00\x00\x00',
1163n/a b'\x8d\x03\x00\x00\x00\x00\x00\x00\x00',
1164n/a b'\x8d\x03\x00\x00\x00\x00\x00\x00\x00ab',
1165n/a b'\x8e', # BINBYTES8
1166n/a b'\x8e\x03\x00\x00\x00\x00\x00\x00',
1167n/a b'\x8e\x03\x00\x00\x00\x00\x00\x00\x00',
1168n/a b'\x8e\x03\x00\x00\x00\x00\x00\x00\x00ab',
1169n/a b'\x95', # FRAME
1170n/a b'\x95\x02\x00\x00\x00\x00\x00\x00',
1171n/a b'\x95\x02\x00\x00\x00\x00\x00\x00\x00',
1172n/a b'\x95\x02\x00\x00\x00\x00\x00\x00\x00N',
1173n/a ]
1174n/a for p in badpickles:
1175n/a self.check_unpickling_error(self.truncated_errors, p)
1176n/a
1177n/a
1178n/aclass AbstractPickleTests(unittest.TestCase):
1179n/a # Subclass must define self.dumps, self.loads.
1180n/a
1181n/a optimized = False
1182n/a
1183n/a _testdata = AbstractUnpickleTests._testdata
1184n/a
1185n/a def setUp(self):
1186n/a pass
1187n/a
1188n/a assert_is_copy = AbstractUnpickleTests.assert_is_copy
1189n/a
1190n/a def test_misc(self):
1191n/a # test various datatypes not tested by testdata
1192n/a for proto in protocols:
1193n/a x = myint(4)
1194n/a s = self.dumps(x, proto)
1195n/a y = self.loads(s)
1196n/a self.assert_is_copy(x, y)
1197n/a
1198n/a x = (1, ())
1199n/a s = self.dumps(x, proto)
1200n/a y = self.loads(s)
1201n/a self.assert_is_copy(x, y)
1202n/a
1203n/a x = initarg(1, x)
1204n/a s = self.dumps(x, proto)
1205n/a y = self.loads(s)
1206n/a self.assert_is_copy(x, y)
1207n/a
1208n/a # XXX test __reduce__ protocol?
1209n/a
1210n/a def test_roundtrip_equality(self):
1211n/a expected = self._testdata
1212n/a for proto in protocols:
1213n/a s = self.dumps(expected, proto)
1214n/a got = self.loads(s)
1215n/a self.assert_is_copy(expected, got)
1216n/a
1217n/a # There are gratuitous differences between pickles produced by
1218n/a # pickle and cPickle, largely because cPickle starts PUT indices at
1219n/a # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
1220n/a # there's a comment with an exclamation point there whose meaning
1221n/a # is a mystery. cPickle also suppresses PUT for objects with a refcount
1222n/a # of 1.
1223n/a def dont_test_disassembly(self):
1224n/a from io import StringIO
1225n/a from pickletools import dis
1226n/a
1227n/a for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
1228n/a s = self.dumps(self._testdata, proto)
1229n/a filelike = StringIO()
1230n/a dis(s, out=filelike)
1231n/a got = filelike.getvalue()
1232n/a self.assertEqual(expected, got)
1233n/a
1234n/a def test_recursive_list(self):
1235n/a l = []
1236n/a l.append(l)
1237n/a for proto in protocols:
1238n/a s = self.dumps(l, proto)
1239n/a x = self.loads(s)
1240n/a self.assertIsInstance(x, list)
1241n/a self.assertEqual(len(x), 1)
1242n/a self.assertIs(x[0], x)
1243n/a
1244n/a def test_recursive_tuple_and_list(self):
1245n/a t = ([],)
1246n/a t[0].append(t)
1247n/a for proto in protocols:
1248n/a s = self.dumps(t, proto)
1249n/a x = self.loads(s)
1250n/a self.assertIsInstance(x, tuple)
1251n/a self.assertEqual(len(x), 1)
1252n/a self.assertIsInstance(x[0], list)
1253n/a self.assertEqual(len(x[0]), 1)
1254n/a self.assertIs(x[0][0], x)
1255n/a
1256n/a def test_recursive_dict(self):
1257n/a d = {}
1258n/a d[1] = d
1259n/a for proto in protocols:
1260n/a s = self.dumps(d, proto)
1261n/a x = self.loads(s)
1262n/a self.assertIsInstance(x, dict)
1263n/a self.assertEqual(list(x.keys()), [1])
1264n/a self.assertIs(x[1], x)
1265n/a
1266n/a def test_recursive_dict_key(self):
1267n/a d = {}
1268n/a k = K(d)
1269n/a d[k] = 1
1270n/a for proto in protocols:
1271n/a s = self.dumps(d, proto)
1272n/a x = self.loads(s)
1273n/a self.assertIsInstance(x, dict)
1274n/a self.assertEqual(len(x.keys()), 1)
1275n/a self.assertIsInstance(list(x.keys())[0], K)
1276n/a self.assertIs(list(x.keys())[0].value, x)
1277n/a
1278n/a def test_recursive_set(self):
1279n/a y = set()
1280n/a k = K(y)
1281n/a y.add(k)
1282n/a for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1283n/a s = self.dumps(y, proto)
1284n/a x = self.loads(s)
1285n/a self.assertIsInstance(x, set)
1286n/a self.assertEqual(len(x), 1)
1287n/a self.assertIsInstance(list(x)[0], K)
1288n/a self.assertIs(list(x)[0].value, x)
1289n/a
1290n/a def test_recursive_list_subclass(self):
1291n/a y = MyList()
1292n/a y.append(y)
1293n/a for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
1294n/a s = self.dumps(y, proto)
1295n/a x = self.loads(s)
1296n/a self.assertIsInstance(x, MyList)
1297n/a self.assertEqual(len(x), 1)
1298n/a self.assertIs(x[0], x)
1299n/a
1300n/a def test_recursive_dict_subclass(self):
1301n/a d = MyDict()
1302n/a d[1] = d
1303n/a for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
1304n/a s = self.dumps(d, proto)
1305n/a x = self.loads(s)
1306n/a self.assertIsInstance(x, MyDict)
1307n/a self.assertEqual(list(x.keys()), [1])
1308n/a self.assertIs(x[1], x)
1309n/a
1310n/a def test_recursive_dict_subclass_key(self):
1311n/a d = MyDict()
1312n/a k = K(d)
1313n/a d[k] = 1
1314n/a for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
1315n/a s = self.dumps(d, proto)
1316n/a x = self.loads(s)
1317n/a self.assertIsInstance(x, MyDict)
1318n/a self.assertEqual(len(list(x.keys())), 1)
1319n/a self.assertIsInstance(list(x.keys())[0], K)
1320n/a self.assertIs(list(x.keys())[0].value, x)
1321n/a
1322n/a def test_recursive_inst(self):
1323n/a i = C()
1324n/a i.attr = i
1325n/a for proto in protocols:
1326n/a s = self.dumps(i, proto)
1327n/a x = self.loads(s)
1328n/a self.assertIsInstance(x, C)
1329n/a self.assertEqual(dir(x), dir(i))
1330n/a self.assertIs(x.attr, x)
1331n/a
1332n/a def test_recursive_multi(self):
1333n/a l = []
1334n/a d = {1:l}
1335n/a i = C()
1336n/a i.attr = d
1337n/a l.append(i)
1338n/a for proto in protocols:
1339n/a s = self.dumps(l, proto)
1340n/a x = self.loads(s)
1341n/a self.assertIsInstance(x, list)
1342n/a self.assertEqual(len(x), 1)
1343n/a self.assertEqual(dir(x[0]), dir(i))
1344n/a self.assertEqual(list(x[0].attr.keys()), [1])
1345n/a self.assertTrue(x[0].attr[1] is x)
1346n/a
1347n/a def check_recursive_collection_and_inst(self, factory):
1348n/a h = H()
1349n/a y = factory([h])
1350n/a h.attr = y
1351n/a for proto in protocols:
1352n/a s = self.dumps(y, proto)
1353n/a x = self.loads(s)
1354n/a self.assertIsInstance(x, type(y))
1355n/a self.assertEqual(len(x), 1)
1356n/a self.assertIsInstance(list(x)[0], H)
1357n/a self.assertIs(list(x)[0].attr, x)
1358n/a
1359n/a def test_recursive_list_and_inst(self):
1360n/a self.check_recursive_collection_and_inst(list)
1361n/a
1362n/a def test_recursive_tuple_and_inst(self):
1363n/a self.check_recursive_collection_and_inst(tuple)
1364n/a
1365n/a def test_recursive_dict_and_inst(self):
1366n/a self.check_recursive_collection_and_inst(dict.fromkeys)
1367n/a
1368n/a def test_recursive_set_and_inst(self):
1369n/a self.check_recursive_collection_and_inst(set)
1370n/a
1371n/a def test_recursive_frozenset_and_inst(self):
1372n/a self.check_recursive_collection_and_inst(frozenset)
1373n/a
1374n/a def test_recursive_list_subclass_and_inst(self):
1375n/a self.check_recursive_collection_and_inst(MyList)
1376n/a
1377n/a def test_recursive_tuple_subclass_and_inst(self):
1378n/a self.check_recursive_collection_and_inst(MyTuple)
1379n/a
1380n/a def test_recursive_dict_subclass_and_inst(self):
1381n/a self.check_recursive_collection_and_inst(MyDict.fromkeys)
1382n/a
1383n/a def test_recursive_set_subclass_and_inst(self):
1384n/a self.check_recursive_collection_and_inst(MySet)
1385n/a
1386n/a def test_recursive_frozenset_subclass_and_inst(self):
1387n/a self.check_recursive_collection_and_inst(MyFrozenSet)
1388n/a
1389n/a def test_unicode(self):
1390n/a endcases = ['', '<\\u>', '<\\\u1234>', '<\n>',
1391n/a '<\\>', '<\\\U00012345>',
1392n/a # surrogates
1393n/a '<\udc80>']
1394n/a for proto in protocols:
1395n/a for u in endcases:
1396n/a p = self.dumps(u, proto)
1397n/a u2 = self.loads(p)
1398n/a self.assert_is_copy(u, u2)
1399n/a
1400n/a def test_unicode_high_plane(self):
1401n/a t = '\U00012345'
1402n/a for proto in protocols:
1403n/a p = self.dumps(t, proto)
1404n/a t2 = self.loads(p)
1405n/a self.assert_is_copy(t, t2)
1406n/a
1407n/a def test_bytes(self):
1408n/a for proto in protocols:
1409n/a for s in b'', b'xyz', b'xyz'*100:
1410n/a p = self.dumps(s, proto)
1411n/a self.assert_is_copy(s, self.loads(p))
1412n/a for s in [bytes([i]) for i in range(256)]:
1413n/a p = self.dumps(s, proto)
1414n/a self.assert_is_copy(s, self.loads(p))
1415n/a for s in [bytes([i, i]) for i in range(256)]:
1416n/a p = self.dumps(s, proto)
1417n/a self.assert_is_copy(s, self.loads(p))
1418n/a
1419n/a def test_ints(self):
1420n/a for proto in protocols:
1421n/a n = sys.maxsize
1422n/a while n:
1423n/a for expected in (-n, n):
1424n/a s = self.dumps(expected, proto)
1425n/a n2 = self.loads(s)
1426n/a self.assert_is_copy(expected, n2)
1427n/a n = n >> 1
1428n/a
1429n/a def test_long(self):
1430n/a for proto in protocols:
1431n/a # 256 bytes is where LONG4 begins.
1432n/a for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
1433n/a nbase = 1 << nbits
1434n/a for npos in nbase-1, nbase, nbase+1:
1435n/a for n in npos, -npos:
1436n/a pickle = self.dumps(n, proto)
1437n/a got = self.loads(pickle)
1438n/a self.assert_is_copy(n, got)
1439n/a # Try a monster. This is quadratic-time in protos 0 & 1, so don't
1440n/a # bother with those.
1441n/a nbase = int("deadbeeffeedface", 16)
1442n/a nbase += nbase << 1000000
1443n/a for n in nbase, -nbase:
1444n/a p = self.dumps(n, 2)
1445n/a got = self.loads(p)
1446n/a # assert_is_copy is very expensive here as it precomputes
1447n/a # a failure message by computing the repr() of n and got,
1448n/a # we just do the check ourselves.
1449n/a self.assertIs(type(got), int)
1450n/a self.assertEqual(n, got)
1451n/a
1452n/a def test_float(self):
1453n/a test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
1454n/a 3.14, 263.44582062374053, 6.022e23, 1e30]
1455n/a test_values = test_values + [-x for x in test_values]
1456n/a for proto in protocols:
1457n/a for value in test_values:
1458n/a pickle = self.dumps(value, proto)
1459n/a got = self.loads(pickle)
1460n/a self.assert_is_copy(value, got)
1461n/a
1462n/a @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
1463n/a def test_float_format(self):
1464n/a # make sure that floats are formatted locale independent with proto 0
1465n/a self.assertEqual(self.dumps(1.2, 0)[0:3], b'F1.')
1466n/a
1467n/a def test_reduce(self):
1468n/a for proto in protocols:
1469n/a inst = AAA()
1470n/a dumped = self.dumps(inst, proto)
1471n/a loaded = self.loads(dumped)
1472n/a self.assertEqual(loaded, REDUCE_A)
1473n/a
1474n/a def test_getinitargs(self):
1475n/a for proto in protocols:
1476n/a inst = initarg(1, 2)
1477n/a dumped = self.dumps(inst, proto)
1478n/a loaded = self.loads(dumped)
1479n/a self.assert_is_copy(inst, loaded)
1480n/a
1481n/a def test_metaclass(self):
1482n/a a = use_metaclass()
1483n/a for proto in protocols:
1484n/a s = self.dumps(a, proto)
1485n/a b = self.loads(s)
1486n/a self.assertEqual(a.__class__, b.__class__)
1487n/a
1488n/a def test_dynamic_class(self):
1489n/a a = create_dynamic_class("my_dynamic_class", (object,))
1490n/a copyreg.pickle(pickling_metaclass, pickling_metaclass.__reduce__)
1491n/a for proto in protocols:
1492n/a s = self.dumps(a, proto)
1493n/a b = self.loads(s)
1494n/a self.assertEqual(a, b)
1495n/a self.assertIs(type(a), type(b))
1496n/a
1497n/a def test_structseq(self):
1498n/a import time
1499n/a import os
1500n/a
1501n/a t = time.localtime()
1502n/a for proto in protocols:
1503n/a s = self.dumps(t, proto)
1504n/a u = self.loads(s)
1505n/a self.assert_is_copy(t, u)
1506n/a if hasattr(os, "stat"):
1507n/a t = os.stat(os.curdir)
1508n/a s = self.dumps(t, proto)
1509n/a u = self.loads(s)
1510n/a self.assert_is_copy(t, u)
1511n/a if hasattr(os, "statvfs"):
1512n/a t = os.statvfs(os.curdir)
1513n/a s = self.dumps(t, proto)
1514n/a u = self.loads(s)
1515n/a self.assert_is_copy(t, u)
1516n/a
1517n/a def test_ellipsis(self):
1518n/a for proto in protocols:
1519n/a s = self.dumps(..., proto)
1520n/a u = self.loads(s)
1521n/a self.assertIs(..., u)
1522n/a
1523n/a def test_notimplemented(self):
1524n/a for proto in protocols:
1525n/a s = self.dumps(NotImplemented, proto)
1526n/a u = self.loads(s)
1527n/a self.assertIs(NotImplemented, u)
1528n/a
1529n/a def test_singleton_types(self):
1530n/a # Issue #6477: Test that types of built-in singletons can be pickled.
1531n/a singletons = [None, ..., NotImplemented]
1532n/a for singleton in singletons:
1533n/a for proto in protocols:
1534n/a s = self.dumps(type(singleton), proto)
1535n/a u = self.loads(s)
1536n/a self.assertIs(type(singleton), u)
1537n/a
1538n/a # Tests for protocol 2
1539n/a
1540n/a def test_proto(self):
1541n/a for proto in protocols:
1542n/a pickled = self.dumps(None, proto)
1543n/a if proto >= 2:
1544n/a proto_header = pickle.PROTO + bytes([proto])
1545n/a self.assertTrue(pickled.startswith(proto_header))
1546n/a else:
1547n/a self.assertEqual(count_opcode(pickle.PROTO, pickled), 0)
1548n/a
1549n/a oob = protocols[-1] + 1 # a future protocol
1550n/a build_none = pickle.NONE + pickle.STOP
1551n/a badpickle = pickle.PROTO + bytes([oob]) + build_none
1552n/a try:
1553n/a self.loads(badpickle)
1554n/a except ValueError as err:
1555n/a self.assertIn("unsupported pickle protocol", str(err))
1556n/a else:
1557n/a self.fail("expected bad protocol number to raise ValueError")
1558n/a
1559n/a def test_long1(self):
1560n/a x = 12345678910111213141516178920
1561n/a for proto in protocols:
1562n/a s = self.dumps(x, proto)
1563n/a y = self.loads(s)
1564n/a self.assert_is_copy(x, y)
1565n/a self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
1566n/a
1567n/a def test_long4(self):
1568n/a x = 12345678910111213141516178920 << (256*8)
1569n/a for proto in protocols:
1570n/a s = self.dumps(x, proto)
1571n/a y = self.loads(s)
1572n/a self.assert_is_copy(x, y)
1573n/a self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
1574n/a
1575n/a def test_short_tuples(self):
1576n/a # Map (proto, len(tuple)) to expected opcode.
1577n/a expected_opcode = {(0, 0): pickle.TUPLE,
1578n/a (0, 1): pickle.TUPLE,
1579n/a (0, 2): pickle.TUPLE,
1580n/a (0, 3): pickle.TUPLE,
1581n/a (0, 4): pickle.TUPLE,
1582n/a
1583n/a (1, 0): pickle.EMPTY_TUPLE,
1584n/a (1, 1): pickle.TUPLE,
1585n/a (1, 2): pickle.TUPLE,
1586n/a (1, 3): pickle.TUPLE,
1587n/a (1, 4): pickle.TUPLE,
1588n/a
1589n/a (2, 0): pickle.EMPTY_TUPLE,
1590n/a (2, 1): pickle.TUPLE1,
1591n/a (2, 2): pickle.TUPLE2,
1592n/a (2, 3): pickle.TUPLE3,
1593n/a (2, 4): pickle.TUPLE,
1594n/a
1595n/a (3, 0): pickle.EMPTY_TUPLE,
1596n/a (3, 1): pickle.TUPLE1,
1597n/a (3, 2): pickle.TUPLE2,
1598n/a (3, 3): pickle.TUPLE3,
1599n/a (3, 4): pickle.TUPLE,
1600n/a }
1601n/a a = ()
1602n/a b = (1,)
1603n/a c = (1, 2)
1604n/a d = (1, 2, 3)
1605n/a e = (1, 2, 3, 4)
1606n/a for proto in protocols:
1607n/a for x in a, b, c, d, e:
1608n/a s = self.dumps(x, proto)
1609n/a y = self.loads(s)
1610n/a self.assert_is_copy(x, y)
1611n/a expected = expected_opcode[min(proto, 3), len(x)]
1612n/a self.assertTrue(opcode_in_pickle(expected, s))
1613n/a
1614n/a def test_singletons(self):
1615n/a # Map (proto, singleton) to expected opcode.
1616n/a expected_opcode = {(0, None): pickle.NONE,
1617n/a (1, None): pickle.NONE,
1618n/a (2, None): pickle.NONE,
1619n/a (3, None): pickle.NONE,
1620n/a
1621n/a (0, True): pickle.INT,
1622n/a (1, True): pickle.INT,
1623n/a (2, True): pickle.NEWTRUE,
1624n/a (3, True): pickle.NEWTRUE,
1625n/a
1626n/a (0, False): pickle.INT,
1627n/a (1, False): pickle.INT,
1628n/a (2, False): pickle.NEWFALSE,
1629n/a (3, False): pickle.NEWFALSE,
1630n/a }
1631n/a for proto in protocols:
1632n/a for x in None, False, True:
1633n/a s = self.dumps(x, proto)
1634n/a y = self.loads(s)
1635n/a self.assertTrue(x is y, (proto, x, s, y))
1636n/a expected = expected_opcode[min(proto, 3), x]
1637n/a self.assertTrue(opcode_in_pickle(expected, s))
1638n/a
1639n/a def test_newobj_tuple(self):
1640n/a x = MyTuple([1, 2, 3])
1641n/a x.foo = 42
1642n/a x.bar = "hello"
1643n/a for proto in protocols:
1644n/a s = self.dumps(x, proto)
1645n/a y = self.loads(s)
1646n/a self.assert_is_copy(x, y)
1647n/a
1648n/a def test_newobj_list(self):
1649n/a x = MyList([1, 2, 3])
1650n/a x.foo = 42
1651n/a x.bar = "hello"
1652n/a for proto in protocols:
1653n/a s = self.dumps(x, proto)
1654n/a y = self.loads(s)
1655n/a self.assert_is_copy(x, y)
1656n/a
1657n/a def test_newobj_generic(self):
1658n/a for proto in protocols:
1659n/a for C in myclasses:
1660n/a B = C.__base__
1661n/a x = C(C.sample)
1662n/a x.foo = 42
1663n/a s = self.dumps(x, proto)
1664n/a y = self.loads(s)
1665n/a detail = (proto, C, B, x, y, type(y))
1666n/a self.assert_is_copy(x, y) # XXX revisit
1667n/a self.assertEqual(B(x), B(y), detail)
1668n/a self.assertEqual(x.__dict__, y.__dict__, detail)
1669n/a
1670n/a def test_newobj_proxies(self):
1671n/a # NEWOBJ should use the __class__ rather than the raw type
1672n/a classes = myclasses[:]
1673n/a # Cannot create weakproxies to these classes
1674n/a for c in (MyInt, MyTuple):
1675n/a classes.remove(c)
1676n/a for proto in protocols:
1677n/a for C in classes:
1678n/a B = C.__base__
1679n/a x = C(C.sample)
1680n/a x.foo = 42
1681n/a p = weakref.proxy(x)
1682n/a s = self.dumps(p, proto)
1683n/a y = self.loads(s)
1684n/a self.assertEqual(type(y), type(x)) # rather than type(p)
1685n/a detail = (proto, C, B, x, y, type(y))
1686n/a self.assertEqual(B(x), B(y), detail)
1687n/a self.assertEqual(x.__dict__, y.__dict__, detail)
1688n/a
1689n/a def test_newobj_not_class(self):
1690n/a # Issue 24552
1691n/a global SimpleNewObj
1692n/a save = SimpleNewObj
1693n/a o = SimpleNewObj.__new__(SimpleNewObj)
1694n/a b = self.dumps(o, 4)
1695n/a try:
1696n/a SimpleNewObj = 42
1697n/a self.assertRaises((TypeError, pickle.UnpicklingError), self.loads, b)
1698n/a finally:
1699n/a SimpleNewObj = save
1700n/a
1701n/a # Register a type with copyreg, with extension code extcode. Pickle
1702n/a # an object of that type. Check that the resulting pickle uses opcode
1703n/a # (EXT[124]) under proto 2, and not in proto 1.
1704n/a
1705n/a def produce_global_ext(self, extcode, opcode):
1706n/a e = ExtensionSaver(extcode)
1707n/a try:
1708n/a copyreg.add_extension(__name__, "MyList", extcode)
1709n/a x = MyList([1, 2, 3])
1710n/a x.foo = 42
1711n/a x.bar = "hello"
1712n/a
1713n/a # Dump using protocol 1 for comparison.
1714n/a s1 = self.dumps(x, 1)
1715n/a self.assertIn(__name__.encode("utf-8"), s1)
1716n/a self.assertIn(b"MyList", s1)
1717n/a self.assertFalse(opcode_in_pickle(opcode, s1))
1718n/a
1719n/a y = self.loads(s1)
1720n/a self.assert_is_copy(x, y)
1721n/a
1722n/a # Dump using protocol 2 for test.
1723n/a s2 = self.dumps(x, 2)
1724n/a self.assertNotIn(__name__.encode("utf-8"), s2)
1725n/a self.assertNotIn(b"MyList", s2)
1726n/a self.assertEqual(opcode_in_pickle(opcode, s2), True, repr(s2))
1727n/a
1728n/a y = self.loads(s2)
1729n/a self.assert_is_copy(x, y)
1730n/a finally:
1731n/a e.restore()
1732n/a
1733n/a def test_global_ext1(self):
1734n/a self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
1735n/a self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
1736n/a
1737n/a def test_global_ext2(self):
1738n/a self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
1739n/a self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
1740n/a self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
1741n/a
1742n/a def test_global_ext4(self):
1743n/a self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
1744n/a self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
1745n/a self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
1746n/a
1747n/a def test_list_chunking(self):
1748n/a n = 10 # too small to chunk
1749n/a x = list(range(n))
1750n/a for proto in protocols:
1751n/a s = self.dumps(x, proto)
1752n/a y = self.loads(s)
1753n/a self.assert_is_copy(x, y)
1754n/a num_appends = count_opcode(pickle.APPENDS, s)
1755n/a self.assertEqual(num_appends, proto > 0)
1756n/a
1757n/a n = 2500 # expect at least two chunks when proto > 0
1758n/a x = list(range(n))
1759n/a for proto in protocols:
1760n/a s = self.dumps(x, proto)
1761n/a y = self.loads(s)
1762n/a self.assert_is_copy(x, y)
1763n/a num_appends = count_opcode(pickle.APPENDS, s)
1764n/a if proto == 0:
1765n/a self.assertEqual(num_appends, 0)
1766n/a else:
1767n/a self.assertTrue(num_appends >= 2)
1768n/a
1769n/a def test_dict_chunking(self):
1770n/a n = 10 # too small to chunk
1771n/a x = dict.fromkeys(range(n))
1772n/a for proto in protocols:
1773n/a s = self.dumps(x, proto)
1774n/a self.assertIsInstance(s, bytes_types)
1775n/a y = self.loads(s)
1776n/a self.assert_is_copy(x, y)
1777n/a num_setitems = count_opcode(pickle.SETITEMS, s)
1778n/a self.assertEqual(num_setitems, proto > 0)
1779n/a
1780n/a n = 2500 # expect at least two chunks when proto > 0
1781n/a x = dict.fromkeys(range(n))
1782n/a for proto in protocols:
1783n/a s = self.dumps(x, proto)
1784n/a y = self.loads(s)
1785n/a self.assert_is_copy(x, y)
1786n/a num_setitems = count_opcode(pickle.SETITEMS, s)
1787n/a if proto == 0:
1788n/a self.assertEqual(num_setitems, 0)
1789n/a else:
1790n/a self.assertTrue(num_setitems >= 2)
1791n/a
1792n/a def test_set_chunking(self):
1793n/a n = 10 # too small to chunk
1794n/a x = set(range(n))
1795n/a for proto in protocols:
1796n/a s = self.dumps(x, proto)
1797n/a y = self.loads(s)
1798n/a self.assert_is_copy(x, y)
1799n/a num_additems = count_opcode(pickle.ADDITEMS, s)
1800n/a if proto < 4:
1801n/a self.assertEqual(num_additems, 0)
1802n/a else:
1803n/a self.assertEqual(num_additems, 1)
1804n/a
1805n/a n = 2500 # expect at least two chunks when proto >= 4
1806n/a x = set(range(n))
1807n/a for proto in protocols:
1808n/a s = self.dumps(x, proto)
1809n/a y = self.loads(s)
1810n/a self.assert_is_copy(x, y)
1811n/a num_additems = count_opcode(pickle.ADDITEMS, s)
1812n/a if proto < 4:
1813n/a self.assertEqual(num_additems, 0)
1814n/a else:
1815n/a self.assertGreaterEqual(num_additems, 2)
1816n/a
1817n/a def test_simple_newobj(self):
1818n/a x = SimpleNewObj.__new__(SimpleNewObj, 0xface) # avoid __init__
1819n/a x.abc = 666
1820n/a for proto in protocols:
1821n/a with self.subTest(proto=proto):
1822n/a s = self.dumps(x, proto)
1823n/a if proto < 1:
1824n/a self.assertIn(b'\nL64206', s) # LONG
1825n/a else:
1826n/a self.assertIn(b'M\xce\xfa', s) # BININT2
1827n/a self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
1828n/a 2 <= proto)
1829n/a self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s))
1830n/a y = self.loads(s) # will raise TypeError if __init__ called
1831n/a self.assert_is_copy(x, y)
1832n/a
1833n/a def test_complex_newobj(self):
1834n/a x = ComplexNewObj.__new__(ComplexNewObj, 0xface) # avoid __init__
1835n/a x.abc = 666
1836n/a for proto in protocols:
1837n/a with self.subTest(proto=proto):
1838n/a s = self.dumps(x, proto)
1839n/a if proto < 1:
1840n/a self.assertIn(b'\nL64206', s) # LONG
1841n/a elif proto < 2:
1842n/a self.assertIn(b'M\xce\xfa', s) # BININT2
1843n/a elif proto < 4:
1844n/a self.assertIn(b'X\x04\x00\x00\x00FACE', s) # BINUNICODE
1845n/a else:
1846n/a self.assertIn(b'\x8c\x04FACE', s) # SHORT_BINUNICODE
1847n/a self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
1848n/a 2 <= proto)
1849n/a self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s))
1850n/a y = self.loads(s) # will raise TypeError if __init__ called
1851n/a self.assert_is_copy(x, y)
1852n/a
1853n/a def test_complex_newobj_ex(self):
1854n/a x = ComplexNewObjEx.__new__(ComplexNewObjEx, 0xface) # avoid __init__
1855n/a x.abc = 666
1856n/a for proto in protocols:
1857n/a with self.subTest(proto=proto):
1858n/a s = self.dumps(x, proto)
1859n/a if proto < 1:
1860n/a self.assertIn(b'\nL64206', s) # LONG
1861n/a elif proto < 2:
1862n/a self.assertIn(b'M\xce\xfa', s) # BININT2
1863n/a elif proto < 4:
1864n/a self.assertIn(b'X\x04\x00\x00\x00FACE', s) # BINUNICODE
1865n/a else:
1866n/a self.assertIn(b'\x8c\x04FACE', s) # SHORT_BINUNICODE
1867n/a self.assertFalse(opcode_in_pickle(pickle.NEWOBJ, s))
1868n/a self.assertEqual(opcode_in_pickle(pickle.NEWOBJ_EX, s),
1869n/a 4 <= proto)
1870n/a y = self.loads(s) # will raise TypeError if __init__ called
1871n/a self.assert_is_copy(x, y)
1872n/a
1873n/a def test_newobj_list_slots(self):
1874n/a x = SlotList([1, 2, 3])
1875n/a x.foo = 42
1876n/a x.bar = "hello"
1877n/a s = self.dumps(x, 2)
1878n/a y = self.loads(s)
1879n/a self.assert_is_copy(x, y)
1880n/a
1881n/a def test_reduce_overrides_default_reduce_ex(self):
1882n/a for proto in protocols:
1883n/a x = REX_one()
1884n/a self.assertEqual(x._reduce_called, 0)
1885n/a s = self.dumps(x, proto)
1886n/a self.assertEqual(x._reduce_called, 1)
1887n/a y = self.loads(s)
1888n/a self.assertEqual(y._reduce_called, 0)
1889n/a
1890n/a def test_reduce_ex_called(self):
1891n/a for proto in protocols:
1892n/a x = REX_two()
1893n/a self.assertEqual(x._proto, None)
1894n/a s = self.dumps(x, proto)
1895n/a self.assertEqual(x._proto, proto)
1896n/a y = self.loads(s)
1897n/a self.assertEqual(y._proto, None)
1898n/a
1899n/a def test_reduce_ex_overrides_reduce(self):
1900n/a for proto in protocols:
1901n/a x = REX_three()
1902n/a self.assertEqual(x._proto, None)
1903n/a s = self.dumps(x, proto)
1904n/a self.assertEqual(x._proto, proto)
1905n/a y = self.loads(s)
1906n/a self.assertEqual(y._proto, None)
1907n/a
1908n/a def test_reduce_ex_calls_base(self):
1909n/a for proto in protocols:
1910n/a x = REX_four()
1911n/a self.assertEqual(x._proto, None)
1912n/a s = self.dumps(x, proto)
1913n/a self.assertEqual(x._proto, proto)
1914n/a y = self.loads(s)
1915n/a self.assertEqual(y._proto, proto)
1916n/a
1917n/a def test_reduce_calls_base(self):
1918n/a for proto in protocols:
1919n/a x = REX_five()
1920n/a self.assertEqual(x._reduce_called, 0)
1921n/a s = self.dumps(x, proto)
1922n/a self.assertEqual(x._reduce_called, 1)
1923n/a y = self.loads(s)
1924n/a self.assertEqual(y._reduce_called, 1)
1925n/a
1926n/a @no_tracing
1927n/a def test_bad_getattr(self):
1928n/a # Issue #3514: crash when there is an infinite loop in __getattr__
1929n/a x = BadGetattr()
1930n/a for proto in protocols:
1931n/a self.assertRaises(RuntimeError, self.dumps, x, proto)
1932n/a
1933n/a def test_reduce_bad_iterator(self):
1934n/a # Issue4176: crash when 4th and 5th items of __reduce__()
1935n/a # are not iterators
1936n/a class C(object):
1937n/a def __reduce__(self):
1938n/a # 4th item is not an iterator
1939n/a return list, (), None, [], None
1940n/a class D(object):
1941n/a def __reduce__(self):
1942n/a # 5th item is not an iterator
1943n/a return dict, (), None, None, []
1944n/a
1945n/a # Python implementation is less strict and also accepts iterables.
1946n/a for proto in protocols:
1947n/a try:
1948n/a self.dumps(C(), proto)
1949n/a except pickle.PicklingError:
1950n/a pass
1951n/a try:
1952n/a self.dumps(D(), proto)
1953n/a except pickle.PicklingError:
1954n/a pass
1955n/a
1956n/a def test_many_puts_and_gets(self):
1957n/a # Test that internal data structures correctly deal with lots of
1958n/a # puts/gets.
1959n/a keys = ("aaa" + str(i) for i in range(100))
1960n/a large_dict = dict((k, [4, 5, 6]) for k in keys)
1961n/a obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
1962n/a
1963n/a for proto in protocols:
1964n/a with self.subTest(proto=proto):
1965n/a dumped = self.dumps(obj, proto)
1966n/a loaded = self.loads(dumped)
1967n/a self.assert_is_copy(obj, loaded)
1968n/a
1969n/a def test_attribute_name_interning(self):
1970n/a # Test that attribute names of pickled objects are interned when
1971n/a # unpickling.
1972n/a for proto in protocols:
1973n/a x = C()
1974n/a x.foo = 42
1975n/a x.bar = "hello"
1976n/a s = self.dumps(x, proto)
1977n/a y = self.loads(s)
1978n/a x_keys = sorted(x.__dict__)
1979n/a y_keys = sorted(y.__dict__)
1980n/a for x_key, y_key in zip(x_keys, y_keys):
1981n/a self.assertIs(x_key, y_key)
1982n/a
1983n/a def test_pickle_to_2x(self):
1984n/a # Pickle non-trivial data with protocol 2, expecting that it yields
1985n/a # the same result as Python 2.x did.
1986n/a # NOTE: this test is a bit too strong since we can produce different
1987n/a # bytecode that 2.x will still understand.
1988n/a dumped = self.dumps(range(5), 2)
1989n/a self.assertEqual(dumped, DATA_XRANGE)
1990n/a dumped = self.dumps(set([3]), 2)
1991n/a self.assertEqual(dumped, DATA_SET2)
1992n/a
1993n/a def test_large_pickles(self):
1994n/a # Test the correctness of internal buffering routines when handling
1995n/a # large data.
1996n/a for proto in protocols:
1997n/a data = (1, min, b'xy' * (30 * 1024), len)
1998n/a dumped = self.dumps(data, proto)
1999n/a loaded = self.loads(dumped)
2000n/a self.assertEqual(len(loaded), len(data))
2001n/a self.assertEqual(loaded, data)
2002n/a
2003n/a def test_int_pickling_efficiency(self):
2004n/a # Test compacity of int representation (see issue #12744)
2005n/a for proto in protocols:
2006n/a with self.subTest(proto=proto):
2007n/a pickles = [self.dumps(2**n, proto) for n in range(70)]
2008n/a sizes = list(map(len, pickles))
2009n/a # the size function is monotonic
2010n/a self.assertEqual(sorted(sizes), sizes)
2011n/a if proto >= 2:
2012n/a for p in pickles:
2013n/a self.assertFalse(opcode_in_pickle(pickle.LONG, p))
2014n/a
2015n/a def _check_pickling_with_opcode(self, obj, opcode, proto):
2016n/a pickled = self.dumps(obj, proto)
2017n/a self.assertTrue(opcode_in_pickle(opcode, pickled))
2018n/a unpickled = self.loads(pickled)
2019n/a self.assertEqual(obj, unpickled)
2020n/a
2021n/a def test_appends_on_non_lists(self):
2022n/a # Issue #17720
2023n/a obj = REX_six([1, 2, 3])
2024n/a for proto in protocols:
2025n/a if proto == 0:
2026n/a self._check_pickling_with_opcode(obj, pickle.APPEND, proto)
2027n/a else:
2028n/a self._check_pickling_with_opcode(obj, pickle.APPENDS, proto)
2029n/a
2030n/a def test_setitems_on_non_dicts(self):
2031n/a obj = REX_seven({1: -1, 2: -2, 3: -3})
2032n/a for proto in protocols:
2033n/a if proto == 0:
2034n/a self._check_pickling_with_opcode(obj, pickle.SETITEM, proto)
2035n/a else:
2036n/a self._check_pickling_with_opcode(obj, pickle.SETITEMS, proto)
2037n/a
2038n/a # Exercise framing (proto >= 4) for significant workloads
2039n/a
2040n/a FRAME_SIZE_TARGET = 64 * 1024
2041n/a
2042n/a def check_frame_opcodes(self, pickled):
2043n/a """
2044n/a Check the arguments of FRAME opcodes in a protocol 4+ pickle.
2045n/a """
2046n/a frame_opcode_size = 9
2047n/a last_arg = last_pos = None
2048n/a for op, arg, pos in pickletools.genops(pickled):
2049n/a if op.name != 'FRAME':
2050n/a continue
2051n/a if last_pos is not None:
2052n/a # The previous frame's size should be equal to the number
2053n/a # of bytes up to the current frame.
2054n/a frame_size = pos - last_pos - frame_opcode_size
2055n/a self.assertEqual(frame_size, last_arg)
2056n/a last_arg, last_pos = arg, pos
2057n/a # The last frame's size should be equal to the number of bytes up
2058n/a # to the pickle's end.
2059n/a frame_size = len(pickled) - last_pos - frame_opcode_size
2060n/a self.assertEqual(frame_size, last_arg)
2061n/a
2062n/a def test_framing_many_objects(self):
2063n/a obj = list(range(10**5))
2064n/a for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
2065n/a with self.subTest(proto=proto):
2066n/a pickled = self.dumps(obj, proto)
2067n/a unpickled = self.loads(pickled)
2068n/a self.assertEqual(obj, unpickled)
2069n/a bytes_per_frame = (len(pickled) /
2070n/a count_opcode(pickle.FRAME, pickled))
2071n/a self.assertGreater(bytes_per_frame,
2072n/a self.FRAME_SIZE_TARGET / 2)
2073n/a self.assertLessEqual(bytes_per_frame,
2074n/a self.FRAME_SIZE_TARGET * 1)
2075n/a self.check_frame_opcodes(pickled)
2076n/a
2077n/a def test_framing_large_objects(self):
2078n/a N = 1024 * 1024
2079n/a obj = [b'x' * N, b'y' * N, b'z' * N]
2080n/a for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
2081n/a with self.subTest(proto=proto):
2082n/a pickled = self.dumps(obj, proto)
2083n/a unpickled = self.loads(pickled)
2084n/a self.assertEqual(obj, unpickled)
2085n/a n_frames = count_opcode(pickle.FRAME, pickled)
2086n/a self.assertGreaterEqual(n_frames, len(obj))
2087n/a self.check_frame_opcodes(pickled)
2088n/a
2089n/a def test_optional_frames(self):
2090n/a if pickle.HIGHEST_PROTOCOL < 4:
2091n/a return
2092n/a
2093n/a def remove_frames(pickled, keep_frame=None):
2094n/a """Remove frame opcodes from the given pickle."""
2095n/a frame_starts = []
2096n/a # 1 byte for the opcode and 8 for the argument
2097n/a frame_opcode_size = 9
2098n/a for opcode, _, pos in pickletools.genops(pickled):
2099n/a if opcode.name == 'FRAME':
2100n/a frame_starts.append(pos)
2101n/a
2102n/a newpickle = bytearray()
2103n/a last_frame_end = 0
2104n/a for i, pos in enumerate(frame_starts):
2105n/a if keep_frame and keep_frame(i):
2106n/a continue
2107n/a newpickle += pickled[last_frame_end:pos]
2108n/a last_frame_end = pos + frame_opcode_size
2109n/a newpickle += pickled[last_frame_end:]
2110n/a return newpickle
2111n/a
2112n/a frame_size = self.FRAME_SIZE_TARGET
2113n/a num_frames = 20
2114n/a obj = [bytes([i]) * frame_size for i in range(num_frames)]
2115n/a
2116n/a for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
2117n/a pickled = self.dumps(obj, proto)
2118n/a
2119n/a frameless_pickle = remove_frames(pickled)
2120n/a self.assertEqual(count_opcode(pickle.FRAME, frameless_pickle), 0)
2121n/a self.assertEqual(obj, self.loads(frameless_pickle))
2122n/a
2123n/a some_frames_pickle = remove_frames(pickled, lambda i: i % 2)
2124n/a self.assertLess(count_opcode(pickle.FRAME, some_frames_pickle),
2125n/a count_opcode(pickle.FRAME, pickled))
2126n/a self.assertEqual(obj, self.loads(some_frames_pickle))
2127n/a
2128n/a def test_nested_names(self):
2129n/a global Nested
2130n/a class Nested:
2131n/a class A:
2132n/a class B:
2133n/a class C:
2134n/a pass
2135n/a for proto in range(pickle.HIGHEST_PROTOCOL + 1):
2136n/a for obj in [Nested.A, Nested.A.B, Nested.A.B.C]:
2137n/a with self.subTest(proto=proto, obj=obj):
2138n/a unpickled = self.loads(self.dumps(obj, proto))
2139n/a self.assertIs(obj, unpickled)
2140n/a
2141n/a def test_recursive_nested_names(self):
2142n/a global Recursive
2143n/a class Recursive:
2144n/a pass
2145n/a Recursive.mod = sys.modules[Recursive.__module__]
2146n/a Recursive.__qualname__ = 'Recursive.mod.Recursive'
2147n/a for proto in range(pickle.HIGHEST_PROTOCOL + 1):
2148n/a with self.subTest(proto=proto):
2149n/a unpickled = self.loads(self.dumps(Recursive, proto))
2150n/a self.assertIs(unpickled, Recursive)
2151n/a del Recursive.mod # break reference loop
2152n/a
2153n/a def test_py_methods(self):
2154n/a global PyMethodsTest
2155n/a class PyMethodsTest:
2156n/a @staticmethod
2157n/a def cheese():
2158n/a return "cheese"
2159n/a @classmethod
2160n/a def wine(cls):
2161n/a assert cls is PyMethodsTest
2162n/a return "wine"
2163n/a def biscuits(self):
2164n/a assert isinstance(self, PyMethodsTest)
2165n/a return "biscuits"
2166n/a class Nested:
2167n/a "Nested class"
2168n/a @staticmethod
2169n/a def ketchup():
2170n/a return "ketchup"
2171n/a @classmethod
2172n/a def maple(cls):
2173n/a assert cls is PyMethodsTest.Nested
2174n/a return "maple"
2175n/a def pie(self):
2176n/a assert isinstance(self, PyMethodsTest.Nested)
2177n/a return "pie"
2178n/a
2179n/a py_methods = (
2180n/a PyMethodsTest.cheese,
2181n/a PyMethodsTest.wine,
2182n/a PyMethodsTest().biscuits,
2183n/a PyMethodsTest.Nested.ketchup,
2184n/a PyMethodsTest.Nested.maple,
2185n/a PyMethodsTest.Nested().pie
2186n/a )
2187n/a py_unbound_methods = (
2188n/a (PyMethodsTest.biscuits, PyMethodsTest),
2189n/a (PyMethodsTest.Nested.pie, PyMethodsTest.Nested)
2190n/a )
2191n/a for proto in range(pickle.HIGHEST_PROTOCOL + 1):
2192n/a for method in py_methods:
2193n/a with self.subTest(proto=proto, method=method):
2194n/a unpickled = self.loads(self.dumps(method, proto))
2195n/a self.assertEqual(method(), unpickled())
2196n/a for method, cls in py_unbound_methods:
2197n/a obj = cls()
2198n/a with self.subTest(proto=proto, method=method):
2199n/a unpickled = self.loads(self.dumps(method, proto))
2200n/a self.assertEqual(method(obj), unpickled(obj))
2201n/a
2202n/a def test_c_methods(self):
2203n/a global Subclass
2204n/a class Subclass(tuple):
2205n/a class Nested(str):
2206n/a pass
2207n/a
2208n/a c_methods = (
2209n/a # bound built-in method
2210n/a ("abcd".index, ("c",)),
2211n/a # unbound built-in method
2212n/a (str.index, ("abcd", "c")),
2213n/a # bound "slot" method
2214n/a ([1, 2, 3].__len__, ()),
2215n/a # unbound "slot" method
2216n/a (list.__len__, ([1, 2, 3],)),
2217n/a # bound "coexist" method
2218n/a ({1, 2}.__contains__, (2,)),
2219n/a # unbound "coexist" method
2220n/a (set.__contains__, ({1, 2}, 2)),
2221n/a # built-in class method
2222n/a (dict.fromkeys, (("a", 1), ("b", 2))),
2223n/a # built-in static method
2224n/a (bytearray.maketrans, (b"abc", b"xyz")),
2225n/a # subclass methods
2226n/a (Subclass([1,2,2]).count, (2,)),
2227n/a (Subclass.count, (Subclass([1,2,2]), 2)),
2228n/a (Subclass.Nested("sweet").count, ("e",)),
2229n/a (Subclass.Nested.count, (Subclass.Nested("sweet"), "e")),
2230n/a )
2231n/a for proto in range(pickle.HIGHEST_PROTOCOL + 1):
2232n/a for method, args in c_methods:
2233n/a with self.subTest(proto=proto, method=method):
2234n/a unpickled = self.loads(self.dumps(method, proto))
2235n/a self.assertEqual(method(*args), unpickled(*args))
2236n/a
2237n/a def test_compat_pickle(self):
2238n/a tests = [
2239n/a (range(1, 7), '__builtin__', 'xrange'),
2240n/a (map(int, '123'), 'itertools', 'imap'),
2241n/a (functools.reduce, '__builtin__', 'reduce'),
2242n/a (dbm.whichdb, 'whichdb', 'whichdb'),
2243n/a (Exception(), 'exceptions', 'Exception'),
2244n/a (collections.UserDict(), 'UserDict', 'IterableUserDict'),
2245n/a (collections.UserList(), 'UserList', 'UserList'),
2246n/a (collections.defaultdict(), 'collections', 'defaultdict'),
2247n/a ]
2248n/a for val, mod, name in tests:
2249n/a for proto in range(3):
2250n/a with self.subTest(type=type(val), proto=proto):
2251n/a pickled = self.dumps(val, proto)
2252n/a self.assertIn(('c%s\n%s' % (mod, name)).encode(), pickled)
2253n/a self.assertIs(type(self.loads(pickled)), type(val))
2254n/a
2255n/a def test_local_lookup_error(self):
2256n/a # Test that whichmodule() errors out cleanly when looking up
2257n/a # an assumed globally-reachable object fails.
2258n/a def f():
2259n/a pass
2260n/a # Since the function is local, lookup will fail
2261n/a for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
2262n/a with self.assertRaises((AttributeError, pickle.PicklingError)):
2263n/a pickletools.dis(self.dumps(f, proto))
2264n/a # Same without a __module__ attribute (exercises a different path
2265n/a # in _pickle.c).
2266n/a del f.__module__
2267n/a for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
2268n/a with self.assertRaises((AttributeError, pickle.PicklingError)):
2269n/a pickletools.dis(self.dumps(f, proto))
2270n/a # Yet a different path.
2271n/a f.__name__ = f.__qualname__
2272n/a for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
2273n/a with self.assertRaises((AttributeError, pickle.PicklingError)):
2274n/a pickletools.dis(self.dumps(f, proto))
2275n/a
2276n/a
2277n/aclass BigmemPickleTests(unittest.TestCase):
2278n/a
2279n/a # Binary protocols can serialize longs of up to 2GB-1
2280n/a
2281n/a @bigmemtest(size=_2G, memuse=3.6, dry_run=False)
2282n/a def test_huge_long_32b(self, size):
2283n/a data = 1 << (8 * size)
2284n/a try:
2285n/a for proto in protocols:
2286n/a if proto < 2:
2287n/a continue
2288n/a with self.subTest(proto=proto):
2289n/a with self.assertRaises((ValueError, OverflowError)):
2290n/a self.dumps(data, protocol=proto)
2291n/a finally:
2292n/a data = None
2293n/a
2294n/a # Protocol 3 can serialize up to 4GB-1 as a bytes object
2295n/a # (older protocols don't have a dedicated opcode for bytes and are
2296n/a # too inefficient)
2297n/a
2298n/a @bigmemtest(size=_2G, memuse=2.5, dry_run=False)
2299n/a def test_huge_bytes_32b(self, size):
2300n/a data = b"abcd" * (size // 4)
2301n/a try:
2302n/a for proto in protocols:
2303n/a if proto < 3:
2304n/a continue
2305n/a with self.subTest(proto=proto):
2306n/a try:
2307n/a pickled = self.dumps(data, protocol=proto)
2308n/a header = (pickle.BINBYTES +
2309n/a struct.pack("<I", len(data)))
2310n/a data_start = pickled.index(data)
2311n/a self.assertEqual(
2312n/a header,
2313n/a pickled[data_start-len(header):data_start])
2314n/a finally:
2315n/a pickled = None
2316n/a finally:
2317n/a data = None
2318n/a
2319n/a @bigmemtest(size=_4G, memuse=2.5, dry_run=False)
2320n/a def test_huge_bytes_64b(self, size):
2321n/a data = b"acbd" * (size // 4)
2322n/a try:
2323n/a for proto in protocols:
2324n/a if proto < 3:
2325n/a continue
2326n/a with self.subTest(proto=proto):
2327n/a if proto == 3:
2328n/a # Protocol 3 does not support large bytes objects.
2329n/a # Verify that we do not crash when processing one.
2330n/a with self.assertRaises((ValueError, OverflowError)):
2331n/a self.dumps(data, protocol=proto)
2332n/a continue
2333n/a try:
2334n/a pickled = self.dumps(data, protocol=proto)
2335n/a header = (pickle.BINBYTES8 +
2336n/a struct.pack("<Q", len(data)))
2337n/a data_start = pickled.index(data)
2338n/a self.assertEqual(
2339n/a header,
2340n/a pickled[data_start-len(header):data_start])
2341n/a finally:
2342n/a pickled = None
2343n/a finally:
2344n/a data = None
2345n/a
2346n/a # All protocols use 1-byte per printable ASCII character; we add another
2347n/a # byte because the encoded form has to be copied into the internal buffer.
2348n/a
2349n/a @bigmemtest(size=_2G, memuse=8, dry_run=False)
2350n/a def test_huge_str_32b(self, size):
2351n/a data = "abcd" * (size // 4)
2352n/a try:
2353n/a for proto in protocols:
2354n/a if proto == 0:
2355n/a continue
2356n/a with self.subTest(proto=proto):
2357n/a try:
2358n/a pickled = self.dumps(data, protocol=proto)
2359n/a header = (pickle.BINUNICODE +
2360n/a struct.pack("<I", len(data)))
2361n/a data_start = pickled.index(b'abcd')
2362n/a self.assertEqual(
2363n/a header,
2364n/a pickled[data_start-len(header):data_start])
2365n/a self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
2366n/a pickled.index(b"abcd")), len(data))
2367n/a finally:
2368n/a pickled = None
2369n/a finally:
2370n/a data = None
2371n/a
2372n/a # BINUNICODE (protocols 1, 2 and 3) cannot carry more than 2**32 - 1 bytes
2373n/a # of utf-8 encoded unicode. BINUNICODE8 (protocol 4) supports these huge
2374n/a # unicode strings however.
2375n/a
2376n/a @bigmemtest(size=_4G, memuse=8, dry_run=False)
2377n/a def test_huge_str_64b(self, size):
2378n/a data = "abcd" * (size // 4)
2379n/a try:
2380n/a for proto in protocols:
2381n/a if proto == 0:
2382n/a continue
2383n/a with self.subTest(proto=proto):
2384n/a if proto < 4:
2385n/a with self.assertRaises((ValueError, OverflowError)):
2386n/a self.dumps(data, protocol=proto)
2387n/a continue
2388n/a try:
2389n/a pickled = self.dumps(data, protocol=proto)
2390n/a header = (pickle.BINUNICODE8 +
2391n/a struct.pack("<Q", len(data)))
2392n/a data_start = pickled.index(b'abcd')
2393n/a self.assertEqual(
2394n/a header,
2395n/a pickled[data_start-len(header):data_start])
2396n/a self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
2397n/a pickled.index(b"abcd")), len(data))
2398n/a finally:
2399n/a pickled = None
2400n/a finally:
2401n/a data = None
2402n/a
2403n/a
2404n/a# Test classes for reduce_ex
2405n/a
2406n/aclass REX_one(object):
2407n/a """No __reduce_ex__ here, but inheriting it from object"""
2408n/a _reduce_called = 0
2409n/a def __reduce__(self):
2410n/a self._reduce_called = 1
2411n/a return REX_one, ()
2412n/a
2413n/aclass REX_two(object):
2414n/a """No __reduce__ here, but inheriting it from object"""
2415n/a _proto = None
2416n/a def __reduce_ex__(self, proto):
2417n/a self._proto = proto
2418n/a return REX_two, ()
2419n/a
2420n/aclass REX_three(object):
2421n/a _proto = None
2422n/a def __reduce_ex__(self, proto):
2423n/a self._proto = proto
2424n/a return REX_two, ()
2425n/a def __reduce__(self):
2426n/a raise TestFailed("This __reduce__ shouldn't be called")
2427n/a
2428n/aclass REX_four(object):
2429n/a """Calling base class method should succeed"""
2430n/a _proto = None
2431n/a def __reduce_ex__(self, proto):
2432n/a self._proto = proto
2433n/a return object.__reduce_ex__(self, proto)
2434n/a
2435n/aclass REX_five(object):
2436n/a """This one used to fail with infinite recursion"""
2437n/a _reduce_called = 0
2438n/a def __reduce__(self):
2439n/a self._reduce_called = 1
2440n/a return object.__reduce__(self)
2441n/a
2442n/aclass REX_six(object):
2443n/a """This class is used to check the 4th argument (list iterator) of
2444n/a the reduce protocol.
2445n/a """
2446n/a def __init__(self, items=None):
2447n/a self.items = items if items is not None else []
2448n/a def __eq__(self, other):
2449n/a return type(self) is type(other) and self.items == other.items
2450n/a def append(self, item):
2451n/a self.items.append(item)
2452n/a def __reduce__(self):
2453n/a return type(self), (), None, iter(self.items), None
2454n/a
2455n/aclass REX_seven(object):
2456n/a """This class is used to check the 5th argument (dict iterator) of
2457n/a the reduce protocol.
2458n/a """
2459n/a def __init__(self, table=None):
2460n/a self.table = table if table is not None else {}
2461n/a def __eq__(self, other):
2462n/a return type(self) is type(other) and self.table == other.table
2463n/a def __setitem__(self, key, value):
2464n/a self.table[key] = value
2465n/a def __reduce__(self):
2466n/a return type(self), (), None, None, iter(self.table.items())
2467n/a
2468n/a
2469n/a# Test classes for newobj
2470n/a
2471n/aclass MyInt(int):
2472n/a sample = 1
2473n/a
2474n/aclass MyFloat(float):
2475n/a sample = 1.0
2476n/a
2477n/aclass MyComplex(complex):
2478n/a sample = 1.0 + 0.0j
2479n/a
2480n/aclass MyStr(str):
2481n/a sample = "hello"
2482n/a
2483n/aclass MyUnicode(str):
2484n/a sample = "hello \u1234"
2485n/a
2486n/aclass MyTuple(tuple):
2487n/a sample = (1, 2, 3)
2488n/a
2489n/aclass MyList(list):
2490n/a sample = [1, 2, 3]
2491n/a
2492n/aclass MyDict(dict):
2493n/a sample = {"a": 1, "b": 2}
2494n/a
2495n/aclass MySet(set):
2496n/a sample = {"a", "b"}
2497n/a
2498n/aclass MyFrozenSet(frozenset):
2499n/a sample = frozenset({"a", "b"})
2500n/a
2501n/amyclasses = [MyInt, MyFloat,
2502n/a MyComplex,
2503n/a MyStr, MyUnicode,
2504n/a MyTuple, MyList, MyDict, MySet, MyFrozenSet]
2505n/a
2506n/a
2507n/aclass SlotList(MyList):
2508n/a __slots__ = ["foo"]
2509n/a
2510n/aclass SimpleNewObj(int):
2511n/a def __init__(self, *args, **kwargs):
2512n/a # raise an error, to make sure this isn't called
2513n/a raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
2514n/a def __eq__(self, other):
2515n/a return int(self) == int(other) and self.__dict__ == other.__dict__
2516n/a
2517n/aclass ComplexNewObj(SimpleNewObj):
2518n/a def __getnewargs__(self):
2519n/a return ('%X' % self, 16)
2520n/a
2521n/aclass ComplexNewObjEx(SimpleNewObj):
2522n/a def __getnewargs_ex__(self):
2523n/a return ('%X' % self,), {'base': 16}
2524n/a
2525n/aclass BadGetattr:
2526n/a def __getattr__(self, key):
2527n/a self.foo
2528n/a
2529n/a
2530n/aclass AbstractPickleModuleTests(unittest.TestCase):
2531n/a
2532n/a def test_dump_closed_file(self):
2533n/a import os
2534n/a f = open(TESTFN, "wb")
2535n/a try:
2536n/a f.close()
2537n/a self.assertRaises(ValueError, pickle.dump, 123, f)
2538n/a finally:
2539n/a os.remove(TESTFN)
2540n/a
2541n/a def test_load_closed_file(self):
2542n/a import os
2543n/a f = open(TESTFN, "wb")
2544n/a try:
2545n/a f.close()
2546n/a self.assertRaises(ValueError, pickle.dump, 123, f)
2547n/a finally:
2548n/a os.remove(TESTFN)
2549n/a
2550n/a def test_load_from_and_dump_to_file(self):
2551n/a stream = io.BytesIO()
2552n/a data = [123, {}, 124]
2553n/a pickle.dump(data, stream)
2554n/a stream.seek(0)
2555n/a unpickled = pickle.load(stream)
2556n/a self.assertEqual(unpickled, data)
2557n/a
2558n/a def test_highest_protocol(self):
2559n/a # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
2560n/a self.assertEqual(pickle.HIGHEST_PROTOCOL, 4)
2561n/a
2562n/a def test_callapi(self):
2563n/a f = io.BytesIO()
2564n/a # With and without keyword arguments
2565n/a pickle.dump(123, f, -1)
2566n/a pickle.dump(123, file=f, protocol=-1)
2567n/a pickle.dumps(123, -1)
2568n/a pickle.dumps(123, protocol=-1)
2569n/a pickle.Pickler(f, -1)
2570n/a pickle.Pickler(f, protocol=-1)
2571n/a
2572n/a def test_bad_init(self):
2573n/a # Test issue3664 (pickle can segfault from a badly initialized Pickler).
2574n/a # Override initialization without calling __init__() of the superclass.
2575n/a class BadPickler(pickle.Pickler):
2576n/a def __init__(self): pass
2577n/a
2578n/a class BadUnpickler(pickle.Unpickler):
2579n/a def __init__(self): pass
2580n/a
2581n/a self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
2582n/a self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
2583n/a
2584n/a
2585n/aclass AbstractPersistentPicklerTests(unittest.TestCase):
2586n/a
2587n/a # This class defines persistent_id() and persistent_load()
2588n/a # functions that should be used by the pickler. All even integers
2589n/a # are pickled using persistent ids.
2590n/a
2591n/a def persistent_id(self, object):
2592n/a if isinstance(object, int) and object % 2 == 0:
2593n/a self.id_count += 1
2594n/a return str(object)
2595n/a elif object == "test_false_value":
2596n/a self.false_count += 1
2597n/a return ""
2598n/a else:
2599n/a return None
2600n/a
2601n/a def persistent_load(self, oid):
2602n/a if not oid:
2603n/a self.load_false_count += 1
2604n/a return "test_false_value"
2605n/a else:
2606n/a self.load_count += 1
2607n/a object = int(oid)
2608n/a assert object % 2 == 0
2609n/a return object
2610n/a
2611n/a def test_persistence(self):
2612n/a L = list(range(10)) + ["test_false_value"]
2613n/a for proto in protocols:
2614n/a self.id_count = 0
2615n/a self.false_count = 0
2616n/a self.load_false_count = 0
2617n/a self.load_count = 0
2618n/a self.assertEqual(self.loads(self.dumps(L, proto)), L)
2619n/a self.assertEqual(self.id_count, 5)
2620n/a self.assertEqual(self.false_count, 1)
2621n/a self.assertEqual(self.load_count, 5)
2622n/a self.assertEqual(self.load_false_count, 1)
2623n/a
2624n/a
2625n/aclass AbstractIdentityPersistentPicklerTests(unittest.TestCase):
2626n/a
2627n/a def persistent_id(self, obj):
2628n/a return obj
2629n/a
2630n/a def persistent_load(self, pid):
2631n/a return pid
2632n/a
2633n/a def _check_return_correct_type(self, obj, proto):
2634n/a unpickled = self.loads(self.dumps(obj, proto))
2635n/a self.assertIsInstance(unpickled, type(obj))
2636n/a self.assertEqual(unpickled, obj)
2637n/a
2638n/a def test_return_correct_type(self):
2639n/a for proto in protocols:
2640n/a # Protocol 0 supports only ASCII strings.
2641n/a if proto == 0:
2642n/a self._check_return_correct_type("abc", 0)
2643n/a else:
2644n/a for obj in [b"abc\n", "abc\n", -1, -1.1 * 0.1, str]:
2645n/a self._check_return_correct_type(obj, proto)
2646n/a
2647n/a def test_protocol0_is_ascii_only(self):
2648n/a non_ascii_str = "\N{EMPTY SET}"
2649n/a self.assertRaises(pickle.PicklingError, self.dumps, non_ascii_str, 0)
2650n/a pickled = pickle.PERSID + non_ascii_str.encode('utf-8') + b'\n.'
2651n/a self.assertRaises(pickle.UnpicklingError, self.loads, pickled)
2652n/a
2653n/a
2654n/aclass AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
2655n/a
2656n/a pickler_class = None
2657n/a unpickler_class = None
2658n/a
2659n/a def setUp(self):
2660n/a assert self.pickler_class
2661n/a assert self.unpickler_class
2662n/a
2663n/a def test_clear_pickler_memo(self):
2664n/a # To test whether clear_memo() has any effect, we pickle an object,
2665n/a # then pickle it again without clearing the memo; the two serialized
2666n/a # forms should be different. If we clear_memo() and then pickle the
2667n/a # object again, the third serialized form should be identical to the
2668n/a # first one we obtained.
2669n/a data = ["abcdefg", "abcdefg", 44]
2670n/a f = io.BytesIO()
2671n/a pickler = self.pickler_class(f)
2672n/a
2673n/a pickler.dump(data)
2674n/a first_pickled = f.getvalue()
2675n/a
2676n/a # Reset BytesIO object.
2677n/a f.seek(0)
2678n/a f.truncate()
2679n/a
2680n/a pickler.dump(data)
2681n/a second_pickled = f.getvalue()
2682n/a
2683n/a # Reset the Pickler and BytesIO objects.
2684n/a pickler.clear_memo()
2685n/a f.seek(0)
2686n/a f.truncate()
2687n/a
2688n/a pickler.dump(data)
2689n/a third_pickled = f.getvalue()
2690n/a
2691n/a self.assertNotEqual(first_pickled, second_pickled)
2692n/a self.assertEqual(first_pickled, third_pickled)
2693n/a
2694n/a def test_priming_pickler_memo(self):
2695n/a # Verify that we can set the Pickler's memo attribute.
2696n/a data = ["abcdefg", "abcdefg", 44]
2697n/a f = io.BytesIO()
2698n/a pickler = self.pickler_class(f)
2699n/a
2700n/a pickler.dump(data)
2701n/a first_pickled = f.getvalue()
2702n/a
2703n/a f = io.BytesIO()
2704n/a primed = self.pickler_class(f)
2705n/a primed.memo = pickler.memo
2706n/a
2707n/a primed.dump(data)
2708n/a primed_pickled = f.getvalue()
2709n/a
2710n/a self.assertNotEqual(first_pickled, primed_pickled)
2711n/a
2712n/a def test_priming_unpickler_memo(self):
2713n/a # Verify that we can set the Unpickler's memo attribute.
2714n/a data = ["abcdefg", "abcdefg", 44]
2715n/a f = io.BytesIO()
2716n/a pickler = self.pickler_class(f)
2717n/a
2718n/a pickler.dump(data)
2719n/a first_pickled = f.getvalue()
2720n/a
2721n/a f = io.BytesIO()
2722n/a primed = self.pickler_class(f)
2723n/a primed.memo = pickler.memo
2724n/a
2725n/a primed.dump(data)
2726n/a primed_pickled = f.getvalue()
2727n/a
2728n/a unpickler = self.unpickler_class(io.BytesIO(first_pickled))
2729n/a unpickled_data1 = unpickler.load()
2730n/a
2731n/a self.assertEqual(unpickled_data1, data)
2732n/a
2733n/a primed = self.unpickler_class(io.BytesIO(primed_pickled))
2734n/a primed.memo = unpickler.memo
2735n/a unpickled_data2 = primed.load()
2736n/a
2737n/a primed.memo.clear()
2738n/a
2739n/a self.assertEqual(unpickled_data2, data)
2740n/a self.assertTrue(unpickled_data2 is unpickled_data1)
2741n/a
2742n/a def test_reusing_unpickler_objects(self):
2743n/a data1 = ["abcdefg", "abcdefg", 44]
2744n/a f = io.BytesIO()
2745n/a pickler = self.pickler_class(f)
2746n/a pickler.dump(data1)
2747n/a pickled1 = f.getvalue()
2748n/a
2749n/a data2 = ["abcdefg", 44, 44]
2750n/a f = io.BytesIO()
2751n/a pickler = self.pickler_class(f)
2752n/a pickler.dump(data2)
2753n/a pickled2 = f.getvalue()
2754n/a
2755n/a f = io.BytesIO()
2756n/a f.write(pickled1)
2757n/a f.seek(0)
2758n/a unpickler = self.unpickler_class(f)
2759n/a self.assertEqual(unpickler.load(), data1)
2760n/a
2761n/a f.seek(0)
2762n/a f.truncate()
2763n/a f.write(pickled2)
2764n/a f.seek(0)
2765n/a self.assertEqual(unpickler.load(), data2)
2766n/a
2767n/a def _check_multiple_unpicklings(self, ioclass):
2768n/a for proto in protocols:
2769n/a with self.subTest(proto=proto):
2770n/a data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len]
2771n/a f = ioclass()
2772n/a pickler = self.pickler_class(f, protocol=proto)
2773n/a pickler.dump(data1)
2774n/a pickled = f.getvalue()
2775n/a
2776n/a N = 5
2777n/a f = ioclass(pickled * N)
2778n/a unpickler = self.unpickler_class(f)
2779n/a for i in range(N):
2780n/a if f.seekable():
2781n/a pos = f.tell()
2782n/a self.assertEqual(unpickler.load(), data1)
2783n/a if f.seekable():
2784n/a self.assertEqual(f.tell(), pos + len(pickled))
2785n/a self.assertRaises(EOFError, unpickler.load)
2786n/a
2787n/a def test_multiple_unpicklings_seekable(self):
2788n/a self._check_multiple_unpicklings(io.BytesIO)
2789n/a
2790n/a def test_multiple_unpicklings_unseekable(self):
2791n/a self._check_multiple_unpicklings(UnseekableIO)
2792n/a
2793n/a def test_unpickling_buffering_readline(self):
2794n/a # Issue #12687: the unpickler's buffering logic could fail with
2795n/a # text mode opcodes.
2796n/a data = list(range(10))
2797n/a for proto in protocols:
2798n/a for buf_size in range(1, 11):
2799n/a f = io.BufferedRandom(io.BytesIO(), buffer_size=buf_size)
2800n/a pickler = self.pickler_class(f, protocol=proto)
2801n/a pickler.dump(data)
2802n/a f.seek(0)
2803n/a unpickler = self.unpickler_class(f)
2804n/a self.assertEqual(unpickler.load(), data)
2805n/a
2806n/a
2807n/a# Tests for dispatch_table attribute
2808n/a
2809n/aREDUCE_A = 'reduce_A'
2810n/a
2811n/aclass AAA(object):
2812n/a def __reduce__(self):
2813n/a return str, (REDUCE_A,)
2814n/a
2815n/aclass BBB(object):
2816n/a pass
2817n/a
2818n/aclass AbstractDispatchTableTests(unittest.TestCase):
2819n/a
2820n/a def test_default_dispatch_table(self):
2821n/a # No dispatch_table attribute by default
2822n/a f = io.BytesIO()
2823n/a p = self.pickler_class(f, 0)
2824n/a with self.assertRaises(AttributeError):
2825n/a p.dispatch_table
2826n/a self.assertFalse(hasattr(p, 'dispatch_table'))
2827n/a
2828n/a def test_class_dispatch_table(self):
2829n/a # A dispatch_table attribute can be specified class-wide
2830n/a dt = self.get_dispatch_table()
2831n/a
2832n/a class MyPickler(self.pickler_class):
2833n/a dispatch_table = dt
2834n/a
2835n/a def dumps(obj, protocol=None):
2836n/a f = io.BytesIO()
2837n/a p = MyPickler(f, protocol)
2838n/a self.assertEqual(p.dispatch_table, dt)
2839n/a p.dump(obj)
2840n/a return f.getvalue()
2841n/a
2842n/a self._test_dispatch_table(dumps, dt)
2843n/a
2844n/a def test_instance_dispatch_table(self):
2845n/a # A dispatch_table attribute can also be specified instance-wide
2846n/a dt = self.get_dispatch_table()
2847n/a
2848n/a def dumps(obj, protocol=None):
2849n/a f = io.BytesIO()
2850n/a p = self.pickler_class(f, protocol)
2851n/a p.dispatch_table = dt
2852n/a self.assertEqual(p.dispatch_table, dt)
2853n/a p.dump(obj)
2854n/a return f.getvalue()
2855n/a
2856n/a self._test_dispatch_table(dumps, dt)
2857n/a
2858n/a def _test_dispatch_table(self, dumps, dispatch_table):
2859n/a def custom_load_dump(obj):
2860n/a return pickle.loads(dumps(obj, 0))
2861n/a
2862n/a def default_load_dump(obj):
2863n/a return pickle.loads(pickle.dumps(obj, 0))
2864n/a
2865n/a # pickling complex numbers using protocol 0 relies on copyreg
2866n/a # so check pickling a complex number still works
2867n/a z = 1 + 2j
2868n/a self.assertEqual(custom_load_dump(z), z)
2869n/a self.assertEqual(default_load_dump(z), z)
2870n/a
2871n/a # modify pickling of complex
2872n/a REDUCE_1 = 'reduce_1'
2873n/a def reduce_1(obj):
2874n/a return str, (REDUCE_1,)
2875n/a dispatch_table[complex] = reduce_1
2876n/a self.assertEqual(custom_load_dump(z), REDUCE_1)
2877n/a self.assertEqual(default_load_dump(z), z)
2878n/a
2879n/a # check picklability of AAA and BBB
2880n/a a = AAA()
2881n/a b = BBB()
2882n/a self.assertEqual(custom_load_dump(a), REDUCE_A)
2883n/a self.assertIsInstance(custom_load_dump(b), BBB)
2884n/a self.assertEqual(default_load_dump(a), REDUCE_A)
2885n/a self.assertIsInstance(default_load_dump(b), BBB)
2886n/a
2887n/a # modify pickling of BBB
2888n/a dispatch_table[BBB] = reduce_1
2889n/a self.assertEqual(custom_load_dump(a), REDUCE_A)
2890n/a self.assertEqual(custom_load_dump(b), REDUCE_1)
2891n/a self.assertEqual(default_load_dump(a), REDUCE_A)
2892n/a self.assertIsInstance(default_load_dump(b), BBB)
2893n/a
2894n/a # revert pickling of BBB and modify pickling of AAA
2895n/a REDUCE_2 = 'reduce_2'
2896n/a def reduce_2(obj):
2897n/a return str, (REDUCE_2,)
2898n/a dispatch_table[AAA] = reduce_2
2899n/a del dispatch_table[BBB]
2900n/a self.assertEqual(custom_load_dump(a), REDUCE_2)
2901n/a self.assertIsInstance(custom_load_dump(b), BBB)
2902n/a self.assertEqual(default_load_dump(a), REDUCE_A)
2903n/a self.assertIsInstance(default_load_dump(b), BBB)
2904n/a
2905n/a
2906n/aif __name__ == "__main__":
2907n/a # Print some stuff that can be used to rewrite DATA{0,1,2}
2908n/a from pickletools import dis
2909n/a x = create_data()
2910n/a for i in range(pickle.HIGHEST_PROTOCOL+1):
2911n/a p = pickle.dumps(x, i)
2912n/a print("DATA{0} = (".format(i))
2913n/a for j in range(0, len(p), 20):
2914n/a b = bytes(p[j:j+20])
2915n/a print(" {0!r}".format(b))
2916n/a print(")")
2917n/a print()
2918n/a print("# Disassembly of DATA{0}".format(i))
2919n/a print("DATA{0}_DIS = \"\"\"\\".format(i))
2920n/a dis(p)
2921n/a print("\"\"\"")
2922n/a print()