aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/Modules/_pickle.c
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.com>2024-08-17 21:51:59 +0300
committershadchin <shadchin@yandex-team.com>2024-08-17 22:04:51 +0300
commitee9edbd8878888bafcd0eeb3b528f3ec4311560b (patch)
treed54d8138e50a446904f10a2092719be86af011b7 /contrib/tools/python3/Modules/_pickle.c
parent72cbe4bad58add0912623ba51351ff1db8587249 (diff)
downloadydb-ee9edbd8878888bafcd0eeb3b528f3ec4311560b.tar.gz
Update Python 3 to 3.12.5
https://docs.python.org/release/3.12.5/whatsnew/changelog.html#python-3-12-5-final de86cdeacd3a8653b9ec36e87975886fafcf6dc2
Diffstat (limited to 'contrib/tools/python3/Modules/_pickle.c')
-rw-r--r--contrib/tools/python3/Modules/_pickle.c62
1 files changed, 42 insertions, 20 deletions
diff --git a/contrib/tools/python3/Modules/_pickle.c b/contrib/tools/python3/Modules/_pickle.c
index 2bf9977f0b..96534a565b 100644
--- a/contrib/tools/python3/Modules/_pickle.c
+++ b/contrib/tools/python3/Modules/_pickle.c
@@ -1876,10 +1876,10 @@ get_dotted_path(PyObject *obj, PyObject *name)
if (_PyUnicode_EqualToASCIIString(subpath, "<locals>")) {
if (obj == NULL)
PyErr_Format(PyExc_AttributeError,
- "Can't pickle local object %R", name);
+ "Can't get local object %R", name);
else
PyErr_Format(PyExc_AttributeError,
- "Can't pickle local attribute %R on %R", name, obj);
+ "Can't get local attribute %R on %R", name, obj);
Py_DECREF(dotted_path);
return NULL;
}
@@ -2566,7 +2566,7 @@ save_picklebuffer(PickleState *st, PicklerObject *self, PyObject *obj)
{
if (self->proto < 5) {
PyErr_SetString(st->PicklingError,
- "PickleBuffer can only pickled with protocol >= 5");
+ "PickleBuffer can only be pickled with protocol >= 5");
return -1;
}
const Py_buffer* view = PyPickleBuffer_GetBuffer(obj);
@@ -3188,6 +3188,7 @@ batch_dict(PickleState *state, PicklerObject *self, PyObject *iter)
if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 2) {
PyErr_SetString(PyExc_TypeError, "dict items "
"iterator must return 2-tuples");
+ Py_DECREF(obj);
return -1;
}
i = save(state, self, PyTuple_GET_ITEM(obj, 0), 0);
@@ -3651,7 +3652,6 @@ save_global(PickleState *st, PicklerObject *self, PyObject *obj,
PyObject *module = NULL;
PyObject *parent = NULL;
PyObject *dotted_path = NULL;
- PyObject *lastname = NULL;
PyObject *cls;
int status = 0;
@@ -3692,10 +3692,7 @@ save_global(PickleState *st, PicklerObject *self, PyObject *obj,
obj, module_name);
goto error;
}
- lastname = Py_NewRef(PyList_GET_ITEM(dotted_path,
- PyList_GET_SIZE(dotted_path) - 1));
cls = get_deep_attribute(module, dotted_path, &parent);
- Py_CLEAR(dotted_path);
if (cls == NULL) {
PyErr_Format(st->PicklingError,
"Can't pickle %R: attribute lookup %S on %S failed",
@@ -3783,7 +3780,10 @@ save_global(PickleState *st, PicklerObject *self, PyObject *obj,
else {
gen_global:
if (parent == module) {
- Py_SETREF(global_name, Py_NewRef(lastname));
+ Py_SETREF(global_name,
+ Py_NewRef(PyList_GET_ITEM(dotted_path,
+ PyList_GET_SIZE(dotted_path) - 1)));
+ Py_CLEAR(dotted_path);
}
if (self->proto >= 4) {
const char stack_global_op = STACK_GLOBAL;
@@ -3796,20 +3796,30 @@ save_global(PickleState *st, PicklerObject *self, PyObject *obj,
if (_Pickler_Write(self, &stack_global_op, 1) < 0)
goto error;
}
- else if (parent != module) {
- PyObject *reduce_value = Py_BuildValue("(O(OO))",
- st->getattr, parent, lastname);
- if (reduce_value == NULL)
- goto error;
- status = save_reduce(st, self, reduce_value, NULL);
- Py_DECREF(reduce_value);
- if (status < 0)
- goto error;
- }
else {
/* Generate a normal global opcode if we are using a pickle
protocol < 4, or if the object is not registered in the
- extension registry. */
+ extension registry.
+
+ Objects with multi-part __qualname__ are represented as
+ getattr(getattr(..., attrname1), attrname2). */
+ const char mark_op = MARK;
+ const char tupletwo_op = (self->proto < 2) ? TUPLE : TUPLE2;
+ const char reduce_op = REDUCE;
+ Py_ssize_t i;
+ if (dotted_path) {
+ if (PyList_GET_SIZE(dotted_path) > 1) {
+ Py_SETREF(global_name, Py_NewRef(PyList_GET_ITEM(dotted_path, 0)));
+ }
+ for (i = 1; i < PyList_GET_SIZE(dotted_path); i++) {
+ if (save(st, self, st->getattr, 0) < 0 ||
+ (self->proto < 2 && _Pickler_Write(self, &mark_op, 1) < 0))
+ {
+ goto error;
+ }
+ }
+ }
+
PyObject *encoded;
PyObject *(*unicode_encoder)(PyObject *);
@@ -3871,6 +3881,17 @@ save_global(PickleState *st, PicklerObject *self, PyObject *obj,
Py_DECREF(encoded);
if (_Pickler_Write(self, "\n", 1) < 0)
goto error;
+
+ if (dotted_path) {
+ for (i = 1; i < PyList_GET_SIZE(dotted_path); i++) {
+ if (save(st, self, PyList_GET_ITEM(dotted_path, i), 0) < 0 ||
+ _Pickler_Write(self, &tupletwo_op, 1) < 0 ||
+ _Pickler_Write(self, &reduce_op, 1) < 0)
+ {
+ goto error;
+ }
+ }
+ }
}
/* Memoize the object. */
if (memo_put(st, self, obj) < 0)
@@ -3886,7 +3907,6 @@ save_global(PickleState *st, PicklerObject *self, PyObject *obj,
Py_XDECREF(module);
Py_XDECREF(parent);
Py_XDECREF(dotted_path);
- Py_XDECREF(lastname);
return status;
}
@@ -6623,11 +6643,13 @@ load_additems(PickleState *state, UnpicklerObject *self)
if (result == NULL) {
Pdata_clear(self->stack, i + 1);
Py_SET_SIZE(self->stack, mark);
+ Py_DECREF(add_func);
return -1;
}
Py_DECREF(result);
}
Py_SET_SIZE(self->stack, mark);
+ Py_DECREF(add_func);
}
return 0;