SF patch #452239 by Gordon McMillan, to fix SF bug #451547.

This patch attempts to do to cPickle what Guido did
   for pickle.py v 1.50. That is: save_global tries
   importing the module, and fetching the name from the
   module. If that fails, or the returned object is not
   the same one we started with, it raises a
   PicklingError. (All this so pickling a lambda will
   fail at save time, rather than load time).
This commit is contained in:
Guido van Rossum 2001-08-18 21:22:07 +00:00
parent 9454ad7263
commit a92d16aaec
1 changed files with 25 additions and 1 deletions

View File

@ -1623,7 +1623,7 @@ finally:
static int static int
save_global(Picklerobject *self, PyObject *args, PyObject *name) { save_global(Picklerobject *self, PyObject *args, PyObject *name) {
PyObject *global_name = 0, *module = 0; PyObject *global_name = 0, *module = 0, *mod = 0, *moddict = 0, *klass = 0;
char *name_str, *module_str; char *name_str, *module_str;
int module_size, name_size, res = -1; int module_size, name_size, res = -1;
@ -1648,6 +1648,29 @@ save_global(Picklerobject *self, PyObject *args, PyObject *name) {
module_str = PyString_AS_STRING((PyStringObject *)module); module_str = PyString_AS_STRING((PyStringObject *)module);
name_str = PyString_AS_STRING((PyStringObject *)global_name); 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;
}
moddict = PyModule_GetDict(mod); /* borrowed ref */
klass = PyDict_GetItemString(moddict, name_str); /* borrowed ref */
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) {
cPickle_ErrFormat(PicklingError,
"Can't pickle %s: it's not the same object as %s.%s",
"OSS", args, module, global_name);
goto finally;
}
if ((*self->write_func)(self, &global, 1) < 0) if ((*self->write_func)(self, &global, 1) < 0)
goto finally; goto finally;
@ -1671,6 +1694,7 @@ save_global(Picklerobject *self, PyObject *args, PyObject *name) {
finally: finally:
Py_XDECREF(module); Py_XDECREF(module);
Py_XDECREF(global_name); Py_XDECREF(global_name);
Py_XDECREF(mod);
return res; return res;
} }