<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
<META NAME="Generator" CONTENT="MS Exchange Server version 6.5.7653.2">
<TITLE>Why does this useage of __setstate__ fail?</TITLE>
</HEAD>
<BODY>
<!-- 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">mika@crd.ge.com</FONT>
</P>
<BR>
</BODY>
</HTML>