Skip to content

Commit

Permalink
Restore dubious "optimization".
Browse files Browse the repository at this point in the history
  • Loading branch information
serhiy-storchaka committed Jul 25, 2024
1 parent 8d22183 commit 1c2aa22
Showing 1 changed file with 37 additions and 20 deletions.
57 changes: 37 additions & 20 deletions Modules/_pickle.c
Original file line number Diff line number Diff line change
Expand Up @@ -1829,22 +1829,27 @@ get_dotted_path(PyObject *obj, PyObject *name)
}

static PyObject *
get_deep_attribute(PyObject *obj, PyObject *names)
get_deep_attribute(PyObject *obj, PyObject *names, PyObject **pparent)
{
Py_ssize_t i, n;
PyObject *parent = NULL;

assert(PyList_CheckExact(names));
Py_INCREF(obj);
n = PyList_GET_SIZE(names);
for (i = 0; i < n; i++) {
PyObject *name = PyList_GET_ITEM(names, i);
PyObject *parent = obj;
Py_XSETREF(parent, obj);
(void)PyObject_GetOptionalAttr(parent, name, &obj);
Py_DECREF(parent);
if (obj == NULL) {
Py_DECREF(parent);
return NULL;
}
}
if (pparent != NULL)
*pparent = parent;
else
Py_XDECREF(parent);
return obj;
}

Expand All @@ -1858,7 +1863,7 @@ getattribute(PyObject *obj, PyObject *name, int allow_qualname)
dotted_path = get_dotted_path(obj, name);
if (dotted_path == NULL)
return NULL;
attr = get_deep_attribute(obj, dotted_path);
attr = get_deep_attribute(obj, dotted_path, NULL);
Py_DECREF(dotted_path);
}
else {
Expand All @@ -1883,7 +1888,7 @@ _checkmodule(PyObject *module_name, PyObject *module,
return -1;
}

PyObject *candidate = get_deep_attribute(module, dotted_path);
PyObject *candidate = get_deep_attribute(module, dotted_path, NULL);
if (candidate == NULL) {
return -1;
}
Expand Down Expand Up @@ -3585,6 +3590,7 @@ save_global(PickleState *st, PicklerObject *self, PyObject *obj,
PyObject *global_name = NULL;
PyObject *module_name = NULL;
PyObject *module = NULL;
PyObject *parent = NULL;
PyObject *dotted_path = NULL;
PyObject *cls;
int status = 0;
Expand Down Expand Up @@ -3626,7 +3632,7 @@ save_global(PickleState *st, PicklerObject *self, PyObject *obj,
obj, module_name);
goto error;
}
cls = get_deep_attribute(module, dotted_path);
cls = get_deep_attribute(module, dotted_path, &parent);
if (cls == NULL) {
PyErr_Format(st->PicklingError,
"Can't pickle %R: attribute lookup %S on %S failed",
Expand Down Expand Up @@ -3713,6 +3719,12 @@ save_global(PickleState *st, PicklerObject *self, PyObject *obj,
}
else {
gen_global:
if (parent == module) {
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;

Expand All @@ -3735,14 +3747,16 @@ save_global(PickleState *st, PicklerObject *self, PyObject *obj,
const char tupletwo_op = (self->proto < 2) ? TUPLE : TUPLE2;
const char reduce_op = REDUCE;
Py_ssize_t i;
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;
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;
}
}
}

Expand Down Expand Up @@ -3808,12 +3822,14 @@ save_global(PickleState *st, PicklerObject *self, PyObject *obj,
if (_Pickler_Write(self, "\n", 1) < 0)
goto error;

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;
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;
}
}
}
}
Expand All @@ -3829,6 +3845,7 @@ save_global(PickleState *st, PicklerObject *self, PyObject *obj,
Py_XDECREF(module_name);
Py_XDECREF(global_name);
Py_XDECREF(module);
Py_XDECREF(parent);
Py_XDECREF(dotted_path);

return status;
Expand Down

0 comments on commit 1c2aa22

Please sign in to comment.