Welcome, guest | Sign In | My Account | Store | Cart
import pickle

class Upgradable:
    class_version = '3.0'
    def __init__(self):
        self.version = self.__class__.class_version
        self.new_attr = 42

    def pickle(self):
        return pickle.dumps(self)

    def new_method(self):
        '''
        Return the answer to life the universe and everything.
        Would normally break pickles prior to the introduction of new_attr.
        '''
        return self.new_attr
    
    @staticmethod
    def unpickle(data):
        out = pickle.loads(data)
        if not hasattr(out, 'version'):
            out.version = '0.0'
        if out.version != out.class_version:
            out.upgrade()
        return out
    
    def upgrade(self):
        version = float(self.version)
        print 'upgrade from version %s' % self.version
        if version < 1.:
            self.version = '1.0'
            print 'upgrade to version 1.0'
        if version < 2.:
            self.version = '2.0'
            print 'upgrade to version 2.0'
        if version < 3.:
            self.version = '3.0'
            self.new_attr = 42 
            print 'upgrade to version 3.0'
            
def __test__():
    ug0 = Upgradable()
    # downgrade to lower version
    del ug0.version
    del ug0.new_attr

    try:
        # breaks old pickles!
        ug0.new_method()
        raise Exception('Should have raised AttributeError!')
    except AttributeError:
        pass

    # check to see if automatic upgrade works
    ug3 = ug0.unpickle(ug0.pickle())
    assert ug3.version == '3.0'
    assert ug3.new_attr == 42
    assert ug3.new_method() == 42

__test__()

History

  • revision 5 (16 years ago)
  • previous revisions are not available