def main(): try: args, kythe_args, options = parse_args.parse_args(sys.argv[1:]) except utils.UsageError as e: print(str(e), file=sys.stderr) sys.exit(1) if options.timeout is not None: signal.alarm(options.timeout) try: ix = indexer.process_file(options, generate_callgraphs=True) except indexer.PytypeError as e: print(e.args[0], file=sys.stderr) if args.debug: traceback.print_exc() else: print("Run with --debug to see a traceback.") sys.exit(1) if args.debug: debug.show_index(ix) else: kythe_graph = kythe.generate_graph(ix, kythe_args) output.output_kythe_graph(kythe_graph)
def generate_kythe(self, code): """Generate a kythe index from a code string.""" with file_utils.Tempdir() as d: d.create_file("t.py", code) options = config.Options.create(d["t.py"]) options.tweak(pythonpath=[d.path], version=self.python_version) kythe_args = kythe.Args(corpus="corpus", root="root", path="path") ix = indexer.process_file(options) kg = kythe.generate_graph(ix, kythe_args) # Collect all the references from the kythe graph. kythe_index = [json.loads(x) for x in output.json_kythe_graph(kg)] return kythe_index
def test_resolved_imports(self): # We need all imports to be valid for pytype code = """ import f import x.y import a.b as c from a import b from p import q as r from u.v import X from u.v import X as Y fx = f.X() cx = c.X() bx = b.X() rx = r.X() yx = x.y.X() uvx = X() X.__name__ uvy = Y() Y.__name__ """ stub = "class X: pass" with file_utils.Tempdir() as d: d.create_file("t.py", code) d.create_file("f.pyi", stub) d.create_file("x/y.pyi", stub) d.create_file("a/b.pyi", stub) d.create_file("p/q.pyi", stub) d.create_file("u/v.pyi", stub) options = config.Options.create(d["t.py"]) options.tweak(pythonpath=[d.path], version=self.python_version) ix = indexer.process_file(options) self.assertDef(ix, "module.c", "c", "Import") self.assertDef(ix, "module.r", "r", "ImportFrom") self.assertEqual(ix.modules["module.f"], "f") self.assertEqual(ix.modules["module.x.y"], "x.y") self.assertEqual(ix.modules["module.b"], "a.b") self.assertEqual(ix.modules["module.c"], "a.b") self.assertEqual(ix.modules["module.r"], "p.q") self.assertAlias(ix, "module.c", "a.b.<__FILE__>") self.assertAlias(ix, "module.r", "p.q.<__FILE__>") self.assertAlias(ix, "module.Y", "u.v.X") # Collect all the references from the kythe graph. kg = kythe.generate_graph(ix, kythe_args=None) kythe_index = [json.loads(x) for x in output.json_kythe_graph(kg)] refs = [ x for x in kythe_index if x.get("edge_kind", "").startswith("/kythe/edge/ref") ] # Extract the span of text and the target symbol for each reference. src = ix.source.text out = [] for r in refs: pos = r["source"]["signature"] start, end = pos[1:].split(":") start, end = int(start), int(end) text = src[start:end] out.append( (text, r["target"]["signature"], r["target"]["path"])) expected = { # Aliased imports as declarations in the source file ("c", "module.c", "t.py"), ("Y", "module.Y", "t.py"), # Class X in remote files ("X", "module.X", "f.py"), ("X", "module.X", "a/b.py"), ("X", "module.X", "x/y.py"), ("X", "module.X", "p/q.py"), # Imports as references to remote files ("r", "module.r", "t.py"), ("b", ":module:", "a/b.py"), ("a.b", ":module:", "a/b.py"), ("f", ":module:", "f.py"), ("q", ":module:", "p/q.py"), ("x.y", ":module:", "x/y.py"), ("X", "module.X", "u/v.py"), ("__name__", "module.X.__name__", "u/v.py"), # x.y as references to remote files ("x", ":module:", "x/__init__.py"), ("y", ":module:", "x/y.py"), } # Resolve filepaths within the tempdir. expected = [(ref, target, d[path]) for (ref, target, path) in expected] self.assertEqual(set(out), set(expected))