1
1
import ast
2
+ import functools
2
3
from typing import List , Tuple , Union
3
4
4
5
from flake8_variables_names .list_helpers import flat
5
6
6
7
7
- def extract_names_from_node (node : Union [ast .expr , ast .stmt ]) -> List [ast .Name ]:
8
- if isinstance (node , ast .Name ):
9
- return [node ]
10
- if isinstance (node , ast .Assign ):
11
- nodes = []
12
- for target in node .targets :
13
- nodes .extend (extract_names_from_node (target ))
14
- return nodes
15
- if isinstance (node , ast .AnnAssign ):
16
- return extract_names_from_node (node .target )
17
- if isinstance (node , ast .Starred ):
18
- return extract_names_from_node (node .value )
19
- if isinstance (node , ast .Tuple ):
20
- nodes = []
21
- for elt in node .elts :
22
- nodes .extend (extract_names_from_node (elt ))
23
- return nodes
8
+ @functools .singledispatch
9
+ def extract_names_from_node (node ) -> List [ast .Name ]:
24
10
return []
25
11
26
12
13
+ @extract_names_from_node .register
14
+ def _extract_names_from_name_node (node : ast .Name ):
15
+ return [node ]
16
+
17
+
18
+ @extract_names_from_node .register
19
+ def _extract_names_from_assign_node (node : ast .Assign ):
20
+ return flat ([extract_names_from_node (target ) for target in node .targets ])
21
+
22
+
23
+ # in some versions of Python, singledispatch does not support `Union` in type annotations
24
+ @extract_names_from_node .register (ast .AnnAssign )
25
+ @extract_names_from_node .register (ast .For )
26
+ def _extract_names_from_annassign_node (node ):
27
+ return extract_names_from_node (node .target )
28
+
29
+
30
+ @extract_names_from_node .register
31
+ def _extract_names_from_starred_node (node : ast .Starred ):
32
+ return extract_names_from_node (node .value )
33
+
34
+
35
+ @extract_names_from_node .register
36
+ def _extract_names_from_tuple_node (node : ast .Tuple ):
37
+ return flat ([extract_names_from_node (elt ) for elt in node .elts ])
38
+
39
+
27
40
def get_var_names_from_assignment (
28
- assignment_node : Union [ast .Assign , ast .AnnAssign ],
41
+ assignment_node : Union [ast .Assign , ast .AnnAssign , ast . For ],
29
42
) -> List [Tuple [str , ast .AST ]]:
30
43
return [(n .id , n ) for n in extract_names_from_node (assignment_node )]
31
44
@@ -39,20 +52,13 @@ def get_var_names_from_funcdef(funcdef_node: ast.FunctionDef) -> List[Tuple[str,
39
52
return vars_info
40
53
41
54
42
- def get_var_names_from_for (for_node : ast .For ) -> List [Tuple [str , ast .AST ]]:
43
- if isinstance (for_node .target , ast .Name ):
44
- return [(for_node .target .id , for_node .target )]
45
- elif isinstance (for_node .target , ast .Tuple ):
46
- return [(n .id , n ) for n in for_node .target .elts if isinstance (n , ast .Name )]
47
- return []
48
-
49
-
50
55
def extract_all_variable_names (ast_tree : ast .AST ) -> List [Tuple [str , ast .AST ]]:
51
56
var_info : List [Tuple [str , ast .AST ]] = []
52
- assignments = [n for n in ast .walk (ast_tree ) if isinstance (n , (ast .Assign , ast .AnnAssign ))]
57
+ assignments = [
58
+ n for n in ast .walk (ast_tree )
59
+ if isinstance (n , (ast .Assign , ast .AnnAssign , ast .For ))
60
+ ]
53
61
var_info += flat ([get_var_names_from_assignment (a ) for a in assignments ])
54
62
funcdefs = [n for n in ast .walk (ast_tree ) if isinstance (n , ast .FunctionDef )]
55
63
var_info += flat ([get_var_names_from_funcdef (f ) for f in funcdefs ])
56
- fors = [n for n in ast .walk (ast_tree ) if isinstance (n , ast .For )]
57
- var_info += flat ([get_var_names_from_for (f ) for f in fors ])
58
64
return var_info
0 commit comments