Commit 13914715 authored by Dylan Trotter's avatar Dylan Trotter Committed by Dylan Trotter

Implement absolute_import.

parent c6c46bd7
......@@ -34,7 +34,7 @@ _NATIVE_MODULE_PREFIX = '__go__.'
class Path(object):
"""Resolves imported modules based on a search path of directories."""
def __init__(self, gopath, modname, script):
def __init__(self, gopath, modname, script, absolute_import):
self.dirs = []
if gopath:
self.dirs.extend(os.path.join(d, 'src', '__python__')
......@@ -50,6 +50,7 @@ class Path(object):
else:
self.package_dir = None
self.package_name = None
self.absolute_import = absolute_import
def resolve_import(self, modname):
"""Find module on the path returning full module name and script path.
......@@ -61,7 +62,7 @@ class Path(object):
A pair (full_name, script), where full_name is the absolute module name
and script is the filename of the associate .py file.
"""
if self.package_dir:
if not self.absolute_import and self.package_dir:
script = self._find_script(self.package_dir, modname)
if script:
return '{}.{}'.format(self.package_name, modname), script
......@@ -178,7 +179,7 @@ _FUTURE_FEATURES = (
'unicode_literals',
)
_IMPLEMENTED_FUTURE_FEATURES = ('print_function',)
_IMPLEMENTED_FUTURE_FEATURES = ('absolute_import', 'print_function',)
# These future features are already in the language proper as of 2.6, so
# importing them via __future__ has no effect.
......@@ -188,8 +189,10 @@ _REDUNDANT_FUTURE_FEATURES = ('generators', 'with_statement', 'nested_scopes')
class FutureFeatures(object):
def __init__(self):
for name in _FUTURE_FEATURES:
setattr(self, name, False)
self.absolute_import = False
self.division = False
self.print_function = False
self.unicode_literals = False
def _make_future_features(node):
......
......@@ -72,18 +72,18 @@ class _MaterializedPathTree(object):
class PathTest(unittest.TestCase):
def testResolveImportEmptyPath(self):
path = imputil.Path(None, 'foo', 'foo.py')
path = imputil.Path(None, 'foo', 'foo.py', False)
self.assertEqual(path.resolve_import('bar'), (None, None))
def testResolveImportTopLevelModule(self):
with _MaterializedPathTree({'bar.py': None}) as tree:
path = imputil.Path(tree.rootdir, 'foo', 'foo.py')
path = imputil.Path(tree.rootdir, 'foo', 'foo.py', False)
want = ('bar', os.path.join(tree.pydir, 'bar.py'))
self.assertEqual(path.resolve_import('bar'), want)
def testResolveImportTopLevelPackage(self):
with _MaterializedPathTree({'bar/': {'__init__.py': None}}) as tree:
path = imputil.Path(tree.rootdir, 'foo', 'foo.py')
path = imputil.Path(tree.rootdir, 'foo', 'foo.py', False)
want = ('bar', os.path.join(tree.pydir, 'bar', '__init__.py'))
self.assertEqual(path.resolve_import('bar'), want)
......@@ -95,7 +95,7 @@ class PathTest(unittest.TestCase):
}
}
with _MaterializedPathTree(spec) as tree:
path = imputil.Path(tree.rootdir, 'foo', 'foo.py')
path = imputil.Path(tree.rootdir, 'foo', 'foo.py', False)
want = ('bar.baz', os.path.join(tree.pydir, 'bar', 'baz.py'))
self.assertEqual(path.resolve_import('bar.baz'), want)
......@@ -104,14 +104,29 @@ class PathTest(unittest.TestCase):
'bar/': {
'__init__.py': None,
'baz.py': None,
}
},
'baz.py': None,
}
with _MaterializedPathTree(spec) as tree:
bar_script = os.path.join(tree.pydir, 'bar', '__init__.py')
path = imputil.Path(tree.rootdir, 'bar', bar_script)
path = imputil.Path(tree.rootdir, 'bar', bar_script, False)
want = ('bar.baz', os.path.join(tree.pydir, 'bar', 'baz.py'))
self.assertEqual(path.resolve_import('baz'), want)
def testResolveImportPackageModuleAbsoluteImport(self):
spec = {
'bar/': {
'__init__.py': None,
'baz.py': None,
},
'baz.py': None,
}
with _MaterializedPathTree(spec) as tree:
bar_script = os.path.join(tree.pydir, 'bar', '__init__.py')
path = imputil.Path(tree.rootdir, 'bar', bar_script, True)
want = ('baz', os.path.join(tree.pydir, 'baz.py'))
self.assertEqual(path.resolve_import('baz'), want)
def testResolveImportPackageModuleRelativeFromSubModule(self):
spec = {
'bar/': {
......@@ -122,7 +137,7 @@ class PathTest(unittest.TestCase):
}
with _MaterializedPathTree(spec) as tree:
foo_script = os.path.join(tree.pydir, 'bar', 'foo.py')
path = imputil.Path(tree.rootdir, 'bar.foo', foo_script)
path = imputil.Path(tree.rootdir, 'bar.foo', foo_script, False)
want = ('bar.baz', os.path.join(tree.pydir, 'bar', 'baz.py'))
self.assertEqual(path.resolve_import('baz'), want)
......@@ -278,8 +293,9 @@ class MakeFutureFeaturesTest(unittest.TestCase):
class ParseFutureFeaturesTest(unittest.TestCase):
def testFutureFeatures(self):
print_function_features = imputil.FutureFeatures()
print_function_features.print_function = True
print_function_features = {'print_function': True}
absolute_import_features = {'absolute_import': True}
all_features = {'print_function': True, 'absolute_import': True}
testcases = [
('from __future__ import print_function',
print_function_features),
......@@ -294,13 +310,17 @@ class ParseFutureFeaturesTest(unittest.TestCase):
from __future__ import print_function, with_statement
from __future__ import nested_scopes
""", print_function_features),
('from __future__ import absolute_import',
absolute_import_features),
('from __future__ import absolute_import, print_function',
all_features),
]
for tc in testcases:
source, want = tc
mod = pythonparser.parse(textwrap.dedent(source))
_, got = imputil.parse_future_features(mod)
self.assertEqual(want.__dict__, got.__dict__)
self.assertEqual(want, got.__dict__)
def testFutureAfterAssignRaises(self):
source = 'foo = 123\nfrom __future__ import print_function'
......
......@@ -64,7 +64,8 @@ def main(args):
print >> sys.stderr, str(e)
return 2
path = imputil.Path(gopath, args.modname, args.script)
path = imputil.Path(gopath, args.modname, args.script,
future_features.absolute_import)
full_package_name = args.modname.replace('.', '/')
mod_block = block.ModuleBlock(path, full_package_name, args.script,
py_contents, future_features)
......
......@@ -36,7 +36,6 @@ def main(args):
if not gopath:
print >> sys.stderr, 'GOPATH not set'
return 1
path = imputil.Path(gopath, args.modname, args.script)
with open(args.script) as py_file:
py_contents = py_file.read()
......@@ -48,11 +47,13 @@ def main(args):
return 2
try:
future_node, _ = imputil.parse_future_features(mod)
future_node, future_features = imputil.parse_future_features(mod)
except util.CompileError as e:
print >> sys.stderr, str(e)
return 2
path = imputil.Path(gopath, args.modname, args.script,
future_features.absolute_import)
visitor = imputil.ImportVisitor(path, future_node)
try:
visitor.visit(mod)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment