Merged revisions 61724-61824 via svnmerge from

svn+ssh://pythondev@svn.python.org/sandbox/trunk/2to3/lib2to3

........
  r61730 | martin.v.loewis | 2008-03-22 02:20:58 +0100 (Sa, 22 Mär 2008) | 2 lines

  More explicit relative imports.
........
  r61755 | david.wolever | 2008-03-22 21:33:52 +0100 (Sa, 22 Mär 2008) | 1 line

  Fixing #2446 -- 2to3 now translates 'import foo' to 'from . import foo'
........
  r61824 | david.wolever | 2008-03-24 01:30:24 +0100 (Mo, 24 Mär 2008) | 3 lines

  Fixed a bug where 'from itertools import izip' would return 'from itertools import'
........
This commit is contained in:
Martin v. Löwis 2008-03-24 00:46:53 +00:00
parent 440ca772f3
commit 966d0e0930
6 changed files with 62 additions and 23 deletions

View File

@ -7,19 +7,20 @@
And this import: And this import:
import spam import spam
Becomes: Becomes:
import .spam from . import spam
""" """
# Local imports # Local imports
from . import basefix from . import basefix
from os.path import dirname, join, exists, pathsep from os.path import dirname, join, exists, pathsep
from .util import FromImport
class FixImport(basefix.BaseFix): class FixImport(basefix.BaseFix):
PATTERN = """ PATTERN = """
import_from< 'from' imp=any 'import' any > import_from< type='from' imp=any 'import' any >
| |
import_name< 'import' imp=any > import_name< type='import' imp=any >
""" """
def transform(self, node, results): def transform(self, node, results):
@ -33,15 +34,19 @@ def transform(self, node, results):
# I guess this is a global import -- skip it! # I guess this is a global import -- skip it!
return return
if results['type'].value == 'from':
# Some imps are top-level (eg: 'import ham') # Some imps are top-level (eg: 'import ham')
# some are first level (eg: 'import ham.eggs') # some are first level (eg: 'import ham.eggs')
# some are third level (eg: 'import ham.eggs as spam') # some are third level (eg: 'import ham.eggs as spam')
# Hence, the loop # Hence, the loop
while not hasattr(imp, 'value'): while not hasattr(imp, 'value'):
imp = imp.children[0] imp = imp.children[0]
imp.value = "." + imp.value imp.value = "." + imp.value
node.changed() node.changed()
else:
new = FromImport('.', getattr(imp, 'content', None) or [imp])
new.prefix = node.get_prefix()
node = new
return node return node
def probably_a_local_import(imp_name, file_path): def probably_a_local_import(imp_name, file_path):

View File

@ -17,6 +17,9 @@ def transform(self, node, results):
# Handle 'import ... as ...' # Handle 'import ... as ...'
continue continue
if child.value in ('imap', 'izip', 'ifilter'): if child.value in ('imap', 'izip', 'ifilter'):
# The value must be set to none in case child == import,
# so that the test for empty imports will work out
child.value = None
child.remove() child.remove()
elif child.value == 'ifilterfalse': elif child.value == 'ifilterfalse':
node.changed() node.changed()
@ -34,10 +37,9 @@ def transform(self, node, results):
if unicode(children[-1]) == ',': if unicode(children[-1]) == ',':
children[-1].remove() children[-1].remove()
# If there is nothing left, return a blank line # If there are no imports left, just get rid of the entire statement
if not (imports.children or getattr(imports, 'value', None)): if not (imports.children or getattr(imports, 'value', None)):
new = BlankLine() p = node.get_prefix()
new.prefix = node.get_prefix() node = BlankLine()
else: node.prefix = p
new = node return node
return new

View File

@ -108,6 +108,26 @@ def ListComp(xp, fp, it, test=None):
inner, inner,
Leaf(token.RBRACE, "]")]) Leaf(token.RBRACE, "]")])
def FromImport(package_name, name_leafs):
""" Return an import statement in the form:
from package import name_leafs"""
# XXX: May not handle dotted imports properly (eg, package_name='foo.bar')
assert package_name == '.' or '.' not in package.name, "FromImport has "\
"not been tested with dotted package names -- use at your own "\
"peril!"
for leaf in name_leafs:
# Pull the leaves out of their old tree
leaf.remove()
children = [Leaf(token.NAME, 'from'),
Leaf(token.NAME, package_name, prefix=" "),
Leaf(token.NAME, 'import', prefix=" "),
Node(syms.import_as_names, name_leafs)]
imp = Node(syms.import_from, children)
return imp
########################################################### ###########################################################
### Determine whether a node represents a given literal ### Determine whether a node represents a given literal
########################################################### ###########################################################

View File

@ -13,7 +13,7 @@
from time import time from time import time
# Test imports # Test imports
from support import adjust_path from .support import adjust_path
adjust_path() adjust_path()
# Local imports # Local imports

View File

@ -7,7 +7,7 @@
__author__ = "Guido van Rossum <guido@python.org>" __author__ = "Guido van Rossum <guido@python.org>"
# Support imports (need to be imported first) # Support imports (need to be imported first)
import support from . import support
# Python imports # Python imports
import os import os

View File

@ -3036,6 +3036,10 @@ def test_none(self):
a = "" a = ""
self.check(b, a) self.check(b, a)
b = "from itertools import izip"
a = ""
self.check(b, a)
def test_import_as(self): def test_import_as(self):
b = "from itertools import izip, bar as bang, imap" b = "from itertools import izip, bar as bang, imap"
a = "from itertools import bar as bang" a = "from itertools import bar as bang"
@ -3105,6 +3109,10 @@ def p(path):
self.failUnlessEqual(set(self.files_checked), expected_checks) self.failUnlessEqual(set(self.files_checked), expected_checks)
def test_from(self): def test_from(self):
b = "from foo import bar, baz"
a = "from .foo import bar, baz"
self.check_both(b, a)
b = "from foo import bar" b = "from foo import bar"
a = "from .foo import bar" a = "from .foo import bar"
self.check_both(b, a) self.check_both(b, a)
@ -3121,17 +3129,21 @@ def test_from_as(self):
def test_import(self): def test_import(self):
b = "import foo" b = "import foo"
a = "import .foo" a = "from . import foo"
self.check_both(b, a)
b = "import foo, bar"
a = "from . import foo, bar"
self.check_both(b, a) self.check_both(b, a)
def test_dotted_import(self): def test_dotted_import(self):
b = "import foo.bar" b = "import foo.bar"
a = "import .foo.bar" a = "from . import foo.bar"
self.check_both(b, a) self.check_both(b, a)
def test_dotted_import_as(self): def test_dotted_import_as(self):
b = "import foo.bar as bang" b = "import foo.bar as bang"
a = "import .foo.bar as bang" a = "from . import foo.bar as bang"
self.check_both(b, a) self.check_both(b, a)