ยปCore Development>Code coverage>Lib/test/test_marshal.py

Python code coverage for Lib/test/test_marshal.py

#countcontent
1n/afrom test import support
2n/aimport array
3n/aimport io
4n/aimport marshal
5n/aimport sys
6n/aimport unittest
7n/aimport os
8n/aimport types
9n/a
10n/atry:
11n/a import _testcapi
12n/aexcept ImportError:
13n/a _testcapi = None
14n/a
15n/aclass HelperMixin:
16n/a def helper(self, sample, *extra):
17n/a new = marshal.loads(marshal.dumps(sample, *extra))
18n/a self.assertEqual(sample, new)
19n/a try:
20n/a with open(support.TESTFN, "wb") as f:
21n/a marshal.dump(sample, f, *extra)
22n/a with open(support.TESTFN, "rb") as f:
23n/a new = marshal.load(f)
24n/a self.assertEqual(sample, new)
25n/a finally:
26n/a support.unlink(support.TESTFN)
27n/a
28n/aclass IntTestCase(unittest.TestCase, HelperMixin):
29n/a def test_ints(self):
30n/a # Test a range of Python ints larger than the machine word size.
31n/a n = sys.maxsize ** 2
32n/a while n:
33n/a for expected in (-n, n):
34n/a self.helper(expected)
35n/a n = n >> 1
36n/a
37n/a def test_bool(self):
38n/a for b in (True, False):
39n/a self.helper(b)
40n/a
41n/aclass FloatTestCase(unittest.TestCase, HelperMixin):
42n/a def test_floats(self):
43n/a # Test a few floats
44n/a small = 1e-25
45n/a n = sys.maxsize * 3.7e250
46n/a while n > small:
47n/a for expected in (-n, n):
48n/a self.helper(float(expected))
49n/a n /= 123.4567
50n/a
51n/a f = 0.0
52n/a s = marshal.dumps(f, 2)
53n/a got = marshal.loads(s)
54n/a self.assertEqual(f, got)
55n/a # and with version <= 1 (floats marshalled differently then)
56n/a s = marshal.dumps(f, 1)
57n/a got = marshal.loads(s)
58n/a self.assertEqual(f, got)
59n/a
60n/a n = sys.maxsize * 3.7e-250
61n/a while n < small:
62n/a for expected in (-n, n):
63n/a f = float(expected)
64n/a self.helper(f)
65n/a self.helper(f, 1)
66n/a n *= 123.4567
67n/a
68n/aclass StringTestCase(unittest.TestCase, HelperMixin):
69n/a def test_unicode(self):
70n/a for s in ["", "Andr\xe8 Previn", "abc", " "*10000]:
71n/a self.helper(marshal.loads(marshal.dumps(s)))
72n/a
73n/a def test_string(self):
74n/a for s in ["", "Andr\xe8 Previn", "abc", " "*10000]:
75n/a self.helper(s)
76n/a
77n/a def test_bytes(self):
78n/a for s in [b"", b"Andr\xe8 Previn", b"abc", b" "*10000]:
79n/a self.helper(s)
80n/a
81n/aclass ExceptionTestCase(unittest.TestCase):
82n/a def test_exceptions(self):
83n/a new = marshal.loads(marshal.dumps(StopIteration))
84n/a self.assertEqual(StopIteration, new)
85n/a
86n/aclass CodeTestCase(unittest.TestCase):
87n/a def test_code(self):
88n/a co = ExceptionTestCase.test_exceptions.__code__
89n/a new = marshal.loads(marshal.dumps(co))
90n/a self.assertEqual(co, new)
91n/a
92n/a def test_many_codeobjects(self):
93n/a # Issue2957: bad recursion count on code objects
94n/a count = 5000 # more than MAX_MARSHAL_STACK_DEPTH
95n/a codes = (ExceptionTestCase.test_exceptions.__code__,) * count
96n/a marshal.loads(marshal.dumps(codes))
97n/a
98n/a def test_different_filenames(self):
99n/a co1 = compile("x", "f1", "exec")
100n/a co2 = compile("y", "f2", "exec")
101n/a co1, co2 = marshal.loads(marshal.dumps((co1, co2)))
102n/a self.assertEqual(co1.co_filename, "f1")
103n/a self.assertEqual(co2.co_filename, "f2")
104n/a
105n/a @support.cpython_only
106n/a def test_same_filename_used(self):
107n/a s = """def f(): pass\ndef g(): pass"""
108n/a co = compile(s, "myfile", "exec")
109n/a co = marshal.loads(marshal.dumps(co))
110n/a for obj in co.co_consts:
111n/a if isinstance(obj, types.CodeType):
112n/a self.assertIs(co.co_filename, obj.co_filename)
113n/a
114n/aclass ContainerTestCase(unittest.TestCase, HelperMixin):
115n/a d = {'astring': 'foo@bar.baz.spam',
116n/a 'afloat': 7283.43,
117n/a 'anint': 2**20,
118n/a 'ashortlong': 2,
119n/a 'alist': ['.zyx.41'],
120n/a 'atuple': ('.zyx.41',)*10,
121n/a 'aboolean': False,
122n/a 'aunicode': "Andr\xe8 Previn"
123n/a }
124n/a
125n/a def test_dict(self):
126n/a self.helper(self.d)
127n/a
128n/a def test_list(self):
129n/a self.helper(list(self.d.items()))
130n/a
131n/a def test_tuple(self):
132n/a self.helper(tuple(self.d.keys()))
133n/a
134n/a def test_sets(self):
135n/a for constructor in (set, frozenset):
136n/a self.helper(constructor(self.d.keys()))
137n/a
138n/a @support.cpython_only
139n/a def test_empty_frozenset_singleton(self):
140n/a # marshal.loads() must reuse the empty frozenset singleton
141n/a obj = frozenset()
142n/a obj2 = marshal.loads(marshal.dumps(obj))
143n/a self.assertIs(obj2, obj)
144n/a
145n/a
146n/aclass BufferTestCase(unittest.TestCase, HelperMixin):
147n/a
148n/a def test_bytearray(self):
149n/a b = bytearray(b"abc")
150n/a self.helper(b)
151n/a new = marshal.loads(marshal.dumps(b))
152n/a self.assertEqual(type(new), bytes)
153n/a
154n/a def test_memoryview(self):
155n/a b = memoryview(b"abc")
156n/a self.helper(b)
157n/a new = marshal.loads(marshal.dumps(b))
158n/a self.assertEqual(type(new), bytes)
159n/a
160n/a def test_array(self):
161n/a a = array.array('B', b"abc")
162n/a new = marshal.loads(marshal.dumps(a))
163n/a self.assertEqual(new, b"abc")
164n/a
165n/a
166n/aclass BugsTestCase(unittest.TestCase):
167n/a def test_bug_5888452(self):
168n/a # Simple-minded check for SF 588452: Debug build crashes
169n/a marshal.dumps([128] * 1000)
170n/a
171n/a def test_patch_873224(self):
172n/a self.assertRaises(Exception, marshal.loads, '0')
173n/a self.assertRaises(Exception, marshal.loads, 'f')
174n/a self.assertRaises(Exception, marshal.loads, marshal.dumps(2**65)[:-1])
175n/a
176n/a def test_version_argument(self):
177n/a # Python 2.4.0 crashes for any call to marshal.dumps(x, y)
178n/a self.assertEqual(marshal.loads(marshal.dumps(5, 0)), 5)
179n/a self.assertEqual(marshal.loads(marshal.dumps(5, 1)), 5)
180n/a
181n/a def test_fuzz(self):
182n/a # simple test that it's at least not *totally* trivial to
183n/a # crash from bad marshal data
184n/a for c in [chr(i) for i in range(256)]:
185n/a try:
186n/a marshal.loads(c)
187n/a except Exception:
188n/a pass
189n/a
190n/a def test_loads_2x_code(self):
191n/a s = b'c' + (b'X' * 4*4) + b'{' * 2**20
192n/a self.assertRaises(ValueError, marshal.loads, s)
193n/a
194n/a def test_loads_recursion(self):
195n/a s = b'c' + (b'X' * 4*5) + b'{' * 2**20
196n/a self.assertRaises(ValueError, marshal.loads, s)
197n/a
198n/a def test_recursion_limit(self):
199n/a # Create a deeply nested structure.
200n/a head = last = []
201n/a # The max stack depth should match the value in Python/marshal.c.
202n/a if os.name == 'nt' and hasattr(sys, 'gettotalrefcount'):
203n/a MAX_MARSHAL_STACK_DEPTH = 1000
204n/a else:
205n/a MAX_MARSHAL_STACK_DEPTH = 2000
206n/a for i in range(MAX_MARSHAL_STACK_DEPTH - 2):
207n/a last.append([0])
208n/a last = last[-1]
209n/a
210n/a # Verify we don't blow out the stack with dumps/load.
211n/a data = marshal.dumps(head)
212n/a new_head = marshal.loads(data)
213n/a # Don't use == to compare objects, it can exceed the recursion limit.
214n/a self.assertEqual(len(new_head), len(head))
215n/a self.assertEqual(len(new_head[0]), len(head[0]))
216n/a self.assertEqual(len(new_head[-1]), len(head[-1]))
217n/a
218n/a last.append([0])
219n/a self.assertRaises(ValueError, marshal.dumps, head)
220n/a
221n/a def test_exact_type_match(self):
222n/a # Former bug:
223n/a # >>> class Int(int): pass
224n/a # >>> type(loads(dumps(Int())))
225n/a # <type 'int'>
226n/a for typ in (int, float, complex, tuple, list, dict, set, frozenset):
227n/a # Note: str subclasses are not tested because they get handled
228n/a # by marshal's routines for objects supporting the buffer API.
229n/a subtyp = type('subtyp', (typ,), {})
230n/a self.assertRaises(ValueError, marshal.dumps, subtyp())
231n/a
232n/a # Issue #1792 introduced a change in how marshal increases the size of its
233n/a # internal buffer; this test ensures that the new code is exercised.
234n/a def test_large_marshal(self):
235n/a size = int(1e6)
236n/a testString = 'abc' * size
237n/a marshal.dumps(testString)
238n/a
239n/a def test_invalid_longs(self):
240n/a # Issue #7019: marshal.loads shouldn't produce unnormalized PyLongs
241n/a invalid_string = b'l\x02\x00\x00\x00\x00\x00\x00\x00'
242n/a self.assertRaises(ValueError, marshal.loads, invalid_string)
243n/a
244n/a def test_multiple_dumps_and_loads(self):
245n/a # Issue 12291: marshal.load() should be callable multiple times
246n/a # with interleaved data written by non-marshal code
247n/a # Adapted from a patch by Engelbert Gruber.
248n/a data = (1, 'abc', b'def', 1.0, (2, 'a', ['b', b'c']))
249n/a for interleaved in (b'', b'0123'):
250n/a ilen = len(interleaved)
251n/a positions = []
252n/a try:
253n/a with open(support.TESTFN, 'wb') as f:
254n/a for d in data:
255n/a marshal.dump(d, f)
256n/a if ilen:
257n/a f.write(interleaved)
258n/a positions.append(f.tell())
259n/a with open(support.TESTFN, 'rb') as f:
260n/a for i, d in enumerate(data):
261n/a self.assertEqual(d, marshal.load(f))
262n/a if ilen:
263n/a f.read(ilen)
264n/a self.assertEqual(positions[i], f.tell())
265n/a finally:
266n/a support.unlink(support.TESTFN)
267n/a
268n/a def test_loads_reject_unicode_strings(self):
269n/a # Issue #14177: marshal.loads() should not accept unicode strings
270n/a unicode_string = 'T'
271n/a self.assertRaises(TypeError, marshal.loads, unicode_string)
272n/a
273n/a def test_bad_reader(self):
274n/a class BadReader(io.BytesIO):
275n/a def readinto(self, buf):
276n/a n = super().readinto(buf)
277n/a if n is not None and n > 4:
278n/a n += 10**6
279n/a return n
280n/a for value in (1.0, 1j, b'0123456789', '0123456789'):
281n/a self.assertRaises(ValueError, marshal.load,
282n/a BadReader(marshal.dumps(value)))
283n/a
284n/a def _test_eof(self):
285n/a data = marshal.dumps(("hello", "dolly", None))
286n/a for i in range(len(data)):
287n/a self.assertRaises(EOFError, marshal.loads, data[0: i])
288n/a
289n/aLARGE_SIZE = 2**31
290n/apointer_size = 8 if sys.maxsize > 0xFFFFFFFF else 4
291n/a
292n/aclass NullWriter:
293n/a def write(self, s):
294n/a pass
295n/a
296n/a@unittest.skipIf(LARGE_SIZE > sys.maxsize, "test cannot run on 32-bit systems")
297n/aclass LargeValuesTestCase(unittest.TestCase):
298n/a def check_unmarshallable(self, data):
299n/a self.assertRaises(ValueError, marshal.dump, data, NullWriter())
300n/a
301n/a @support.bigmemtest(size=LARGE_SIZE, memuse=2, dry_run=False)
302n/a def test_bytes(self, size):
303n/a self.check_unmarshallable(b'x' * size)
304n/a
305n/a @support.bigmemtest(size=LARGE_SIZE, memuse=2, dry_run=False)
306n/a def test_str(self, size):
307n/a self.check_unmarshallable('x' * size)
308n/a
309n/a @support.bigmemtest(size=LARGE_SIZE, memuse=pointer_size + 1, dry_run=False)
310n/a def test_tuple(self, size):
311n/a self.check_unmarshallable((None,) * size)
312n/a
313n/a @support.bigmemtest(size=LARGE_SIZE, memuse=pointer_size + 1, dry_run=False)
314n/a def test_list(self, size):
315n/a self.check_unmarshallable([None] * size)
316n/a
317n/a @support.bigmemtest(size=LARGE_SIZE,
318n/a memuse=pointer_size*12 + sys.getsizeof(LARGE_SIZE-1),
319n/a dry_run=False)
320n/a def test_set(self, size):
321n/a self.check_unmarshallable(set(range(size)))
322n/a
323n/a @support.bigmemtest(size=LARGE_SIZE,
324n/a memuse=pointer_size*12 + sys.getsizeof(LARGE_SIZE-1),
325n/a dry_run=False)
326n/a def test_frozenset(self, size):
327n/a self.check_unmarshallable(frozenset(range(size)))
328n/a
329n/a @support.bigmemtest(size=LARGE_SIZE, memuse=2, dry_run=False)
330n/a def test_bytearray(self, size):
331n/a self.check_unmarshallable(bytearray(size))
332n/a
333n/adef CollectObjectIDs(ids, obj):
334n/a """Collect object ids seen in a structure"""
335n/a if id(obj) in ids:
336n/a return
337n/a ids.add(id(obj))
338n/a if isinstance(obj, (list, tuple, set, frozenset)):
339n/a for e in obj:
340n/a CollectObjectIDs(ids, e)
341n/a elif isinstance(obj, dict):
342n/a for k, v in obj.items():
343n/a CollectObjectIDs(ids, k)
344n/a CollectObjectIDs(ids, v)
345n/a return len(ids)
346n/a
347n/aclass InstancingTestCase(unittest.TestCase, HelperMixin):
348n/a intobj = 123321
349n/a floatobj = 1.2345
350n/a strobj = "abcde"*3
351n/a dictobj = {"hello":floatobj, "goodbye":floatobj, floatobj:"hello"}
352n/a
353n/a def helper3(self, rsample, recursive=False, simple=False):
354n/a #we have two instances
355n/a sample = (rsample, rsample)
356n/a
357n/a n0 = CollectObjectIDs(set(), sample)
358n/a
359n/a s3 = marshal.dumps(sample, 3)
360n/a n3 = CollectObjectIDs(set(), marshal.loads(s3))
361n/a
362n/a #same number of instances generated
363n/a self.assertEqual(n3, n0)
364n/a
365n/a if not recursive:
366n/a #can compare with version 2
367n/a s2 = marshal.dumps(sample, 2)
368n/a n2 = CollectObjectIDs(set(), marshal.loads(s2))
369n/a #old format generated more instances
370n/a self.assertGreater(n2, n0)
371n/a
372n/a #if complex objects are in there, old format is larger
373n/a if not simple:
374n/a self.assertGreater(len(s2), len(s3))
375n/a else:
376n/a self.assertGreaterEqual(len(s2), len(s3))
377n/a
378n/a def testInt(self):
379n/a self.helper(self.intobj)
380n/a self.helper3(self.intobj, simple=True)
381n/a
382n/a def testFloat(self):
383n/a self.helper(self.floatobj)
384n/a self.helper3(self.floatobj)
385n/a
386n/a def testStr(self):
387n/a self.helper(self.strobj)
388n/a self.helper3(self.strobj)
389n/a
390n/a def testDict(self):
391n/a self.helper(self.dictobj)
392n/a self.helper3(self.dictobj)
393n/a
394n/a def testModule(self):
395n/a with open(__file__, "rb") as f:
396n/a code = f.read()
397n/a if __file__.endswith(".py"):
398n/a code = compile(code, __file__, "exec")
399n/a self.helper(code)
400n/a self.helper3(code)
401n/a
402n/a def testRecursion(self):
403n/a d = dict(self.dictobj)
404n/a d["self"] = d
405n/a self.helper3(d, recursive=True)
406n/a l = [self.dictobj]
407n/a l.append(l)
408n/a self.helper3(l, recursive=True)
409n/a
410n/aclass CompatibilityTestCase(unittest.TestCase):
411n/a def _test(self, version):
412n/a with open(__file__, "rb") as f:
413n/a code = f.read()
414n/a if __file__.endswith(".py"):
415n/a code = compile(code, __file__, "exec")
416n/a data = marshal.dumps(code, version)
417n/a marshal.loads(data)
418n/a
419n/a def test0To3(self):
420n/a self._test(0)
421n/a
422n/a def test1To3(self):
423n/a self._test(1)
424n/a
425n/a def test2To3(self):
426n/a self._test(2)
427n/a
428n/a def test3To3(self):
429n/a self._test(3)
430n/a
431n/aclass InterningTestCase(unittest.TestCase, HelperMixin):
432n/a strobj = "this is an interned string"
433n/a strobj = sys.intern(strobj)
434n/a
435n/a def testIntern(self):
436n/a s = marshal.loads(marshal.dumps(self.strobj))
437n/a self.assertEqual(s, self.strobj)
438n/a self.assertEqual(id(s), id(self.strobj))
439n/a s2 = sys.intern(s)
440n/a self.assertEqual(id(s2), id(s))
441n/a
442n/a def testNoIntern(self):
443n/a s = marshal.loads(marshal.dumps(self.strobj, 2))
444n/a self.assertEqual(s, self.strobj)
445n/a self.assertNotEqual(id(s), id(self.strobj))
446n/a s2 = sys.intern(s)
447n/a self.assertNotEqual(id(s2), id(s))
448n/a
449n/a@support.cpython_only
450n/a@unittest.skipUnless(_testcapi, 'requires _testcapi')
451n/aclass CAPI_TestCase(unittest.TestCase, HelperMixin):
452n/a
453n/a def test_write_long_to_file(self):
454n/a for v in range(marshal.version + 1):
455n/a _testcapi.pymarshal_write_long_to_file(0x12345678, support.TESTFN, v)
456n/a with open(support.TESTFN, 'rb') as f:
457n/a data = f.read()
458n/a support.unlink(support.TESTFN)
459n/a self.assertEqual(data, b'\x78\x56\x34\x12')
460n/a
461n/a def test_write_object_to_file(self):
462n/a obj = ('\u20ac', b'abc', 123, 45.6, 7+8j, 'long line '*1000)
463n/a for v in range(marshal.version + 1):
464n/a _testcapi.pymarshal_write_object_to_file(obj, support.TESTFN, v)
465n/a with open(support.TESTFN, 'rb') as f:
466n/a data = f.read()
467n/a support.unlink(support.TESTFN)
468n/a self.assertEqual(marshal.loads(data), obj)
469n/a
470n/a def test_read_short_from_file(self):
471n/a with open(support.TESTFN, 'wb') as f:
472n/a f.write(b'\x34\x12xxxx')
473n/a r, p = _testcapi.pymarshal_read_short_from_file(support.TESTFN)
474n/a support.unlink(support.TESTFN)
475n/a self.assertEqual(r, 0x1234)
476n/a self.assertEqual(p, 2)
477n/a
478n/a with open(support.TESTFN, 'wb') as f:
479n/a f.write(b'\x12')
480n/a with self.assertRaises(EOFError):
481n/a _testcapi.pymarshal_read_short_from_file(support.TESTFN)
482n/a support.unlink(support.TESTFN)
483n/a
484n/a def test_read_long_from_file(self):
485n/a with open(support.TESTFN, 'wb') as f:
486n/a f.write(b'\x78\x56\x34\x12xxxx')
487n/a r, p = _testcapi.pymarshal_read_long_from_file(support.TESTFN)
488n/a support.unlink(support.TESTFN)
489n/a self.assertEqual(r, 0x12345678)
490n/a self.assertEqual(p, 4)
491n/a
492n/a with open(support.TESTFN, 'wb') as f:
493n/a f.write(b'\x56\x34\x12')
494n/a with self.assertRaises(EOFError):
495n/a _testcapi.pymarshal_read_long_from_file(support.TESTFN)
496n/a support.unlink(support.TESTFN)
497n/a
498n/a def test_read_last_object_from_file(self):
499n/a obj = ('\u20ac', b'abc', 123, 45.6, 7+8j)
500n/a for v in range(marshal.version + 1):
501n/a data = marshal.dumps(obj, v)
502n/a with open(support.TESTFN, 'wb') as f:
503n/a f.write(data + b'xxxx')
504n/a r, p = _testcapi.pymarshal_read_last_object_from_file(support.TESTFN)
505n/a support.unlink(support.TESTFN)
506n/a self.assertEqual(r, obj)
507n/a
508n/a with open(support.TESTFN, 'wb') as f:
509n/a f.write(data[:1])
510n/a with self.assertRaises(EOFError):
511n/a _testcapi.pymarshal_read_last_object_from_file(support.TESTFN)
512n/a support.unlink(support.TESTFN)
513n/a
514n/a def test_read_object_from_file(self):
515n/a obj = ('\u20ac', b'abc', 123, 45.6, 7+8j)
516n/a for v in range(marshal.version + 1):
517n/a data = marshal.dumps(obj, v)
518n/a with open(support.TESTFN, 'wb') as f:
519n/a f.write(data + b'xxxx')
520n/a r, p = _testcapi.pymarshal_read_object_from_file(support.TESTFN)
521n/a support.unlink(support.TESTFN)
522n/a self.assertEqual(r, obj)
523n/a self.assertEqual(p, len(data))
524n/a
525n/a with open(support.TESTFN, 'wb') as f:
526n/a f.write(data[:1])
527n/a with self.assertRaises(EOFError):
528n/a _testcapi.pymarshal_read_object_from_file(support.TESTFN)
529n/a support.unlink(support.TESTFN)
530n/a
531n/a
532n/aif __name__ == "__main__":
533n/a unittest.main()