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) if node.module == '__future__' and node != self.future_node: raise util.LateFutureError(node) for imp in self.block.root.importer.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) else: self._import_and_bind(imp)
def visit_ImportFrom(self, node): self._write_py_context(node.lineno) visitor = imputil.ImportVisitor(self.block.root.path) visitor.visit(node) for imp in visitor.imports: 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.LateFutureError(node) else: self._import_and_bind(imp)
def visit_ImportFrom(self, node): self._write_py_context(node.lineno) if node.module == '__future__' and node != self.future_node: raise util.LateFutureError(node) for imp in self.block.root.importer.visit(node): self._import_and_bind(imp)
def visit_future(node): """Accumulates a set of compiler flags for the compiler __future__ imports. Returns an instance of FutureFeatures which encapsulates the flags and the line number of the last valid future import parsed. A downstream parser can use the latter to detect invalid future imports that appear too late in the file. """ # If this is the module node, do an initial pass through the module body's # statements to detect future imports and process their directives (i.e., # set compiler flags), and detect ones that don't appear at the beginning of # the file. The only things that can proceed a future statement are other # future statements and/or a doc string. assert isinstance(node, ast.Module) ff = FutureFeatures() done = False found_docstring = False for node in node.body: if isinstance(node, ast.ImportFrom): modname = node.module if modname == '__future__': if done: raise util.LateFutureError(node) ff.parser_flags |= import_from_future(node) ff.future_lineno = node.lineno else: done = True elif isinstance(node, ast.Expr) and not found_docstring: e = node.value if not isinstance(e, ast.Str): # pylint: disable=simplifiable-if-statement done = True else: found_docstring = True else: done = True return ff
def visit_ImportFrom(self, node): if node.module == '__future__': if node != self.future_node: raise util.LateFutureError(node) return self.imports.extend(self.importer.visit(node))