diff options
author | Martin v. Löwis <martin@v.loewis.de> | 2007-07-18 02:28:27 (GMT) |
---|---|---|
committer | Martin v. Löwis <martin@v.loewis.de> | 2007-07-18 02:28:27 (GMT) |
commit | 10a60b3ec0cdf7eeac98258fc53a33b7026f8ff3 (patch) | |
tree | 533e2a67c2c082cd9534c70293977f9245425188 /Modules | |
parent | 6f2df4d5e193d54244b0c2de91ef0ab1604b9243 (diff) | |
download | cpython-10a60b3ec0cdf7eeac98258fc53a33b7026f8ff3.zip cpython-10a60b3ec0cdf7eeac98258fc53a33b7026f8ff3.tar.gz cpython-10a60b3ec0cdf7eeac98258fc53a33b7026f8ff3.tar.bz2 |
Change Py_BuildValue to generate Unicode objects for
's' and 'c' codes.
Change pickle to dump bytes objects using the 'S'
code, and to load the 'S' code as byte objects.
Change datetime and array to generate and expect
bytes objects in reduce/unreduce.
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/arraymodule.c | 2 | ||||
-rw-r--r-- | Modules/cPickle.c | 109 | ||||
-rw-r--r-- | Modules/datetimemodule.c | 50 |
3 files changed, 131 insertions, 30 deletions
diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 11819e2..7ddc7e8 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -1126,7 +1126,7 @@ array_reduce(arrayobject *array) Py_INCREF(dict); } if (array->ob_size > 0) { - result = Py_BuildValue("O(cs#)O", + result = Py_BuildValue("O(cy#)O", array->ob_type, array->ob_descr->typecode, array->ob_item, diff --git a/Modules/cPickle.c b/Modules/cPickle.c index d50c743..ff29b67 100644 --- a/Modules/cPickle.c +++ b/Modules/cPickle.c @@ -1151,6 +1151,92 @@ save_string(Picklerobject *self, PyObject *args, int doput) } +static int +save_bytes(Picklerobject *self, PyObject *args, int doput) +{ + int size, len; + PyObject *repr=0; + + if ((size = PyBytes_Size(args)) < 0) + return -1; + + if (!self->bin) { + char *repr_str; + + static char string = STRING; + + if (!( repr = PyObject_ReprStr8(args))) + return -1; + + if ((len = PyString_Size(repr)) < 0) + goto err; + repr_str = PyString_AS_STRING((PyStringObject *)repr); + + /* Strip leading 's' due to repr() of str8() returning s'...' */ + if (repr_str[0] == 'b') { + repr_str++; + len--; + } + + if (self->write_func(self, &string, 1) < 0) + goto err; + + if (self->write_func(self, repr_str, len) < 0) + goto err; + + if (self->write_func(self, "\n", 1) < 0) + goto err; + + Py_XDECREF(repr); + } + else { + int i; + char c_str[5]; + + if ((size = PyBytes_Size(args)) < 0) + return -1; + + if (size < 256) { + c_str[0] = SHORT_BINSTRING; + c_str[1] = size; + len = 2; + } + else if (size <= INT_MAX) { + c_str[0] = BINSTRING; + for (i = 1; i < 5; i++) + c_str[i] = (int)(size >> ((i - 1) * 8)); + len = 5; + } + else + return -1; /* string too large */ + + if (self->write_func(self, c_str, len) < 0) + return -1; + + if (size > 128 && Pdata_Check(self->file)) { + if (write_other(self, NULL, 0) < 0) return -1; + PDATA_APPEND(self->file, args, -1); + } + else { + if (self->write_func(self, + PyBytes_AsString(args), + size) < 0) + return -1; + } + } + + if (doput) + if (put(self, args) < 0) + return -1; + + return 0; + + err: + Py_XDECREF(repr); + return -1; +} + + /* A copy of PyUnicode_EncodeRawUnicodeEscape() that also translates backslash and newline characters to \uXXXX escapes. */ static PyObject * @@ -2086,11 +2172,11 @@ save(Picklerobject *self, PyObject *args, int pers_save) type = args->ob_type; switch (type->tp_name[0]) { - case 'b': + case 'b': /* XXX may want to save short byte strings here. */ if (args == Py_False || args == Py_True) { res = save_bool(self, args); goto finally; - } + } break; case 'i': if (type == &PyLong_Type) { @@ -2197,6 +2283,11 @@ save(Picklerobject *self, PyObject *args, int pers_save) res = save_global(self, args, NULL); goto finally; } + else if (type == &PyBytes_Type) { + res = save_bytes(self, args, 1); + goto finally; + } + break; } if (!pers_save && self->inst_pers_func) { @@ -3131,11 +3222,17 @@ load_string(Unpicklerobject *self) goto insecure; /********************************************/ + /* XXX avoid going through str8 here. */ str = PyString_DecodeEscape(p, len, NULL, 0, NULL); free(s); if (str) { - PDATA_PUSH(self->stack, str, -1); - res = 0; + PyObject *str2 = PyBytes_FromStringAndSize( + PyString_AsString(str), PyString_Size(str)); + Py_DECREF(str); + if (str2) { + PDATA_PUSH(self->stack, str2, -1); + res = 0; + } } return res; @@ -3160,7 +3257,7 @@ load_binstring(Unpicklerobject *self) if (self->read_func(self, &s, l) < 0) return -1; - if (!( py_string = PyString_FromStringAndSize(s, l))) + if (!( py_string = PyBytes_FromStringAndSize(s, l))) return -1; PDATA_PUSH(self->stack, py_string, -1); @@ -3182,7 +3279,7 @@ load_short_binstring(Unpicklerobject *self) if (self->read_func(self, &s, l) < 0) return -1; - if (!( py_string = PyString_FromStringAndSize(s, l))) return -1; + if (!( py_string = PyBytes_FromStringAndSize(s, l))) return -1; PDATA_PUSH(self->stack, py_string, -1); return 0; diff --git a/Modules/datetimemodule.c b/Modules/datetimemodule.c index 61f9ab7..aa037c2 100644 --- a/Modules/datetimemodule.c +++ b/Modules/datetimemodule.c @@ -2183,15 +2183,15 @@ date_new(PyTypeObject *type, PyObject *args, PyObject *kw) /* Check for invocation from pickle with __getstate__ state */ if (PyTuple_GET_SIZE(args) == 1 && - PyString_Check(state = PyTuple_GET_ITEM(args, 0)) && - PyString_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE && - MONTH_IS_SANE(PyString_AS_STRING(state)[2])) + PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) && + PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE && + MONTH_IS_SANE(PyBytes_AS_STRING(state)[2])) { PyDateTime_Date *me; me = (PyDateTime_Date *) (type->tp_alloc(type, 0)); if (me != NULL) { - char *pdata = PyString_AS_STRING(state); + char *pdata = PyBytes_AS_STRING(state); memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE); me->hashcode = -1; } @@ -2509,13 +2509,13 @@ date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw) return clone; } -static PyObject *date_getstate(PyDateTime_Date *self); +static PyObject *date_getstate(PyDateTime_Date *self, int hashable); static long date_hash(PyDateTime_Date *self) { if (self->hashcode == -1) { - PyObject *temp = date_getstate(self); + PyObject *temp = date_getstate(self, 1); if (temp != NULL) { self->hashcode = PyObject_Hash(temp); Py_DECREF(temp); @@ -2543,18 +2543,22 @@ date_weekday(PyDateTime_Date *self) /* __getstate__ isn't exposed */ static PyObject * -date_getstate(PyDateTime_Date *self) +date_getstate(PyDateTime_Date *self, int hashable) { - return Py_BuildValue( - "(N)", - PyString_FromStringAndSize((char *)self->data, - _PyDateTime_DATE_DATASIZE)); + PyObject* field; + if (hashable) + field = PyString_FromStringAndSize( + (char*)self->data, _PyDateTime_DATE_DATASIZE); + else + field = PyBytes_FromStringAndSize( + (char*)self->data, _PyDateTime_DATE_DATASIZE); + return Py_BuildValue("(N)", field); } static PyObject * date_reduce(PyDateTime_Date *self, PyObject *arg) { - return Py_BuildValue("(ON)", self->ob_type, date_getstate(self)); + return Py_BuildValue("(ON)", self->ob_type, date_getstate(self, 0)); } static PyMethodDef date_methods[] = { @@ -2998,9 +3002,9 @@ time_new(PyTypeObject *type, PyObject *args, PyObject *kw) /* Check for invocation from pickle with __getstate__ state */ if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2 && - PyString_Check(state = PyTuple_GET_ITEM(args, 0)) && - PyString_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE && - ((unsigned char) (PyString_AS_STRING(state)[0])) < 24) + PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) && + PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE && + ((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24) { PyDateTime_Time *me; char aware; @@ -3016,7 +3020,7 @@ time_new(PyTypeObject *type, PyObject *args, PyObject *kw) aware = (char)(tzinfo != Py_None); me = (PyDateTime_Time *) (type->tp_alloc(type, aware)); if (me != NULL) { - char *pdata = PyString_AS_STRING(state); + char *pdata = PyBytes_AS_STRING(state); memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE); me->hashcode = -1; @@ -3331,7 +3335,7 @@ time_getstate(PyDateTime_Time *self) PyObject *basestate; PyObject *result = NULL; - basestate = PyString_FromStringAndSize((char *)self->data, + basestate = PyBytes_FromStringAndSize((char *)self->data, _PyDateTime_TIME_DATASIZE); if (basestate != NULL) { if (! HASTZINFO(self) || self->tzinfo == Py_None) @@ -3513,9 +3517,9 @@ datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw) /* Check for invocation from pickle with __getstate__ state */ if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2 && - PyString_Check(state = PyTuple_GET_ITEM(args, 0)) && - PyString_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE && - MONTH_IS_SANE(PyString_AS_STRING(state)[2])) + PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) && + PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE && + MONTH_IS_SANE(PyBytes_AS_STRING(state)[2])) { PyDateTime_DateTime *me; char aware; @@ -3531,7 +3535,7 @@ datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw) aware = (char)(tzinfo != Py_None); me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware)); if (me != NULL) { - char *pdata = PyString_AS_STRING(state); + char *pdata = PyBytes_AS_STRING(state); memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE); me->hashcode = -1; @@ -4375,8 +4379,8 @@ datetime_getstate(PyDateTime_DateTime *self) PyObject *basestate; PyObject *result = NULL; - basestate = PyString_FromStringAndSize((char *)self->data, - _PyDateTime_DATETIME_DATASIZE); + basestate = PyBytes_FromStringAndSize((char *)self->data, + _PyDateTime_DATETIME_DATASIZE); if (basestate != NULL) { if (! HASTZINFO(self) || self->tzinfo == Py_None) result = PyTuple_Pack(1, basestate); |