diff --git a/libcst/metadata/type_inference_provider.py b/libcst/metadata/type_inference_provider.py index 7cb7da28b..9975d0235 100644 --- a/libcst/metadata/type_inference_provider.py +++ b/libcst/metadata/type_inference_provider.py @@ -57,10 +57,11 @@ def gen_cache( root_path: Path, paths: List[str], timeout: Optional[int] ) -> Mapping[str, object]: params = ",".join(f"path='{root_path / path}'" for path in paths) - cmd = f'''pyre --noninteractive query "types({params})"''' + cmd_args = ["pyre", "--noninteractive", "query", f'"types({params})"'] try: - stdout, stderr, return_code = run_command(cmd, timeout=timeout) + stdout, stderr, return_code = run_command(cmd_args, timeout=timeout) except subprocess.TimeoutExpired as exc: + raise exc if return_code != 0: @@ -101,12 +102,11 @@ def visit_Call(self, node: cst.Call) -> Optional[bool]: self._parse_metadata(node) -def run_command(command: str, timeout: Optional[int] = None) -> Tuple[str, str, int]: - process = subprocess.Popen( - command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True - ) - stdout, stderr = process.communicate(timeout=timeout) - return stdout.decode(), stderr.decode(), process.returncode +def run_command( + cmd_args: List[str], timeout: Optional[int] = None +) -> Tuple[str, str, int]: + process = subprocess.run(cmd_args, capture_output=True, timeout=timeout) + return process.stdout.decode(), process.stderr.decode(), process.returncode class RawPyreData(TypedDict): diff --git a/libcst/tests/test_pyre_integration.py b/libcst/tests/test_pyre_integration.py index 11fd7f8de..6192dcff1 100644 --- a/libcst/tests/test_pyre_integration.py +++ b/libcst/tests/test_pyre_integration.py @@ -123,13 +123,15 @@ def test_type_availability(self, source_path: Path, data_path: Path) -> None: stdout: str stderr: str return_code: int - stdout, stderr, return_code = run_command("pyre start") + 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}')"''' + # 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: