From 4c786944e8781093098da3233d3b55cc167b75e7 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Mon, 1 Jun 2009 22:42:14 +0000 Subject: [PATCH] - Fixed another 0.5.4 bug whereby mutable attributes (i.e. PickleType) wouldn't be deserialized correctly when the whole object was serialized. [ticket:1426] --- CHANGES | 4 ++++ lib/sqlalchemy/orm/state.py | 4 +++- test/orm/attributes.py | 6 ++++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 94a0acf88a..f240f2d0b2 100644 --- a/CHANGES +++ b/CHANGES @@ -9,6 +9,10 @@ CHANGES - orm - Fixed bug introduced in 0.5.4 whereby Composite types fail when default-holding columns are flushed. + + - Fixed another 0.5.4 bug whereby mutable attributes (i.e. PickleType) + wouldn't be deserialized correctly when the whole object + was serialized. [ticket:1426] - sql - Removed an obscure feature of execute() (including connection, diff --git a/lib/sqlalchemy/orm/state.py b/lib/sqlalchemy/orm/state.py index 1b73a1bb62..92500758ff 100644 --- a/lib/sqlalchemy/orm/state.py +++ b/lib/sqlalchemy/orm/state.py @@ -130,7 +130,8 @@ class InstanceState(object): 'load_path':interfaces.serialize_path(self.load_path), 'instance': self.obj(), 'expired_attributes':self.expired_attributes, - 'callables': self.callables} + 'callables': self.callables, + 'mutable_dict':self.mutable_dict} def __setstate__(self, state): self.committed_state = state['committed_state'] @@ -148,6 +149,7 @@ class InstanceState(object): self.runid = None self.expired = state['expired'] self.expired_attributes = state['expired_attributes'] + self.mutable_dict = state['mutable_dict'] def initialize(self, key): self.manager.get_impl(key).initialize(self, self.dict) diff --git a/test/orm/attributes.py b/test/orm/attributes.py index 76108a713e..7c116fcf78 100644 --- a/test/orm/attributes.py +++ b/test/orm/attributes.py @@ -51,17 +51,18 @@ class AttributesTest(_base.ORMTest): attributes.register_attribute(MyTest, 'user_id', uselist=False, useobject=False) attributes.register_attribute(MyTest, 'user_name', uselist=False, useobject=False) attributes.register_attribute(MyTest, 'email_address', uselist=False, useobject=False) + attributes.register_attribute(MyTest, 'some_mutable_data', mutable_scalars=True, copy_function=list, compare_function=cmp, uselist=False, useobject=False) attributes.register_attribute(MyTest2, 'a', uselist=False, useobject=False) attributes.register_attribute(MyTest2, 'b', uselist=False, useobject=False) # shouldnt be pickling callables at the class level def somecallable(*args): return None - attr_name = 'mt2' - attributes.register_attribute(MyTest, attr_name, uselist = True, trackparent=True, callable_=somecallable, useobject=True) + attributes.register_attribute(MyTest, "mt2", uselist = True, trackparent=True, callable_=somecallable, useobject=True) o = MyTest() o.mt2.append(MyTest2()) o.user_id=7 + o.some_mutable_data = [1,2,3] o.mt2[0].a = 'abcde' pk_o = pickle.dumps(o) @@ -100,6 +101,7 @@ class AttributesTest(_base.ORMTest): self.assert_(o4.user_id == 7) self.assert_(o4.user_name is None) self.assert_(o4.email_address is None) + self.assert_(o4.some_mutable_data == [1,2,3]) self.assert_(len(o4.mt2) == 1) self.assert_(o4.mt2[0].a == 'abcde') self.assert_(o4.mt2[0].b is None) -- 2.47.2