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