A pickle framework that supports unpickling of refactored versions of
old classes. Part of the AppTools project of the Enthought Tool Suite.
Beyond refactoring support, there are additional useful capabilities of
this package:
- HasTraits objects are fully pickled when sweet_pickle.dump() or
sweet_pickle.dumps() are called. This means every trait's value
is pickled explicitly. This allows improved self-consistency as
values within unpickled objects correspond to the default trait
values of the instance that was pickled rather than the default
values of the current class definition.
- Multiple updaters can be registered to update state for any version
of a class. This is extremely useful when an instance being
pickled and unpickled is the result of an addition of one or more
Trait Categories to a class. In that case, the Category contributor
can also register a state function to update the Category's traits
through versioning.
We have duplicated the API of the Python 'pickle' module within this
package. Thus, users can simply import sweet_pickle in places where
they previously used pickle or cPickle. For example:
import cPickle ---> import enthought.sweet_pickle as pickle
s = pickle.dumps(obj) s = pickle.dumps(obj)
pickle.loads(s) pickle.loads(s)
Pickles generated by this package can be unpickled by standard pickle
or cPickle, though you lose the benefit of the refactoring support during
unpickling.
As a result of the above, this package is a drop-in replacement for the
Python 'pickle' module or 'cPickle' module and should be safe to use even
if you never version or refactor your own classes. In fact, we STRONGLY
RECOMMEND that you use this framework for all of your pickle needs because
you never know when one of the classes you encounter during unpickling has
been versioned or otherwise refactored by someone else.
See module 'pickle' for more basic information about pickling.
The most common way to benefit from the versioning capabilities of this
framework is to register class mappings and state modification functions
with the global updater registry (more detail is below.) However, you may
also choose to explicitly instantiate an Unpickler and provide it with your
own explicit definition of class mappings and state modification functions.
We do not provide any help on the latter at this time.
You can register class mappings and state modification functions with the
global updater registry using the methods provided on the Updater instance
that is the global registry. You can get this instance by calling the
'get_global_registry' function exposed through this package's namespace.
This framework has been designed so that you can register your class
mappings and state modification functions during the import of the module
or package that contained the original class. However, you may also
register your mappings and functions at any point such that the they are
known to the framework prior to, or become known during the attempt to,
unpickle the class they modify.
The framework will call a __setstate__ method on the final target class
of any unpickled instance. It will not call __setstate__ methods on any
beginning or intermediate classes within a chain of class mappings.
A class mapping is used to redirect the unpickling of one class to return
an instantiation of another class. The classes can be in different
modules, and the modules in different packages. Mappings can be chained.
For example, given the mappings:
foo.bar.Bar --> foo.baz.Baz
foo.baz.Baz --> foo.Foo
An attempt to unpickle a foo.bar.Bar would actually generate a foo.Foo
instance.
A state modification function is called during the execution of the
__setstate__ method during unpickling of an object of the type and version
for which it was registered for. The function must accept a single
argument which is a state dictionary and must then return the modified
state dictionary. Additionally, the function should change the version
variable within the state to represent the version the new state
represents. (The framework will assume an increment of one if this is
not done.) The framework ensures that state modification functions
are chained appropriately to convert through multiple versions and/or class
mappings.
Note that refactorings that cause classes to be completed removed from
the source code can be supported, without breaking unpickling of object
hierarchies that include an instace of that class, by adding a mapping
to the Placeholder class in the placeholder module.
© Copyright 2002-2009 Enthought, Inc.