|
1 | 1 | from __future__ import generator_stop
|
2 | 2 |
|
3 |
| -from fissix import fixer_util |
4 |
| -from fissix.pgen2 import token |
5 |
| -from fissix.pygram import python_symbols as syms |
6 |
| -from fissix.pytree import Leaf, Node |
7 |
| - |
8 | 3 | __version__ = "0.8.1.dev0"
|
9 |
| - |
10 |
| - |
11 |
| -def _check_future_import(node): |
12 |
| - """If this is a future import, return set of symbols that are imported, |
13 |
| - else return None.""" |
14 |
| - # node should be the import statement here |
15 |
| - if not (node.type == syms.simple_stmt and node.children): |
16 |
| - return set() |
17 |
| - node = node.children[0] |
18 |
| - # now node is the import_from node |
19 |
| - if not ( |
20 |
| - node.type == syms.import_from |
21 |
| - and node.children[1].type == token.NAME |
22 |
| - and node.children[1].value == "__future__" |
23 |
| - ): |
24 |
| - return set() |
25 |
| - |
26 |
| - if node.children[3].type == token.LPAR: |
27 |
| - # from __future__ import (.. |
28 |
| - node = node.children[4] |
29 |
| - else: |
30 |
| - # from __future__ import ... |
31 |
| - node = node.children[3] |
32 |
| - # now node is the import_as_name[s] |
33 |
| - |
34 |
| - # print(python_grammar.number2symbol[node.type]) |
35 |
| - if node.type == syms.import_as_names: |
36 |
| - result = set() |
37 |
| - for n in node.children: |
38 |
| - if n.type == token.NAME: |
39 |
| - result.add(n.value) |
40 |
| - elif n.type == syms.import_as_name: |
41 |
| - n = n.children[0] |
42 |
| - assert n.type == token.NAME |
43 |
| - result.add(n.value) |
44 |
| - return result |
45 |
| - elif node.type == syms.import_as_name: |
46 |
| - node = node.children[0] |
47 |
| - assert node.type == token.NAME |
48 |
| - return {node.value} |
49 |
| - elif node.type == token.NAME: |
50 |
| - return {node.value} |
51 |
| - else: # pragma: no cover |
52 |
| - assert 0, "strange import" |
53 |
| - |
54 |
| - |
55 |
| -def add_future(node, symbol): |
56 |
| - |
57 |
| - root = fixer_util.find_root(node) |
58 |
| - |
59 |
| - for idx, node in enumerate(root.children): |
60 |
| - if ( |
61 |
| - node.type == syms.simple_stmt |
62 |
| - and len(node.children) > 0 |
63 |
| - and node.children[0].type == token.STRING |
64 |
| - ): |
65 |
| - # skip over docstring |
66 |
| - continue |
67 |
| - names = _check_future_import(node) |
68 |
| - if not names: |
69 |
| - # not a future statement; need to insert before this |
70 |
| - break |
71 |
| - if symbol in names: |
72 |
| - # already imported |
73 |
| - return |
74 |
| - |
75 |
| - import_ = fixer_util.FromImport( |
76 |
| - "__future__", [Leaf(token.NAME, symbol, prefix=" ")] |
77 |
| - ) |
78 |
| - |
79 |
| - # Place after any comments or whitespace. (copyright, shebang etc.) |
80 |
| - import_.prefix = node.prefix |
81 |
| - node.prefix = "" |
82 |
| - |
83 |
| - children = [import_, fixer_util.Newline()] |
84 |
| - root.insert_child(idx, Node(syms.simple_stmt, children)) |
85 |
| - |
86 |
| - |
87 |
| -def is_listcomp(node): |
88 |
| - def _is_listcomp(node): |
89 |
| - return ( |
90 |
| - isinstance(node, Node) |
91 |
| - and node.type == syms.atom |
92 |
| - and len(node.children) >= 2 |
93 |
| - and isinstance(node.children[0], Leaf) |
94 |
| - and node.children[0].value == "[" |
95 |
| - and isinstance(node.children[-1], Leaf) |
96 |
| - and node.children[-1].value == "]" |
97 |
| - ) |
98 |
| - |
99 |
| - def _is_noop_power_node(node): |
100 |
| - """https://github.com/python/cpython/pull/2235 changed the node |
101 |
| - structure for fix_map / fix_filter to contain a top-level `power` node |
102 |
| - """ |
103 |
| - return ( |
104 |
| - isinstance(node, Node) |
105 |
| - and node.type == syms.power |
106 |
| - and len(node.children) == 1 |
107 |
| - ) |
108 |
| - |
109 |
| - return ( |
110 |
| - _is_listcomp(node) |
111 |
| - or _is_noop_power_node(node) |
112 |
| - and _is_listcomp(node.children[0]) |
113 |
| - ) |
0 commit comments