Jeffrey Barish wrote: > I have a class derived from string that is used in a pickle. In the new > version of my program, I moved the module containing the definition of the > class. Now the unpickle fails because it doesn't find the module. I was > thinking that I could make the unpickle work by putting a copy of the > module in the original location and then redefine the class by sticking a > __setstate__ in the class thusly: > > def __setstate__(self, state): > self.__dict__.update(state) > self.__class__ = NewClassName > > My plan was to specify the new location of the module in NewClassName. > However, when I do this I get the message "'class' object layout differs > from 'class'". I don't think that they do as the new module is a copy of > the old one. I suspect that I am not allowed to make the class assignment > because my class is derived from string. What is the best way to update > the pickle? The only thought I have is to read all the data with the old > class module, store the data in some nonpickle format, and then, with > another program, read the nonpickle-format file and rewrite the pickle > with the class module in the new location.
You could overwrite Unpickler.find_class(): import pickle from cStringIO import StringIO class AliasUnpickler(pickle.Unpickler): def __init__(self, aliases, *args, **kw): pickle.Unpickler.__init__(self, *args, **kw) self.aliases = aliases def find_class(self, module, name): module, name = self.aliases.get((module, name), (module, name)) return pickle.Unpickler.find_class(self, module, name) def loads(aliases, str): file = StringIO(str) return AliasUnpickler(aliases, file).load() if __name__ == "__main__": import before, after data = before.A() print data.__class__, data dump = pickle.dumps(data) data = loads({("before", "A"): ("after", "B")}, dump) print data.__class__, data In the example the aliases dictionary maps (module, classname) pairs to (module, classname) pairs. Of course this only works when the class layout wasn't changed. Peter -- http://mail.python.org/mailman/listinfo/python-list