summaryrefslogtreecommitdiffstats
path: root/Modules/_pickle.c
diff options
context:
space:
mode:
authorAlexander Belopolsky <alexander.belopolsky@gmail.com>2010-07-17 22:50:45 (GMT)
committerAlexander Belopolsky <alexander.belopolsky@gmail.com>2010-07-17 22:50:45 (GMT)
commitd92f04062a8cb3c01ac44f67f7bde8a11b285457 (patch)
tree2259b2ace42de43b616f624a07de20dd2d2dbf6c /Modules/_pickle.c
parentbbda0c5fbc757a2751263720dc6a255f517e5261 (diff)
downloadcpython-d92f04062a8cb3c01ac44f67f7bde8a11b285457.zip
cpython-d92f04062a8cb3c01ac44f67f7bde8a11b285457.tar.gz
cpython-d92f04062a8cb3c01ac44f67f7bde8a11b285457.tar.bz2
Issue #5180: Fixed a bug that prevented loading 2.x pickles in 3.x
python when they contain instances of old-style classes.
Diffstat (limited to 'Modules/_pickle.c')
-rw-r--r--Modules/_pickle.c38
1 files changed, 14 insertions, 24 deletions
diff --git a/Modules/_pickle.c b/Modules/_pickle.c
index 0e1c2cd..96f194e 100644
--- a/Modules/_pickle.c
+++ b/Modules/_pickle.c
@@ -3466,29 +3466,19 @@ load_dict(UnpicklerObject *self)
static PyObject *
instantiate(PyObject *cls, PyObject *args)
{
- PyObject *r = NULL;
-
- /* XXX: The pickle.py module does not create instances this way when the
- args tuple is empty. See Unpickler._instantiate(). */
- if ((r = PyObject_CallObject(cls, args)))
- return r;
-
- /* XXX: Is this still nescessary? */
- {
- PyObject *tp, *v, *tb, *tmp_value;
-
- PyErr_Fetch(&tp, &v, &tb);
- tmp_value = v;
- /* NULL occurs when there was a KeyboardInterrupt */
- if (tmp_value == NULL)
- tmp_value = Py_None;
- if ((r = PyTuple_Pack(3, tmp_value, cls, args))) {
- Py_XDECREF(v);
- v = r;
- }
- PyErr_Restore(tp, v, tb);
+ PyObject *result = NULL;
+ /* Caller must assure args are a tuple. Normally, args come from
+ Pdata_poptuple which packs objects from the top of the stack
+ into a newly created tuple. */
+ assert(PyTuple_Check(args));
+ if (Py_SIZE(args) > 0 || !PyType_Check(cls) ||
+ PyObject_HasAttrString(cls, "__getinitargs__")) {
+ result = PyObject_CallObject(cls, args);
}
- return NULL;
+ else {
+ result = PyObject_CallMethod(cls, "__new__", "O", cls);
+ }
+ return result;
}
static int
@@ -3547,7 +3537,7 @@ load_inst(UnpicklerObject *self)
if (len < 2)
return bad_readline();
class_name = PyUnicode_DecodeASCII(s, len - 1, "strict");
- if (class_name == NULL) {
+ if (class_name != NULL) {
cls = find_class(self, module_name, class_name);
Py_DECREF(class_name);
}
@@ -4276,7 +4266,7 @@ load_reduce(UnpicklerObject *self)
return -1;
PDATA_POP(self->stack, callable);
if (callable) {
- obj = instantiate(callable, argtup);
+ obj = PyObject_CallObject(callable, argtup);
Py_DECREF(callable);
}
Py_DECREF(argtup);