Skip to content

Commit 55e8227

Browse files
committed
Refactor and clean up fixer_util a bit
1 parent 0922f8d commit 55e8227

File tree

1 file changed

+48
-9
lines changed

1 file changed

+48
-9
lines changed

src/libfuturize/fixer_util.py

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,38 @@
1717
import re
1818

1919

20+
def canonical_fix_name(fix, avail_fixes):
21+
"""
22+
Examples:
23+
>>> canonical_fix_name('fix_wrap_text_literals')
24+
'libfuturize.fixes.fix_wrap_text_literals'
25+
>>> canonical_fix_name('wrap_text_literals')
26+
'libfuturize.fixes.fix_wrap_text_literals'
27+
>>> canonical_fix_name('wrap_te')
28+
ValueError("unknown fixer name")
29+
>>> canonical_fix_name('wrap')
30+
ValueError("ambiguous fixer name")
31+
"""
32+
if ".fix_" in fix:
33+
return fix
34+
else:
35+
if fix.startswith('fix_'):
36+
fix = fix[4:]
37+
# Infer the full module name for the fixer.
38+
# First ensure that no names clash (e.g.
39+
# lib2to3.fixes.fix_blah and libfuturize.fixes.fix_blah):
40+
found = [f for f in avail_fixes
41+
if f.endswith('fix_{0}'.format(fix))]
42+
if len(found) > 1:
43+
raise ValueError("Ambiguous fixer name. Choose a fully qualified "
44+
"module name instead from these:\n" +
45+
"\n".join(" " + myf for myf in found))
46+
elif len(found) == 0:
47+
raise ValueError("Unknown fixer. Use --list-fixes or -l for a list.")
48+
return found[0]
49+
50+
51+
2052
## These functions are from 3to2 by Joe Amenta:
2153

2254
def Star(prefix=None):
@@ -29,7 +61,7 @@ def Minus(prefix=None):
2961
return Leaf(token.MINUS, u'-', prefix=prefix)
3062

3163
def commatize(leafs):
32-
u"""
64+
"""
3365
Accepts/turns: (Name, Name, ..., Name, Name)
3466
Returns/into: (Name, Comma, Name, Comma, ..., Name, Comma, Name)
3567
"""
@@ -41,7 +73,7 @@ def commatize(leafs):
4173
return new_leafs
4274

4375
def indentation(node):
44-
u"""
76+
"""
4577
Returns the indentation for this node
4678
Iff a node is in a suite, then it has indentation.
4779
"""
@@ -62,7 +94,7 @@ def indentation(node):
6294
return node.prefix
6395

6496
def indentation_step(node):
65-
u"""
97+
"""
6698
Dirty little trick to get the difference between each indentation level
6799
Implemented by finding the shortest indentation string
68100
(technically, the "least" of all of the indentation strings, but
@@ -78,7 +110,7 @@ def indentation_step(node):
78110
return min(all_indents)
79111

80112
def suitify(parent):
81-
u"""
113+
"""
82114
Turn the stuff after the first colon in parent's children
83115
into a suite, if it wasn't already
84116
"""
@@ -102,7 +134,7 @@ def suitify(parent):
102134
parent.append_child(suite)
103135

104136
def NameImport(package, as_name=None, prefix=None):
105-
u"""
137+
"""
106138
Accepts a package (Name node), name to import it as (string), and
107139
optional prefix and returns a node:
108140
import <package> [as <as_name>]
@@ -119,7 +151,7 @@ def NameImport(package, as_name=None, prefix=None):
119151
_import_stmts = (syms.import_name, syms.import_from)
120152

121153
def import_binding_scope(node):
122-
u"""
154+
"""
123155
Generator yields all nodes for which a node (an import_stmt) has scope
124156
The purpose of this is for a call to _find() on each of them
125157
"""
@@ -187,6 +219,14 @@ def ImportAsName(name, as_name, prefix=None):
187219
return new_node
188220

189221

222+
def is_docstring(node):
223+
"""
224+
Returns True if the node appears to be a docstring
225+
"""
226+
return (node.type == syms.simple_stmt and
227+
len(node.children) > 0 and node.children[0].type == token.STRING)
228+
229+
190230
def future_import(feature, node):
191231
"""
192232
This seems to work
@@ -203,8 +243,7 @@ def future_import(feature, node):
203243
# Is it a shebang or encoding line?
204244
if is_shebang_comment(node) or is_encoding_comment(node):
205245
shebang_encoding_idx = idx
206-
if node.type == syms.simple_stmt and \
207-
len(node.children) > 0 and node.children[0].type == token.STRING:
246+
if is_docstring(node):
208247
# skip over docstring
209248
continue
210249
names = check_future_import(node)
@@ -346,7 +385,7 @@ def touch_import_top(package, name_to_import, node):
346385
for idx, node in enumerate(root.children):
347386
if node.type != syms.simple_stmt:
348387
break
349-
if not (node.children and node.children[0].type == token.STRING):
388+
if not is_docstring(node):
350389
# This is the usual case.
351390
break
352391
insert_pos = idx

0 commit comments

Comments
 (0)