PCART  v1.4
Automated Repair of Python API Parameter Compatibility Issues
callsite.py
Go to the documentation of this file.
1 
12 
13 import hashlib
14 import json
15 import os
16 import re
17 from dataclasses import dataclass
18 from typing import Optional
19 
20 
21 
28 @dataclass(frozen=True)
30 
32  rel_path: str
33 
34 
36  lineno: int
37 
38 
40  col_offset: int
41 
42 
44  end_lineno: Optional[int]
45 
46 
48  end_col_offset: Optional[int]
49 
50 
52  call_text: str
53 
54 
56  normalized_call: str
57 
58 
60  def artifactPayload(self):
61  return {
62  'rel_path': self.rel_path,
63  'lineno': self.lineno,
64  'col_offset': self.col_offset,
65  'end_lineno': self.end_lineno,
66  'end_col_offset': self.end_col_offset,
67  'normalized_call': self.normalized_call,
68  }
69 
70 
72  def artifactHash(self):
73  payload = json.dumps(self.artifactPayloadartifactPayload(),sort_keys=True,separators=(',', ':')).encode('utf-8')
74  return hashlib.sha256(payload).hexdigest()
75 
76 
78  def artifactId(self):
79  MAX_REL = 64 # max slug length for relative path
80  MAX_CALL = 48 # max slug length for call name
81  # slugify relative path
82  rel_slug = re.sub(r'[^0-9A-Za-z]+', '_', str(self.rel_path)).strip('_').lower()
83  rel_slug = re.sub(r'_+', '_', rel_slug)[:MAX_REL].strip('_') or 'source'
84  # slugify call name (everything before the first '(')
85  call_name = str(self.normalized_call).split('(', 1)[0]
86  call_slug = re.sub(r'[^0-9A-Za-z]+', '_', call_name).strip('_').lower()
87  call_slug = re.sub(r'_+', '_', call_slug)[:MAX_CALL].strip('_') or 'call'
88  return f'{rel_slug}__L{self.lineno}C{self.col_offset}__{call_slug}__{self.artifactHash()}'
89 
90 
91 
98 @dataclass(frozen=True)
100 
102  identity: CallsiteIdentity
103 
104 
106  artifact_id: str
107 
108 
110  format_api: str
111 
112 
114  parameters: str
115 
116 
119  def toDict(self):
120  return {
121  'id': self.artifact_id,
122  'artifact_hash': self.identity.artifactHash(),
123  'rel_path': self.identity.rel_path,
124  'lineno': self.identity.lineno,
125  'col_offset': self.identity.col_offset,
126  'end_lineno': self.identity.end_lineno,
127  'end_col_offset': self.identity.end_col_offset,
128  'call_text': self.identity.call_text,
129  'normalized_call': self.identity.normalized_call,
130  'format_api': self.format_api,
131  'parameters': self.parameters,
132  }
133 
134 
135 
140 def normalizeCallText(call_text):
141  return call_text.replace(' ', '').replace('"', '').replace("'", '')
142 
143 
144 
150 def normalizeRelPath(file_path, proj_path=None):
151  normalized_file = os.path.abspath(file_path).replace('\\', '/')
152  if proj_path:
153  normalized_root = os.path.abspath(proj_path).replace('\\', '/').rstrip('/')
154  try:
155  rel_path = os.path.relpath(normalized_file, normalized_root).replace('\\', '/')
156  if not rel_path.startswith('..'):
157  return rel_path
158  except ValueError:
159  pass
160  return normalized_file
161 
162 
163 
177  file_path,
178  call_text,
179  format_api,
180  parameters,
181  lineno,
182  col_offset,
183  end_lineno=None,
184  end_col_offset=None,
185  proj_path=None,
186 ):
187  identity = CallsiteIdentity(rel_path=normalizeRelPath(file_path, proj_path),lineno=int(lineno),col_offset=int(col_offset),end_lineno=end_lineno,end_col_offset=end_col_offset,call_text=call_text,normalized_call=normalizeCallText(call_text))
188  record = CallsiteRecord(identity=identity,artifact_id=identity.artifactId(),format_api=format_api,parameters=parameters)
189  return record.toDict()
Callsite identity class 调用点身份类
Definition: callsite.py:29
def artifactPayload(self)
The relative path from project root 相对于项目根目录的文件路径
Definition: callsite.py:60
def artifactId(self)
Return stable readable artifact id for a callsite 返回调用点稳定可读运行产物id.
Definition: callsite.py:78
def artifactHash(self)
Return stable artifact hash for a callsite 返回调用点稳定运行产物hash.
Definition: callsite.py:72
Callsite record class 调用点记录类
Definition: callsite.py:99
def toDict(self)
The structured callsite identity 结构化调用点身份
Definition: callsite.py:119
def normalizeRelPath(file_path, proj_path=None)
Normalize source file path to project relative path 将源码路径归一化为项目相对路径
Definition: callsite.py:150
def normalizeCallText(call_text)
Normalize call text for identity generation 归一化调用文本,用于生成调用点身份
Definition: callsite.py:140
def makeCallsiteRecord(file_path, call_text, format_api, parameters, lineno, col_offset, end_lineno=None, end_col_offset=None, proj_path=None)
Make callsite record 构造调用点记录
Definition: callsite.py:186