|
23 | 23 | import itertools |
24 | 24 | import os |
25 | 25 | import re |
| 26 | +import shlex |
26 | 27 | import sys |
27 | 28 | import textwrap |
28 | 29 | from collections.abc import Iterable, Sequence |
@@ -388,7 +389,27 @@ def _supports_ansi_colors() -> bool: |
388 | 389 | def parse_options( |
389 | 390 | args: Sequence[str], |
390 | 391 | ) -> tuple[argparse.Namespace, argparse.ArgumentParser, list[str]]: |
391 | | - parser = argparse.ArgumentParser(formatter_class=NewlineHelpFormatter) |
| 392 | + # Split lines read from `@PATH` using shlex.split(), otherwise default |
| 393 | + # behaviour is to have one arg per line. See: |
| 394 | + # https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.convert_arg_line_to_args |
| 395 | + class ArgumentParser2(argparse.ArgumentParser): |
| 396 | + def convert_arg_line_to_args(self, arg_line: str) -> list[str]: |
| 397 | + if sys.platform == "win32": |
| 398 | + # On Windows, shlex.split() seems to be messed up by back |
| 399 | + # slashes. Temporarily changing them to forward slashes seems |
| 400 | + # to make things work better. |
| 401 | + arg_line = arg_line.replace("\\", "/") |
| 402 | + ret = shlex.split(arg_line) |
| 403 | + ret = [p.replace("/", "\\") for p in ret] |
| 404 | + else: |
| 405 | + ret = shlex.split(arg_line) |
| 406 | + return ret |
| 407 | + |
| 408 | + parser = ArgumentParser2( |
| 409 | + formatter_class=NewlineHelpFormatter, |
| 410 | + fromfile_prefix_chars="@", |
| 411 | + epilog="Use @PATH to read additional arguments from file PATH.", |
| 412 | + ) |
392 | 413 |
|
393 | 414 | parser.set_defaults(colors=_supports_ansi_colors()) |
394 | 415 | parser.add_argument("--version", action="version", version=VERSION) |
|
0 commit comments