cpython/Lib/test/test_marshal.py
Alexandre Vassalotti 5f8ced2b95 Merged revisions 62998-63003,63005-63006,63009-63012,63014-63017,63019-63020,63022-63024,63026-63029,63031-63041,63043-63045,63047-63054,63056-63062 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r62998 | andrew.kuchling | 2008-05-10 15:51:55 -0400 (Sat, 10 May 2008) | 7 lines

  #1858 from Tarek Ziade:
  Allow multiple repositories in .pypirc; see http://wiki.python.org/moin/EnhancedPyPI
  for discussion.

  The patch is slightly revised from Tarek's last patch: I've simplified
  the PyPIRCCommand.finalize_options() method to not look at sys.argv.
  Tests still pass.
........
  r63000 | alexandre.vassalotti | 2008-05-10 15:59:16 -0400 (Sat, 10 May 2008) | 5 lines

  Cleaned up io._BytesIO.write().

  I am amazed that the old code, for inserting null-bytes, actually
  worked. Who wrote that thing? Oh, it is me... doh.
........
  r63002 | brett.cannon | 2008-05-10 16:52:01 -0400 (Sat, 10 May 2008) | 2 lines

  Revert r62998 as it broke the build (seems distutils.config is missing).
........
  r63014 | andrew.kuchling | 2008-05-10 18:12:38 -0400 (Sat, 10 May 2008) | 1 line

  #1858: add distutils.config module
........
  r63027 | brett.cannon | 2008-05-10 21:09:32 -0400 (Sat, 10 May 2008) | 2 lines

  Flesh out the 3.0 deprecation to suggest using the ctypes module.
........
  r63028 | skip.montanaro | 2008-05-10 22:59:30 -0400 (Sat, 10 May 2008) | 4 lines

  Copied two versions of the example from the interactive session.  Delete
  one.
........
  r63037 | georg.brandl | 2008-05-11 03:02:17 -0400 (Sun, 11 May 2008) | 2 lines

  reload() takes the module itself.
........
  r63038 | alexandre.vassalotti | 2008-05-11 03:06:04 -0400 (Sun, 11 May 2008) | 4 lines

  Added test framework for handling module renames.
  Factored the import guard in test_py3kwarn.TestStdlibRemovals into
  a context manager, namely test_support.CleanImport.
........
  r63039 | georg.brandl | 2008-05-11 03:06:05 -0400 (Sun, 11 May 2008) | 2 lines

  #2742: ``''`` is not converted to NULL in getaddrinfo.
........
  r63040 | alexandre.vassalotti | 2008-05-11 03:08:12 -0400 (Sun, 11 May 2008) | 2 lines

  Fixed typo in a comment of test_support.CleanImport.
........
  r63041 | alexandre.vassalotti | 2008-05-11 03:10:25 -0400 (Sun, 11 May 2008) | 2 lines

  Removed a dead line of code.
........
  r63043 | georg.brandl | 2008-05-11 04:47:53 -0400 (Sun, 11 May 2008) | 2 lines

  #2812: document property.getter/setter/deleter.
........
  r63049 | georg.brandl | 2008-05-11 05:06:30 -0400 (Sun, 11 May 2008) | 2 lines

  #1153769: document PEP 237 changes to string formatting.
........
  r63050 | georg.brandl | 2008-05-11 05:11:40 -0400 (Sun, 11 May 2008) | 2 lines

  #2809: elaborate str.split docstring a bit.
........
  r63051 | georg.brandl | 2008-05-11 06:13:59 -0400 (Sun, 11 May 2008) | 2 lines

  Fix typo.
........
  r63052 | georg.brandl | 2008-05-11 06:33:27 -0400 (Sun, 11 May 2008) | 2 lines

  #2709: clarification.
........
  r63053 | georg.brandl | 2008-05-11 06:42:28 -0400 (Sun, 11 May 2008) | 2 lines

  #2659: add ``break_on_hyphens`` to TextWrapper.
