[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