cpython: 680959a3ae2e (original) (raw)

--- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -6,7 +6,8 @@ import cStringIO import pickletools import copy_reg -from test.test_support import TestFailed, have_unicode, TESTFN +from test.test_support import (TestFailed, have_unicode, TESTFN, _2G, _1M,

Tests that try a number of pickle protocols should have a

for proto in protocols:

@@ -1280,3 +1281,31 @@ class AbstractPicklerUnpicklerObjectTest f.write(pickled2) f.seek(0) self.assertEqual(unpickler.load(), data2) + +class BigmemPickleTests(unittest.TestCase): +

+

+

--- a/Lib/test/test_cpickle.py +++ b/Lib/test/test_cpickle.py @@ -1,7 +1,9 @@ import cPickle, unittest from cStringIO import StringIO -from test.pickletester import AbstractPickleTests, AbstractPickleModuleTests -from test.pickletester import AbstractPicklerUnpicklerObjectTests +from test.pickletester import (AbstractPickleTests,

from test import test_support class cPickleTests(AbstractPickleTests, AbstractPickleModuleTests): @@ -101,6 +103,16 @@ class cPicklePicklerUnpicklerObjectTests pickler_class = cPickle.Pickler unpickler_class = cPickle.Unpickler +class cPickleBigmemPickleTests(BigmemPickleTests): +

+

+ class Node(object): pass @@ -133,6 +145,7 @@ def test_main(): cPickleFastPicklerTests, cPickleDeepRecursive, cPicklePicklerUnpicklerObjectTests,

--- a/Lib/test/test_pickle.py +++ b/Lib/test/test_pickle.py @@ -3,10 +3,11 @@ from cStringIO import StringIO from test import test_support -from test.pickletester import AbstractPickleTests -from test.pickletester import AbstractPickleModuleTests -from test.pickletester import AbstractPersistentPicklerTests -from test.pickletester import AbstractPicklerUnpicklerObjectTests +from test.pickletester import (AbstractPickleTests,

class PickleTests(AbstractPickleTests, AbstractPickleModuleTests): @@ -66,6 +67,16 @@ class PicklerUnpicklerObjectTests(Abstra pickler_class = pickle.Pickler unpickler_class = pickle.Unpickler +class PickleBigmemPickleTests(BigmemPickleTests): +

+

+ def test_main(): test_support.run_unittest( @@ -73,6 +84,7 @@ def test_main(): PicklerTests, PersPicklerTests, PicklerUnpicklerObjectTests,

--- a/Misc/NEWS +++ b/Misc/NEWS @@ -202,6 +202,8 @@ Core and Builtins Library ------- +- Issue #13555: cPickle now supports files larger than 2 GiB. +

--- a/Modules/cPickle.c +++ b/Modules/cPickle.c @@ -139,15 +139,15 @@ static PyObject *__class___str, *__getin typedef struct { PyObject_HEAD

+ PyObject **tmp;

@@ -280,10 +279,10 @@ Pdata_grow(Pdata *self) static PyObject * -Pdata_popTuple(Pdata *self, int start) +Pdata_popTuple(Pdata *self, Py_ssize_t start) { PyObject *r;

l = self->length-start; r = PyTuple_New(l); @@ -297,10 +296,10 @@ Pdata_popTuple(Pdata *self, int start) } static PyObject * -Pdata_popList(Pdata *self, int start) +Pdata_popList(Pdata *self, Py_ssize_t start) { PyObject *r;

l=self->length-start; if (!( r=PyList_New(l))) return NULL; @@ -347,9 +346,9 @@ typedef struct Picklerobject { int bin; int fast; /* Fast mode doesn't save in memo, don't use if circ ref */

-static int +static Py_ssize_t write_file(Picklerobject *self, const char *s, Py_ssize_t n) { size_t nbyteswritten; @@ -433,11 +432,6 @@ write_file(Picklerobject *self, const ch return 0; }

- PyFile_IncUseCount((PyFileObject *)self->file); Py_BEGIN_ALLOW_THREADS nbyteswritten = fwrite(s, sizeof(char), n, self->fp); @@ -448,40 +442,44 @@ write_file(Picklerobject *self, const ch return -1; }

} -static int +static Py_ssize_t write_cStringIO(Picklerobject *self, const char *s, Py_ssize_t n) {

+ if (s == NULL) { return 0; }

+ if (PycStringIO->cwrite((PyObject *)self->file, s, n) != n) { return -1; }

} -static int +static Py_ssize_t write_none(Picklerobject *self, const char *s, Py_ssize_t n) { if (s == NULL) return 0;

} -static int -write_other(Picklerobject *self, const char *s, Py_ssize_t _n) +static Py_ssize_t +write_other(Picklerobject *self, const char *s, Py_ssize_t n) { PyObject *py_str = 0, *junk = 0;

-

+ if (s == NULL) { if (!( self->buf_size )) return 0; py_str = PyString_FromStringAndSize(self->write_buf, @@ -490,7 +488,7 @@ write_other(Picklerobject *self, const c return -1; } else {

@@ -531,7 +529,7 @@ read_file(Unpicklerobject *self, char ** size_t nbytesread; if (self->buf_size == 0) {

size = ((n < 32) ? 32 : n); if (!( self->buf = (char *)malloc(size))) { @@ -575,7 +573,7 @@ read_file(Unpicklerobject *self, char ** static Py_ssize_t readline_file(Unpicklerobject *self, char **s) {

if (self->buf_size == 0) { if (!( self->buf = (char *)malloc(40))) { @@ -587,7 +585,7 @@ readline_file(Unpicklerobject *self, cha i = 0; while (1) {

@@ -597,13 +595,13 @@ readline_file(Unpicklerobject *self, cha return i + 1; } }

@@ -616,30 +614,63 @@ readline_file(Unpicklerobject *self, cha static Py_ssize_t read_cStringIO(Unpicklerobject *self, char **s, Py_ssize_t n) {

-

-

-

+

+

+

} static Py_ssize_t readline_cStringIO(Unpicklerobject *self, char **s) {

-

-

+

+

return n; } @@ -700,7 +731,7 @@ readline_other(Unpicklerobject *self, ch

if (!self->bin #if SIZEOF_LONG > 4 @@ -1201,7 +1233,7 @@ done: static int save_string(Picklerobject *self, PyObject *args, int doput) {

if (self->fast && !fast_save_enter(self, args)) goto finally; @@ -2027,7 +2059,7 @@ save_inst(Picklerobject *self, PyObject if ((getinitargs_func = PyObject_GetAttr(args, __getinitargs___str))) { PyObject *element = 0;

if (!( class_args = PyObject_Call(getinitargs_func, empty_tuple, NULL))) @@ -2289,7 +2321,8 @@ static int save_pers(Picklerobject *self, PyObject *args, PyObject *f) { PyObject *pid = 0;

static char persid = PERSID, binpersid = BINPERSID; @@ -2431,7 +2464,7 @@ save_reduce(Picklerobject *self, PyObjec if (use_newobj) { PyObject *cls; PyObject *newargtup;

/* Sanity checks. */ n = PyTuple_Size(argtup); @@ -2815,7 +2848,7 @@ Pickle_clear_memo(Picklerobject *self, P static PyObject * Pickle_getvalue(Picklerobject *self, PyObject *args) {

-static int +static Py_ssize_t marker(Unpicklerobject *self) { if (self->num_marks < 1) { @@ -3345,7 +3378,8 @@ load_int(Unpicklerobject *self) { PyObject *py_int = 0; char *endptr, *s;

if ((len = self->readline_func(self, &s)) < 0) return -1; if (len < 2) return bad_readline(); @@ -3541,7 +3576,8 @@ load_float(Unpicklerobject *self) { PyObject *py_float = 0; char *endptr, *s;

PDATA_PUSH(self->stack, str, -1); return 0; -

} #endif @@ -3714,7 +3748,7 @@ static int load_binunicode(Unpicklerobject *self) { PyObject *unicode;

if ((i = marker(self)) < 0) return -1; if (!( tup=Pdata_popTuple(self->stack, i))) return -1; @@ -3798,7 +3832,7 @@ static int load_list(Unpicklerobject *self) { PyObject *list = 0;

if ((i = marker(self)) < 0) return -1; if (!( list=Pdata_popList(self->stack, i))) return -1; @@ -3810,7 +3844,7 @@ static int load_dict(Unpicklerobject *self) { PyObject *dict, *key, *value;

if ((i = marker(self)) < 0) return -1; j=self->stack->length; @@ -3886,7 +3920,7 @@ static int load_obj(Unpicklerobject *self) { PyObject *class, *tup, *obj=0;

if ((i = marker(self)) < 0) return -1; if (!( tup=Pdata_popTuple(self->stack, i+1))) return -1; @@ -3907,7 +3941,7 @@ static int load_inst(Unpicklerobject *self) { PyObject *tup, *class=0, *obj=0, *module_name, *class_name;

/* Note that we split the (pickle.py) stack into two stacks, an object stack and a mark stack. We have to be clever and @@ -4127,7 +4161,7 @@ load_pop(Unpicklerobject *self) static int load_pop_mark(Unpicklerobject *self) {

if ((i = marker(self)) < 0) return -1; @@ -4142,7 +4176,7 @@ static int load_dup(Unpicklerobject *self) { PyObject *last;

if ((len = self->stack->length) <= 0) return stackUnderflow(); last=self->stack->data[len-1]; @@ -4156,7 +4190,7 @@ static int load_get(Unpicklerobject *self) { PyObject *py_str = 0, *value = 0;

if (self->read_func(self, &s, 1) < 0) return -1; if (!( (len=self->stack->length) > 0 )) return stackUnderflow(); @@ -4356,10 +4390,10 @@ static int load_long_binput(Unpicklerobject *self) { PyObject *py_key = 0, *value = 0;

if (self->read_func(self, &s, 4) < 0) return -1; if (!( len=self->stack->length )) return stackUnderflow(); @@ -4382,10 +4416,10 @@ load_long_binput(Unpicklerobject *self) static int -do_append(Unpicklerobject *self, int x) +do_append(Unpicklerobject *self, Py_ssize_t x) { PyObject *value = 0, *list = 0, *append_method = 0;

len=self->stack->length; if (!( len >= x && x > 0 )) return stackUnderflow(); @@ -4451,11 +4485,11 @@ load_appends(Unpicklerobject *self) } -static int -do_setitems(Unpicklerobject *self, int x) +static Py_ssize_t +do_setitems(Unpicklerobject *self, Py_ssize_t x) { PyObject *value = 0, *key = 0, *dict = 0;

if (!( (len=self->stack->length) >= x && x > 0 )) return stackUnderflow(); @@ -4496,8 +4530,8 @@ load_build(Unpicklerobject *self) PyObject *state, *inst, *slotstate; PyObject *setstate; PyObject *d_key, *d_value;

/* Stack is ... instance, state. We want to leave instance at * the stack top, possibly mutated via instance.setstate(state). @@ -4596,7 +4630,7 @@ load_build(Unpicklerobject *self) static int load_mark(Unpicklerobject *self) {

/* Note that we split the (pickle.py) stack into two stacks, an object stack and a mark stack. Here we push a mark onto the @@ -4604,14 +4638,14 @@ load_mark(Unpicklerobject *self) */ if ((self->num_marks + 1) >= self->marks_size) {

@@ -4981,7 +5015,7 @@ load(Unpicklerobject *self) static int noload_obj(Unpicklerobject *self) {

if ((i = marker(self)) < 0) return -1; return Pdata_clear(self->stack, i+1); @@ -4991,7 +5025,7 @@ noload_obj(Unpicklerobject *self) static int noload_inst(Unpicklerobject *self) {

@@ -5082,7 +5116,7 @@ noload_setitem(Unpicklerobject *self) static int noload_setitems(Unpicklerobject *self) {

--- a/Modules/cStringIO.c +++ b/Modules/cStringIO.c @@ -210,11 +210,8 @@ IO_creadline(PyObject *self, char **outp if (n < end) n++; len = n - start;

*output=start;