A simplified implementation of xargs. color: Make a pty if on a platform that supports it target_concurrency: Target number of partitions to run concurrently
(
cmd: tuple[str, ...],
varargs: Sequence[str],
*,
color: bool = False,
target_concurrency: int = 1,
_max_length: int = _get_platform_max_length(),
**kwargs: Any,
)
| 129 | |
| 130 | |
| 131 | def xargs( |
| 132 | cmd: tuple[str, ...], |
| 133 | varargs: Sequence[str], |
| 134 | *, |
| 135 | color: bool = False, |
| 136 | target_concurrency: int = 1, |
| 137 | _max_length: int = _get_platform_max_length(), |
| 138 | **kwargs: Any, |
| 139 | ) -> tuple[int, bytes]: |
| 140 | """A simplified implementation of xargs. |
| 141 | |
| 142 | color: Make a pty if on a platform that supports it |
| 143 | target_concurrency: Target number of partitions to run concurrently |
| 144 | """ |
| 145 | cmd_fn = cmd_output_p if color else cmd_output_b |
| 146 | retcode = 0 |
| 147 | stdout = b'' |
| 148 | |
| 149 | try: |
| 150 | cmd = parse_shebang.normalize_cmd(cmd) |
| 151 | except parse_shebang.ExecutableNotFoundError as e: |
| 152 | return e.to_output()[:2] |
| 153 | |
| 154 | # on windows, batch files have a separate length limit than windows itself |
| 155 | if ( |
| 156 | sys.platform == 'win32' and |
| 157 | cmd[0].lower().endswith(('.bat', '.cmd')) |
| 158 | ): # pragma: win32 cover |
| 159 | # this is implementation details but the command gets translated into |
| 160 | # full/path/to/cmd.exe /c *cmd |
| 161 | cmd_exe = parse_shebang.find_executable('cmd.exe') |
| 162 | # 1024 is additionally subtracted to give headroom for further |
| 163 | # expansion inside the batch file |
| 164 | _max_length = 8192 - len(cmd_exe) - len(' /c ') - 1024 |
| 165 | |
| 166 | partitions = partition(cmd, varargs, target_concurrency, _max_length) |
| 167 | |
| 168 | def run_cmd_partition( |
| 169 | run_cmd: tuple[str, ...], |
| 170 | ) -> tuple[int, bytes, bytes | None]: |
| 171 | return cmd_fn( |
| 172 | *run_cmd, check=False, stderr=subprocess.STDOUT, **kwargs, |
| 173 | ) |
| 174 | |
| 175 | threads = min(len(partitions), target_concurrency) |
| 176 | with _thread_mapper(threads) as thread_map: |
| 177 | results = thread_map(run_cmd_partition, partitions) |
| 178 | |
| 179 | for proc_retcode, proc_out, _ in results: |
| 180 | if abs(proc_retcode) > abs(retcode): |
| 181 | retcode = proc_retcode |
| 182 | stdout += proc_out |
| 183 | |
| 184 | return retcode, stdout |
no test coverage detected