Kaydet (Commit) b289b87a authored tarafından Guido van Rossum's avatar Guido van Rossum

Use __reduce_ex__.

üst 9c9cf41a
...@@ -119,14 +119,9 @@ static PyObject *extension_cache; ...@@ -119,14 +119,9 @@ static PyObject *extension_cache;
/* For looking up name pairs in copy_reg._extension_registry. */ /* For looking up name pairs in copy_reg._extension_registry. */
static PyObject *two_tuple; static PyObject *two_tuple;
/* object.__reduce__, the default reduce callable. */
static PyObject *object_reduce;
/* copy_reg._better_reduce, the protocol 2 reduction function. */
static PyObject *better_reduce;
static PyObject *__class___str, *__getinitargs___str, *__dict___str, static PyObject *__class___str, *__getinitargs___str, *__dict___str,
*__getstate___str, *__setstate___str, *__name___str, *__reduce___str, *__getstate___str, *__setstate___str, *__name___str, *__reduce___str,
*__reduce_ex___str,
*write_str, *append_str, *write_str, *append_str,
*read_str, *readline_str, *__main___str, *__basicnew___str, *read_str, *readline_str, *__main___str, *__basicnew___str,
*copy_reg_str, *dispatch_table_str; *copy_reg_str, *dispatch_table_str;
...@@ -2505,48 +2500,50 @@ save(Picklerobject *self, PyObject *args, int pers_save) ...@@ -2505,48 +2500,50 @@ save(Picklerobject *self, PyObject *args, int pers_save)
goto finally; goto finally;
} }
/* Get a reduction callable. This may come from /* Get a reduction callable, and call it. This may come from
* copy_reg.dispatch_table, the object's __reduce__ method, * copy_reg.dispatch_table, the object's __reduce_ex__ method,
* the default object.__reduce__, or copy_reg._better_reduce. * or the object's __reduce__ method.
*/ */
__reduce__ = PyDict_GetItem(dispatch_table, (PyObject *)type); __reduce__ = PyDict_GetItem(dispatch_table, (PyObject *)type);
if (__reduce__ != NULL) { if (__reduce__ != NULL) {
Py_INCREF(__reduce__); Py_INCREF(__reduce__);
Py_INCREF(args);
ARG_TUP(self, args);
if (self->arg) {
t = PyObject_Call(__reduce__, self->arg, NULL);
FREE_ARG_TUP(self);
}
} }
else { else {
/* Check for a __reduce__ method. /* Check for a __reduce_ex__ method. */
* Subtle: get the unbound method from the class, so that __reduce__ = PyObject_GetAttr(args, __reduce_ex___str);
* protocol 2 can override the default __reduce__ that all if (__reduce__ != NULL) {
* classes inherit from object. t = PyInt_FromLong(self->proto);
* XXX object.__reduce__ should really be rewritten so that if (t != NULL) {
* XXX we don't need to call back into Python code here ARG_TUP(self, t);
* XXX (better_reduce), but no time to do that. t = NULL;
*/ if (self->arg) {
__reduce__ = PyObject_GetAttr((PyObject *)type, t = PyObject_Call(__reduce__,
__reduce___str); self->arg, NULL);
if (__reduce__ == NULL) { FREE_ARG_TUP(self);
PyErr_Clear(); }
PyErr_SetObject(UnpickleableError, args); }
goto finally;
} }
else {
if (self->proto >= 2 && __reduce__ == object_reduce) { PyErr_Clear();
/* Proto 2 can do better than the default. */ /* Check for a __reduce__ method. */
Py_DECREF(__reduce__); __reduce__ = PyObject_GetAttr(args, __reduce___str);
Py_INCREF(better_reduce); if (__reduce__ != NULL) {
__reduce__ = better_reduce; t = PyObject_Call(__reduce__,
empty_tuple, NULL);
}
else {
PyErr_SetObject(UnpickleableError, args);
goto finally;
}
} }
} }
/* Call the reduction callable, setting t to the result. */
assert(__reduce__ != NULL);
assert(t == NULL);
Py_INCREF(args);
ARG_TUP(self, args);
if (self->arg) {
t = PyObject_Call(__reduce__, self->arg, NULL);
FREE_ARG_TUP(self);
}
if (t == NULL) if (t == NULL)
goto finally; goto finally;
...@@ -5590,6 +5587,7 @@ init_stuff(PyObject *module_dict) ...@@ -5590,6 +5587,7 @@ init_stuff(PyObject *module_dict)
INIT_STR(__name__); INIT_STR(__name__);
INIT_STR(__main__); INIT_STR(__main__);
INIT_STR(__reduce__); INIT_STR(__reduce__);
INIT_STR(__reduce_ex__);
INIT_STR(write); INIT_STR(write);
INIT_STR(append); INIT_STR(append);
INIT_STR(read); INIT_STR(read);
...@@ -5618,15 +5616,8 @@ init_stuff(PyObject *module_dict) ...@@ -5618,15 +5616,8 @@ init_stuff(PyObject *module_dict)
"_extension_cache"); "_extension_cache");
if (!extension_cache) return -1; if (!extension_cache) return -1;
better_reduce = PyObject_GetAttrString(copy_reg, "_better_reduce");
if (!better_reduce) return -1;
Py_DECREF(copy_reg); Py_DECREF(copy_reg);
object_reduce = PyObject_GetAttrString((PyObject *)&PyBaseObject_Type,
"__reduce__");
if (object_reduce == NULL) return -1;
if (!(empty_tuple = PyTuple_New(0))) if (!(empty_tuple = PyTuple_New(0)))
return -1; return -1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment