Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b289b87

Browse files
committed
Use __reduce_ex__.
1 parent 9c9cf41 commit b289b87

1 file changed

Lines changed: 36 additions & 45 deletions

File tree

Modules/cPickle.c

Lines changed: 36 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -119,14 +119,9 @@ static PyObject *extension_cache;
119119
/* For looking up name pairs in copy_reg._extension_registry. */
120120
static PyObject *two_tuple;
121121

122-
/* object.__reduce__, the default reduce callable. */
123-
static PyObject *object_reduce;
124-
125-
/* copy_reg._better_reduce, the protocol 2 reduction function. */
126-
static PyObject *better_reduce;
127-
128122
static PyObject *__class___str, *__getinitargs___str, *__dict___str,
129123
*__getstate___str, *__setstate___str, *__name___str, *__reduce___str,
124+
*__reduce_ex___str,
130125
*write_str, *append_str,
131126
*read_str, *readline_str, *__main___str, *__basicnew___str,
132127
*copy_reg_str, *dispatch_table_str;
@@ -2505,48 +2500,50 @@ save(Picklerobject *self, PyObject *args, int pers_save)
25052500
goto finally;
25062501
}
25072502

2508-
/* Get a reduction callable. This may come from
2509-
* copy_reg.dispatch_table, the object's __reduce__ method,
2510-
* the default object.__reduce__, or copy_reg._better_reduce.
2503+
/* Get a reduction callable, and call it. This may come from
2504+
* copy_reg.dispatch_table, the object's __reduce_ex__ method,
2505+
* or the object's __reduce__ method.
25112506
*/
25122507
__reduce__ = PyDict_GetItem(dispatch_table, (PyObject *)type);
25132508
if (__reduce__ != NULL) {
25142509
Py_INCREF(__reduce__);
2510+
Py_INCREF(args);
2511+
ARG_TUP(self, args);
2512+
if (self->arg) {
2513+
t = PyObject_Call(__reduce__, self->arg, NULL);
2514+
FREE_ARG_TUP(self);
2515+
}
25152516
}
25162517
else {
2517-
/* Check for a __reduce__ method.
2518-
* Subtle: get the unbound method from the class, so that
2519-
* protocol 2 can override the default __reduce__ that all
2520-
* classes inherit from object.
2521-
* XXX object.__reduce__ should really be rewritten so that
2522-
* XXX we don't need to call back into Python code here
2523-
* XXX (better_reduce), but no time to do that.
2524-
*/
2525-
__reduce__ = PyObject_GetAttr((PyObject *)type,
2526-
__reduce___str);
2527-
if (__reduce__ == NULL) {
2528-
PyErr_Clear();
2529-
PyErr_SetObject(UnpickleableError, args);
2530-
goto finally;
2518+
/* Check for a __reduce_ex__ method. */
2519+
__reduce__ = PyObject_GetAttr(args, __reduce_ex___str);
2520+
if (__reduce__ != NULL) {
2521+
t = PyInt_FromLong(self->proto);
2522+
if (t != NULL) {
2523+
ARG_TUP(self, t);
2524+
t = NULL;
2525+
if (self->arg) {
2526+
t = PyObject_Call(__reduce__,
2527+
self->arg, NULL);
2528+
FREE_ARG_TUP(self);
2529+
}
2530+
}
25312531
}
2532-
2533-
if (self->proto >= 2 && __reduce__ == object_reduce) {
2534-
/* Proto 2 can do better than the default. */
2535-
Py_DECREF(__reduce__);
2536-
Py_INCREF(better_reduce);
2537-
__reduce__ = better_reduce;
2532+
else {
2533+
PyErr_Clear();
2534+
/* Check for a __reduce__ method. */
2535+
__reduce__ = PyObject_GetAttr(args, __reduce___str);
2536+
if (__reduce__ != NULL) {
2537+
t = PyObject_Call(__reduce__,
2538+
empty_tuple, NULL);
2539+
}
2540+
else {
2541+
PyErr_SetObject(UnpickleableError, args);
2542+
goto finally;
2543+
}
25382544
}
25392545
}
25402546

2541-
/* Call the reduction callable, setting t to the result. */
2542-
assert(__reduce__ != NULL);
2543-
assert(t == NULL);
2544-
Py_INCREF(args);
2545-
ARG_TUP(self, args);
2546-
if (self->arg) {
2547-
t = PyObject_Call(__reduce__, self->arg, NULL);
2548-
FREE_ARG_TUP(self);
2549-
}
25502547
if (t == NULL)
25512548
goto finally;
25522549

@@ -5590,6 +5587,7 @@ init_stuff(PyObject *module_dict)
55905587
INIT_STR(__name__);
55915588
INIT_STR(__main__);
55925589
INIT_STR(__reduce__);
5590+
INIT_STR(__reduce_ex__);
55935591
INIT_STR(write);
55945592
INIT_STR(append);
55955593
INIT_STR(read);
@@ -5618,15 +5616,8 @@ init_stuff(PyObject *module_dict)
56185616
"_extension_cache");
56195617
if (!extension_cache) return -1;
56205618

5621-
better_reduce = PyObject_GetAttrString(copy_reg, "_better_reduce");
5622-
if (!better_reduce) return -1;
5623-
56245619
Py_DECREF(copy_reg);
56255620

5626-
object_reduce = PyObject_GetAttrString((PyObject *)&PyBaseObject_Type,
5627-
"__reduce__");
5628-
if (object_reduce == NULL) return -1;
5629-
56305621
if (!(empty_tuple = PyTuple_New(0)))
56315622
return -1;
56325623

0 commit comments

Comments
 (0)