Exemple #1
0
  def process_import(self, node):
    """Common code for Import and ImportFrom."""

    for alias, (loc, (op, symbol, data)) in zip(node.names, self.match(node)):
      # If an import is aliased, match() returns only the symbol/loc of
      # the alias, whereas the indexer also needs access to the unaliased
      # name in order to reference the imported module.
      defn = None  # type: Optional[Definition]
      if alias.asname:
        defn = self.add_local_def(
            node, name=symbol, target=alias.name, data=data)
        defloc = self.locs[defn.id].pop()
        self.locs[defn.id].append(DefLocation(defloc.def_id, loc))

        # Shift symbol/loc back to the unaliased name.
        symbol = alias.name
        m = re.search("[ ,]" + symbol + r"\b", self.source.line(loc.line))
        assert m is not None
        c, _ = m.span()
        loc = source.Location(loc.line, c + 1)

      try:
        [imported] = _unwrap(data)
      except ValueError:
        continue  # Unresolved import.

      if op == "STORE_NAME":
        # for |import x.y as z| or |from x import y as z| we want {z: x.y}
        self.add_local_ref(node, name=symbol, data=data, location=loc)
        if not isinstance(imported, abstract.Module):
          # Make the from-imported symbol available in the current namespace.
          remote = Remote(imported.module, name=symbol, resolved=True)
          if defn:
            self.aliases[defn.id] = remote
          self.current_env[symbol] = remote
          self.typemap[remote.id] = [imported]
          continue

        if defn:
          remote = Remote(imported.full_name, IMPORT_FILE_MARKER, resolved=True)
          self.aliases[defn.id] = remote
          self.modules[defn.id] = imported.full_name
        else:
          self.modules[self.scope_id() + "." + symbol] = imported.full_name
      elif op == "IMPORT_NAME":
        # |import x.y| puts both {x: x} and {x.y: x.y} in modules
        self.add_local_ref(node, name=symbol, data=data, location=loc)
        # TODO(slebedev): Reference every import path component.
        # For example here
        #
        #   from foo.bar import boo
        #   import foo.bar.boo
        #
        # we should reference both foo and foo.bar (in addition to foo.bar.boo).
        for mod in module_utils.get_all_prefixes(symbol):
          self.modules[self.scope_id() + "." + mod] = mod
Exemple #2
0
    def process_import(self, node, is_from):
        """Common code for Import and ImportFrom."""

        store_ops = get_opcodes(self.traces, node.lineno, "STORE_NAME")
        import_ops = get_opcodes(self.traces, node.lineno, "IMPORT_NAME")

        # Only record modules that pytype has resolved in self.modules
        def is_resolved(defn, symbol, data):
            return (symbol == defn.name and data
                    and isinstance(data[0], abstract.Module))

        def filter_ops(op_list, defn):
            return [(symbol, data) for _, symbol, data in op_list
                    if is_resolved(defn, symbol, data)]

        def add_import_ref(name, data, loc):
            self.add_global_ref(node,
                                name=name,
                                data=data,
                                location=loc,
                                typ="Import")

        for alias in node.names:
            name = alias.asname if alias.asname else alias.name
            # defn, defloc = self.make_def(node, **kwargs)
            d = self.add_local_def(node, name=name)
            defloc = self.locs[d.id][-1]
            loc = defloc.location

            # tweak the definition location slightly
            line, _ = loc
            text = self.source.line(line)
            c = text.find("import ")
            if c > -1:
                # (If we haven't found "import " on the line, give up for now.)
                self.locs[d.id][-1] = DefLocation(defloc.def_id, (line, c))

            if alias.asname or is_from:
                # for |import x.y as z| or |from x import y as z| we want {z: x.y}
                for symbol, data in filter_ops(store_ops, d):
                    self.modules[d.id] = data[0].full_name
                    add_import_ref(name=symbol, data=data, loc=loc)
            else:
                # |import x.y| puts both {x: x} and {x.y: x.y} in modules
                for symbol, data in filter_ops(import_ops, d):
                    add_import_ref(name=symbol, data=data, loc=loc)
                    for mod in module_utils.get_all_prefixes(name):
                        # TODO(mdemello): Create references for every element.
                        self.modules[d.scope + "." + mod] = mod
