Package PyFoam :: Package Applications :: Module CompareDictionary
[hide private]
[frames] | no frames]

Source Code for Module PyFoam.Applications.CompareDictionary

  1  #  ICE Revision: $Id$ 
  2  """ 
  3  Application class that implements pyFoamCompareDictionary.py 
  4  """ 
  5   
  6  from os import path 
  7   
  8  import sys 
  9   
 10  from .PyFoamApplication import PyFoamApplication 
 11   
 12  from PyFoam.RunDictionary.ParsedParameterFile import ParsedParameterFile,PyFoamParserError 
 13  from PyFoam.Basics.DataStructures import DictProxy,Dimension,Tensor,SymmTensor,Vector,Field,TupleProxy 
 14  from PyFoam.Basics.FoamFileGenerator import makeString 
 15   
 16  from PyFoam.Error import error,warning 
 17   
 18  from .CommonParserOptions import CommonParserOptions 
 19   
 20  from PyFoam.Basics.TerminalFormatter import TerminalFormatter 
 21   
 22  from PyFoam.ThirdParty.six import print_,integer_types 
 23   
 24  f=TerminalFormatter() 
 25  f.getConfigFormat("source",shortName="src") 
 26  f.getConfigFormat("destination",shortName="dst") 
 27  f.getConfigFormat("difference",shortName="diff") 
 28  f.getConfigFormat("error",shortName="name") 
 29   
