diff options
Diffstat (limited to 'Modules/_pickle.c')
-rw-r--r-- | Modules/_pickle.c | 92 |
1 files changed, 55 insertions, 37 deletions
diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 920b46fc28..e65b88e9c0 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -346,7 +346,7 @@ _Pickle_FastCall(PyObject *func, PyObject *obj) { PyObject *result; - result = _PyObject_CallArg1(func, obj); + result = PyObject_CallFunctionObjArgs(func, obj, NULL); Py_DECREF(obj); return result; } @@ -1936,7 +1936,7 @@ save_long(PicklerObject *self, PyObject *obj) goto error; } else { - char *string; + const char *string; /* proto < 2: write the repr and newline. This is quadratic-time (in the number of digits), in both directions. We add a trailing 'L' @@ -2213,7 +2213,7 @@ write_unicode_binary(PicklerObject *self, PyObject *obj) { PyObject *encoded = NULL; Py_ssize_t size; - char *data; + const char *data; int r; if (PyUnicode_READY(obj)) @@ -2782,10 +2782,10 @@ batch_dict_exact(PicklerObject *self, PyObject *obj) const char setitem_op = SETITEM; const char setitems_op = SETITEMS; - assert(obj != NULL); + assert(obj != NULL && PyDict_CheckExact(obj)); assert(self->proto > 0); - dict_size = PyDict_Size(obj); + dict_size = PyDict_GET_SIZE(obj); /* Special-case len(d) == 1 to save space. */ if (dict_size == 1) { @@ -2814,7 +2814,7 @@ batch_dict_exact(PicklerObject *self, PyObject *obj) } if (_Pickler_Write(self, &setitems_op, 1) < 0) return -1; - if (PyDict_Size(obj) != dict_size) { + if (PyDict_GET_SIZE(obj) != dict_size) { PyErr_Format( PyExc_RuntimeError, "dictionary changed size during iteration"); @@ -2832,6 +2832,7 @@ save_dict(PicklerObject *self, PyObject *obj) char header[3]; Py_ssize_t len; int status = 0; + assert(PyDict_Check(obj)); if (self->fast && !fast_save_enter(self, obj)) goto error; @@ -2850,14 +2851,10 @@ save_dict(PicklerObject *self, PyObject *obj) if (_Pickler_Write(self, header, len) < 0) goto error; - /* Get dict size, and bow out early if empty. */ - if ((len = PyDict_Size(obj)) < 0) - goto error; - if (memo_put(self, obj) < 0) goto error; - if (len != 0) { + if (PyDict_GET_SIZE(obj)) { /* Save the dict items. */ if (PyDict_CheckExact(obj) && self->proto > 0) { /* We can take certain shortcuts if we know this is a dict and @@ -4565,8 +4562,8 @@ find_class(UnpicklerObject *self, PyObject *module_name, PyObject *global_name) { _Py_IDENTIFIER(find_class); - return _PyObject_CallMethodId((PyObject *)self, &PyId_find_class, "OO", - module_name, global_name); + return _PyObject_CallMethodIdObjArgs((PyObject *)self, &PyId_find_class, + module_name, global_name, NULL); } static Py_ssize_t @@ -4756,7 +4753,7 @@ static int load_long(UnpicklerObject *self) { PyObject *value; - char *s; + char *s = NULL; Py_ssize_t len; if ((len = _Unpickler_Readline(self, &s)) < 0) @@ -4987,7 +4984,7 @@ load_unicode(UnpicklerObject *self) { PyObject *str; Py_ssize_t len; - char *s; + char *s = NULL; if ((len = _Unpickler_Readline(self, &s)) < 0) return -1; @@ -5178,7 +5175,7 @@ instantiate(PyObject *cls, PyObject *args) else { _Py_IDENTIFIER(__new__); - result = _PyObject_CallMethodId(cls, &PyId___new__, "O", cls); + result = _PyObject_CallMethodIdObjArgs(cls, &PyId___new__, cls, NULL); } return result; } @@ -5726,7 +5723,7 @@ load_put(UnpicklerObject *self) PyObject *key, *value; Py_ssize_t idx; Py_ssize_t len; - char *s; + char *s = NULL; if ((len = _Unpickler_Readline(self, &s)) < 0) return -1; @@ -5810,7 +5807,9 @@ static int do_append(UnpicklerObject *self, Py_ssize_t x) { PyObject *value; + PyObject *slice; PyObject *list; + PyObject *result; Py_ssize_t len, i; len = Py_SIZE(self->stack); @@ -5821,8 +5820,7 @@ do_append(UnpicklerObject *self, Py_ssize_t x) list = self->stack->data[x - 1]; - if (PyList_Check(list)) { - PyObject *slice; + if (PyList_CheckExact(list)) { Py_ssize_t list_len; int ret; @@ -5835,27 +5833,47 @@ do_append(UnpicklerObject *self, Py_ssize_t x) return ret; } else { - PyObject *append_func; - _Py_IDENTIFIER(append); - - append_func = _PyObject_GetAttrId(list, &PyId_append); - if (append_func == NULL) - return -1; - for (i = x; i < len; i++) { - PyObject *result; - - value = self->stack->data[i]; - result = _Pickle_FastCall(append_func, value); - if (result == NULL) { - Pdata_clear(self->stack, i + 1); - Py_SIZE(self->stack) = x; - Py_DECREF(append_func); + PyObject *extend_func; + _Py_IDENTIFIER(extend); + + extend_func = _PyObject_GetAttrId(list, &PyId_extend); + if (extend_func != NULL) { + slice = Pdata_poplist(self->stack, x); + if (!slice) { + Py_DECREF(extend_func); return -1; } + result = _Pickle_FastCall(extend_func, slice); + Py_DECREF(extend_func); + if (result == NULL) + return -1; Py_DECREF(result); } - Py_SIZE(self->stack) = x; - Py_DECREF(append_func); + else { + PyObject *append_func; + _Py_IDENTIFIER(append); + + /* Even if the PEP 307 requires extend() and append() methods, + fall back on append() if the object has no extend() method + for backward compatibility. */ + PyErr_Clear(); + append_func = _PyObject_GetAttrId(list, &PyId_append); + if (append_func == NULL) + return -1; + for (i = x; i < len; i++) { + value = self->stack->data[i]; + result = _Pickle_FastCall(append_func, value); + if (result == NULL) { + Pdata_clear(self->stack, i + 1); + Py_SIZE(self->stack) = x; + Py_DECREF(append_func); + return -1; + } + Py_DECREF(result); + } + Py_SIZE(self->stack) = x; + Py_DECREF(append_func); + } } return 0; @@ -6872,7 +6890,7 @@ Unpickler_set_memo(UnpicklerObject *self, PyObject *obj) Py_ssize_t i = 0; PyObject *key, *value; - new_memo_size = PyDict_Size(obj); + new_memo_size = PyDict_GET_SIZE(obj); new_memo = _Unpickler_NewMemo(new_memo_size); if (new_memo == NULL) return -1; |