PCART  v1.4
Automated Repair of Python API Parameter Compatibility Issues
loadData.py
Go to the documentation of this file.
1 
10 
11 
12 
13 import os
14 import re
15 import json
16 from Path.getPath import Path
17 from API.LibApi import *
18 from Tool.tool import cmp
19 
20 
21 
22 
30 def loadLib(libName,version):
31  # 使用源码位置定位仓库根目录,避免切换运行工作区后找不到LibAPIExtraction
32  repoRoot=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
33  libPath=os.path.join(repoRoot,'LibAPIExtraction',libName,f'{libName}{version}')
34  f = open(libPath, 'r', encoding='utf-8')
35  lst=f.readlines()
36  f.close()
37  libAPIs=[] #既包含了非内置也包含了内置
38  libAPIIns=[] #记录内置的API
39  assignDict={}
40  pyiFlag=0
41  for item in lst:
42  if item[0]!='\n' and item[0]!='-':
43  item=item.replace(' ','').replace('\n','') #去掉空格和结尾的换行符
44  if item[0]=='A':
45  item=item.replace('\n','')
46  pos=item.find(':')
47  s=item[pos+1:]
48  temp=s.split('->')
49  assignDict[temp[0]]=temp[1]
50  else:
51  libAPIs.append(item)
52 
53  if '.pyi' in item:
54  pyiFlag=1
55  continue
56 
57  if pyiFlag==1:
58  if item[0]!='\n' and item[0]!='A':
59  item=item.replace('\n','')
60  libAPIIns.append(item)
61  elif item[0]=='\n':
62  pyiFlag=0
63 
64  #再单独对Assign字典进行处理
65  #a1:r1,a2:a1防止值也是别名,最后a2:r1
66  for k,v in assignDict.items():
67  #判断值是否也可能是别名,即key
68  if v in assignDict: #若值也是个别名
69  assignDict[k]=assignDict[v]
70 
71  tempLst=list(set(libAPIs))
72  tempLst.sort(key=libAPIs.index) #去重之后保持原来的顺序
73  return tempLst,assignDict,libAPIIns
74 
75 
76 
77 
83 def func(libApiObjLst,libApiName):
84  lst=[]
85  for it in libApiObjLst:
86  if it.name==libApiName:
87  lst.append(it.full_item)
88  return lst
89 
90 
91 
92 
99 def getAPILst(filePath):
100  # pattern_v='.*?Torch(.*).txt'
101  pattern_v=r'\d+\.(?:\d+\.)*\d+'
102  obj_v=re.compile(pattern_v)
103  version=obj_v.findall(filePath)[0]
104  # f=open(filePath,'r')
105  f = open(filePath, 'r', encoding='utf-8')
106  apiLst=f.readlines()
107  ans=[]
108  for it in apiLst:
109  if it[0]!='A' and it[0]!='-' and it[0]!='\n':
110  it=it.replace(' ','').replace('\n','') #去掉空格和换行
111  ans.append(it)
112 
113  #这一步要对ans进行去重,因为在提取库API的时候,分别从.py和.pyi文件中提取
114  #所以肯定会包含重复的部分
115  tempLst=list(set(ans))
116  tempLst.sort(key=ans.index)
117  return version,tempLst
118 
119 
120 
121 
129 def lib2json(sourceFilePath,saveFilePath):
130  pathObj=Path('F') #只获取当前目录下的一级子文件
131  pathObj.getPath(sourceFilePath)
132  path=pathObj.path
133  #dic的value是一个列表,列表中的每个元素都是一个字典
134  # libAPI1与libAPI2之间是重载的关系
135  dic={} #{libAPI: [ {'1.1.0': [libAPI1,LibAPI2,...]}, {'1.2.0': [libAPI1,libAPI2,...] },{'1.3.0': [...] }]}
136  for item in path: #每个item对应一个版本的库所在的路径
137  version,apiLst=getAPILst(item)
138  apiObj=APIOBJ()
139  apiObj.toAPIObj(version,apiLst) #把字符串API转化为API对象
140  for it in apiObj.objLst:
141  if it.name not in dic:
142  dic[it.name]=[]
143  #首先在当前版本中找出所有和it.name同名的API,构造一个字典元素,即{version:[libAPI1,libAPI2,...]}
144  #此处的list可能为空,即API在当前的版本中找不到,说明在该版本中被删除了
145  lst=func(apiObj.objLst,it.name) #lst中的元素是API字符串
146  subDic={} # {'1.1.0': [LibAPI1,LibAPI2,...]}
147  subDic[version]=lst
148  if subDic not in dic[it.name]: #防止同名的API反复加入字典
149  dic[it.name].append(subDic)
150 
151  #再对dic中的列表元素,按版本号从小到大进行排序
152  for value in dic.values():
153  value.sort(key=lambda it:cmp([v for v in it.keys()][0])) #it就是value中的每个元素,即字典
154 
155  #再把dic字典保存为json格式的文件
156  # fw=open(saveFilePath,'w')
157  fw = open(saveFilePath, 'w', encoding='utf-8')
158  json.dump(dic,fw,indent=4,ensure_ascii=False)
159  fw.close()
160  print(f"API total number={len(dic)}")
161  #再判断是否有超过两个以上的API
162  for api,subLst in dic.items():
163  for subDict in subLst:
164  breakFlag=0
165  for version,ssubLst in subDict.items():
166  if len(ssubLst)>1:
167  print(f"Multiple over loads:{api} at {version}")
168  breakFlag=1
169  break
170  if breakFlag==1:
171  break
def loadLib(libName, version)
Load the extracted definitions of lib APIs for static signature mapping 把之前抽取出来的库API加载到字典中,在项目API与库AP...
Definition: loadData.py:30
def lib2json(sourceFilePath, saveFilePath)
Traverse all library API versions and consolidate into a JSON file 遍历所有版本的库API,将其整理成一个json格式的文件
Definition: loadData.py:129
def getAPILst(filePath)
Parse API list from a library extraction file 从库API提取文件中解析API列表
Definition: loadData.py:99
def func(libApiObjLst, libApiName)
Get all overloaded API strings for a given API name 获取给定API名称的所有重载API字符串
Definition: loadData.py:83
def cmp(version)
Normalize and compare version strings 归一化并比较版本号字符串
Definition: tool.py:431