cpickle.c
来自「python s60 1.4.5版本的源代码」· C语言 代码 · 共 2,601 行 · 第 1/5 页
C
2,601 行
}
if ((getinitargs_func = PyObject_GetAttr(args, __getinitargs___str))) {
PyObject *element = 0;
int i, len;
UNLESS (class_args =
PyObject_Call(getinitargs_func, empty_tuple, NULL))
goto finally;
if ((len = PyObject_Size(class_args)) < 0)
goto finally;
for (i = 0; i < len; i++) {
UNLESS (element = PySequence_GetItem(class_args, i))
goto finally;
if (save(self, element, 0) < 0) {
Py_DECREF(element);
goto finally;
}
Py_DECREF(element);
}
}
else {
PyErr_Clear();
}
if (!self->bin) {
UNLESS (name = ((PyClassObject *)class)->cl_name) {
PyErr_SetString(PicklingError, "class has no name");
goto finally;
}
UNLESS (module = whichmodule(class, name))
goto finally;
if ((module_size = PyString_Size(module)) < 0 ||
(name_size = PyString_Size(name)) < 0)
goto finally;
module_str = PyString_AS_STRING((PyStringObject *)module);
name_str = PyString_AS_STRING((PyStringObject *)name);
if ((*self->write_func)(self, &inst, 1) < 0)
goto finally;
if ((*self->write_func)(self, module_str, module_size) < 0)
goto finally;
if ((*self->write_func)(self, "\n", 1) < 0)
goto finally;
if ((*self->write_func)(self, name_str, name_size) < 0)
goto finally;
if ((*self->write_func)(self, "\n", 1) < 0)
goto finally;
}
else if ((*self->write_func)(self, &obj, 1) < 0) {
goto finally;
}
if ((getstate_func = PyObject_GetAttr(args, __getstate___str))) {
UNLESS (state = PyObject_Call(getstate_func, empty_tuple, NULL))
goto finally;
}
else {
PyErr_Clear();
UNLESS (state = PyObject_GetAttr(args, __dict___str)) {
PyErr_Clear();
res = 0;
goto finally;
}
}
if (!PyDict_Check(state)) {
if (put2(self, args) < 0)
goto finally;
}
else {
if (put(self, args) < 0)
goto finally;
}
if (save(self, state, 0) < 0)
goto finally;
if ((*self->write_func)(self, &build, 1) < 0)
goto finally;
res = 0;
finally:
if (self->fast && !fast_save_leave(self, args))
res = -1;
Py_XDECREF(module);
Py_XDECREF(class);
Py_XDECREF(state);
Py_XDECREF(getinitargs_func);
Py_XDECREF(getstate_func);
Py_XDECREF(class_args);
return res;
}
static int
save_global(Picklerobject *self, PyObject *args, PyObject *name) {
PyObject *global_name = 0, *module = 0, *mod = 0, *klass = 0;
char *name_str, *module_str;
int module_size, name_size, res = -1;
static char global = GLOBAL;
if (name) {
global_name = name;
Py_INCREF(global_name);
}
else {
UNLESS (global_name = PyObject_GetAttr(args, __name___str))
goto finally;
}
UNLESS (module = whichmodule(args, global_name))
goto finally;
if ((module_size = PyString_Size(module)) < 0 ||
(name_size = PyString_Size(global_name)) < 0)
goto finally;
module_str = PyString_AS_STRING((PyStringObject *)module);
name_str = PyString_AS_STRING((PyStringObject *)global_name);
mod = PyImport_ImportModule(module_str);
if (mod == NULL) {
/* Py_ErrClear(); ?? */
cPickle_ErrFormat(PicklingError,
"Can't pickle %s: it's not found as %s.%s",
"OSS", args, module, global_name);
goto finally;
}
klass = PyObject_GetAttrString(mod, name_str);
if (klass == NULL) {
cPickle_ErrFormat(PicklingError,
"Can't pickle %s: it's not found as %s.%s",
"OSS", args, module, global_name);
goto finally;
}
if (klass != args) {
Py_DECREF(klass);
cPickle_ErrFormat(PicklingError,
"Can't pickle %s: it's not the same object as %s.%s",
"OSS", args, module, global_name);
goto finally;
}
Py_DECREF(klass);
if ((*self->write_func)(self, &global, 1) < 0)
goto finally;
if ((*self->write_func)(self, module_str, module_size) < 0)
goto finally;
if ((*self->write_func)(self, "\n", 1) < 0)
goto finally;
if ((*self->write_func)(self, name_str, name_size) < 0)
goto finally;
if ((*self->write_func)(self, "\n", 1) < 0)
goto finally;
if (put(self, args) < 0)
goto finally;
res = 0;
finally:
Py_XDECREF(module);
Py_XDECREF(global_name);
Py_XDECREF(mod);
return res;
}
static int
save_pers(Picklerobject *self, PyObject *args, PyObject *f) {
PyObject *pid = 0;
int size, res = -1;
static char persid = PERSID, binpersid = BINPERSID;
Py_INCREF(args);
ARG_TUP(self, args);
if (self->arg) {
pid = PyObject_Call(f, self->arg, NULL);
FREE_ARG_TUP(self);
}
if (! pid) return -1;
if (pid != Py_None) {
if (!self->bin) {
if (!PyString_Check(pid)) {
PyErr_SetString(PicklingError,
"persistent id must be string");
goto finally;
}
if ((*self->write_func)(self, &persid, 1) < 0)
goto finally;
if ((size = PyString_Size(pid)) < 0)
goto finally;
if ((*self->write_func)(self,
PyString_AS_STRING((PyStringObject *)pid), size) < 0)
goto finally;
if ((*self->write_func)(self, "\n", 1) < 0)
goto finally;
res = 1;
goto finally;
}
else if (save(self, pid, 1) >= 0) {
if ((*self->write_func)(self, &binpersid, 1) < 0)
res = -1;
else
res = 1;
}
goto finally;
}
res = 0;
finally:
Py_XDECREF(pid);
return res;
}
static int
save_reduce(Picklerobject *self, PyObject *callable,
PyObject *tup, PyObject *state, PyObject *ob) {
static char reduce = REDUCE, build = BUILD;
if (save(self, callable, 0) < 0)
return -1;
if (save(self, tup, 0) < 0)
return -1;
if ((*self->write_func)(self, &reduce, 1) < 0)
return -1;
if (ob != NULL) {
if (state && !PyDict_Check(state)) {
if (put2(self, ob) < 0)
return -1;
}
else {
if (put(self, ob) < 0)
return -1;
}
}
if (state) {
if (save(self, state, 0) < 0)
return -1;
if ((*self->write_func)(self, &build, 1) < 0)
return -1;
}
return 0;
}
static int
save(Picklerobject *self, PyObject *args, int pers_save) {
PyTypeObject *type;
PyObject *py_ob_id = 0, *__reduce__ = 0, *t = 0, *arg_tup = 0,
*callable = 0, *state = 0;
int res = -1, tmp, size;
if (self->nesting++ > Py_GetRecursionLimit()){
PyErr_SetString(PyExc_RuntimeError,
"maximum recursion depth exceeded");
goto finally;
}
if (!pers_save && self->pers_func) {
if ((tmp = save_pers(self, args, self->pers_func)) != 0) {
res = tmp;
goto finally;
}
}
if (args == Py_None) {
res = save_none(self, args);
goto finally;
}
type = args->ob_type;
switch (type->tp_name[0]) {
case 'i':
if (type == &PyInt_Type) {
res = save_int(self, args);
goto finally;
}
break;
case 'l':
if (type == &PyLong_Type) {
res = save_long(self, args);
goto finally;
}
break;
case 'f':
if (type == &PyFloat_Type) {
res = save_float(self, args);
goto finally;
}
break;
case 't':
if (type == &PyTuple_Type && PyTuple_Size(args)==0) {
if (self->bin) res = save_empty_tuple(self, args);
else res = save_tuple(self, args);
goto finally;
}
break;
case 's':
if ((type == &PyString_Type) && (PyString_GET_SIZE(args) < 2)) {
res = save_string(self, args, 0);
goto finally;
}
#ifdef Py_USING_UNICODE
case 'u':
if ((type == &PyUnicode_Type) && (PyString_GET_SIZE(args) < 2)) {
res = save_unicode(self, args, 0);
goto finally;
}
#endif
}
if (args->ob_refcnt > 1) {
UNLESS (py_ob_id = PyLong_FromVoidPtr(args))
goto finally;
if (PyDict_GetItem(self->memo, py_ob_id)) {
if (get(self, py_ob_id) < 0)
goto finally;
res = 0;
goto finally;
}
}
switch (type->tp_name[0]) {
case 's':
if (type == &PyString_Type) {
res = save_string(self, args, 1);
goto finally;
}
break;
#ifdef Py_USING_UNICODE
case 'u':
if (type == &PyUnicode_Type) {
res = save_unicode(self, args, 1);
goto finally;
}
break;
#endif
case 't':
if (type == &PyTuple_Type) {
res = save_tuple(self, args);
goto finally;
}
if (type == &PyType_Type) {
res = save_global(self, args, NULL);
goto finally;
}
break;
case 'l':
if (type == &PyList_Type) {
res = save_list(self, args);
goto finally;
}
break;
case 'd':
if (type == &PyDict_Type) {
res = save_dict(self, args);
goto finally;
}
break;
case 'i':
if (type == &PyInstance_Type) {
res = save_inst(self, args);
goto finally;
}
break;
case 'c':
if (type == &PyClass_Type) {
res = save_global(self, args, NULL);
goto finally;
}
break;
case 'f':
if (type == &PyFunction_Type) {
res = save_global(self, args, NULL);
goto finally;
}
break;
case 'b':
if (type == &PyCFunction_Type) {
res = save_global(self, args, NULL);
goto finally;
}
}
if (!pers_save && self->inst_pers_func) {
if ((tmp = save_pers(self, args, self->inst_pers_func)) != 0) {
res = tmp;
goto finally;
}
}
if (PyType_IsSubtype(type, &PyType_Type)) {
res = save_global(self, args, NULL);
goto finally;
}
if ((__reduce__ = PyDict_GetItem(dispatch_table, (PyObject *)type))) {
Py_INCREF(__reduce__);
Py_INCREF(args);
ARG_TUP(self, args);
if (self->arg) {
t = PyObject_Call(__reduce__, self->arg, NULL);
FREE_ARG_TUP(self);
}
if (! t) goto finally;
}
else {
PyErr_Clear();
if ((__reduce__ = PyObject_GetAttr(args, __reduce___str))) {
UNLESS (t = PyObject_Call(__reduce__, empty_tuple, NULL))
goto finally;
}
else {
PyErr_Clear();
}
}
if (t) {
if (PyString_Check(t)) {
res = save_global(self, args, t);
goto finally;
}
if (!PyTuple_Check(t)) {
cPickle_ErrFormat(PicklingError, "Value returned by %s must "
"be a tuple", "O", __reduce__);
goto finally;
}
size = PyTuple_Size(t);
if ((size != 3) && (size != 2)) {
cPickle_ErrFormat(PicklingError, "tuple returned by %s must "
"contain only two or three elements", "O", __reduce__);
goto finally;
}
callable = PyTuple_GET_ITEM(t, 0);
arg_tup = PyTuple_GET_ITEM(t, 1);
if (size > 2) {
state = PyTuple_GET_ITEM(t, 2);
}
UNLESS (PyTuple_Check(arg_tup) || arg_tup==Py_None) {
cPickle_ErrFormat(PicklingError, "Second element of tuple "
"returned by %s must be a tuple", "O", __reduce__);
goto finally;
}
res = save_reduce(self, callable, arg_tup, state, args);
goto finally;
}
PyErr_SetObject(UnpickleableError, args);
finally:
self->nesting--;
Py_XDECREF(py_ob_id);
Py_XDECREF(__reduce__);
Py_XDECREF(t);
return res;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?