def main(self): """ IN: self.root OT: dict. { lino: [(node_type, node_value), (...), ...], ... } lino: int. count from 1 but not consecutive. the linos are already sorted by ascending order. node_type: str. refer to _ast class types, e.g. "<class '_ast .Import'>", "<class '_ast.FunctionDef'>", ... node_value: str/dict. e.g. 'os.path.abspath', {'os': 'os'}, ... """ out = {} for node in ast_walk(self.root): if not hasattr(node, 'lineno'): continue if node.col_offset == -1: # 说明这个节点是 docstring continue x = out.setdefault(node.lineno, []) x.append((str(type(node)), self.eval_node(node))) # sort linos sorted_out = {k: out[k] for k in sorted(out.keys())} return sorted_out
def get_lino_indent_dict(self): """ IN: self.file self.root OT: {lino: indent} lino: int. count from 1 but not consecutive. the linos are already sorted by ascending order. indent: int. the column offset, assert all of them would be integral multiple of 4, e.g. 0, 4, 8, 12, ... and no exception. """ import re from lk_utils.read_and_write_basic import read_file_by_line reg = re.compile(r'^ *') code_lines = read_file_by_line(self.file) lino_indent = {} for node in ast_walk(self.root): if not hasattr(node, 'lineno'): continue line = code_lines[node.lineno - 1] indent = reg.findall(line)[0] lino_indent[node.lineno] = len(indent) # sort linos sorted_lino_indent = { k: lino_indent[k] for k in sorted(lino_indent.keys()) } return sorted_lino_indent
def _get_class_names(self, file): try: with open(file) as fd: parsed_source = ast_parse(fd.read()) class_names = [n.name for n in ast_walk(parsed_source) if isinstance(n, ClassDef)] except IOError, e: raise ClassLoaderError('Error - Couldn\'t open : \'{:}\'. Reason : {:}'.format(file, e.strerror))
def _get_class_names(self, file): try: with open(file) as fd: parsed_source = ast_parse(fd.read()) class_names = [ node.name for node in ast_walk(parsed_source) if isinstance(node, ClassDef) ] except IOError, e: raise ClassLoaderError( 'Error - Couldn\'t open : \'{0}\'. Reason : {1}'.format( file, e.strerror))
def _get_class_names(self, filename): class_names = [] try: with open(filename) as fd: parsed_source = ast_parse(fd.read().strip(self.ENCODING_DECLARATION)) class_names = [n.name for n in ast_walk(parsed_source) if isinstance(n, ClassDef)] except IOError as e: raise ClassLoaderError('Error - Couldn\'t open : \'{:}\'. Reason : {:}.'.format(filename, e.strerror)) except SyntaxError as e: raise ClassLoaderError('Error - Couldn\'t parse \'{:}\'. Reason: {:}.'.format(filename, e)) return class_names
def get_lineno_indent_dict2(self): """ IN: self.root OT: {lineno: indent} lineno: int. 行号, 从 1 开始数 indent: int. 列缩进量, 是 4 的整数倍, 如 0, 4, 8, ... 注意有一个特殊值 -1 """ out = {} for node in ast_walk(self.root): if not hasattr(node, 'lineno'): continue out[node.lineno] = node.col_offset return out
def main(self): """ IN: self.root OT: dict. { lineno: [(node_type, node_value), (...), ...], ... } """ out = {} for node in ast_walk(self.root): if not hasattr(node, 'lineno'): continue x = out.setdefault(node.lineno, []) x.append((str(type(node)), self.eval_node(node))) return out
def get_lino_indent_dict(self): """ refer: {lkdemo}/ast_demo.py NOTICE: 使用 regex 计算行缩进, 不要用 node.col_offset. 为什么: 假设存在以下代码: 1 | def func(): 2 | if a == 1: 3 | pass 对第 2 行 `if a == 1:`, 使用正则计算结果是 indent = 4, 而 node.col_offset 的值是 7. 原因在于, node.col_offset 计算的是变量 `a` 的列位置, 而非该行的缩进 位置. IN: self.file self.root OT: {lino: indent} lino: int. count from 1 but not consecutive. the linos are already sorted by ascending order. indent: int. the column offset, assert all of them would be integral multiple of 4, e.g. 0, 4, 8, 12, ... """ from lk_utils.read_and_write_basic import read_file_by_line lino_indent = {} code_lines = read_file_by_line(self.file) reg = re.compile(r'^ *') for node in ast_walk(self.root): if not (hasattr(node, 'lineno') and hasattr(node, 'col_offset')): continue if node.lineno in lino_indent: continue if node.col_offset == -1: # 说明这个节点是 docstring continue lino_indent[node.lineno] = len( reg.findall(code_lines[node.lineno - 1])[0]) # sort linos sorted_lino_indent = { k: lino_indent[k] for k in sorted(lino_indent.keys()) } return sorted_lino_indent
def get_lineno_indent_dict(self, file): """ IN: self.root OT: {lineno: indent} lineno: int. 行号, 从 1 开始数 indent: int. 列缩进量, 是 4 的整数倍, 如 0, 4, 8, ... 注意有一个特殊值 -1 """ import re from lk_utils.read_and_write_basic import read_file_by_line reg = re.compile(r'^ *') code_lines = read_file_by_line(file) out = {} for node in ast_walk(self.root): if not hasattr(node, 'lineno'): continue line = code_lines[node.lineno - 1] indent = reg.findall(line)[0] out[node.lineno] = len(indent) return out
def get_lino_indent_dict2(self): """ another way calculating indent by ast column_offset. IN: self.file self.root OT: {lino: indent} """ lino_indent = {} for node in ast_walk(self.root): if not (hasattr(node, 'lineno') and hasattr(node, 'col_offset')): continue if node.lineno in lino_indent: continue lino_indent[node.lineno] = node.col_offset # sort linos sorted_lino_indent = { k: lino_indent[k] for k in sorted(lino_indent.keys()) } return sorted_lino_indent