Commit cdc7a91d authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #13555: cPickle now supports files larger than 2 GiB.

parent da5c2a06
...@@ -6,7 +6,8 @@ import cStringIO ...@@ -6,7 +6,8 @@ import cStringIO
import pickletools import pickletools
import copy_reg import copy_reg
from test.test_support import TestFailed, have_unicode, TESTFN from test.test_support import (TestFailed, have_unicode, TESTFN, _2G, _1M,
precisionbigmemtest)
# Tests that try a number of pickle protocols should have a # Tests that try a number of pickle protocols should have a
# for proto in protocols: # for proto in protocols:
...@@ -1280,3 +1281,31 @@ class AbstractPicklerUnpicklerObjectTests(unittest.TestCase): ...@@ -1280,3 +1281,31 @@ class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
f.write(pickled2) f.write(pickled2)
f.seek(0) f.seek(0)
self.assertEqual(unpickler.load(), data2) self.assertEqual(unpickler.load(), data2)
class BigmemPickleTests(unittest.TestCase):
# Memory requirements: 1 byte per character for input strings, 1 byte
# for pickled data, 1 byte for unpickled strings, 1 byte for internal
# buffer and 1 byte of free space for resizing of internal buffer.
@precisionbigmemtest(size=_2G + 100*_1M, memuse=5)
def test_huge_strlist(self, size):
chunksize = 2**20
data = []
while size > chunksize:
data.append('x' * chunksize)
size -= chunksize
chunksize += 1
data.append('y' * size)
try:
for proto in protocols:
try:
pickled = self.dumps(data, proto)
res = self.loads(pickled)
self.assertEqual(res, data)
finally:
res = None
pickled = None
finally:
data = None
import cPickle, unittest import cPickle, unittest
from cStringIO import StringIO from cStringIO import StringIO
from test.pickletester import AbstractPickleTests, AbstractPickleModuleTests from test.pickletester import (AbstractPickleTests,
from test.pickletester import AbstractPicklerUnpicklerObjectTests AbstractPickleModuleTests,
AbstractPicklerUnpicklerObjectTests,
BigmemPickleTests)
from test import test_support from test import test_support
class cPickleTests(AbstractPickleTests, AbstractPickleModuleTests): class cPickleTests(AbstractPickleTests, AbstractPickleModuleTests):
...@@ -101,6 +103,16 @@ class cPicklePicklerUnpicklerObjectTests(AbstractPicklerUnpicklerObjectTests): ...@@ -101,6 +103,16 @@ class cPicklePicklerUnpicklerObjectTests(AbstractPicklerUnpicklerObjectTests):
pickler_class = cPickle.Pickler pickler_class = cPickle.Pickler
unpickler_class = cPickle.Unpickler unpickler_class = cPickle.Unpickler
class cPickleBigmemPickleTests(BigmemPickleTests):
def dumps(self, arg, proto=0, fast=0):
# Ignore fast
return cPickle.dumps(arg, proto)
def loads(self, buf):
# Ignore fast
return cPickle.loads(buf)
class Node(object): class Node(object):
pass pass
...@@ -133,6 +145,7 @@ def test_main(): ...@@ -133,6 +145,7 @@ def test_main():
cPickleFastPicklerTests, cPickleFastPicklerTests,
cPickleDeepRecursive, cPickleDeepRecursive,
cPicklePicklerUnpicklerObjectTests, cPicklePicklerUnpicklerObjectTests,
cPickleBigmemPickleTests,
) )
if __name__ == "__main__": if __name__ == "__main__":
......
...@@ -3,10 +3,11 @@ from cStringIO import StringIO ...@@ -3,10 +3,11 @@ from cStringIO import StringIO
from test import test_support from test import test_support
from test.pickletester import AbstractPickleTests from test.pickletester import (AbstractPickleTests,
from test.pickletester import AbstractPickleModuleTests AbstractPickleModuleTests,
from test.pickletester import AbstractPersistentPicklerTests AbstractPersistentPicklerTests,
from test.pickletester import AbstractPicklerUnpicklerObjectTests AbstractPicklerUnpicklerObjectTests,
BigmemPickleTests)
class PickleTests(AbstractPickleTests, AbstractPickleModuleTests): class PickleTests(AbstractPickleTests, AbstractPickleModuleTests):
...@@ -66,6 +67,16 @@ class PicklerUnpicklerObjectTests(AbstractPicklerUnpicklerObjectTests): ...@@ -66,6 +67,16 @@ class PicklerUnpicklerObjectTests(AbstractPicklerUnpicklerObjectTests):
pickler_class = pickle.Pickler pickler_class = pickle.Pickler
unpickler_class = pickle.Unpickler unpickler_class = pickle.Unpickler
class PickleBigmemPickleTests(BigmemPickleTests):
def dumps(self, arg, proto=0, fast=0):
# Ignore fast
return pickle.dumps(arg, proto)
def loads(self, buf):
# Ignore fast
return pickle.loads(buf)
def test_main(): def test_main():
test_support.run_unittest( test_support.run_unittest(
...@@ -73,6 +84,7 @@ def test_main(): ...@@ -73,6 +84,7 @@ def test_main():
PicklerTests, PicklerTests,
PersPicklerTests, PersPicklerTests,
PicklerUnpicklerObjectTests, PicklerUnpicklerObjectTests,
PickleBigmemPickleTests,
) )
test_support.run_doctest(pickle) test_support.run_doctest(pickle)
......
...@@ -202,6 +202,8 @@ Core and Builtins ...@@ -202,6 +202,8 @@ Core and Builtins
Library Library
------- -------
- Issue #13555: cPickle now supports files larger than 2 GiB.
- Issue #17052: unittest discovery should use self.testLoader. - Issue #17052: unittest discovery should use self.testLoader.
- Issue #4591: Uid and gid values larger than 2**31 are supported now. - Issue #4591: Uid and gid values larger than 2**31 are supported now.
......
This diff is collapsed.
...@@ -210,11 +210,8 @@ IO_creadline(PyObject *self, char **output) { ...@@ -210,11 +210,8 @@ IO_creadline(PyObject *self, char **output) {
if (n < end) n++; if (n < end) n++;
len = n - start; len = n - start;
if (len > INT_MAX) { if (len > INT_MAX)
PyErr_SetString(PyExc_OverflowError, len = INT_MAX;
"length too large");
return -1;
}
*output=start; *output=start;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment