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:
parent
9454ad7263
commit
a92d16aaec
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue