Mercurial > repos > shellac > guppy_basecaller
comparison env/lib/python3.7/site-packages/libpasteurize/fixes/fix_kwargs.py @ 5:9b1c78e6ba9c draft default tip
"planemo upload commit 6c0a8142489327ece472c84e558c47da711a9142"
| author | shellac |
|---|---|
| date | Mon, 01 Jun 2020 08:59:25 -0400 |
| parents | 79f47841a781 |
| children |
comparison
equal
deleted
inserted
replaced
| 4:79f47841a781 | 5:9b1c78e6ba9c |
|---|---|
| 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)) |
