# HG changeset patch # User Paul Boddie # Date 1381258449 -7200 # Node ID d3a80d3d317ae3e6338ab9b7c24da80dca4976e9 # Parent dae271433bf57d848470c2f18c007f515fa47a20 Added support for explicit relative imports. diff -r dae271433bf5 -r d3a80d3d317a micropython/inspect.py --- a/micropython/inspect.py Tue Oct 08 20:53:03 2013 +0200 +++ b/micropython/inspect.py Tue Oct 08 20:54:09 2013 +0200 @@ -224,16 +224,17 @@ # Module import declarations. elif isinstance(n, compiler.ast.From): + modname = self.get_module_name(n) # Load the mentioned module. - self.record_import(n.modname, n) + self.record_import(modname, n) # Speculatively load modules for names beneath the module. for name, alias in n.names: - modname = n.modname + "." + name - self.record_import(modname, n) + subname = modname + "." + name + self.record_import(subname, n) elif isinstance(n, compiler.ast.Import): @@ -252,6 +253,32 @@ else: self.process_structure(n) + def get_module_name(self, node): + + """ + Return the module name from the given 'node', calculated using any + relative import information. + """ + + # Absolute import. + + if node.level == 0: + return node.modname + + # Relative to this module. + + elif node.level == 1: + return "%s.%s" % (self.full_name(), node.modname) + + # Relative to an ancestor of this module. + + else: + path = self.full_name().split(".") + if node.level > len(path): + raise InspectError("Relative import %r involves too many levels up from module %r" % (("." * node.level + node.modname), self.full_name())) + else: + return "%s.%s" % (".".join(path[:-node.level+1]), node.modname) + def get_module_paths(self, name): """ @@ -1125,7 +1152,8 @@ self.resume_broken_branches() def visitFrom(self, node): - module = self.complete_import(node.modname, True) + modname = self.get_module_name(node) + module = self.complete_import(modname, True) for name, alias in node.names: @@ -1137,7 +1165,7 @@ # Missing names may refer to submodules. - submodule = self.complete_import(node.modname + "." + name, True) + submodule = self.complete_import(modname + "." + name, True) if submodule: if not module.has_key(name): module.store(name, submodule) @@ -1152,7 +1180,7 @@ # Support the import of names from missing modules. - self.store(alias or name, UnresolvedName(name, node.modname, self)) + self.store(alias or name, UnresolvedName(name, modname, self)) # For wildcards, obtain and store all objects from a module in the # current namespace. diff -r dae271433bf5 -r d3a80d3d317a tests/relative/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/relative/__init__.py Tue Oct 08 20:54:09 2013 +0200 @@ -0,0 +1,3 @@ +#!/usr/bin/env python + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r dae271433bf5 -r d3a80d3d317a tests/relative/subpackage/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/relative/subpackage/__init__.py Tue Oct 08 20:54:09 2013 +0200 @@ -0,0 +1,6 @@ +#!/usr/bin/env python + +from ..upper import x +from .sibling import y + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r dae271433bf5 -r d3a80d3d317a tests/relative/subpackage/sibling.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/relative/subpackage/sibling.py Tue Oct 08 20:54:09 2013 +0200 @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +y = 456 + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r dae271433bf5 -r d3a80d3d317a tests/relative/upper.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/relative/upper.py Tue Oct 08 20:54:09 2013 +0200 @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +x = 123 + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r dae271433bf5 -r d3a80d3d317a tests/relative_import.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/relative_import.py Tue Oct 08 20:54:09 2013 +0200 @@ -0,0 +1,8 @@ +#!/usr/bin/env python + +import relative.subpackage + +result_123 = relative.subpackage.x +result_456 = relative.subpackage.y + +# vim: tabstop=4 expandtab shiftwidth=4