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))) if not self._script_exists(dirname, modname): raise util.ImportError(node, 'no such module: {}'.format(modname)) parts = self.package_name.split('.') return Import('.'.join(parts[:len(parts)-uplevel]) + '.' + modname)
def visit_ImportFrom(self, node): if any(a.name == '*' for a in node.names): msg = 'wildcard member import is not implemented: from %s import *' % ( node.module) raise util.ImportError(node, msg) if node.module == '__future__': if node != self.future_node: raise util.LateFutureError(node) return if node.module.startswith(_NATIVE_MODULE_PREFIX): imp = Import(node.module[len(_NATIVE_MODULE_PREFIX):], is_native=True) for alias in node.names: asname = alias.asname or alias.name imp.add_binding(Import.MEMBER, asname, alias.name) self.imports.append(imp) return member_imp = None for alias in node.names: asname = alias.asname or alias.name full_name, _ = self.path.resolve_import( '{}.{}'.format(node.module, alias.name)) if full_name: # Imported name is a submodule within a package, so bind that module. imp = Import(full_name) imp.add_binding(Import.MODULE, asname, imp.name.count('.')) self.imports.append(imp) else: # A member (not a submodule) is being imported, so bind it. if not member_imp: member_imp = self._resolve_import(node, node.module) self.imports.append(member_imp) member_imp.add_binding(Import.MEMBER, asname, alias.name)
def visit_ImportFrom(self, node): self._write_py_context(node.lineno) for imp in util.ImportVisitor().visit(node): if imp.is_native: values = [b.value for b in imp.bindings] with self._import_native(imp.name, values) as mod: for binding in imp.bindings: # Strip the 'type_' prefix when populating the module. This means # that, e.g. 'from __go__.foo import type_Bar' will populate foo # with a member called Bar, not type_Bar (although the symbol in # the importing module will still be type_Bar unless aliased). This # bends the semantics of import but makes native module contents # more sensible. name = binding.value if name.startswith(_NATIVE_TYPE_PREFIX): name = name[len(_NATIVE_TYPE_PREFIX):] with self.block.alloc_temp() as member: self.writer.write_checked_call2( member, 'πg.GetAttr(πF, {}, {}, nil)', mod.expr, self.block.root.intern(name)) self.block.bind_var( self.writer, binding.alias, member.expr) elif node.module == '__future__': # At this stage all future imports are done in an initial pass (see # visit() above), so if they are encountered here after the last valid # __future__ then it's a syntax error. if node.lineno > self.future_features.future_lineno: raise util.ImportError(node, late_future) else: self._import_and_bind(imp)
def _resolve_import(self, node, modname): if not self.absolute_import and self.package_dir: if self._script_exists(self.package_dir, modname): return Import('{}.{}'.format(self.package_name, modname)) for dirname in self.pathdirs: if self._script_exists(dirname, modname): return Import(modname) raise util.ImportError(node, 'no such module: {}'.format(modname))
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('{}.{}'.format(self.package_name, modname), script) for dirname in self.pathdirs: script = find_script(dirname, modname) if script: return Import(modname, script) raise util.ImportError(node, 'no such module: {}'.format(modname))
def visit_Import(self, node): for alias in node.names: if alias.name.startswith(_NATIVE_MODULE_PREFIX): raise util.ImportError( node, 'for native imports use "from __go__.xyz import ..." syntax') imp = self._resolve_import(node, alias.name) if alias.asname: imp.add_binding(Import.MODULE, alias.asname, imp.name.count('.')) else: parts = alias.name.split('.') imp.add_binding(Import.MODULE, parts[-1], imp.name.count('.') - len(parts) + 1) self.imports.append(imp)
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 = [] if not node.module: # Import of the form 'from .. import foo, bar'. All named imports must be # modules, not module members. for alias in node.names: imp = self._resolve_relative_import(node.level, node, alias.name) imp.add_binding(Import.MODULE, alias.asname or alias.name, imp.name.count('.')) imports.append(imp) return 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: imp = resolver(node, '{}.{}'.format(node.module, alias.name)) except util.ImportError: # 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
def _resolve_import(self, node, name): full_name, _ = self.path.resolve_import(name) if not full_name: raise util.ImportError(node, 'no such module: {}'.format(name)) return Import(full_name)