def _resolve_relative_import(self, level, node, modname): if not self.package_dir: raise util.ImportError(node, 'attempted relative import in non-package') uplevel = level - 1 if uplevel > self.package_name.count('.'): raise util.ImportError( node, 'attempted relative import beyond toplevel package') dirname = os.path.normpath( os.path.join(self.package_dir, *(['..'] * uplevel))) script = find_script(dirname, modname or '__init__') if not script: raise util.ImportError( node, 'no such module: {} (script: {})'.format(modname, self.script)) parts = self.package_name.split('.') return Import( '.'.join(parts[:len(parts) - uplevel] + ([modname] if modname else [])), script)
def _resolve_import(self, node, modname): if not self.absolute_import and self.package_dir: script = find_script(self.package_dir, modname) if script: return Import( '.'.join((self.package_name, modname)).lstrip('.'), script) for dirname in self.pathdirs: script = find_script(dirname, modname) if script: return Import(modname, script) raise util.ImportError( node, 'no such module: {} (script: {})'.format(modname, self.script))
def visit_ImportFrom(self, node): if any(a.name == '*' for a in node.names): if len(node.names) != 1: # TODO: Change to SyntaxError, as CPython does on "from foo import *, bar" raise util.ImportError(node, 'invalid syntax on wildcard import') # Imported name is * (star). Will bind __all__ the module contents. imp = self._resolve_import(node, node.module, allow_error=True) imp.add_binding(Import.STAR, '*', imp.name.count('.')) return [imp] if not node.level and node.module == '__future__': return [] if not node.level and node.module.startswith(_NATIVE_MODULE_PREFIX): imp = Import(node.module, is_native=True) for alias in node.names: asname = alias.asname or alias.name imp.add_binding(Import.MEMBER, asname, alias.name) return [imp] imports = [] member_imp = None for alias in node.names: asname = alias.asname or alias.name if node.level: resolver = functools.partial(self._resolve_relative_import, node.level) else: resolver = self._resolve_import try: if not node.module: modname = alias.name else: modname = '{}.{}'.format(node.module, alias.name) imp = resolver(node, modname) except (util.ImportError, AttributeError): # A member (not a submodule) is being imported, so bind it. if not member_imp: member_imp = resolver(node, node.module, allow_error=True) imports.append(member_imp) member_imp.add_binding(Import.MEMBER, asname, alias.name) else: # Imported name is a submodule within a package, so bind that module. imp.add_binding(Import.MODULE, asname, imp.name.count('.')) imports.append(imp) return imports
def visit_ImportFrom(self, node): if any(a.name == '*' for a in node.names): raise util.ImportError( node, 'wildcard member import is not implemented') if not node.level and node.module == '__future__': return [] if not node.level and node.module.startswith(_NATIVE_MODULE_PREFIX): imp = Import(node.module, is_native=True) for alias in node.names: asname = alias.asname or alias.name imp.add_binding(Import.MEMBER, asname, alias.name) return [imp] imports = [] member_imp = None for alias in node.names: asname = alias.asname or alias.name if node.level: resolver = functools.partial(self._resolve_relative_import, node.level) else: resolver = self._resolve_import try: if not node.module: modname = alias.name else: modname = '{}.{}'.format(node.module, alias.name) imp = resolver(node, modname) except (util.ImportError, AttributeError): # A member (not a submodule) is being imported, so bind it. if not member_imp: member_imp = resolver(node, node.module) imports.append(member_imp) member_imp.add_binding(Import.MEMBER, asname, alias.name) else: # Imported name is a submodule within a package, so bind that module. imp.add_binding(Import.MODULE, asname, imp.name.count('.')) imports.append(imp) return imports