<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>Hi David,</div><div><br class="webkit-block-placeholder"></div><div>It looks like you might be assuming that the tests run in the order</div><div>you wrote them. The test_persistence() function actually gets called</div><div>before the test_setstate(), so there is no chance for the color to be 'red'.</div><div><br></div><div>I don't think the failure of this particular test has anything to do with </div><div>your __setstate__() method. When I write __setstate__() methods,</div><div>though, I modify the state dictionary and then call Persistent.__setstate__. </div><div>This avoids triggering the persistent attribute machinery at all.</div><div><br></div><div>David Binger</div><div><br></div><div><div><div>On Jan 16, 2008, at 9:43 PM, Mika, David P (GE, Research) wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"> <div> <!-- Converted from text/rtf format --><p><font size="2" face="Arial">Can someone explain why the test below (test_persistence) is failing? I am adding an attribute after object creation with __setstate__, but I can't get the new attribute to persist.</font></p><p><font size="2" face="Arial">------------------------------------------------</font> <br><font size="2" face="Arial">import transaction</font> <br><font size="2" face="Arial">import unittest</font> <br><font size="2" face="Arial">from persistent import Persistent</font> <br><font size="2" face="Arial">from ZODB import FileStorage, DB</font> </p><p><font size="2" face="Arial">TMP_DB = 'zodb-test-filestorage.fs'</font> </p><p><font size="2" face="Arial">class User(Persistent):</font> <br><font size="2" face="Arial"> def __init__(self):</font> <br><font size="2" face="Arial"> pass</font> <br><font size="2" face="Arial"> def __setstate__(self, state):</font> <br><font size="2" face="Arial"> Persistent.__setstate__(self, state)</font> <br><font size="2" face="Arial"> if not hasattr(self, 'color'):</font> <br><font size="2" face="Arial"> self.color = 'blue'</font> <br><font size="2" face="Arial"> def getColor(self):</font> <br><font size="2" face="Arial"> return self.color</font> <br><font size="2" face="Arial"> def setColor(self, color):</font> <br><font size="2" face="Arial"> self.color = color</font> <br><font size="2" face="Arial"> transaction.commit()</font> </p><p><font size="2" face="Arial">class ZODB_TestCase(unittest.TestCase):</font> <br><font size="2" face="Arial"> def setUp(self):</font> <br><font size="2" face="Arial"> storage = FileStorage.FileStorage(TMP_DB)</font> <br><font size="2" face="Arial"> self.db = DB(storage)</font> <br><font size="2" face="Arial"> conn = self.db.open()</font> <br><font size="2" face="Arial"> dbroot = conn.root()</font> <br><font size="2" face="Arial"> # Ensure that a 'userdb' key is present</font> <br><font size="2" face="Arial"> # in the root</font> <br><font size="2" face="Arial"> if not dbroot.has_key('userdb'):</font> <br><font size="2" face="Arial"> from BTrees.OOBTree import OOBTree</font> <br><font size="2" face="Arial"> dbroot['userdb'] = OOBTree()</font> <br><font size="2" face="Arial"> self.userdb = dbroot['userdb']</font> </p><p><font size="2" face="Arial"> self.id = 'amk'</font> </p><p><font size="2" face="Arial"> def tearDown(self):</font> <br><font size="2" face="Arial"> self.db.close()</font> </p><p><font size="2" face="Arial"> def test_AddUser(self):</font> <br><font size="2" face="Arial"> newuser = User()</font> <br><font size="2" face="Arial"> newuser.first_name = 'Andrew'; newuser.last_name = 'Kuchling'</font> <br><font size="2" face="Arial"> # Add object to the BTree, keyed on the ID</font> <br><font size="2" face="Arial"> self.userdb[self.id] = newuser</font> <br><font size="2" face="Arial"> # Commit the change</font> <br><font size="2" face="Arial"> transaction.commit()</font> </p><p><font size="2" face="Arial"> # setstate is not called after the constructor</font> <br><font size="2" face="Arial"> assert not hasattr(newuser, 'color')</font> </p><p><font size="2" face="Arial"> def test_setstate(self):</font> <br><font size="2" face="Arial"> newuser = self.userdb[self.id]</font> <br><font size="2" face="Arial"> # setstate is called subsequently</font> <br><font size="2" face="Arial"> assert hasattr(newuser, 'color')</font> <br><font size="2" face="Arial"> assert newuser.color == 'blue'</font> <br><font size="2" face="Arial"> newuser.setColor('red')</font> <br><font size="2" face="Arial"> assert newuser.color == 'red' </font> </p><p><font size="2" face="Arial"> def test_persistence(self):</font> <br><font size="2" face="Arial"> newuser = self.userdb[self.id]</font> <br><font size="2" face="Arial"> assert newuser.color == 'red' # this fails! </font> </p><p><font size="2" face="Arial">if __name__ == '__main__':</font> <br><font size="2" face="Arial"> import os</font> <br><font size="2" face="Arial"> if os.path.exists(TMP_DB):</font> <br><font size="2" face="Arial"> os.unlink(TMP_DB)</font> <br><font size="2" face="Arial"> unittest.main()</font> </p><p><font size="2" face="Arial">---------------------------------------------------------------------------------</font> <br><b><font size="2" face="GE Inspira">David Mika, PhD</font></b> <br><font size="2" face="GE Inspira">Material Systems Technologies</font> <br><font size="2" face="GE Inspira">k1-mb 235</font> <br><font size="2" face="GE Inspira">GE Research Center</font> <br><font size="2" face="GE Inspira">Niskayuna, NY 12309</font> <br><font size="2" face="GE Inspira">518 387 4223 (phone)</font> <br><font size="2" face="GE Inspira"><a href="mailto:mika@crd.ge.com">mika@crd.ge.com</a></font> </p> <br> </div> _______________________________________________<br>For more information about ZODB, see the ZODB Wiki:<br><a href="http://www.zope.org/Wikis/ZODB/">http://www.zope.org/Wikis/ZODB/</a><br><br>ZODB-Dev mailing list - ZODB-Dev@zope.org<br>http://mail.zope.org/mailman/listinfo/zodb-dev<br></blockquote></div><br></div></body></html>