|
1 | 1 | import argparse |
| 2 | +import sys |
2 | 3 | import warnings |
| 4 | +from gettext import gettext |
3 | 5 |
|
4 | 6 | import py |
5 | 7 |
|
@@ -328,6 +330,7 @@ def __init__(self, parser, extra_info=None, prog=None): |
328 | 330 | usage=parser._usage, |
329 | 331 | add_help=False, |
330 | 332 | formatter_class=DropShorterLongHelpFormatter, |
| 333 | + allow_abbrev=False, |
331 | 334 | ) |
332 | 335 | # extra_info is a dict of (param -> value) to display if there's |
333 | 336 | # an usage error to provide more contextual information to the user |
@@ -355,6 +358,42 @@ def parse_args(self, args=None, namespace=None): |
355 | 358 | getattr(args, FILE_OR_DIR).extend(argv) |
356 | 359 | return args |
357 | 360 |
|
| 361 | + if sys.version_info[:2] < (3, 8): # pragma: no cover |
| 362 | + # Backport of https://github.com/python/cpython/pull/14316 so we can |
| 363 | + # disable long --argument abbreviations without breaking short flags. |
| 364 | + def _parse_optional(self, arg_string): |
| 365 | + if not arg_string: |
| 366 | + return None |
| 367 | + if not arg_string[0] in self.prefix_chars: |
| 368 | + return None |
| 369 | + if arg_string in self._option_string_actions: |
| 370 | + action = self._option_string_actions[arg_string] |
| 371 | + return action, arg_string, None |
| 372 | + if len(arg_string) == 1: |
| 373 | + return None |
| 374 | + if "=" in arg_string: |
| 375 | + option_string, explicit_arg = arg_string.split("=", 1) |
| 376 | + if option_string in self._option_string_actions: |
| 377 | + action = self._option_string_actions[option_string] |
| 378 | + return action, option_string, explicit_arg |
| 379 | + if self.allow_abbrev or not arg_string.startswith("--"): |
| 380 | + option_tuples = self._get_option_tuples(arg_string) |
| 381 | + if len(option_tuples) > 1: |
| 382 | + msg = gettext( |
| 383 | + "ambiguous option: %(option)s could match %(matches)s" |
| 384 | + ) |
| 385 | + options = ", ".join(option for _, option, _ in option_tuples) |
| 386 | + self.error(msg % {"option": arg_string, "matches": options}) |
| 387 | + elif len(option_tuples) == 1: |
| 388 | + option_tuple, = option_tuples |
| 389 | + return option_tuple |
| 390 | + if self._negative_number_matcher.match(arg_string): |
| 391 | + if not self._has_negative_number_optionals: |
| 392 | + return None |
| 393 | + if " " in arg_string: |
| 394 | + return None |
| 395 | + return None, arg_string, None |
| 396 | + |
358 | 397 |
|
359 | 398 | class DropShorterLongHelpFormatter(argparse.HelpFormatter): |
360 | 399 | """shorten help for long options that differ only in extra hyphens |
|
0 commit comments