def has_import_like(module_name, ast_tree): pat = prepare_pattern("import ??") matches = _get_matches(pat, ast_tree) if not matches: pat = prepare_pattern("from ?? import ??") matches = _get_matches(pat, ast_tree) if not matches: return False ret = False for match in matches: if isinstance(match, ast.Import) or isinstance(match, ast.ImportFrom): for name in match.names: if name.name.lower().startswith(module_name.lower()): return True # Repeat with from lookup if not ret: pat = prepare_pattern("from ?? import ??") matches = _get_matches(pat, ast_tree) for match in matches: if isinstance(match, ast.ImportFrom): if match.module.lower().startswith(module_name.lower()): return True for name in match.names: if name.name.lower().startswith(module_name.lower()): return True return ret
def test_import_multi(self): pat = prepare_pattern("import ??") assert isinstance(pat, ast.Import) assert not hasattr(pat, 'names') pat = prepare_pattern("from x import ??") assert isinstance(pat, ast.ImportFrom) assert pat.module == 'x' assert not hasattr(pat, 'names')
def test_wildcard_body(self): pat = prepare_pattern('if True: ??\nelse: ??') assert isinstance(pat, ast.If) assert pat.body is must_exist_checker assert pat.orelse is must_exist_checker pat2 = prepare_pattern('if True: ??') assert isinstance(pat2, ast.If) assert pat.body is must_exist_checker assert not hasattr(pat2, 'orelse')
def has_import(module_name, ast_tree): pat = prepare_pattern(f"import {module_name}") matches = _get_matches(pat, ast_tree) if not matches: pat = prepare_pattern(f"from {module_name} import ??") matches = _get_matches(pat, ast_tree) if not matches: return False for match in matches: if isinstance(match, ast.Import) or isinstance(match, ast.ImportFrom): for name in match.names: if name.name.lower() == module_name.lower(): return True return False
def test_wildcard_call_keywords(self): pat = prepare_pattern("f(a=1, ??=??)") assert pat.args == must_not_exist_checker if sys.version_info < (3, 5): assert pat.starargs is None assert isinstance(pat.keywords, types.FunctionType) assert not hasattr(pat, 'kwargs')
def test_keywords_wildcard(self): apf = ASTPatternFinder(prepare_pattern("f(e=4, ??=??)")) it = apf.scan_ast(self.ast) assert_ast_like(next(it), ast.Call(keywords=[ast.keyword(arg='d'), ast.keyword(arg='e'),]) ) self.assert_no_more(it)
def test_wildcard_some_call_args(self): pat = prepare_pattern("f(??, 1)") assert isinstance(pat.args, listmiddle) assert pat.args.front == [] assert_ast_like(pat.args.back[0], ast.Num(n=1)) assert pat.starargs is None assert pat.keywords == must_not_exist_checker
def get_assignments_as_dict(pattern, ast_tree): pat = prepare_pattern(pattern) node_list = _get_matches(pat, ast_tree) literals_dict = {} if not node_list: return literals_dict for node in node_list: if isinstance(node, ast.Assign): for target in node.targets: left_hand_side = target right_hand_side = node.value if isinstance(right_hand_side, ast.Call): right_hand_side = node.value.func if isinstance(right_hand_side, ast.Constant): right_hand_side = node.value if isinstance(target, ast.Subscript): left_hand_side = target.slice.value key = "" if hasattr(left_hand_side, "value"): key = left_hand_side.value elif hasattr(left_hand_side, "id"): key = left_hand_side.id if key: literals_dict[key] = { "left_hand_side": left_hand_side, "right_hand_side": right_hand_side, } return literals_dict
def has_method_call(pattern, ast_tree): pat = prepare_pattern(pattern) node_list = _get_matches(pat, ast_tree) for node in node_list: if isinstance(node, ast.Call): return True return False
def test_subscript_no_ctx(self): pat = prepare_pattern('?[2]') assert_ast_like(pat, ast.Subscript(slice=ast.Index(value=ast.Num(n=2)))) assert not hasattr(pat, 'ctx') matches = get_matches(pat, 'd[2] = 1') assert len(matches) == 1
def test_wildcard_funcdef_kwonlyargs(self): pat = prepare_pattern("def f(*, a, ??): ??") assert isinstance(pat.args, ArgsDefChecker) assert [a.arg for a, d in pat.args.kwonly_args_dflts] == ['a'] assert pat.args.koa_subset assert pat.args.kwarg is None assert pat.args.args is must_not_exist_checker assert pat.args.vararg is must_not_exist_checker
def test_wildcard_some_call_args(self): pat = prepare_pattern("f(??, 1)") assert isinstance(pat.args, listmiddle) assert pat.args.front == [] assert_ast_like(pat.args.back[0], ast.Num(n=1)) if sys.version_info < (3, 5): assert pat.starargs is None assert pat.keywords == must_not_exist_checker
def test_import_from(self): pat = prepare_pattern("from ? import ?") assert isinstance(pat, ast.ImportFrom) assert pat.module is must_exist_checker assert len(pat.names) == 1 assert pat.names[0].name is must_exist_checker assert not hasattr(pat.names[0], 'asname') assert not hasattr(pat, 'level')
def test_wildcard_funcdef_kwonlyargs(self): pat = prepare_pattern("def f(*, a, ??): ??") assert isinstance(pat.args, ArgsDefChecker) assert [a.arg for a,d in pat.args.kwonly_args_dflts] == ['a'] assert pat.args.koa_subset assert pat.args.kwarg is None assert pat.args.args is must_not_exist_checker assert pat.args.vararg is must_not_exist_checker
def test_wildcard_call_mixed_args(self): pat = prepare_pattern("f(1, ??, a=2, **{'b':3})") assert isinstance(pat.args, listmiddle) assert_ast_like(pat.args.front[0], ast.Num(n=1)) assert not hasattr(pat, 'starargs') assert isinstance(pat.keywords, types.FunctionType) assert_ast_like(pat.kwargs, ast.Dict(keys=[ast.Str(s='b')], values=[ast.Num(n=3)]))
def test_wildcard_call_args(self): pat = prepare_pattern("f(??)") assert isinstance(pat, ast.Call) assert isinstance(pat.args, listmiddle) assert pat.args.front == [] assert pat.args.back == [] assert not hasattr(pat, 'keywords') assert not hasattr(pat, 'starargs') assert not hasattr(pat, 'kwargs')
def test_wildcard_funcdef(self): pat = prepare_pattern("def f(??): ??") assert_ast_like(pat, ast.FunctionDef(name='f')) assert isinstance(pat.args.args, listmiddle) assert pat.args.args.front == [] assert pat.args.args.back == [] assert not hasattr(pat.args.args, 'vararg') assert not hasattr(pat.args.args, 'kwonlyargs') assert not hasattr(pat.args.args, 'kwarg')
def test_keywords_wildcard(self): apf = ASTPatternFinder(prepare_pattern("f(e=4, ??=??)")) it = apf.scan_ast(self.ast) assert_ast_like( next(it), ast.Call(keywords=[ ast.keyword(arg='d'), ast.keyword(arg='e'), ])) self.assert_no_more(it)
def get_method_as_dict(pattern, ast_tree): pat = prepare_pattern(pattern) node_list = _get_matches(pat, ast_tree) if not node_list: return None invocations = [] for node in node_list: if isinstance(node, ast.Call): node_obj = ast2dict(node) invocations.append(node_obj) return invocations
def test_wildcard_call_mixed_args(self): pat = prepare_pattern("f(1, ??, a=2, **{'b':3})") assert isinstance(pat.args, listmiddle) assert_ast_like(pat.args.front[0], ast.Num(n=1)) assert not hasattr(pat, 'starargs') assert isinstance(pat.keywords, types.FunctionType) kwargs_dict = ast.Dict(keys=[ast.Str(s='b')], values=[ast.Num(n=3)]) if sys.version_info < (3, 5): assert_ast_like(pat.kwargs, kwargs_dict) else: pat.keywords([ast.keyword(arg=None, value=kwargs_dict), ast.keyword(arg='a', value=ast.Num(n=2))], [])
def test_pos_final_wildcard(self): apf = ASTPatternFinder(prepare_pattern("f(1, ??)")) it = apf.scan_ast(self.ast) assert_ast_like(next(it), ast.Call(args=[ast.Num(n=1)])) assert_ast_like(next(it), ast.Call(args=[ast.Num(n=1), ast.Num(n=2)])) assert_ast_like(next(it), ast.Call(starargs=ast.Name(id='c'))) assert_ast_like(next(it), ast.Call(args=[ast.Num(n=1)], keywords=[ast.keyword(arg='d'), ast.keyword(arg='e'), ]) ) assert_ast_like(next(it), ast.Call(kwargs=ast.Name(id='k'))) self.assert_no_more(it)
def test_wildcard_call_mixed_args(self): pat = prepare_pattern("f(1, ??, a=2, **{'b':3})") assert isinstance(pat.args, listmiddle) assert_ast_like(pat.args.front[0], ast.Num(n=1)) assert not hasattr(pat, 'starargs') assert isinstance(pat.keywords, types.FunctionType) kwargs_dict = ast.Dict(keys=[ast.Str(s='b')], values=[ast.Num(n=3)]) if sys.version_info < (3, 5): assert_ast_like(pat.kwargs, kwargs_dict) else: pat.keywords([ ast.keyword(arg=None, value=kwargs_dict), ast.keyword(arg='a', value=ast.Num(n=2)) ], [])
def test_pos_final_wildcard(self): apf = ASTPatternFinder(prepare_pattern("f(1, ??)")) it = apf.scan_ast(self.ast) assert_ast_like(next(it), ast.Call(args=[ast.Num(n=1)])) assert_ast_like(next(it), ast.Call(args=[ast.Num(n=1), ast.Num(n=2)])) assert_ast_like(next(it), ast.Call(starargs=ast.Name(id='c'))) assert_ast_like( next(it), ast.Call(args=[ast.Num(n=1)], keywords=[ ast.keyword(arg='d'), ast.keyword(arg='e'), ])) assert_ast_like(next(it), ast.Call(kwargs=ast.Name(id='k'))) self.assert_no_more(it)
def get_comparison_as_dict(pattern, ast_tree): pat = prepare_pattern(pattern) node_list = _get_matches(pat, ast_tree) literals_dict = {} for node in node_list: if isinstance(node, ast.Compare): left_hand_side = node.comparators[0] right_hand_side = node.comparators[-1] key = "" if isinstance(left_hand_side, ast.Name): key = left_hand_side.id elif isinstance(left_hand_side, ast.Attribute): key = left_hand_side.attr if key: literals_dict[key] = { "left_hand_side": left_hand_side, "right_hand_side": right_hand_side, } return literals_dict
def test_name_or_attr(self): pat = prepare_pattern('a = 1') assert_ast_like(pat, ast.Assign(value=ast.Num(1))) assert (isinstance(pat.targets[0], types.FunctionType) \ or isinstance(pat.targets[0], name_or_attr))
def test_wildcard_body_part(self): pat = prepare_pattern("def foo():\n ??\n return a") assert isinstance(pat, ast.FunctionDef) assert isinstance(pat.body, listmiddle) assert_ast_like(pat.body.back[0], ast.Return(ast.Name(id='a')))
def test_mixed_wildcard(self): apf = ASTPatternFinder(prepare_pattern("f(??, d=?)")) matches = list(apf.scan_ast(self.ast)) assert len(matches) == 4 assert_ast_like(matches[-1], ast.Call(kwargs=ast.Name(id='k')))
def get_matching_names(self, pat): apf = ASTPatternFinder(prepare_pattern(pat)) matches = apf.scan_ast(self.ast) return {f.name for f in matches}
def test_wildcard_funcdef_earlyargs(self): pat = prepare_pattern("def f(??, a): ??") assert isinstance(pat.args.args, listmiddle) assert_ast_like(pat.args.args.back[0], ast.arg(arg='a')) assert pat.args.vararg is must_not_exist_checker assert pat.args.kwonly_args_dflts == []
def test_wildcard_all(self): apf = ASTPatternFinder(prepare_pattern("f(??)")) matches = list(apf.scan_ast(self.ast)) assert len(matches) == 8
def test_attr_no_ctx(self): pat = prepare_pattern('?.baz') assert_ast_like(pat, ast.Attribute(attr='baz')) assert not hasattr(pat, 'ctx') matches = get_matches(pat, 'foo.baz = 1') assert len(matches) == 1
def test_pos_leading_wildcard(self): apf = ASTPatternFinder(prepare_pattern("f(??, 2)")) it = apf.scan_ast(self.ast) assert_ast_like(next(it), ast.Call(args=[ast.Num(n=1), ast.Num(n=2)])) self.assert_no_more(it)
def test_simple_wildcard(self): pat = prepare_pattern('?/?') assert_ast_like(pat, ast.BinOp(op=ast.Div())) assert pat.left is must_exist_checker assert pat.right is must_exist_checker
def test_plain(self): pat = prepare_pattern('1/2') assert_ast_like(pat, ast.BinOp(left=ast.Num(n=1), op=ast.Div(), right=ast.Num(n=2)) )
def test_import(self): pat = prepare_pattern("import ?") assert isinstance(pat, ast.Import) assert len(pat.names) == 1 assert pat.names[0].name is must_exist_checker
def test_keywords_wildcard2(self): apf = ASTPatternFinder(prepare_pattern("f(d=?, ??=??)")) matches = list(apf.scan_ast(self.ast)) assert len(matches) == 2
def __init__(self): self._pattern = astsearch.prepare_pattern(self.pattern) self._finder = astsearch.ASTPatternFinder(self._pattern)
def test_single_and_multi_wildcard(self): apf = ASTPatternFinder(prepare_pattern("f(?, ??)")) matches = list(apf.scan_ast(self.ast)) assert len(matches) == 5
def test_plain(self): pat = prepare_pattern('1/2') assert_ast_like( pat, ast.BinOp(left=ast.Num(n=1), op=ast.Div(), right=ast.Num(n=2)))