def gen_types(rule: CstLintRule, rule_fixture_dir: Path) -> None: if not rule.requires_metadata_caches(): raise RuleNotTypeDependentError( "Rule does not list any cache-dependent providers in its `METADATA_DEPENDENCIES`." ) if hasattr(rule, "VALID") or hasattr(rule, "INVALID"): print("Starting pyre server") stdout, stderr, return_code = run_command("pyre start") if return_code != 0: print(stdout) print(stderr) else: class_name = getattr(rule, "__name__") if hasattr(rule, "VALID"): for idx, valid_tc in enumerate(getattr(rule, "VALID")): path: Path = rule_fixture_dir / f"{class_name}_VALID_{idx}.json" gen_types_for_test_case(source_code=valid_tc.code, dest_path=path) if hasattr(rule, "INVALID"): for idx, invalid_tc in enumerate(getattr(rule, "INVALID")): path: Path = rule_fixture_dir / f"{class_name}_INVALID_{idx}.json" gen_types_for_test_case(source_code=invalid_tc.code, dest_path=path) run_command("pyre stop")
def _handle_pyre_cache(self, paths: List[str]) -> Mapping[str, object]: params = ",".join(f"path='{self.root_path/path}'" for path in paths) cmd = f'''pyre query "types({params})"''' try: stdout, stderr, return_code = run_command(cmd, timeout=self._timeout) except subprocess.TimeoutExpired as exc: raise exc if return_code != 0: raise Exception(f"stderr:\n {stderr}\nstdout:\n {stdout}") try: resp = json.loads(stdout)["response"] except Exception as e: raise Exception(f"{e}\n\nstderr:\n {stderr}\nstdout:\n {stdout}") return { path: _process_pyre_data(data) for path, data in zip(paths, resp) }
def pyre_query_types(project_path: str, file_path: str, timeout: int = 600) -> Optional[PyreData]: try: file_types = None stdout, stderr, r_code = run_command( '''cd %s; pyre query "types(path='%s')"''' % (project_path, str( Path(file_path).relative_to(Path(project_path)))), timeout=timeout) if r_code == 0: file_types = json.loads(stdout)["response"][0] else: print(f"[PYRE_ERROR] p: {project_path}", stderr) except KeyError: print(f"[PYRE_ERROR] p: {project_path}", json.loads(stdout)['error']) except TimeoutExpired as te: print(f"[PYRE_TIMEOUT] p: {project_path}", te) finally: return file_types
def gen_types_for_test_case(source_code: str, dest_path: Path) -> None: rule_fixture_subdir: Path = dest_path.parent if not rule_fixture_subdir.exists(): rule_fixture_subdir.mkdir(parents=True) with tempfile.NamedTemporaryFile("w", dir=rule_fixture_subdir, suffix=".py") as temp: temp.write(_dedent(source_code)) temp.seek(0) cmd = f'''pyre query "types(path='{temp.name}')"''' stdout, stderr, return_code = run_command(cmd) if return_code != 0: raise PyreQueryError(cmd, f"{stdout}\n{stderr}") data = json.loads(stdout) # Check if error is a key in `data` since pyre may report errors this way. if "error" in data: raise PyreQueryError(cmd, data["error"]) data = data["response"][0] data: PyreData = _process_pyre_data(data) print(f"Writing output to {dest_path}") dest_path.write_text(json.dumps({"types": data["types"]}, indent=2))
loc = t["location"] start = loc["start"] stop = loc["stop"] lookup[(start["line"], start["column"], stop["line"], stop["column"])] = t["annotation"] MetadataWrapper(module).visit(TypeVerificationVisitor(lookup, self)) if __name__ == "__main__": """Run this script directly to generate pyre data for test suite (tests/pyre/*.py)""" print("start pyre server") stdout: str stderr: str return_code: int os.chdir(TEST_SUITE_PATH) stdout, stderr, return_code = run_command( ["pyre", "start", "--no-watchman"]) if return_code != 0: print(stdout) print(stderr) for path in TEST_SUITE_PATH.glob("*.py"): # Pull params into it's own arg to avoid the string escaping in subprocess params = f"path='{path}'" cmd = ["pyre", "query", f"types({params})"] print(cmd) stdout, stderr, return_code = run_command(cmd) if return_code != 0: print(stdout) print(stderr) data = json.loads(stdout) data = data["response"][0]
for t in data["types"]: loc = t["location"] start = loc["start"] stop = loc["stop"] lookup[(start["line"], start["column"], stop["line"], stop["column"])] = t["annotation"] MetadataWrapper(module).visit(TypeVerificationVisitor(lookup, self)) if __name__ == "__main__": """Run this script directly to generate pyre data for test suite (tests/pyre/*.py)""" print("start pyre server") stdout: str stderr: str return_code: int stdout, stderr, return_code = run_command("pyre start") if return_code != 0: print(stdout) print(stderr) for path in TEST_SUITE_PATH.glob("*.py"): cmd = f'''pyre query "types(path='{path}')"''' print(cmd) stdout, stderr, return_code = run_command(cmd) if return_code != 0: print(stdout) print(stderr) data = json.loads(stdout) data = data["response"][0] data = _process_pyre_data(data) output_path = path.with_suffix(".json")
for t in data["types"]: loc = t["location"] start = loc["start"] stop = loc["stop"] lookup[(start["line"], start["column"], stop["line"], stop["column"])] = t["annotation"] MetadataWrapper(module).visit(TypeVerificationVisitor(lookup, self)) if __name__ == "__main__": """Run this script directly to generate pyre data for test suite (tests/pyre/*.py)""" print("start pyre server") stdout: str stderr: str return_code: int stdout, stderr, return_code = run_command(["pyre", "start"]) if return_code != 0: print(stdout) print(stderr) for path in TEST_SUITE_PATH.glob("*.py"): # Pull params into it's own arg to avoid the string escaping in subprocess params = f"path='{path}'" cmd = ["pyre", "query", f"types({params})"] print(cmd) stdout, stderr, return_code = run_command(cmd) if return_code != 0: print(stdout) print(stderr) data = json.loads(stdout) data = data["response"][0]
def pyre_kill_all_servers(): run_command("pyre kill") print("Killed all instances of pyre's servers")
def pyre_server_init(project_path: str): stdout, stderr, r_code = run_command( "cd %s; echo -ne '.\n' | pyre init; pyre start" % project_path) print(f"[PYRE_SERVER] initialized at {project_path} ", stdout, stderr)