30 -class CompareDictionary(PyFoamApplication, 31 CommonParserOptions):
32 - def __init__(self, 33 args=None, 34 **kwargs):
35 description="""\ 36 Takes two dictionary and compares them semantically (by looking at the 37 structure, not the textual representation. If the dictionaries do not 38 have the same name, it looks for the destination file by searching the 39 equivalent place in the destination case. If more than two files are 40 specified then the last name is assumed to be a directory and all the 41 equivalents to the other files are searched there. 42 """ 43 44 PyFoamApplication.__init__(self, 45 args=args, 46 description=description, 47 usage="%prog [options] <source> <destination-case>", 48 nr=2, 49 exactNr=False, 50 interspersed=True, 51 **kwargs)
52
53 - def addOptions(self):
54 self.parser.add_option("--not-equal", 55 action="store_true", 56 default=False, 57 dest="notequal", 58 help="Allow source and destination to have different names") 59 self.parser.add_option("--debug", 60 action="store_true", 61 default=False, 62 dest="debug", 63 help="Debug the comparing process") 64 self.parser.add_option("--long-field-threshold", 65 action="store", 66 type="int", 67 default=None, 68 dest="longlist", 69 help="Fields that are longer than this won't be parsed, but read into memory (and compared as strings)") 70 71 CommonParserOptions.addOptions(self)
72 73 74
75 - def run(self):
76 sFiles=self.parser.getArgs()[0:-1] 77 dFile=path.abspath(self.parser.getArgs()[-1]) 78 79 for s in sFiles: 80 sName=path.abspath(s) 81 dName=dFile 82 83 if len(s)>1: 84 print_(f.name+"Source file",sName,f.reset) 85 try: 86 source=ParsedParameterFile(sName, 87 backup=False, 88 debug=self.opts.debugParser, 89 listLengthUnparsed=self.opts.longlist, 90 noBody=self.opts.noBody, 91 noHeader=self.opts.noHeader, 92 boundaryDict=self.opts.boundaryDict, 93 listDict=self.opts.listDict, 94 listDictWithHeader=self.opts.listDictWithHeader) 95 except IOError: 96 e = sys.exc_info()[1] # Needed because python 2.5 does not support 'as e' 97 self.warning("Problem with file",sName,":",e) 98 continue 99 except PyFoamParserError: 100 e = sys.exc_info()[1] # Needed because python 2.5 does not support 'as e' 101 self.warning("Parser problem with",sName,":",e) 102 continue 103 104 found=False 105 106 if path.isfile(sName) and path.isfile(dName): 107 found=True 108 109 if not found and not self.opts.notequal and path.basename(sName)!=path.basename(dName): 110 parts=sName.split(path.sep) 111 for i in range(len(parts)): 112 tmp=path.join(*[dName]+parts[-(i+1):]) 113 114 if path.exists(tmp): 115 found=True 116 dName=tmp 117 warning("Found",dName,"and using this") 118 break 119 120 if not found: 121 error("Could not find a file named",path.basename(sName),"in",dName) 122 123 if path.samefile(sName,dName): 124 error("Source",sName,"and destination",dName,"are the same") 125 126 try: 127 dest=ParsedParameterFile(dName, 128 backup=False, 129 debug=self.opts.debugParser, 130 listLengthUnparsed=self.opts.longlist, 131 noBody=self.opts.noBody, 132 noHeader=self.opts.noHeader, 133 boundaryDict=self.opts.boundaryDict, 134 listDict=self.opts.listDict, 135 listDictWithHeader=self.opts.listDictWithHeader) 136 except IOError: 137 e = sys.exc_info()[1] # Needed because python 2.5 does not support 'as e' 138 self.error("Problem with file",dName,":",e) 139 140 self.pling=False 141 142 if not self.opts.boundaryDict and not self.opts.listDict and not self.opts.listDictWithHeader: 143 self.compareDict(source.content,dest.content,1,path.basename(sName)) 144 else: 145 self.compareIterable(source.content,dest.content,1,path.basename(sName)) 146 147 if not self.pling: 148 print_("\nNo differences found")
149
150 - def dictString(self,path,name):
151 return "%s[%s]" % (path,name)
152
153 - def iterString(self,path,index):
154 return "%s[%d]" % (path,index)
155
156 - def compare(self,src,dst,depth,name):
157 if type(src)!=type(dst): 158 print_(f.diff+">><<",name,": Types differ"+f.reset+"\n+"+f.src+">>Source:"+f.reset+"\n",makeString(src),"\n"+f.dst+"<<Destination:"+f.reset+"\n",makeString(dst)+f.reset) 159 self.pling=True 160 elif type(src) in [tuple,list,TupleProxy]: 161 self.compareIterable(src,dst,depth,name) 162 elif isinstance(src,(str,float)+integer_types) or src==None: 163 self.comparePrimitive(src,dst,depth,name) 164 elif src.__class__ in [Dimension,Tensor,SymmTensor,Vector]: 165 self.comparePrimitive(src,dst,depth,name) 166 elif src.__class__==Field: 167 self.compareField(src,dst,depth,name) 168 elif type(src) in [DictProxy,dict]: 169 self.compareDict(src,dst,depth,name) 170 else: 171 warning("Type of",name,"=",type(src),"unknown") 172 if self.opts.debug: 173 try: 174 print_("Class of",name,"=",src.__class__,"unknown") 175 except: 176 pass
177
178 - def compareField(self,src,dst,depth,name):
179 if src!=dst: 180 self.pling=True 181 print_(f.diff+">><< Field",name,": Differs"+f.reset+"\n"+f.src+">>Source:"+f.reset+"\n",end=" ") 182 if src.uniform: 183 print_(src) 184 else: 185 print_("nonuniform - field not printed") 186 print_(f.dst+"<<Destination:"+f.reset+"\n",end=" ") 187 if dst.uniform: 188 print_(dst) 189 else: 190 print_("nonuniform - field not printed")
191
192 - def comparePrimitive(self,src,dst,depth,name):
193 if src!=dst: 194 print_(f.diff+">><<",name,": Differs"+f.reset+"\n"+f.src+">>Source:"+f.reset+"\n",src,"\n"+f.dst+"<<Destination:"+f.reset+"\n",dst) 195 self.pling=True
196
197 - def compareIterable(self,src,dst,depth,name):
198 nr=min(len(src),len(dst)) 199 200 for i in range(nr): 201 if self.opts.debug: 202 print_("Comparing",self.iterString(name,i)) 203 self.compare(src[i],dst[i],depth+1,self.iterString(name,i)) 204 205 if nr<len(src): 206 print_(f.src+">>>>",self.iterString(name,nr),"to",self.iterString(name,len(src)-1),"missing from destination\n"+f.reset,makeString(src[nr:])) 207 self.pling=True 208 elif nr<len(dst): 209 print_(f.dst+"<<<<",self.iterString(name,nr),"to",self.iterString(name,len(dst)-1),"missing from source\n"+f.reset,makeString(dst[nr:])) 210 self.pling=True
211
212 - def compareDict(self,src,dst,depth,name):
213 for n in src: 214 if not n in dst: 215 print_(f.src+">>>>",self.dictString(name,n),": Missing from destination\n"+f.reset,makeString(src[n])) 216 self.pling=True 217 else: 218 if self.opts.debug: 219 print_("Comparing",self.dictString(name,n)) 220 self.compare(src[n],dst[n],depth+1,self.dictString(name,n)) 221 222 for n in dst: 223 if not n in src: 224 print_(f.dst+"<<<<",self.dictString(name,n),": Missing from source\n"+f.reset,makeString(dst[n])) 225 self.pling=True
226 227 # Should work with Python3 and Python2 228