diff options
author | Benjamin Peterson <benjamin@python.org> | 2009-01-03 16:53:14 (GMT) |
---|---|---|
committer | Benjamin Peterson <benjamin@python.org> | 2009-01-03 16:53:14 (GMT) |
commit | 8bcddcabd770dd424b97d7c667ef8e5337436215 (patch) | |
tree | 7a35c40c0a1cf0b67b7b2cee1a53cf049d6cd9a5 /Lib/lib2to3/fixes/fix_import.py | |
parent | 627cf6a976d1401a7121fd58d0620ecb969a3fcd (diff) | |
download | cpython-8bcddcabd770dd424b97d7c667ef8e5337436215.zip cpython-8bcddcabd770dd424b97d7c667ef8e5337436215.tar.gz cpython-8bcddcabd770dd424b97d7c667ef8e5337436215.tar.bz2 |
Merged revisions 68197 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
................
r68197 | benjamin.peterson | 2009-01-03 10:34:02 -0600 (Sat, 03 Jan 2009) | 55 lines
Merged revisions 67900-67901,67919,67928,67984,67991-67993,68106-68108,68110 via svnmerge from
svn+ssh://pythondev@svn.python.org/sandbox/trunk/2to3/lib2to3
........
r67900 | benjamin.peterson | 2008-12-22 14:02:45 -0600 (Mon, 22 Dec 2008) | 4 lines
fix_execfile: wrap the open(fn).read() call in compile(), so the filename is preserved
also add unittests for the fixer
........
r67901 | benjamin.peterson | 2008-12-22 14:09:55 -0600 (Mon, 22 Dec 2008) | 1 line
remove unused import
........
r67919 | benjamin.peterson | 2008-12-23 13:12:22 -0600 (Tue, 23 Dec 2008) | 1 line
copy permission bits from the backup to the original
........
r67928 | benjamin.peterson | 2008-12-26 20:49:30 -0600 (Fri, 26 Dec 2008) | 1 line
don't be so idiot about multiple local imports in fix_import; still won't handle absolute and local imports on the same line
........
r67984 | benjamin.peterson | 2008-12-28 09:55:16 -0600 (Sun, 28 Dec 2008) | 1 line
don't need loop
........
r67991 | benjamin.peterson | 2008-12-28 14:30:26 -0600 (Sun, 28 Dec 2008) | 1 line
actually call finish_tree()
........
r67992 | benjamin.peterson | 2008-12-28 14:34:47 -0600 (Sun, 28 Dec 2008) | 1 line
remove useless test
........
r67993 | benjamin.peterson | 2008-12-28 15:04:32 -0600 (Sun, 28 Dec 2008) | 1 line
update pyk3's test grammar
........
r68106 | benjamin.peterson | 2008-12-31 11:53:58 -0600 (Wed, 31 Dec 2008) | 1 line
#2734 don't convert every instance of long (eg if it's an attribute)
........
r68107 | benjamin.peterson | 2008-12-31 11:55:10 -0600 (Wed, 31 Dec 2008) | 1 line
add another test
........
r68108 | benjamin.peterson | 2008-12-31 12:00:12 -0600 (Wed, 31 Dec 2008) | 1 line
don't change long even if it's the only argument name
........
r68110 | benjamin.peterson | 2008-12-31 14:13:26 -0600 (Wed, 31 Dec 2008) | 1 line
remove unused import
........
................
Diffstat (limited to 'Lib/lib2to3/fixes/fix_import.py')
-rw-r--r-- | Lib/lib2to3/fixes/fix_import.py | 87 |
1 files changed, 55 insertions, 32 deletions
diff --git a/Lib/lib2to3/fixes/fix_import.py b/Lib/lib2to3/fixes/fix_import.py index c065f70..4c75133 100644 --- a/Lib/lib2to3/fixes/fix_import.py +++ b/Lib/lib2to3/fixes/fix_import.py @@ -13,55 +13,78 @@ Becomes: # Local imports from .. import fixer_base from os.path import dirname, join, exists, pathsep -from ..fixer_util import FromImport, syms +from ..fixer_util import FromImport, syms, token + + +def traverse_imports(names): + """ + Walks over all the names imported in a dotted_as_names node. + """ + pending = [names] + while pending: + node = pending.pop() + if node.type == token.NAME: + yield node.value + elif node.type == syms.dotted_name: + yield "".join([ch.value for ch in node.children]) + elif node.type == syms.dotted_as_name: + pending.append(node.children[0]) + elif node.type == syms.dotted_as_names: + pending.extend(node.children[::-2]) + else: + raise AssertionError("unkown node type") + class FixImport(fixer_base.BaseFix): PATTERN = """ - import_from< type='from' imp=any 'import' ['('] any [')'] > + import_from< 'from' imp=any 'import' ['('] any [')'] > | - import_name< type='import' imp=any > + import_name< 'import' imp=any > """ def transform(self, node, results): imp = results['imp'] - mod_name = str(imp.children[0] if imp.type == syms.dotted_as_name \ - else imp) - - if str(imp).startswith('.'): - # Already a new-style import - return - - if not probably_a_local_import(str(mod_name), self.filename): - # I guess this is a global import -- skip it! - return - - if results['type'].value == 'from': + if node.type == syms.import_from: # Some imps are top-level (eg: 'import ham') # some are first level (eg: 'import ham.eggs') # some are third level (eg: 'import ham.eggs as spam') # Hence, the loop while not hasattr(imp, 'value'): imp = imp.children[0] - imp.value = "." + imp.value - node.changed() + if self.probably_a_local_import(imp.value): + imp.value = "." + imp.value + imp.changed() + return node else: - new = FromImport('.', getattr(imp, 'content', None) or [imp]) + have_local = False + have_absolute = False + for mod_name in traverse_imports(imp): + if self.probably_a_local_import(mod_name): + have_local = True + else: + have_absolute = True + if have_absolute: + if have_local: + # We won't handle both sibling and absolute imports in the + # same statement at the moment. + self.warning(node, "absolute and local imports together") + return + + new = FromImport('.', [imp]) new.set_prefix(node.get_prefix()) - node = new - return node + return new -def probably_a_local_import(imp_name, file_path): - # Must be stripped because the right space is included by the parser - imp_name = imp_name.split('.', 1)[0].strip() - base_path = dirname(file_path) - base_path = join(base_path, imp_name) - # If there is no __init__.py next to the file its not in a package - # so can't be a relative import. - if not exists(join(dirname(base_path), '__init__.py')): + def probably_a_local_import(self, imp_name): + imp_name = imp_name.split('.', 1)[0] + base_path = dirname(self.filename) + base_path = join(base_path, imp_name) + # If there is no __init__.py next to the file its not in a package + # so can't be a relative import. + if not exists(join(dirname(base_path), '__init__.py')): + return False + for ext in ['.py', pathsep, '.pyc', '.so', '.sl', '.pyd']: + if exists(base_path + ext): + return True return False - for ext in ['.py', pathsep, '.pyc', '.so', '.sl', '.pyd']: - if exists(base_path + ext): - return True - return False |