Mercurial > repos > shellac > guppy_basecaller
comparison env/lib/python3.7/site-packages/libpasteurize/fixes/fix_kwargs.py @ 0:26e78fe6e8c4 draft
"planemo upload commit c699937486c35866861690329de38ec1a5d9f783"
author | shellac |
---|---|
date | Sat, 02 May 2020 07:14:21 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:26e78fe6e8c4 |
---|---|
1 u""" | |
2 Fixer for Python 3 function parameter syntax | |
3 This fixer is rather sensitive to incorrect py3k syntax. | |
4 """ | |
5 | |
6 # Note: "relevant" parameters are parameters following the first STAR in the list. | |
7 | |
8 from lib2to3 import fixer_base | |
9 from lib2to3.fixer_util import token, String, Newline, Comma, Name | |
10 from libfuturize.fixer_util import indentation, suitify, DoubleStar | |
11 | |
12 _assign_template = u"%(name)s = %(kwargs)s['%(name)s']; del %(kwargs)s['%(name)s']" | |
13 _if_template = u"if '%(name)s' in %(kwargs)s: %(assign)s" | |
14 _else_template = u"else: %(name)s = %(default)s" | |
15 _kwargs_default_name = u"_3to2kwargs" | |
16 | |
17 def gen_params(raw_params): | |
18 u""" | |
19 Generator that yields tuples of (name, default_value) for each parameter in the list | |
20 If no default is given, then it is default_value is None (not Leaf(token.NAME, 'None')) | |
21 """ | |
22 assert raw_params[0].type == token.STAR and len(raw_params) > 2 | |
23 curr_idx = 2 # the first place a keyword-only parameter name can be is index 2 | |
24 max_idx = len(raw_params) | |
25 while curr_idx < max_idx: | |
26 curr_item = raw_params[curr_idx] | |
27 prev_item = curr_item.prev_sibling | |
28 if curr_item.type != token.NAME: | |
29 curr_idx += 1 | |
30 continue | |
31 if prev_item is not None and prev_item.type == token.DOUBLESTAR: | |
32 break | |
33 name = curr_item.value | |
34 nxt = curr_item.next_sibling | |
35 if nxt is not None and nxt.type == token.EQUAL: | |
36 default_value = nxt.next_sibling | |
37 curr_idx += 2 | |
38 else: | |
39 default_value = None | |
40 yield (name, default_value) | |
41 curr_idx += 1 | |
42 | |
43 def remove_params(raw_params, kwargs_default=_kwargs_default_name): | |
44 u""" | |
45 Removes all keyword-only args from the params list and a bare star, if any. | |
46 Does not add the kwargs dict if needed. | |
47 Returns True if more action is needed, False if not | |
48 (more action is needed if no kwargs dict exists) | |
49 """ | |
50 assert raw_params[0].type == token.STAR | |
51 if raw_params[1].type == token.COMMA: | |
52 raw_params[0].remove() | |
53 raw_params[1].remove() | |
54 kw_params = raw_params[2:] | |
55 else: | |
56 kw_params = raw_params[3:] | |
57 for param in kw_params: | |
58 if param.type != token.DOUBLESTAR: | |
59 param.remove() | |
60 else: | |
61 return False | |
62 else: | |
63 return True | |
64 | |
65 def needs_fixing(raw_params, kwargs_default=_kwargs_default_name): | |
66 u""" | |
67 Returns string with the name of the kwargs dict if the params after the first star need fixing | |
68 Otherwise returns empty string | |
69 """ | |
70 found_kwargs = False | |
71 needs_fix = False | |
72 | |
73 for t in raw_params[2:]: | |
74 if t.type == token.COMMA: | |
75 # Commas are irrelevant at this stage. | |
76 continue | |
77 elif t.type == token.NAME and not found_kwargs: | |
78 # Keyword-only argument: definitely need to fix. | |
79 needs_fix = True | |
80 elif t.type == token.NAME and found_kwargs: | |
81 # Return 'foobar' of **foobar, if needed. | |
82 return t.value if needs_fix else u'' | |
83 elif t.type == token.DOUBLESTAR: | |
84 # Found either '*' from **foobar. | |
85 found_kwargs = True | |
86 else: | |
87 # Never found **foobar. Return a synthetic name, if needed. | |
88 return kwargs_default if needs_fix else u'' | |
89 | |
90 class FixKwargs(fixer_base.BaseFix): | |
91 | |
92 run_order = 7 # Run after function annotations are removed | |
93 | |
94 PATTERN = u"funcdef< 'def' NAME parameters< '(' arglist=typedargslist< params=any* > ')' > ':' suite=any >" | |
95 | |
96 def transform(self, node, results): | |
97 params_rawlist = results[u"params"] | |
98 for i, item in enumerate(params_rawlist): | |
99 if item.type == token.STAR: | |
100 params_rawlist = params_rawlist[i:] | |
101 break | |
102 else: | |
103 return | |
104 # params is guaranteed to be a list starting with *. | |
105 # if fixing is needed, there will be at least 3 items in this list: | |
106 # [STAR, COMMA, NAME] is the minimum that we need to worry about. | |
107 new_kwargs = needs_fixing(params_rawlist) | |
108 # new_kwargs is the name of the kwargs dictionary. | |
109 if not new_kwargs: | |
110 return | |
111 suitify(node) | |
112 | |
113 # At this point, params_rawlist is guaranteed to be a list | |
114 # beginning with a star that includes at least one keyword-only param | |
115 # e.g., [STAR, NAME, COMMA, NAME, COMMA, DOUBLESTAR, NAME] or | |
116 # [STAR, COMMA, NAME], or [STAR, COMMA, NAME, COMMA, DOUBLESTAR, NAME] | |
117 | |
118 # Anatomy of a funcdef: ['def', 'name', parameters, ':', suite] | |
119 # Anatomy of that suite: [NEWLINE, INDENT, first_stmt, all_other_stmts] | |
120 # We need to insert our new stuff before the first_stmt and change the | |
121 # first_stmt's prefix. | |
122 | |
123 suite = node.children[4] | |
124 first_stmt = suite.children[2] | |
125 ident = indentation(first_stmt) | |
126 | |
127 for name, default_value in gen_params(params_rawlist): | |
128 if default_value is None: | |
129 suite.insert_child(2, Newline()) | |
130 suite.insert_child(2, String(_assign_template %{u'name':name, u'kwargs':new_kwargs}, prefix=ident)) | |
131 else: | |
132 suite.insert_child(2, Newline()) | |
133 suite.insert_child(2, String(_else_template %{u'name':name, u'default':default_value}, prefix=ident)) | |
134 suite.insert_child(2, Newline()) | |
135 suite.insert_child(2, String(_if_template %{u'assign':_assign_template %{u'name':name, u'kwargs':new_kwargs}, u'name':name, u'kwargs':new_kwargs}, prefix=ident)) | |
136 first_stmt.prefix = ident | |
137 suite.children[2].prefix = u"" | |
138 | |
139 # Now, we need to fix up the list of params. | |
140 | |
141 must_add_kwargs = remove_params(params_rawlist) | |
142 if must_add_kwargs: | |
143 arglist = results[u'arglist'] | |
144 if len(arglist.children) > 0 and arglist.children[-1].type != token.COMMA: | |
145 arglist.append_child(Comma()) | |
146 arglist.append_child(DoubleStar(prefix=u" ")) | |
147 arglist.append_child(Name(new_kwargs)) |