summaryrefslogtreecommitdiffstats
path: root/Lib/lib2to3/fixer_util.py
diff options
context:
space:
mode:
authorBenjamin Peterson <benjamin@python.org>2008-12-16 03:49:59 (GMT)
committerBenjamin Peterson <benjamin@python.org>2008-12-16 03:49:59 (GMT)
commitc3224e2ca89fa25b4674a9b79e934d15e7fc7052 (patch)
treedaa171ea896b4fad27158594c5f44bad75da3cc5 /Lib/lib2to3/fixer_util.py
parent360d8cfc9dc0c2c1e2ecb0dfc4cc340efceca017 (diff)
downloadcpython-c3224e2ca89fa25b4674a9b79e934d15e7fc7052.zip
cpython-c3224e2ca89fa25b4674a9b79e934d15e7fc7052.tar.gz
cpython-c3224e2ca89fa25b4674a9b79e934d15e7fc7052.tar.bz2
Merged revisions 67806 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ................ r67806 | benjamin.peterson | 2008-12-15 21:35:28 -0600 (Mon, 15 Dec 2008) | 111 lines Merged revisions 67427,67431,67433,67435,67630,67652,67656-67657,67674-67675,67678-67679,67705-67706,67716,67723,67765-67771,67774,67776,67778 via svnmerge from svn+ssh://pythondev@svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r67427 | benjamin.peterson | 2008-11-28 16:07:41 -0600 (Fri, 28 Nov 2008) | 1 line fix spelling in comment ........ r67431 | benjamin.peterson | 2008-11-28 17:14:08 -0600 (Fri, 28 Nov 2008) | 1 line add a scripts directory; move things to it ........ r67433 | benjamin.peterson | 2008-11-28 17:18:48 -0600 (Fri, 28 Nov 2008) | 1 line run svneol.py ........ r67435 | benjamin.peterson | 2008-11-28 17:25:03 -0600 (Fri, 28 Nov 2008) | 1 line rename pre/post_order_mapping to pre/post_order_heads ........ r67630 | alexandre.vassalotti | 2008-12-06 21:51:56 -0600 (Sat, 06 Dec 2008) | 2 lines Fix typo in the urllib2.HTTPDigestAuthHandler fixer. ........ r67652 | armin.ronacher | 2008-12-07 15:39:43 -0600 (Sun, 07 Dec 2008) | 5 lines Added a fixer that cleans up a tuple argument to isinstance after the tokens in it were fixed. This is mainly used to remove double occurrences of tokens as a leftover of the long -> int / unicode -> str conversion. ........ r67656 | armin.ronacher | 2008-12-07 16:54:16 -0600 (Sun, 07 Dec 2008) | 3 lines Added missing copyright fo 2to3 fix_isinstance. ........ r67657 | armin.ronacher | 2008-12-07 18:29:35 -0600 (Sun, 07 Dec 2008) | 3 lines 2to3: intern and reduce fixes now add the imports if missing. Because that is a common task the fixer_util module now has a function "touch_import" that adds imports if missing. ........ r67674 | benjamin.peterson | 2008-12-08 19:58:11 -0600 (Mon, 08 Dec 2008) | 1 line copy permission bits when making backup files #4602 ........ r67675 | benjamin.peterson | 2008-12-08 19:59:11 -0600 (Mon, 08 Dec 2008) | 1 line add forgotten import ........ r67678 | benjamin.peterson | 2008-12-08 20:08:30 -0600 (Mon, 08 Dec 2008) | 1 line fix #4602 for real ........ r67679 | armin.ronacher | 2008-12-09 00:54:03 -0600 (Tue, 09 Dec 2008) | 3 lines Removed redudant code from the 2to3 long fixer. This fixes #4590. ........ r67705 | benjamin.peterson | 2008-12-11 13:04:08 -0600 (Thu, 11 Dec 2008) | 1 line put trailers after a range call after the list() ........ r67706 | benjamin.peterson | 2008-12-11 13:17:57 -0600 (Thu, 11 Dec 2008) | 1 line add html related modules to the fix_imports mapping ........ r67716 | benjamin.peterson | 2008-12-11 22:16:47 -0600 (Thu, 11 Dec 2008) | 1 line consolidate tests ........ r67723 | benjamin.peterson | 2008-12-12 19:49:31 -0600 (Fri, 12 Dec 2008) | 1 line fix name ........ r67765 | benjamin.peterson | 2008-12-14 14:05:05 -0600 (Sun, 14 Dec 2008) | 1 line run fix_isinstance after fix_long and fix_unicode ........ r67766 | benjamin.peterson | 2008-12-14 14:13:05 -0600 (Sun, 14 Dec 2008) | 1 line use run_order instead of order ........ r67767 | benjamin.peterson | 2008-12-14 14:28:12 -0600 (Sun, 14 Dec 2008) | 1 line don't retain parenthesis if there is only one item left ........ r67768 | benjamin.peterson | 2008-12-14 14:32:30 -0600 (Sun, 14 Dec 2008) | 1 line use insert_child() ........ r67769 | benjamin.peterson | 2008-12-14 14:59:10 -0600 (Sun, 14 Dec 2008) | 1 line parenthesize doesn't belong in pygram or FixerBase ........ r67770 | alexandre.vassalotti | 2008-12-14 15:15:36 -0600 (Sun, 14 Dec 2008) | 2 lines Fix typo: html.paser -> html.parser. ........ r67771 | benjamin.peterson | 2008-12-14 15:22:09 -0600 (Sun, 14 Dec 2008) | 1 line altering .children needs to call changed() ........ r67774 | benjamin.peterson | 2008-12-14 15:55:38 -0600 (Sun, 14 Dec 2008) | 1 line employ an evil hack to fix multiple names in the same import statement ........ r67776 | benjamin.peterson | 2008-12-14 16:22:38 -0600 (Sun, 14 Dec 2008) | 1 line make a common mixin class for Test_imports and friends ........ r67778 | alexandre.vassalotti | 2008-12-14 17:48:20 -0600 (Sun, 14 Dec 2008) | 2 lines Make fix_imports refactor multiple imports as. ........ ................
Diffstat (limited to 'Lib/lib2to3/fixer_util.py')
-rw-r--r--Lib/lib2to3/fixer_util.py74
1 files changed, 67 insertions, 7 deletions
diff --git a/Lib/lib2to3/fixer_util.py b/Lib/lib2to3/fixer_util.py
index ea394e8..0c485f0 100644
--- a/Lib/lib2to3/fixer_util.py
+++ b/Lib/lib2to3/fixer_util.py
@@ -158,6 +158,9 @@ def is_list(node):
### Misc
###########################################################
+def parenthesize(node):
+ return Node(syms.atom, [LParen(), node, RParen()])
+
consuming_calls = set(["sorted", "list", "set", "any", "all", "tuple", "sum",
"min", "max"])
@@ -232,20 +235,77 @@ def make_suite(node):
suite.parent = parent
return suite
-def does_tree_import(package, name, node):
- """ Returns true if name is imported from package at the
- top level of the tree which node belongs to.
- To cover the case of an import like 'import foo', use
- Null for the package and 'foo' for the name. """
+def find_root(node):
+ """Find the top level namespace."""
# Scamper up to the top level namespace
while node.type != syms.file_input:
assert node.parent, "Tree is insane! root found before "\
"file_input node was found."
node = node.parent
+ return node
- binding = find_binding(name, node, package)
+def does_tree_import(package, name, node):
+ """ Returns true if name is imported from package at the
+ top level of the tree which node belongs to.
+ To cover the case of an import like 'import foo', use
+ None for the package and 'foo' for the name. """
+ binding = find_binding(name, find_root(node), package)
return bool(binding)
+def is_import(node):
+ """Returns true if the node is an import statement."""
+ return node.type in (syms.import_name, syms.import_from)
+
+def touch_import(package, name, node):
+ """ Works like `does_tree_import` but adds an import statement
+ if it was not imported. """
+ def is_import_stmt(node):
+ return node.type == syms.simple_stmt and node.children and \
+ is_import(node.children[0])
+
+ root = find_root(node)
+
+ if does_tree_import(package, name, root):
+ return
+
+ add_newline_before = False
+
+ # figure out where to insert the new import. First try to find
+ # the first import and then skip to the last one.
+ insert_pos = offset = 0
+ for idx, node in enumerate(root.children):
+ if not is_import_stmt(node):
+ continue
+ for offset, node2 in enumerate(root.children[idx:]):
+ if not is_import_stmt(node2):
+ break
+ insert_pos = idx + offset
+ break
+
+ # if there are no imports where we can insert, find the docstring.
+ # if that also fails, we stick to the beginning of the file
+ if insert_pos == 0:
+ for idx, node in enumerate(root.children):
+ if node.type == syms.simple_stmt and node.children and \
+ node.children[0].type == token.STRING:
+ insert_pos = idx + 1
+ add_newline_before
+ break
+
+ if package is None:
+ import_ = Node(syms.import_name, [
+ Leaf(token.NAME, 'import'),
+ Leaf(token.NAME, name, prefix=' ')
+ ])
+ else:
+ import_ = FromImport(package, [Leaf(token.NAME, name, prefix=' ')])
+
+ children = [import_, Newline()]
+ if add_newline_before:
+ children.insert(0, Newline())
+ root.insert_child(insert_pos, Node(syms.simple_stmt, children))
+
+
_def_syms = set([syms.classdef, syms.funcdef])
def find_binding(name, node, package=None):
""" Returns the node which binds variable name, otherwise None.
@@ -285,7 +345,7 @@ def find_binding(name, node, package=None):
if ret:
if not package:
return ret
- if ret.type in (syms.import_name, syms.import_from):
+ if is_import(ret):
return ret
return None