python pickle, __getstate__, setstate__ problem
ed_tsang at yahoo.com
ed_tsang at yahoo.com
Mon Apr 23 16:54:08 EDT 2001
I have a problem about my script in initializeing the class attribtes
and, pickle them and load them back again in the next invokation.
Here is some backgrond:
The script that I wrote is for drawing the primitives, received from
and sent to the Implementation under test. The reason I am using
pickle is to store the state of the Gui, like all the data user
entered to the script, so that when the scirpt got invoked again, the
ser do not need to reenter te again. All the states are stores as
class attributes in class GuiState.
To remember the last known state of Gui. Class Gui either load the
the last known instance of GuiState State through using python pickle
or create a new instance when that failed or the first time the
script is invoked. When the suer click on quit, that will invoke the
quit function of class Gui. Class Gui will then update all the class
GuiState attributes through calling the updateAttribute of class
GuiState. Then store the object as persistence objects through
calling pickle.dump.
But I ran into two problems:
1. whenever some of the states are not given values (e.g. user no
selecting a input file or output file) the whole script hangs on
quit. I traced that to inside the function of updateAttribute of
Class Gui State when it try to append the elements of inputFileList
to self.inputFileList, it will have an infinite loop!!! That is why I
comment those lines out. But without actually copying the contents, I
doubt the Class GuiState will get the values of the attributes, as I
suspect what I am doing in the code that I sent you just copy the
reference which will be destroyed afer the porcess exists ....
I print out the list of inputFileList & outputFileList:
inputFile List ['/la02/qa/etsang1/ts/9005016/modules/gui/1']
outputFileList [<Tkinter.StringVar instance at 124960>]
outputFileList has nothing in it as no outputFile has been
selected. .....
Thatlets me suspect if the way I initialise the two list simply but
assigning [] to them in the init mehtod of Class GuiState is correct
or not ... signed ....
2. when some of the attributes are not set during the last invokation
of script, even though they are initiliazed. There seems to have
problem in loading them back in through pickle. Instead of getting
attributes that contain the initilized values, an istance is returned
cauaing error!! Sample error message when when user does not set
self.type as below, even though they have been set as zero before:
Exception in Tkinter callback
Traceback (innermost last):
File "/sd/ps/alexma/proj/ntharn/lib/python1.5/lib-tk/Tkinter.py",
line 764, in __call__
File "msggen.py", line 284, in buildMSC
value = self.type.get()
File "/sd/ps/alexma/proj/ntharn/lib/python1.5/lib-tk/Tkinter.py",
line 119, in get
ValueError: invalid literal for int(): PY_VAR5
start shelf attributes
end self inputName and outputName
['/la02/qa/etsang1/ts/9005016/modules/gui/1'] [<Tkinter.StringVar
instance at 124960>]
end shelf all attributes
[1] + Terminated python msggen.py
Acutally I suspect the attributes have been shelved at all .... as
when the program loads and try to get the values, it found an
istance!! as shown in above error message!!
Can someone kindly have a look at the the way I shelf, relaod the
attributes?? Or are they due to another problem. I know thisis a long
posting .. but not many people seems to know pickle nor python on my
end to provide assitance.
Thanks
Below is the code: the new stuff is marked by ####
from Tkinter import *
from tkFileDialog import *
from Dialog import Dialog
import re
import string
import time
import os
import stat
import math
# to preserve class instance attributes
import pickle
def makeMenu(gui):
# make menu button : "File"
File_button = Menubutton(gui.menuframe, text='File', underline=0)
File_button.grid(row=0, column=0, sticky=W)
tempText = Text()
color = tempText.cget('background')
Dummy_button = Menubutton(gui.menuframe, width=63,
activebackground=color, highlightcolor='Blue',text='', underline=0)
Dummy_button.grid(row=0, column=1, sticky=W)
Dummy_button.menu = Menu(Dummy_button)
File_button.menu = Menu(File_button)
File_button.menu.add_command(label='Open Test Log ...',
underline=0,
command=gui.openfile)
File_button.menu.add_command(label='Save Message Sequence
Chart...', underline=0,
command=gui.save)
File_button.menu.add('separator')
File_button.menu.add_command(label='Quit', underline=0,
command=gui.quit)
File_button['menu'] = File_button.menu
gui.menuframe.tk_menuBar(File_button, Dummy_button)
def getTabs(line):
num=0
for char in line:
if (char != '\t'):
break
num=num+1
return(num)
######################################################333
# customer object to hold the state of class Gui
class GuiState:
def __init__(self):
self.inputName = StringVar()
self.outputName = StringVar()
self.inputName.set("")
self.outputName.set("")
self.inputFileList = []
self.outputFileList = []
self.stackname = StringVar()
self.stackname.set("")
self.name = StringVar()
self.iut = StringVar()
self.name.set("")
self.iut.set("")
# define all buttons
self.type = IntVar()
self.type.set(0)
# return data representaton for pickled object
def __getstate__(self):
oldDict = self.__dict__ # get attribute dictionary
del oldDict['inputName']
del oldDict['outputName']
del oldDict['inputFileList']
del oldDict['outputFileList']
del oldDict['stackname']
del oldDict['name']
del oldDict['iut']
del oldDict['type']
return oldDict
# restore object state from data representation generated by
_getstate__
def __setstate__(self,dict):
self.inputName = open(dict['inputName'])
self.outputName = open(dict['outputName'])
self.inputFileList = open(dict['inputFileList'])
self.outputFileList = open(dict['outputFileList'])
self.stackname = open(dict['stackname'])
self.name = open(dict['name'])
self.iut = open(dict['iut'])
self.type = open(dict['type'])
def updateAttribute
(self,inputName,outputName,stackname,name,iut,type,inputFileList,outpu
tFileList):
print "start shelf attributes"
self.inputName.set(inputName)
self.outputName.set(outputName)
print "end self inputName and outputName"
print inputFileList, outputFileList
#if inputFileList != []:
# print "shelf nonempty inputFileList"
# map(self.inputFileList.append,inputFileList)
# print "end shelf inputFileList"
#else:
# print "self empty inputFileList"
# self.inputFileList = []
#if outputFileList != []:
# print "self nonempty outputFileList"
# map(self.outputFileList.append,outputFileList)
# print "end self outputlist"
#else:
# self.outputFileList = []
self.inputFileList = inputFileList
self.outputFileList = outputFileList
self.stackname.set(stackname)
self.name.set(name)
self.iut.set(iut)
self.type.set(type)
print "end shelf all attributes"
return
###################### END NEW#############################
class Gui:
def __init__(self, master, img):
self.master = master;
# define each frame
# main frame is at the very top
# button frame is the command button frame
# list frame is used for all of the list boxes
# quit frame is used for the quit button
self.headerframe = Frame(self.master, width = 80)
self.headerframe.grid(row=0, column=0, sticky='W')
self.menuframe = Frame(self.headerframe, relief=RAISED,
borderwidth=2, width = 80)
self.menuframe.grid(row=0, column=0, sticky='W')
makeMenu(self)
self.logoframe = Frame(self.headerframe, width = 80)
self.logoframe.grid(row=0, column=0, sticky='E')
# column affects locaton of logo
self.buttonframe = Frame(self.master, width = 80)
self.buttonframe.grid(row=1, column=0, sticky='W')
self.octetframe = Frame(self.master, width = 80)
self.octetframe.grid(row=2, column=0, sticky='W')
self.octetframe2 = Frame(self.master, width = 5)
self.octetframe2.grid(row=80, column=0, sticky='W')
self.listFrame = Frame(self.master, width = 80)
self.groupsList = Frame(self.listFrame, width = 50)
self.groupsList.grid(row=0, column=0, sticky=N)
# intialize Gui state class
try:
# depersist and display an object
self.stateObj = pickle.load(open("msc.dat","rb"))
except:
########################## NEW START #######################
# invoke the first time
self.stateObj = GuiState()
self.inputName = StringVar()
self.outputName = StringVar()
self.inputName.set(self.stateObj.inputName)
self.outputName.set(self.stateObj.outputName)
self.inputFileList = self.stateObj.inputFileList
self.outputFileList = self.stateObj.outputFileList
self.stackname = StringVar()
self.stackname.set(self.stateObj.stackname)
self.name = StringVar()
self.iut = StringVar()
self.name.set(self.stateObj.name)
self.iut.set(self.stateObj.iut)
# define all buttons
self.type = IntVar()
self.type.set(self.stateObj.type)
########################## NEW END #######################
self.counter = IntVar()
self.ie = Checkbutton(self.buttonframe,
text="Build ALL ",
variable=self.type, onvalue = 1, offvalue =0)
self.ie.pack()
self.ie.grid(row=0, column=1, pady=10, sticky=W)
self.build = Button(self.buttonframe,
text="Build", command=self.buildMSC)
self.build.grid(row=0, column=3)
self.clear = Button(self.buttonframe,
text="Clear", command=self.clear)
self.clear.grid(row=0, column=4)
# define all labels
Label(self.logoframe, image=img).grid(row=0,column=4,sticky=E)
# define all listboxes
self.pdudfn = Text(self.octetframe,
font='*-Courier-Bold-R-Normal-*-120-*',
height=20,
width=80)
self.pdudfn.grid(row=0, column=0, sticky=W)
self.pdudfn.tag_config('HIGHLIGHT', background="White")
self.pdubuild = Text(self.octetframe2,
font='*-Courier-Bold-R-Normal-*-120-*',
height=5,
width=80)
self.pdubuild.grid(row=0, column=0, sticky=W)
self.pdubuild.tag_config('HIGHLIGHT', background="White")
# define all scrollbars
self.pdudfn.scrollY = Scrollbar(self.octetframe,
orient=VERTICAL)
self.pdudfn['yscrollcommand'] = self.pdudfn.scrollY.set
self.pdudfn.scrollY['command'] = self.pdudfn.yview
self.pdudfn.scrollY.grid(row=0, column=1,sticky='NS')
self.pdubuild.scrollY = Scrollbar(self.octetframe2,
orient=VERTICAL)
self.pdubuild['yscrollcommand'] = self.pdubuild.scrollY.set
self.pdubuild.scrollY['command'] = self.pdubuild.yview
self.pdubuild.scrollY.grid(row=0, column=1,sticky='NS')
def buildMSC(self):
value = self.type.get()
if value == 1:
self.buildAllMsc()
self.saveArrows()
def clear(self):
self.pdubuild['state']=NORMAL
self.pdubuild.delete("0.0", END)
self.pdudfn.delete("0.0", END)
self.pdubuild['state']=DISABLED
filename = self.outputName.get()
try:
self.fd = open(filename,"w")
except IOError:
Dialog(self.master,
text="Cannot open file to clear.",
title="Error",
bitmap='error',
default=0,
strings=('OK',))
return
self.fd.close()
def save(self, event=None):
defaultfile = self.inputName.get()
if self.type.get() == 1:
Dialog(self.master,
text="Application is under auto mode.
File names are self generated.",
title="Error",
bitmap='error',
default=0,
strings=('OK',))
return
outputName = asksaveasfilename(defaultextension=".arr",
filetypes=["{Message Sequence Chart} {.arr}"],
initialfile="%s.arr"%defaultfile )
self.outputName.set(outputName)
try:
self.fd=open(outputName,"w");
self.fd.close();
except IOError:
Dialog(self.master,
text="Cannot open file to save.",
title="Error",
bitmap='error',
default=0,
strings=('OK',))
except:
pass
def buildFileList(self,arg,dirname,files):
inputfile = self.inputName.get()
if inputfile == "":
return
inputfile = os.path.basename(inputfile)
for file in files:
if re.search(inputfile,file):
fullpath= os.path.join(dirname, file)
if fullpath[-4:] == '.arr':
pass
else:
self.inputFileList.append(fullpath)
self.outputFileList.append(fullpath+'.arr')
self.inputFileList.sort()
self.outputFileList.sort()
def openfile(self, event=None):
try:
inputName = askopenfilename(filetypes=["{Test Log Files}
{*}"])
if inputName == "":
Dialog(self.master,
text="Input Log File name must be
specified to produce arrow diagrams",
title="Error",
bitmap='error',
default=0,
strings=('OK',))
return
self.inputName.set(inputName)
self.inputFileList.append(inputName)
outputName = inputName + '.arr'
self.outputName.set(outputName)
self.outputFileList.append(self.outputName)
except:
Dialog(self.master,
text="Input Log File name must be
specified to produce arrow diagrams",
title="Error",
bitmap='error',
default=0,
strings=('OK',))
return
def quit(self, event=None):
########################## NEW START #######################
self.stateObj.updateAttribute
(self.inputName,self.outputName,self.stackname,self.name,self.iut,self
.type,self.inputFileList,self.outputFileList)
self.menuframe.quit()
# persist and dump object attributes.
pickle.dump(self.stateObj, open("msc.dat","wb"))
########################## NEW END #######################
def ctfPrint(self,string):
if self.outputName.get() == "":
self.save()
#Open file and append string
fd = open(self.outputName.get(),"a+")
fd.write(string)
self.pdudfn.insert(END, string)
#Close file
fd.close()
def createTestList(self):
line = None
inputfile = self.inputName.get()
try:
fd = open(inputfile, 'r')
except IOError:
Dialog(self.master,
text="Cannot open file",
title="Error",
bitmap='error',
default=0,
strings=('OK',))
return
# display status to stdout and status window
stateString = "\nBuild MSC for %s"%inputfile
print stateString
self.pdubuild.insert(END, stateString)
trclist = fd.readlines()
strip = string.strip
for x in range(0,len(trclist)):
trclist[x]=strip(trclist[x])
fd.close()
idx = 0
counter = 0
tstlist = []
for line in trclist:
if line == "": # skip blank line
continue
if line[0] == "-":
counter = counter+1
if counter == 1:
tstlist.append([])
if counter > 0:
tstlist[idx].append(line)
if counter == 4:
idx = idx + 1
counter = 0
return tstlist
def getData(self):
self.name.get()
self.iut.get()
self.inputWindow.destroy()
def stackData(self):
self.inputWindow = Toplevel(self.master)
self.inputWindow.geometry("+%d+%d" % (self.master.winfo_rootx
()+180,
self.master.winfo_rooty()+180))
self.inputWindow.title("Enter stack data")
Label(self.inputWindow, text ="Please enter the 2 letter
prefix for each stack seperated by a space.").grid(row=1,
columnspan=2, pady=2, sticky=W)
Label(self.inputWindow, text = "There must be a minimum of 2
stacks and a maximum of 5.").grid(row=2, columnspan=2, pady=2,
sticky=W)
Label(self.inputWindow, text = "The second entry is the IUT
i.e Xx Yy Zz").grid(row=3, columnspan=2, pady=2, sticky=W)
Label(self.inputWindow, text="Stack Names:").grid(row=4,
sticky=W)
self.e1 = Entry(self.inputWindow,
textvariable=self.stackname, width=35)
self.e1.grid(row=4, column=1, sticky="EW", pady=1)
okButton = Button(self.inputWindow, text="Ok",
command=self.getData)
okButton.grid(row=5, column=1, sticky=W, pady=6)
self.inputWindow.wait_window()
def buildAllMsc(self):
index = 0
listDir = os.getcwd()
os.path.walk(listDir,self.buildFileList,None)
if self.inputFileList != []:
for file in self.inputFileList:
self.inputName.set(file)
self.outputName.set(self.outputFileList[index])
self.saveArrows()
index = index +1
self.master.update()
self.pdubuild.insert(END, "Processing Completed")
else:
Dialog(self.master,
text="Input Log File name must be
specified to produce arrow diagrams",
title="Error",
bitmap='error',
default=0,
strings=('OK',))
return
def saveArrows(self):
tstList = None
temp = None
stackList = {}
numStacks = None
upper = 0
lower = 0
mngmt = 0
other = 0
columnWidth = None
emptySpace = None
arrowLine = None
stack = None
emptyLine = None
space = ""
stacknames = ""
upperTx = None
upperRx = None
lowerTx = None
lowerRx = None
mngmtTx = None
mngmtRx = None
otherTx = None
otherRx = None
lowerFunction = None
upperFunction = None
mngmtFunction = None
otherFunction = None
test = None
testList = None
event = None
eventList = None
line = None
function = None
if self.outputName == "":
save()
tstList = self.createTestList()
if tstList == None:
return
temp = self.stackname.get()
# first time invoked
if self.counter.get() == 0:
self.stackData()
temp = self.stackname.get()
self.counter.set(1)
# this is no the first run, stackname should be stored already
temp = self.stackname.get()
if temp == "":
return
# clear msc window
self.pdudfn.delete("0.0", END)
stackList = string.split(temp)
numStacks = len(stackList)
upper = 0
lower = 0
mngmt = 0
other = 0
if numStacks > 2:
lower = 2
if numStacks > 3:
mngmt = 3
if numStacks > 4:
other = 4
columnWidth = 70/(numStacks-1)
emptySpace = " "*columnWidth
arrowLine = "-"*(columnWidth-1)
stack = "|%s"%emptySpace
emptyLine = stack*(numStacks-1) + "|\n"
space = ""
stacknames = ""
for name in stackList:
stacknames = stacknames + space + name
space = " "*(columnWidth - len(name)+1)
# Arrow for event travels from upper stack to the right?
upperTx = "|%s>"%arrowLine + stack*(numStacks-2) + "|\n"
upperRx = "|<%s"%arrowLine + stack*(numStacks-2) + "|\n"
upperFunction = "|%s" + stack*(numStacks-2) + "|\n"
lowerTx = stack + "|<%s"%arrowLine + stack*(numStacks-3)
+ "|\n"
lowerRx = stack + "|%s>"%arrowLine + stack*(numStacks-3)
+ "|\n"
lowerFunction = stack + "|%s" + stack*(numStacks-3) + "|\n"
mngmtTx = stack + "|<--%s"%(arrowLine*2) + stack*(numStacks-
4) +"|\n"
mngmtRx = stack + "|%s-->"%(arrowLine*2) + stack*(numStacks-
4) +"|\n"
mngmtFunction = stack + "|%s" + stack*(numStacks-4) + "|\n"
otherTx = stack + "|<----%s"%(arrowLine*3) + stack*(numStacks-
5) +"|\n"
otherRx = stack + "|%s---->"%(arrowLine*3) + stack*(numStacks-
5) +"|\n"
otherFunction = stack+ "|%s" + stack*(numStacks-5) +"|\n"
split = string.split
strip = string.strip
search = re.search
linecounter = 0
for test in tstList:
evntsList = []
if linecounter < 1:
self.ctfPrint(stacknames + "\n")
linecounter = linecounter +1
isFunction = FALSE
for line in test:
if ((search( "CallFunc", line) != None) or (search
( "@event@", line) != None)):
wordList = split(line)
for word in wordList :
if isFunction == TRUE :
print "Found a primitive: %s"%word
newLine = "Transmit : " + word
evntsList.append(newLine)
isFunction = FALSE
break
if word == "CallFunc":
isFunction = TRUE
if (search("@event@", word)) != None :
word = re.sub("@event@", "", word)
print "Found an event: %s"%word
newLine = "Received : " + word
evntsList.append(newLine)
break
for event in evntsList:
function = split(event)[2]
extra_info = split(event, function)[1]
extra_info = strip(extra_info)
if event[0:8] == "Transmit":
if event[14:16] == stackList[upper]:
function = function + " "*(columnWidth-len
(function))
extra_info = extra_info + " "*(columnWidth-len
(extra_info))
self.ctfPrint(upperTx)
self.ctfPrint(upperFunction%function)
self.ctfPrint(upperFunction%extra_info)
self.ctfPrint(emptyLine)
elif event[14:16] == stackList[lower]:
function = " "*(columnWidth-len(function)) +
function
extra_info = " "*(columnWidth-len
(extra_info)) + extra_info
self.ctfPrint(lowerTx)
self.ctfPrint(lowerFunction%function)
self.ctfPrint(lowerFunction%extra_info)
self.ctfPrint(emptyLine)
elif event[14:16] == stackList[mngmt]:
function = emptySpace + "|" +" "*
(columnWidth-len(function)) + function
extra_info = emptySpace + "|" +" "*
(columnWidth-len(extra_info)) + extra_info
self.ctfPrint(mngmtTx)
self.ctfPrint(mngmtFunction%function)
self.ctfPrint(mngmtFunction%extra_info)
self.ctfPrint(emptyLine)
elif event[14:16] == stackList[other]:
function = (emptySpace + "|")*2 +" "*
(columnWidth-len(function)) + function
extra_info = (emptySpace + "|")*2 +" "*
(columnWidth-len(extra_info)) + extra_info
self.ctfPrint(otherTx)
self.ctfPrint(otherFunction%function)
self.ctfPrint(otherFunction%extra_info)
self.ctfPrint(emptyLine)
elif event[0:8] == "Received":
if event[14:16] == stackList[upper]:
function = function + " "*(columnWidth-len
(function))
extra_info = extra_info + " "*(columnWidth-len
(extra_info))
self.ctfPrint(upperTx)
self.ctfPrint(upperFunction%function)
self.ctfPrint(upperFunction%extra_info)
self.ctfPrint(emptyLine)
elif event[14:16] == stackList[lower]:
function = " "*(columnWidth-len(function)) +
function
extra_info = " "*(columnWidth-len
(extra_info)) + extra_info
self.ctfPrint(lowerTx)
self.ctfPrint(lowerFunction%function)
self.ctfPrint(lowerFunction%extra_info)
self.ctfPrint(emptyLine)
elif event[14:16] == stackList[mngmt]:
function = function + " "*(columnWidth-len
(function)) + stack
self.ctfPrint(mngmtRx)
self.ctfPrint(mngmtFunction%function)
self.ctfPrint(emptyLine)
elif event[14:16] == stackList[other]:
function = function + " "*(columnWidth-len
(function)) + stack*2
self.ctfPrint(otherRx)
self.ctfPrint(otherFunction%function)
self.ctfPrint(emptyLine)
self.ctfPrint("hor
\n")
# Main function, run as a standalone program
def main():
sep = os.sep
print "Loading \n"
root = Tk()
tharnbase = os.environ['THARN']
img = PhotoImage
(file=tharnbase+sep+'modules'+sep+'gui'+sep+'trillium.gif')
gui = Gui(root,img)
root.protocol('WM_DELETE_WINDOW', root.quit)
root.title("TRILLIUM MSC Builder")
root.iconname("MSCBld")
root.mainloop()
if __name__ == '__main__':
main()
More information about the Python-list
mailing list