........
  r63057 | georg.brandl | 2008-05-11 06:59:39 -0400 (Sun, 11 May 2008) | 2 lines

  #2741: clarification of value range for address_family.
........
  r63058 | georg.brandl | 2008-05-11 07:09:35 -0400 (Sun, 11 May 2008) | 2 lines

  #2452: timeout is used for all blocking operations.
........
  r63059 | andrew.kuchling | 2008-05-11 09:33:56 -0400 (Sun, 11 May 2008) | 2 lines

  #1792: Improve performance of marshal.dumps() on large objects by increasing
  the size of the buffer more quickly.
........
  r63060 | andrew.kuchling | 2008-05-11 10:00:00 -0400 (Sun, 11 May 2008) | 1 line

  #1858: re-apply patch for this, adding the missing files
........
  r63061 | benjamin.peterson | 2008-05-11 10:13:25 -0400 (Sun, 11 May 2008) | 2 lines

  Add the "until" command to pdb
........
  r63062 | georg.brandl | 2008-05-11 10:17:13 -0400 (Sun, 11 May 2008) | 2 lines

  Add some sentence endings.
........
2008-05-16 00:03:33 +00:00

220 lines
7.1 KiB
Python

#!/usr/bin/env python
from test import test_support
import marshal
import sys
import unittest
import os
class HelperMixin:
def helper(self, sample, *extra):
new = marshal.loads(marshal.dumps(sample, *extra))
self.assertEqual(sample, new)
try:
f = open(test_support.TESTFN, "wb")
try:
marshal.dump(sample, f, *extra)
finally:
f.close()
f = open(test_support.TESTFN, "rb")
try:
new = marshal.load(f)
finally:
f.close()
self.assertEqual(sample, new)
finally:
test_support.unlink(test_support.TESTFN)
class IntTestCase(unittest.TestCase, HelperMixin):
def test_ints(self):
# Test the full range of Python ints.
n = sys.maxsize
while n:
for expected in (-n, n):
self.helper(expected)
n = n >> 1
def test_int64(self):
# Simulate int marshaling on a 64-bit box. This is most interesting if
# we're running the test on a 32-bit box, of course.
def to_little_endian_string(value, nbytes):
b = bytearray()
for i in range(nbytes):
b.append(value & 0xff)
value >>= 8
return b
maxint64 = (1 << 63) - 1
minint64 = -maxint64-1
for base in maxint64, minint64, -maxint64, -(minint64 >> 1):
while base:
s = b'I' + to_little_endian_string(base, 8)
got = marshal.loads(s)
self.assertEqual(base, got)
if base == -1: # a fixed-point for shifting right 1
base = 0
else:
base >>= 1
def test_bool(self):
for b in (True, False):
self.helper(b)
class FloatTestCase(unittest.TestCase, HelperMixin):
def test_floats(self):
# Test a few floats
small = 1e-25
n = sys.maxsize * 3.7e250
while n > small:
for expected in (-n, n):
self.helper(float(expected))
n /= 123.4567
f = 0.0
s = marshal.dumps(f, 2)
got = marshal.loads(s)
self.assertEqual(f, got)
# and with version <= 1 (floats marshalled differently then)
s = marshal.dumps(f, 1)
got = marshal.loads(s)
self.assertEqual(f, got)
n = sys.maxsize * 3.7e-250
while n < small:
for expected in (-n, n):
f = float(expected)
self.helper(f)
self.helper(f, 1)
n *= 123.4567
class StringTestCase(unittest.TestCase, HelperMixin):
def test_unicode(self):
for s in ["", "Andr\xe8 Previn", "abc", " "*10000]:
self.helper(marshal.loads(marshal.dumps(s)))
def test_string(self):
for s in ["", "Andr\xe8 Previn", "abc", " "*10000]:
self.helper(s)
def test_bytes(self):
for s in [b"", b"Andr\xe8 Previn", b"abc", b" "*10000]:
self.helper(s)
class ExceptionTestCase(unittest.TestCase):
def test_exceptions(self):
new = marshal.loads(marshal.dumps(StopIteration))
self.assertEqual(StopIteration, new)
class CodeTestCase(unittest.TestCase):
def test_code(self):
co = ExceptionTestCase.test_exceptions.__code__
new = marshal.loads(marshal.dumps(co))
self.assertEqual(co, new)
class ContainerTestCase(unittest.TestCase, HelperMixin):
d = {'astring': 'foo@bar.baz.spam',
'afloat': 7283.43,
'anint': 2**20,
'ashortlong': 2,
'alist': ['.zyx.41'],
'atuple': ('.zyx.41',)*10,
'aboolean': False,
'aunicode': "Andr\xe8 Previn"
}
def test_dict(self):
self.helper(self.d)
def test_list(self):
self.helper(list(self.d.items()))
def test_tuple(self):
self.helper(tuple(self.d.keys()))
def test_sets(self):
for constructor in (set, frozenset):
self.helper(constructor(self.d.keys()))
class BugsTestCase(unittest.TestCase):
def test_bug_5888452(self):
# Simple-minded check for SF 588452: Debug build crashes
marshal.dumps([128] * 1000)
def test_patch_873224(self):
self.assertRaises(Exception, marshal.loads, '0')
self.assertRaises(Exception, marshal.loads, 'f')
self.assertRaises(Exception, marshal.loads, marshal.dumps(2**65)[:-1])
def test_version_argument(self):
# Python 2.4.0 crashes for any call to marshal.dumps(x, y)
self.assertEquals(marshal.loads(marshal.dumps(5, 0)), 5)
self.assertEquals(marshal.loads(marshal.dumps(5, 1)), 5)
def test_fuzz(self):
# simple test that it's at least not *totally* trivial to
# crash from bad marshal data
for c in [chr(i) for i in range(256)]:
try:
marshal.loads(c)
except Exception:
pass
def test_loads_recursion(self):
s = 'c' + ('X' * 4*4) + '{' * 2**20
self.assertRaises(ValueError, marshal.loads, s)
def test_recursion_limit(self):
# Create a deeply nested structure.
head = last = []
# The max stack depth should match the value in Python/marshal.c.
if os.name == 'nt' and hasattr(sys, 'gettotalrefcount'):
MAX_MARSHAL_STACK_DEPTH = 1500
else:
MAX_MARSHAL_STACK_DEPTH = 2000
for i in range(MAX_MARSHAL_STACK_DEPTH - 2):
last.append([0])
last = last[-1]
# Verify we don't blow out the stack with dumps/load.
data = marshal.dumps(head)
new_head = marshal.loads(data)
# Don't use == to compare objects, it can exceed the recursion limit.
self.assertEqual(len(new_head), len(head))
self.assertEqual(len(new_head[0]), len(head[0]))
self.assertEqual(len(new_head[-1]), len(head[-1]))
last.append([0])
self.assertRaises(ValueError, marshal.dumps, head)
def test_exact_type_match(self):
# Former bug:
# >>> class Int(int): pass
# >>> type(loads(dumps(Int())))
# <type 'int'>
for typ in (int, float, complex, tuple, list, dict, set, frozenset):
# Note: str sublclasses are not tested because they get handled
# by marshal's routines for objects supporting the buffer API.
subtyp = type('subtyp', (typ,), {})
self.assertRaises(ValueError, marshal.dumps, subtyp())
# Issue #1792 introduced a change in how marshal increases the size of its
# internal buffer; this test ensures that the new code is exercised.
def test_large_marshal(self):
size = int(1e6)
testString = 'abc' * size
marshal.dumps(testString)
def test_main():
test_support.run_unittest(IntTestCase,
FloatTestCase,
StringTestCase,
CodeTestCase,
ContainerTestCase,
ExceptionTestCase,
BugsTestCase)
if __name__ == "__main__":
test_main()