Exemple #3
0
 def visit_Import(self, node):
     store_ops = get_opcodes(self.traces, node.lineno, "STORE_NAME")
     import_ops = get_opcodes(self.traces, node.lineno, "IMPORT_NAME")
     for alias in node.names:
         name = alias.asname if alias.asname else alias.name
         d = self.add_local_def(node, name=name)
         # Only record modules that pytype has resolved in self.modules
         if alias.asname:
             # for |import x.y as z| we want {z: x.y}
             for _, symbol, data in store_ops:
                 if (symbol == d.name and data
                         and isinstance(data[0], abstract.Module)):
                     self.modules[d.id] = data[0].full_name
         else:
             for _, symbol, data in import_ops:
                 if (symbol == d.name and data
                         and isinstance(data[0], abstract.Module)):
                     # |import x.y| puts both {x: x} and {x.y: x.y} in modules
                     for mod in module_utils.get_all_prefixes(name):
                         self.modules[d.scope + "." + mod] = mod
Exemple #4
0
    def process_import(self, node):
        """Common code for Import and ImportFrom."""

        # Only record modules that pytype has resolved in self.modules
        def is_resolved(data):
            return data and isinstance(data[0], abstract.Module)

        def add_import_ref(name, data, loc):
            self.add_global_ref(node,
                                name=name,
                                data=data,
                                location=loc,
                                typ="Import")

        for loc, (op, symbol, data) in self.match(node):
            d = self.add_local_def(node, name=symbol)
            defloc = self.locs[d.id][-1]

            # tweak the definition location slightly
            line, _ = loc
            text = self.source.line(line)
            c = text.find("import ")
            new_loc = source.Location(line, c) if c > -1 else loc
            self.locs[d.id][-1] = DefLocation(defloc.def_id, new_loc)

            if not is_resolved(_unwrap(data)):
                continue
            elif op == "STORE_NAME":
                # for |import x.y as z| or |from x import y as z| we want {z: x.y}
                self.modules[d.id] = _unwrap(data)[0].full_name
                add_import_ref(name=symbol, data=data, loc=loc)
            elif op == "IMPORT_NAME":
                # |import x.y| puts both {x: x} and {x.y: x.y} in modules
                add_import_ref(name=symbol, data=data, loc=loc)
                for mod in module_utils.get_all_prefixes(symbol):
                    # TODO(mdemello): Create references for every element.
                    self.modules[d.scope + "." + mod] = mod
Exemple #5
0
  def process_import(self, node, is_from):
    """Common code for Import and ImportFrom."""

    store_ops = get_opcodes(self.traces, node.lineno, "STORE_NAME")
    import_ops = get_opcodes(self.traces, node.lineno, "IMPORT_NAME")

    # Only record modules that pytype has resolved in self.modules
    def is_resolved(defn, symbol, data):
      return (symbol == defn.name and data and
              isinstance(data[0], abstract.Module))

    def filter_ops(op_list, defn):
      return [(symbol, data) for _, symbol, data in op_list
              if is_resolved(defn, symbol, data)]

    def add_import_ref(name, data, loc):
      self.add_global_ref(
          node, name=name, data=data, location=loc, typ="Import")

    for alias in node.names:
      name = alias.asname if alias.asname else alias.name
      d = self.add_local_def(node, name=name)
      loc = self.locs[d.id][-1].location

      if alias.asname or is_from:
        # for |import x.y as z| or |from x import y as z| we want {z: x.y}
        for symbol, data in filter_ops(store_ops, d):
          self.modules[d.id] = data[0].full_name
          add_import_ref(name=symbol, data=data, loc=loc)
      else:
        # |import x.y| puts both {x: x} and {x.y: x.y} in modules
        for symbol, data in filter_ops(import_ops, d):
          add_import_ref(name=symbol, data=data, loc=loc)
          for mod in module_utils.get_all_prefixes(name):
            # TODO(mdemello): Create references for every element.
            self.modules[d.scope + "." + mod] = mod
Exemple #6
0
 def add_module_prefixes(self, module_name):
   for prefix in module_utils.get_all_prefixes(module_name):
     self._prefixes.add(prefix)