I've taken over somebody's code for a fairly large project. I'm trying to save program state, and there's one massive object which stores pretty much all the other objects. I'm trying to pickle this object, but I get this error:
pickle.PicklingError: Can't pickle : it's not found as builtin.module
From what I can find on google, this is because somewhere I'm importing something outside of python init, or that a class attribute is referencing a module. So, I've got a two questions:
Can anybody confirm that that's why this error is being given? Am I looking for the right things in my code?
Is there a way to find what line of code/object member is causing the difficulties in pickle? The traceback only gives the line in pickle where the error occurs, not the line of the object being pickled.
Something like this exists in
dill
. Let's look at a list of objects, and see what we can do:Ok,
dill
fails to pickle the list. So what's the problem?Ok, the first item in the list fails to pickle. What about the rest?
Hm. The other objects pickle just fine. So, let's replace the first object.
Now our object pickles. Well, we could be taking advantage of some built-in object sharing that happens for pickling on linux/unix/mac… so what about a stronger check, like actually pickling across a sub-process (like happens on windows)?
Nope, the list still works… so this is an object that could be sent to another process successfully.
Now, with regard to your error, which everyone seemed to ignore…
The
ModuleType
object is not pickleable, and that's causing your error.However, if we import
dill
, it magically works.As a quick-and-dirty way to find what attribute/member of the object is causing the problem, you could try:
1) There's a slight difference from what you've found. This is a problem caused by some variable (class attribute, list or dict item, it could be anything) that is referencing the module type (not a module directly). This code should reproduce the issue:
2) You can subclass pickle.Pickler and monkey-patch it to show a log of what it's pickling. This should make it easier to trace where the problem is.
This will only work with the Python implementation of pickle.Pickler. In Python 3.x, the pickle module uses the C implementation by default, the pure-Python version of Pickler is called _Pickler.