(tool: str, args: typing.Iterable[str], echo: bool = False)
| 38 | |
| 39 | |
| 40 | async def _run(tool: str, args: typing.Iterable[str], echo: bool = False) -> str | None: |
| 41 | command = [tool, *args] |
| 42 | async with _CORES: |
| 43 | if echo: |
| 44 | print(shlex.join(command)) |
| 45 | |
| 46 | if os.name == "nt": |
| 47 | # When building with /p:PlatformToolset=ClangCL, the VS build |
| 48 | # system puts that clang's include path into INCLUDE. The JIT's |
| 49 | # clang may be a different version, and mismatched headers cause |
| 50 | # build errors. See https://github.com/python/cpython/issues/146210. |
| 51 | env = os.environ.copy() |
| 52 | env.pop("INCLUDE", None) |
| 53 | else: |
| 54 | env = None |
| 55 | try: |
| 56 | process = await asyncio.create_subprocess_exec( |
| 57 | *command, stdout=subprocess.PIPE, env=env |
| 58 | ) |
| 59 | except FileNotFoundError: |
| 60 | return None |
| 61 | out, _ = await process.communicate() |
| 62 | if process.returncode: |
| 63 | raise RuntimeError(f"{tool} exited with return code {process.returncode}") |
| 64 | return out.decode() |
| 65 | |
| 66 | |
| 67 | @_async_cache |
no test coverage detected
searching dependent graphs…