[Python-checkins] r61477 - sandbox/trunk/2to3/lib2to3/fixes/util.py
david.wolever
python-checkins at python.org
Tue Mar 18 04:11:28 CET 2008
Author: david.wolever
Date: Tue Mar 18 04:11:27 2008
New Revision: 61477
Modified:
sandbox/trunk/2to3/lib2to3/fixes/util.py
Log:
Fixes bugs in find_binding where it would miss certain cases (especially with imports), added the package argument which makes it easy to filter imports. See docstrings.
Modified: sandbox/trunk/2to3/lib2to3/fixes/util.py
==============================================================================
--- sandbox/trunk/2to3/lib2to3/fixes/util.py (original)
+++ sandbox/trunk/2to3/lib2to3/fixes/util.py Tue Mar 18 04:11:27 2008
@@ -194,36 +194,57 @@
return suite
_def_syms = set([syms.classdef, syms.funcdef])
-def find_binding(name, node):
+def find_binding(name, node, package=None):
+ """ Returns the node which binds variable name, otherwise None.
+ If optional argument package is supplied, only imports will
+ be returned.
+ >>> for args in (('map', 'map = 3'),
+ ('map', 'from foo import map'),
+ ('map', 'from foo import map', 'foo'),
+ ('map', 'from bar import map', 'foo'),
+ ('map', 'map = 3', 'foo')):
+ print bool(find_binding(*args))
+ True
+ True
+ True
+ False
+ False
+ >>> """
for child in node.children:
+ ret = None
if child.type == syms.for_stmt:
if _find(name, child.children[1]):
return child
- n = find_binding(name, make_suite(child.children[-1]))
- if n:
- return n
+ n = find_binding(name, make_suite(child.children[-1]), package)
+ if n: ret = n
elif child.type in (syms.if_stmt, syms.while_stmt):
- n = find_binding(name, make_suite(child.children[-1]))
- if n:
- return n
+ n = find_binding(name, make_suite(child.children[-1]), package)
+ if n: ret = n
elif child.type == syms.try_stmt:
- n = find_binding(name, make_suite(child.children[2]))
+ n = find_binding(name, make_suite(child.children[2]), package)
if n:
- return n
- for i, kid in enumerate(child.children[3:]):
- if kid.type == token.COLON and kid.value == ":":
- # i+3 is the colon, i+4 is the suite
- n = find_binding(name, make_suite(child.children[i+4]))
- if n:
- return n
+ ret = n
+ else:
+ for i, kid in enumerate(child.children[3:]):
+ if kid.type == token.COLON and kid.value == ":":
+ # i+3 is the colon, i+4 is the suite
+ n = find_binding(name, make_suite(child.children[i+4]), package)
+ if n: ret = n
elif child.type in _def_syms and child.children[1].value == name:
- return child
- elif _is_import_binding(child, name):
+ ret = child
+ elif _is_import_binding(child, name, package):
return child
elif child.type == syms.simple_stmt:
- if child.children[0].type == syms.expr_stmt:
- if _find(name, child.children[0].children[0]):
- return child.children[0]
+ ret = find_binding(name, child, package)
+ elif child.type == syms.expr_stmt:
+ if _find(name, child.children[0]):
+ ret = child
+
+ if not package and ret:
+ # Because the _is_import_binding returns directly, we don't want
+ # to return here if a package is defined.
+ return ret
+ return None
_block_syms = set([syms.funcdef, syms.classdef, syms.trailer])
def _find(name, node):
@@ -236,32 +257,49 @@
return node
return None
-def _is_import_binding(node, name):
- if node.type == syms.simple_stmt:
- i = node.children[0]
- if i.type == syms.import_name:
- imp = i.children[1]
- if imp.type == syms.dotted_as_names:
- for child in imp.children:
- if child.type == syms.dotted_as_name:
- if child.children[2].value == name:
- return i
- elif child.type == token.NAME and child.value == name:
- return i
- elif imp.type == syms.dotted_as_name:
- last = imp.children[-1]
- if last.type == token.NAME and last.value == name:
- return i
- elif imp.type == token.NAME and imp.value == name:
- return i
- elif i.type == syms.import_from:
- n = i.children[3]
- if n.type == syms.import_as_names and _find(name, n):
- return i
- elif n.type == syms.import_as_name:
- child = n.children[2]
- if child.type == token.NAME and child.value == name:
- return i
- elif n.type == token.NAME and n.value == name:
- return i
+def _is_import_binding(node, name, package=None):
+ """ Will reuturn node if node will import name, or node
+ will import * from package. None is returned otherwise.
+ >>> for n in ('from datetime import date',
+ 'from datetime import *',
+ 'import date',
+ 'from spam import date'):
+ print bool(_is_import_binding(n, 'date', 'datetime'))
+ True
+ True
+ True
+ False
+ >>> bool(_is_import_binding('from spam import date', 'date')
+ True
+ >>> """
+
+ if node.type == syms.import_name:
+ imp = node.children[1]
+ if imp.type == syms.dotted_as_names:
+ for child in imp.children:
+ if child.type == syms.dotted_as_name:
+ if child.children[2].value == name:
+ return node
+ elif child.type == token.NAME and child.value == name:
+ return node
+ elif imp.type == syms.dotted_as_name:
+ last = imp.children[-1]
+ if last.type == token.NAME and last.value == name:
+ return node
+ elif imp.type == token.NAME and imp.value == name:
+ return node
+ elif node.type == syms.import_from:
+ if package and node.children[1].value != package:
+ return None
+ n = node.children[3]
+ if n.type == syms.import_as_names and _find(name, n):
+ return node
+ elif n.type == syms.import_as_name:
+ child = n.children[2]
+ if child.type == token.NAME and child.value == name:
+ return node
+ elif n.type == token.NAME and n.value == name:
+ return node
+ elif package and n.type == token.STAR:
+ return node
return None
More information about the Python-checkins
mailing list