summaryrefslogtreecommitdiffstats
path: root/Lib/test
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2010-10-12 20:51:21 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2010-10-12 20:51:21 (GMT)
commit04248a8d99e518e7e833a1e2de9e3a8c1a325245 (patch)
tree652372e86d2d672b00832b3820910e5351b28e9b /Lib/test
parentb0182c8ca5a98d2c61f44e87e9b5dc6e8b7a9f30 (diff)
downloadcpython-04248a8d99e518e7e833a1e2de9e3a8c1a325245.zip
cpython-04248a8d99e518e7e833a1e2de9e3a8c1a325245.tar.gz
cpython-04248a8d99e518e7e833a1e2de9e3a8c1a325245.tar.bz2
Issue #3873: Speed up unpickling from file objects which have a peek()
method.
Diffstat (limited to 'Lib/test')
-rw-r--r--Lib/test/pickletester.py43
1 files changed, 42 insertions, 1 deletions
diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py
index 33c85dc..7645b54 100644
--- a/Lib/test/pickletester.py
+++ b/Lib/test/pickletester.py
@@ -30,6 +30,21 @@ def count_opcode(code, pickle):
n += 1
return n
+
+class UnseekableIO(io.BytesIO):
+ def peek(self, *args):
+ raise NotImplementedError
+
+ def seekable(self):
+ return False
+
+ def seek(self, *args):
+ raise io.UnsupportedOperation
+
+ def tell(self):
+ raise io.UnsupportedOperation
+
+
# We can't very well test the extension registry without putting known stuff
# in it, but we have to be careful to restore its original state. Code
# should do this:
@@ -1072,9 +1087,10 @@ class AbstractPickleTests(unittest.TestCase):
# Test the correctness of internal buffering routines when handling
# large data.
for proto in protocols:
- data = (1, b'x' * (256 * 1024))
+ data = (1, min, b'xy' * (30 * 1024), len)
dumped = self.dumps(data, proto)
loaded = self.loads(dumped)
+ self.assertEqual(len(loaded), len(data))
self.assertEqual(loaded, data)
@@ -1373,6 +1389,31 @@ class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
f.seek(0)
self.assertEqual(unpickler.load(), data2)
+ def _check_multiple_unpicklings(self, ioclass):
+ for proto in protocols:
+ data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len]
+ f = ioclass()
+ pickler = self.pickler_class(f, protocol=proto)
+ pickler.dump(data1)
+ pickled = f.getvalue()
+
+ N = 5
+ f = ioclass(pickled * N)
+ unpickler = self.unpickler_class(f)
+ for i in range(N):
+ if f.seekable():
+ pos = f.tell()
+ self.assertEqual(unpickler.load(), data1)
+ if f.seekable():
+ self.assertEqual(f.tell(), pos + len(pickled))
+ self.assertRaises(EOFError, unpickler.load)
+
+ def test_multiple_unpicklings_seekable(self):
+ self._check_multiple_unpicklings(io.BytesIO)
+
+ def test_multiple_unpicklings_unseekable(self):
+ self._check_multiple_unpicklings(UnseekableIO)
+
if __name__ == "__main__":
# Print some stuff that can be used to rewrite DATA{0,1,2}