1# Author: Steven J. Bethard <steven.bethard@gmail.com>. 2# New maintainer as of 29 August 2019: Raymond Hettinger <raymond.hettinger@gmail.com> 3 4"""Command-line parsing library 5 6This module is an optparse-inspired command-line parsing library that: 7 8 - handles both optional and positional arguments 9 - produces highly informative usage messages 10 - supports parsers that dispatch to sub-parsers 11 12The following is a simple usage example that sums integers from the 13command-line and writes the result to a file:: 14 15 parser = argparse.ArgumentParser( 16 description='sum the integers at the command line') 17 parser.add_argument( 18 'integers', metavar='int', nargs='+', type=int, 19 help='an integer to be summed') 20 parser.add_argument( 21 '--log', default=sys.stdout, type=argparse.FileType('w'), 22 help='the file where the sum should be written') 23 args = parser.parse_args() 24 args.log.write('%s' % sum(args.integers)) 25 args.log.close() 26 27The module contains the following public classes: 28 29 - ArgumentParser -- The main entry point for command-line parsing. As the 30 example above shows, the add_argument() method is used to populate 31 the parser with actions for optional and positional arguments. Then 32 the parse_args() method is invoked to convert the args at the 33 command-line into an object with attributes. 34 35 - ArgumentError -- The exception raised by ArgumentParser objects when 36 there are errors with the parser's actions. Errors raised while 37 parsing the command-line are caught by ArgumentParser and emitted 38 as command-line messages. 39 40 - FileType -- A factory for defining types of files to be created. As the 41 example above shows, instances of FileType are typically passed as 42 the type= argument of add_argument() calls. 43 44 - Action -- The base class for parser actions. Typically actions are 45 selected by passing strings like 'store_true' or 'append_const' to 46 the action= argument of add_argument(). However, for greater 47 customization of ArgumentParser actions, subclasses of Action may 48 be defined and passed as the action= argument. 49 50 - HelpFormatter, RawDescriptionHelpFormatter, RawTextHelpFormatter, 51 ArgumentDefaultsHelpFormatter -- Formatter classes which 52 may be passed as the formatter_class= argument to the 53 ArgumentParser constructor. HelpFormatter is the default, 54 RawDescriptionHelpFormatter and RawTextHelpFormatter tell the parser 55 not to change the formatting for help text, and 56 ArgumentDefaultsHelpFormatter adds information about argument defaults 57 to the help. 58 59All other classes in this module are considered implementation details. 60(Also note that HelpFormatter and RawDescriptionHelpFormatter are only 61considered public as object names -- the API of the formatter objects is 62still considered an implementation detail.) 63""" 64 65__version__ = '1.1' 66__all__ = [ 67 'ArgumentParser', 68 'ArgumentError', 69 'ArgumentTypeError', 70 'BooleanOptionalAction', 71 'FileType', 72 'HelpFormatter', 73 'ArgumentDefaultsHelpFormatter', 74 'RawDescriptionHelpFormatter', 75 'RawTextHelpFormatter', 76 'MetavarTypeHelpFormatter', 77 'Namespace', 78 'Action', 79 'ONE_OR_MORE', 80 'OPTIONAL', 81 'PARSER', 82 'REMAINDER', 83 'SUPPRESS', 84 'ZERO_OR_MORE', 85] 86 87 88import os as _os 89import re as _re 90import sys as _sys 91 92from gettext import gettext as _, ngettext 93 94SUPPRESS = '==SUPPRESS==' 95 96OPTIONAL = '?' 97ZERO_OR_MORE = '*' 98ONE_OR_MORE = '+' 99PARSER = 'A...' 100REMAINDER = '...' 101_UNRECOGNIZED_ARGS_ATTR = '_unrecognized_args' 102 103# ============================= 104# Utility functions and classes 105# ============================= 106 107class _AttributeHolder(object): 108 """Abstract base class that provides __repr__. 109 110 The __repr__ method returns a string in the format:: 111 ClassName(attr=name, attr=name, ...) 112 The attributes are determined either by a class-level attribute, 113 '_kwarg_names', or by inspecting the instance __dict__. 114 """ 115 116 def __repr__(self): 117 type_name = type(self).__name__ 118 arg_strings = [] 119 star_args = {} 120 for arg in self._get_args(): 121 arg_strings.append(repr(arg)) 122 for name, value in self._get_kwargs(): 123 if name.isidentifier(): 124 arg_strings.append('%s=%r' % (name, value)) 125 else: 126 star_args[name] = value 127 if star_args: 128 arg_strings.append('**%s' % repr(star_args)) 129 return '%s(%s)' % (type_name, ', '.join(arg_strings)) 130 131 def _get_kwargs(self): 132 return list(self.__dict__.items()) 133 134 def _get_args(self): 135 return [] 136 137 138def _copy_items(items): 139 if items is None: 140 return [] 141 # The copy module is used only in the 'append' and 'append_const' 142 # actions, and it is needed only when the default value isn't a list. 143 # Delay its import for speeding up the common case. 144 if type(items) is list: 145 return items[:] 146 import copy 147 return copy.copy(items) 148 149 150# =============== 151# Formatting Help 152# =============== 153 154 155class HelpFormatter(object): 156 """Formatter for generating usage messages and argument help strings. 157 158 Only the name of this class is considered a public API. All the methods 159 provided by the class are considered an implementation detail. 160 """ 161 162 def __init__(self, 163 prog, 164 indent_increment=2, 165 max_help_position=24, 166 width=None): 167 168 # default setting for width 169 if width is None: 170 import shutil 171 width = shutil.get_terminal_size().columns 172 width -= 2 173 174 self._prog = prog 175 self._indent_increment = indent_increment 176 self._max_help_position = min(max_help_position, 177 max(width - 20, indent_increment * 2)) 178 self._width = width 179 180 self._current_indent = 0 181 self._level = 0 182 self._action_max_length = 0 183 184 self._root_section = self._Section(self, None) 185 self._current_section = self._root_section 186 187 self._whitespace_matcher = _re.compile(r'\s+', _re.ASCII) 188 self._long_break_matcher = _re.compile(r'\n\n\n+') 189 190 # =============================== 191 # Section and indentation methods 192 # =============================== 193 def _indent(self): 194 self._current_indent += self._indent_increment 195 self._level += 1 196 197 def _dedent(self): 198 self._current_indent -= self._indent_increment 199 assert self._current_indent >= 0, 'Indent decreased below 0.' 200 self._level -= 1 201 202 class _Section(object): 203 204 def __init__(self, formatter, parent, heading=None): 205 self.formatter = formatter 206 self.parent = parent 207 self.heading = heading 208 self.items = [] 209 210 def format_help(self): 211 # format the indented section 212 if self.parent is not None: 213 self.formatter._indent() 214 join = self.formatter._join_parts 215 item_help = join([func(*args) for func, args in self.items]) 216 if self.parent is not None: 217 self.formatter._dedent() 218 219 # return nothing if the section was empty 220 if not item_help: 221 return '' 222 223 # add the heading if the section was non-empty 224 if self.heading is not SUPPRESS and self.heading is not None: 225 current_indent = self.formatter._current_indent 226 heading_text = _('%(heading)s:') % dict(heading=self.heading) 227 heading = '%*s%s\n' % (current_indent, '', heading_text) 228 else: 229 heading = '' 230 231 # join the section-initial newline, the heading and the help 232 return join(['\n', heading, item_help, '\n']) 233 234 def _add_item(self, func, args): 235 self._current_section.items.append((func, args)) 236 237 # ======================== 238 # Message building methods 239 # ======================== 240 def start_section(self, heading): 241 self._indent() 242 section = self._Section(self, self._current_section, heading) 243 self._add_item(section.format_help, []) 244 self._current_section = section 245 246 def end_section(self): 247 self._current_section = self._current_section.parent 248 self._dedent() 249 250 def add_text(self, text): 251 if text is not SUPPRESS and text is not None: 252 self._add_item(self._format_text, [text]) 253 254 def add_usage(self, usage, actions, groups, prefix=None): 255 if usage is not SUPPRESS: 256 args = usage, actions, groups, prefix 257 self._add_item(self._format_usage, args) 258 259 def add_argument(self, action): 260 if action.help is not SUPPRESS: 261 262 # find all invocations 263 get_invocation = self._format_action_invocation 264 invocation_lengths = [len(get_invocation(action)) + self._current_indent] 265 for subaction in self._iter_indented_subactions(action): 266 invocation_lengths.append(len(get_invocation(subaction)) + self._current_indent) 267 268 # update the maximum item length 269 action_length = max(invocation_lengths) 270 self._action_max_length = max(self._action_max_length, 271 action_length) 272 273 # add the item to the list 274 self._add_item(self._format_action, [action]) 275 276 def add_arguments(self, actions): 277 for action in actions: 278 self.add_argument(action) 279 280 # ======================= 281 # Help-formatting methods 282 # ======================= 283 def format_help(self): 284 help = self._root_section.format_help() 285 if help: 286 help = self._long_break_matcher.sub('\n\n', help) 287 help = help.strip('\n') + '\n' 288 return help 289 290 def _join_parts(self, part_strings): 291 return ''.join([part 292 for part in part_strings 293 if part and part is not SUPPRESS]) 294 295 def _format_usage(self, usage, actions, groups, prefix): 296 if prefix is None: 297 prefix = _('usage: ') 298 299 # if usage is specified, use that 300 if usage is not None: 301 usage = usage % dict(prog=self._prog) 302 303 # if no optionals or positionals are available, usage is just prog 304 elif usage is None and not actions: 305 usage = '%(prog)s' % dict(prog=self._prog) 306 307 # if optionals and positionals are available, calculate usage 308 elif usage is None: 309 prog = '%(prog)s' % dict(prog=self._prog) 310 311 # split optionals from positionals 312 optionals = [] 313 positionals = [] 314 for action in actions: 315 if action.option_strings: 316 optionals.append(action) 317 else: 318 positionals.append(action) 319 320 # build full usage string 321 format = self._format_actions_usage 322 action_usage = format(optionals + positionals, groups) 323 usage = ' '.join([s for s in [prog, action_usage] if s]) 324 325 # wrap the usage parts if it's too long 326 text_width = self._width - self._current_indent 327 if len(prefix) + len(usage) > text_width: 328 329 # break usage into wrappable parts 330 opt_parts = self._get_actions_usage_parts(optionals, groups) 331 pos_parts = self._get_actions_usage_parts(positionals, groups) 332 333 # helper for wrapping lines 334 def get_lines(parts, indent, prefix=None): 335 lines = [] 336 line = [] 337 indent_length = len(indent) 338 if prefix is not None: 339 line_len = len(prefix) - 1 340 else: 341 line_len = indent_length - 1 342 for part in parts: 343 if line_len + 1 + len(part) > text_width and line: 344 lines.append(indent + ' '.join(line)) 345 line = [] 346 line_len = indent_length - 1 347 line.append(part) 348 line_len += len(part) + 1 349 if line: 350 lines.append(indent + ' '.join(line)) 351 if prefix is not None: 352 lines[0] = lines[0][indent_length:] 353 return lines 354 355 # if prog is short, follow it with optionals or positionals 356 if len(prefix) + len(prog) <= 0.75 * text_width: 357 indent = ' ' * (len(prefix) + len(prog) + 1) 358 if opt_parts: 359 lines = get_lines([prog] + opt_parts, indent, prefix) 360 lines.extend(get_lines(pos_parts, indent)) 361 elif pos_parts: 362 lines = get_lines([prog] + pos_parts, indent, prefix) 363 else: 364 lines = [prog] 365 366 # if prog is long, put it on its own line 367 else: 368 indent = ' ' * len(prefix) 369 parts = opt_parts + pos_parts 370 lines = get_lines(parts, indent) 371 if len(lines) > 1: 372 lines = [] 373 lines.extend(get_lines(opt_parts, indent)) 374 lines.extend(get_lines(pos_parts, indent)) 375 lines = [prog] + lines 376 377 # join lines into usage 378 usage = '\n'.join(lines) 379 380 # prefix with 'usage:' 381 return '%s%s\n\n' % (prefix, usage) 382 383 def _format_actions_usage(self, actions, groups): 384 return ' '.join(self._get_actions_usage_parts(actions, groups)) 385 386 def _get_actions_usage_parts(self, actions, groups): 387 # find group indices and identify actions in groups 388 group_actions = set() 389 inserts = {} 390 for group in groups: 391 if not group._group_actions: 392 raise ValueError(f'empty group {group}') 393 394 if all(action.help is SUPPRESS for action in group._group_actions): 395 continue 396 397 try: 398 start = actions.index(group._group_actions[0]) 399 except ValueError: 400 continue 401 else: 402 end = start + len(group._group_actions) 403 if actions[start:end] == group._group_actions: 404 group_actions.update(group._group_actions) 405 inserts[start, end] = group 406 407 # collect all actions format strings 408 parts = [] 409 for action in actions: 410 411 # suppressed arguments are marked with None 412 if action.help is SUPPRESS: 413 part = None 414 415 # produce all arg strings 416 elif not action.option_strings: 417 default = self._get_default_metavar_for_positional(action) 418 part = self._format_args(action, default) 419 420 # if it's in a group, strip the outer [] 421 if action in group_actions: 422 if part[0] == '[' and part[-1] == ']': 423 part = part[1:-1] 424 425 # produce the first way to invoke the option in brackets 426 else: 427 option_string = action.option_strings[0] 428 429 # if the Optional doesn't take a value, format is: 430 # -s or --long 431 if action.nargs == 0: 432 part = action.format_usage() 433 434 # if the Optional takes a value, format is: 435 # -s ARGS or --long ARGS 436 else: 437 default = self._get_default_metavar_for_optional(action) 438 args_string = self._format_args(action, default) 439 part = '%s %s' % (option_string, args_string) 440 441 # make it look optional if it's not required or in a group 442 if not action.required and action not in group_actions: 443 part = '[%s]' % part 444 445 # add the action string to the list 446 parts.append(part) 447 448 # group mutually exclusive actions 449 inserted_separators_indices = set() 450 for start, end in sorted(inserts, reverse=True): 451 group = inserts[start, end] 452 group_parts = [item for item in parts[start:end] if item is not None] 453 group_size = len(group_parts) 454 if group.required: 455 open, close = "()" if group_size > 1 else ("", "") 456 else: 457 open, close = "[]" 458 group_parts[0] = open + group_parts[0] 459 group_parts[-1] = group_parts[-1] + close 460 for i, part in enumerate(group_parts[:-1], start=start): 461 # insert a separator if not already done in a nested group 462 if i not in inserted_separators_indices: 463 parts[i] = part + ' |' 464 inserted_separators_indices.add(i) 465 parts[start + group_size - 1] = group_parts[-1] 466 for i in range(start + group_size, end): 467 parts[i] = None 468 469 # return the usage parts 470 return [item for item in parts if item is not None] 471 472 def _format_text(self, text): 473 if '%(prog)' in text: 474 text = text % dict(prog=self._prog) 475 text_width = max(self._width - self._current_indent, 11) 476 indent = ' ' * self._current_indent 477 return self._fill_text(text, text_width, indent) + '\n\n' 478 479 def _format_action(self, action): 480 # determine the required width and the entry label 481 help_position = min(self._action_max_length + 2, 482 self._max_help_position) 483 help_width = max(self._width - help_position, 11) 484 action_width = help_position - self._current_indent - 2 485 action_header = self._format_action_invocation(action) 486 487 # no help; start on same line and add a final newline 488 if not action.help: 489 tup = self._current_indent, '', action_header 490 action_header = '%*s%s\n' % tup 491 492 # short action name; start on the same line and pad two spaces 493 elif len(action_header) <= action_width: 494 tup = self._current_indent, '', action_width, action_header 495 action_header = '%*s%-*s ' % tup 496 indent_first = 0 497 498 # long action name; start on the next line 499 else: 500 tup = self._current_indent, '', action_header 501 action_header = '%*s%s\n' % tup 502 indent_first = help_position 503 504 # collect the pieces of the action help 505 parts = [action_header] 506 507 # if there was help for the action, add lines of help text 508 if action.help and action.help.strip(): 509 help_text = self._expand_help(action) 510 if help_text: 511 help_lines = self._split_lines(help_text, help_width) 512 parts.append('%*s%s\n' % (indent_first, '', help_lines[0])) 513 for line in help_lines[1:]: 514 parts.append('%*s%s\n' % (help_position, '', line)) 515 516 # or add a newline if the description doesn't end with one 517 elif not action_header.endswith('\n'): 518 parts.append('\n') 519 520 # if there are any sub-actions, add their help as well 521 for subaction in self._iter_indented_subactions(action): 522 parts.append(self._format_action(subaction)) 523 524 # return a single string 525 return self._join_parts(parts) 526 527 def _format_action_invocation(self, action): 528 if not action.option_strings: 529 default = self._get_default_metavar_for_positional(action) 530 return ' '.join(self._metavar_formatter(action, default)(1)) 531 532 else: 533 534 # if the Optional doesn't take a value, format is: 535 # -s, --long 536 if action.nargs == 0: 537 return ', '.join(action.option_strings) 538 539 # if the Optional takes a value, format is: 540 # -s, --long ARGS 541 else: 542 default = self._get_default_metavar_for_optional(action) 543 args_string = self._format_args(action, default) 544 return ', '.join(action.option_strings) + ' ' + args_string 545 546 def _metavar_formatter(self, action, default_metavar): 547 if action.metavar is not None: 548 result = action.metavar 549 elif action.choices is not None: 550 result = '{%s}' % ','.join(map(str, action.choices)) 551 else: 552 result = default_metavar 553 554 def format(tuple_size): 555 if isinstance(result, tuple): 556 return result 557 else: 558 return (result, ) * tuple_size 559 return format 560 561 def _format_args(self, action, default_metavar): 562 get_metavar = self._metavar_formatter(action, default_metavar) 563 if action.nargs is None: 564 result = '%s' % get_metavar(1) 565 elif action.nargs == OPTIONAL: 566 result = '[%s]' % get_metavar(1) 567 elif action.nargs == ZERO_OR_MORE: 568 metavar = get_metavar(1) 569 if len(metavar) == 2: 570 result = '[%s [%s ...]]' % metavar 571 else: 572 result = '[%s ...]' % metavar 573 elif action.nargs == ONE_OR_MORE: 574 result = '%s [%s ...]' % get_metavar(2) 575 elif action.nargs == REMAINDER: 576 result = '...' 577 elif action.nargs == PARSER: 578 result = '%s ...' % get_metavar(1) 579 elif action.nargs == SUPPRESS: 580 result = '' 581 else: 582 try: 583 formats = ['%s' for _ in range(action.nargs)] 584 except TypeError: 585 raise ValueError("invalid nargs value") from None 586 result = ' '.join(formats) % get_metavar(action.nargs) 587 return result 588 589 def _expand_help(self, action): 590 params = dict(vars(action), prog=self._prog) 591 for name in list(params): 592 if params[name] is SUPPRESS: 593 del params[name] 594 for name in list(params): 595 if hasattr(params[name], '__name__'): 596 params[name] = params[name].__name__ 597 if params.get('choices') is not None: 598 params['choices'] = ', '.join(map(str, params['choices'])) 599 return self._get_help_string(action) % params 600 601 def _iter_indented_subactions(self, action): 602 try: 603 get_subactions = action._get_subactions 604 except AttributeError: 605 pass 606 else: 607 self._indent() 608 yield from get_subactions() 609 self._dedent() 610 611 def _split_lines(self, text, width): 612 text = self._whitespace_matcher.sub(' ', text).strip() 613 # The textwrap module is used only for formatting help. 614 # Delay its import for speeding up the common usage of argparse. 615 import textwrap 616 return textwrap.wrap(text, width) 617 618 def _fill_text(self, text, width, indent): 619 text = self._whitespace_matcher.sub(' ', text).strip() 620 import textwrap 621 return textwrap.fill(text, width, 622 initial_indent=indent, 623 subsequent_indent=indent) 624 625 def _get_help_string(self, action): 626 return action.help 627 628 def _get_default_metavar_for_optional(self, action): 629 return action.dest.upper() 630 631 def _get_default_metavar_for_positional(self, action): 632 return action.dest 633 634 635class RawDescriptionHelpFormatter(HelpFormatter): 636 """Help message formatter which retains any formatting in descriptions. 637 638 Only the name of this class is considered a public API. All the methods 639 provided by the class are considered an implementation detail. 640 """ 641 642 def _fill_text(self, text, width, indent): 643 return ''.join(indent + line for line in text.splitlines(keepends=True)) 644 645 646class RawTextHelpFormatter(RawDescriptionHelpFormatter): 647 """Help message formatter which retains formatting of all help text. 648 649 Only the name of this class is considered a public API. All the methods 650 provided by the class are considered an implementation detail. 651 """ 652 653 def _split_lines(self, text, width): 654 return text.splitlines() 655 656 657class ArgumentDefaultsHelpFormatter(HelpFormatter): 658 """Help message formatter which adds default values to argument help. 659 660 Only the name of this class is considered a public API. All the methods 661 provided by the class are considered an implementation detail. 662 """ 663 664 def _get_help_string(self, action): 665 help = action.help 666 if help is None: 667 help = '' 668 669 if '%(default)' not in help: 670 if action.default is not SUPPRESS: 671 defaulting_nargs = [OPTIONAL, ZERO_OR_MORE] 672 if action.option_strings or action.nargs in defaulting_nargs: 673 help += _(' (default: %(default)s)') 674 return help 675 676 677 678class MetavarTypeHelpFormatter(HelpFormatter): 679 """Help message formatter which uses the argument 'type' as the default 680 metavar value (instead of the argument 'dest') 681 682 Only the name of this class is considered a public API. All the methods 683 provided by the class are considered an implementation detail. 684 """ 685 686 def _get_default_metavar_for_optional(self, action): 687 return action.type.__name__ 688 689 def _get_default_metavar_for_positional(self, action): 690 return action.type.__name__ 691 692 693# ===================== 694# Options and Arguments 695# ===================== 696 697def _get_action_name(argument): 698 if argument is None: 699 return None 700 elif argument.option_strings: 701 return '/'.join(argument.option_strings) 702 elif argument.metavar not in (None, SUPPRESS): 703 metavar = argument.metavar 704 if not isinstance(metavar, tuple): 705 return metavar 706 if argument.nargs == ZERO_OR_MORE and len(metavar) == 2: 707 return '%s[, %s]' % metavar 708 elif argument.nargs == ONE_OR_MORE: 709 return '%s[, %s]' % metavar 710 else: 711 return ', '.join(metavar) 712 elif argument.dest not in (None, SUPPRESS): 713 return argument.dest 714 elif argument.choices: 715 return '{%s}' % ','.join(map(str, argument.choices)) 716 else: 717 return None 718 719 720class ArgumentError(Exception): 721 """An error from creating or using an argument (optional or positional). 722 723 The string value of this exception is the message, augmented with 724 information about the argument that caused it. 725 """ 726 727 def __init__(self, argument, message): 728 self.argument_name = _get_action_name(argument) 729 self.message = message 730 731 def __str__(self): 732 if self.argument_name is None: 733 format = '%(message)s' 734 else: 735 format = _('argument %(argument_name)s: %(message)s') 736 return format % dict(message=self.message, 737 argument_name=self.argument_name) 738 739 740class ArgumentTypeError(Exception): 741 """An error from trying to convert a command line string to a type.""" 742 pass 743 744 745# ============== 746# Action classes 747# ============== 748 749class Action(_AttributeHolder): 750 """Information about how to convert command line strings to Python objects. 751 752 Action objects are used by an ArgumentParser to represent the information 753 needed to parse a single argument from one or more strings from the 754 command line. The keyword arguments to the Action constructor are also 755 all attributes of Action instances. 756 757 Keyword Arguments: 758 759 - option_strings -- A list of command-line option strings which 760 should be associated with this action. 761 762 - dest -- The name of the attribute to hold the created object(s) 763 764 - nargs -- The number of command-line arguments that should be 765 consumed. By default, one argument will be consumed and a single 766 value will be produced. Other values include: 767 - N (an integer) consumes N arguments (and produces a list) 768 - '?' consumes zero or one arguments 769 - '*' consumes zero or more arguments (and produces a list) 770 - '+' consumes one or more arguments (and produces a list) 771 Note that the difference between the default and nargs=1 is that 772 with the default, a single value will be produced, while with 773 nargs=1, a list containing a single value will be produced. 774 775 - const -- The value to be produced if the option is specified and the 776 option uses an action that takes no values. 777 778 - default -- The value to be produced if the option is not specified. 779 780 - type -- A callable that accepts a single string argument, and 781 returns the converted value. The standard Python types str, int, 782 float, and complex are useful examples of such callables. If None, 783 str is used. 784 785 - choices -- A container of values that should be allowed. If not None, 786 after a command-line argument has been converted to the appropriate 787 type, an exception will be raised if it is not a member of this 788 collection. 789 790 - required -- True if the action must always be specified at the 791 command line. This is only meaningful for optional command-line 792 arguments. 793 794 - help -- The help string describing the argument. 795 796 - metavar -- The name to be used for the option's argument with the 797 help string. If None, the 'dest' value will be used as the name. 798 """ 799 800 def __init__(self, 801 option_strings, 802 dest, 803 nargs=None, 804 const=None, 805 default=None, 806 type=None, 807 choices=None, 808 required=False, 809 help=None, 810 metavar=None, 811 deprecated=False): 812 self.option_strings = option_strings 813 self.dest = dest 814 self.nargs = nargs 815 self.const = const 816 self.default = default 817 self.type = type 818 self.choices = choices 819 self.required = required 820 self.help = help 821 self.metavar = metavar 822 self.deprecated = deprecated 823 824 def _get_kwargs(self): 825 names = [ 826 'option_strings', 827 'dest', 828 'nargs', 829 'const', 830 'default', 831 'type', 832 'choices', 833 'required', 834 'help', 835 'metavar', 836 'deprecated', 837 ] 838 return [(name, getattr(self, name)) for name in names] 839 840 def format_usage(self): 841 return self.option_strings[0] 842 843 def __call__(self, parser, namespace, values, option_string=None): 844 raise NotImplementedError(_('.__call__() not defined')) 845 846 847# FIXME: remove together with `BooleanOptionalAction` deprecated arguments. 848_deprecated_default = object() 849 850class BooleanOptionalAction(Action): 851 def __init__(self, 852 option_strings, 853 dest, 854 default=None, 855 type=_deprecated_default, 856 choices=_deprecated_default, 857 required=False, 858 help=None, 859 metavar=_deprecated_default, 860 deprecated=False): 861 862 _option_strings = [] 863 for option_string in option_strings: 864 _option_strings.append(option_string) 865 866 if option_string.startswith('--'): 867 option_string = '--no-' + option_string[2:] 868 _option_strings.append(option_string) 869 870 # We need `_deprecated` special value to ban explicit arguments that 871 # match default value. Like: 872 # parser.add_argument('-f', action=BooleanOptionalAction, type=int) 873 for field_name in ('type', 'choices', 'metavar'): 874 if locals()[field_name] is not _deprecated_default: 875 import warnings 876 warnings._deprecated( 877 field_name, 878 "{name!r} is deprecated as of Python 3.12 and will be " 879 "removed in Python {remove}.", 880 remove=(3, 14)) 881 882 if type is _deprecated_default: 883 type = None 884 if choices is _deprecated_default: 885 choices = None 886 if metavar is _deprecated_default: 887 metavar = None 888 889 super().__init__( 890 option_strings=_option_strings, 891 dest=dest, 892 nargs=0, 893 default=default, 894 type=type, 895 choices=choices, 896 required=required, 897 help=help, 898 metavar=metavar, 899 deprecated=deprecated) 900 901 902 def __call__(self, parser, namespace, values, option_string=None): 903 if option_string in self.option_strings: 904 setattr(namespace, self.dest, not option_string.startswith('--no-')) 905 906 def format_usage(self): 907 return ' | '.join(self.option_strings) 908 909 910class _StoreAction(Action): 911 912 def __init__(self, 913 option_strings, 914 dest, 915 nargs=None, 916 const=None, 917 default=None, 918 type=None, 919 choices=None, 920 required=False, 921 help=None, 922 metavar=None, 923 deprecated=False): 924 if nargs == 0: 925 raise ValueError('nargs for store actions must be != 0; if you ' 926 'have nothing to store, actions such as store ' 927 'true or store const may be more appropriate') 928 if const is not None and nargs != OPTIONAL: 929 raise ValueError('nargs must be %r to supply const' % OPTIONAL) 930 super(_StoreAction, self).__init__( 931 option_strings=option_strings, 932 dest=dest, 933 nargs=nargs, 934 const=const, 935 default=default, 936 type=type, 937 choices=choices, 938 required=required, 939 help=help, 940 metavar=metavar, 941 deprecated=deprecated) 942 943 def __call__(self, parser, namespace, values, option_string=None): 944 setattr(namespace, self.dest, values) 945 946 947class _StoreConstAction(Action): 948 949 def __init__(self, 950 option_strings, 951 dest, 952 const=None, 953 default=None, 954 required=False, 955 help=None, 956 metavar=None, 957 deprecated=False): 958 super(_StoreConstAction, self).__init__( 959 option_strings=option_strings, 960 dest=dest, 961 nargs=0, 962 const=const, 963 default=default, 964 required=required, 965 help=help, 966 deprecated=deprecated) 967 968 def __call__(self, parser, namespace, values, option_string=None): 969 setattr(namespace, self.dest, self.const) 970 971 972class _StoreTrueAction(_StoreConstAction): 973 974 def __init__(self, 975 option_strings, 976 dest, 977 default=False, 978 required=False, 979 help=None, 980 deprecated=False): 981 super(_StoreTrueAction, self).__init__( 982 option_strings=option_strings, 983 dest=dest, 984 const=True, 985 deprecated=deprecated, 986 required=required, 987 help=help, 988 default=default) 989 990 991class _StoreFalseAction(_StoreConstAction): 992 993 def __init__(self, 994 option_strings, 995 dest, 996 default=True, 997 required=False, 998 help=None, 999 deprecated=False): 1000 super(_StoreFalseAction, self).__init__( 1001 option_strings=option_strings, 1002 dest=dest, 1003 const=False, 1004 default=default, 1005 required=required, 1006 help=help, 1007 deprecated=deprecated) 1008 1009 1010class _AppendAction(Action): 1011 1012 def __init__(self, 1013 option_strings, 1014 dest, 1015 nargs=None, 1016 const=None, 1017 default=None, 1018 type=None, 1019 choices=None, 1020 required=False, 1021 help=None, 1022 metavar=None, 1023 deprecated=False): 1024 if nargs == 0: 1025 raise ValueError('nargs for append actions must be != 0; if arg ' 1026 'strings are not supplying the value to append, ' 1027 'the append const action may be more appropriate') 1028 if const is not None and nargs != OPTIONAL: 1029 raise ValueError('nargs must be %r to supply const' % OPTIONAL) 1030 super(_AppendAction, self).__init__( 1031 option_strings=option_strings, 1032 dest=dest, 1033 nargs=nargs, 1034 const=const, 1035 default=default, 1036 type=type, 1037 choices=choices, 1038 required=required, 1039 help=help, 1040 metavar=metavar, 1041 deprecated=deprecated) 1042 1043 def __call__(self, parser, namespace, values, option_string=None): 1044 items = getattr(namespace, self.dest, None) 1045 items = _copy_items(items) 1046 items.append(values) 1047 setattr(namespace, self.dest, items) 1048 1049 1050class _AppendConstAction(Action): 1051 1052 def __init__(self, 1053 option_strings, 1054 dest, 1055 const=None, 1056 default=None, 1057 required=False, 1058 help=None, 1059 metavar=None, 1060 deprecated=False): 1061 super(_AppendConstAction, self).__init__( 1062 option_strings=option_strings, 1063 dest=dest, 1064 nargs=0, 1065 const=const, 1066 default=default, 1067 required=required, 1068 help=help, 1069 metavar=metavar, 1070 deprecated=deprecated) 1071 1072 def __call__(self, parser, namespace, values, option_string=None): 1073 items = getattr(namespace, self.dest, None) 1074 items = _copy_items(items) 1075 items.append(self.const) 1076 setattr(namespace, self.dest, items) 1077 1078 1079class _CountAction(Action): 1080 1081 def __init__(self, 1082 option_strings, 1083 dest, 1084 default=None, 1085 required=False, 1086 help=None, 1087 deprecated=False): 1088 super(_CountAction, self).__init__( 1089 option_strings=option_strings, 1090 dest=dest, 1091 nargs=0, 1092 default=default, 1093 required=required, 1094 help=help, 1095 deprecated=deprecated) 1096 1097 def __call__(self, parser, namespace, values, option_string=None): 1098 count = getattr(namespace, self.dest, None) 1099 if count is None: 1100 count = 0 1101 setattr(namespace, self.dest, count + 1) 1102 1103 1104class _HelpAction(Action): 1105 1106 def __init__(self, 1107 option_strings, 1108 dest=SUPPRESS, 1109 default=SUPPRESS, 1110 help=None, 1111 deprecated=False): 1112 super(_HelpAction, self).__init__( 1113 option_strings=option_strings, 1114 dest=dest, 1115 default=default, 1116 nargs=0, 1117 help=help, 1118 deprecated=deprecated) 1119 1120 def __call__(self, parser, namespace, values, option_string=None): 1121 parser.print_help() 1122 parser.exit() 1123 1124 1125class _VersionAction(Action): 1126 1127 def __init__(self, 1128 option_strings, 1129 version=None, 1130 dest=SUPPRESS, 1131 default=SUPPRESS, 1132 help=None, 1133 deprecated=False): 1134 if help is None: 1135 help = _("show program's version number and exit") 1136 super(_VersionAction, self).__init__( 1137 option_strings=option_strings, 1138 dest=dest, 1139 default=default, 1140 nargs=0, 1141 help=help) 1142 self.version = version 1143 1144 def __call__(self, parser, namespace, values, option_string=None): 1145 version = self.version 1146 if version is None: 1147 version = parser.version 1148 formatter = parser._get_formatter() 1149 formatter.add_text(version) 1150 parser._print_message(formatter.format_help(), _sys.stdout) 1151 parser.exit() 1152 1153 1154class _SubParsersAction(Action): 1155 1156 class _ChoicesPseudoAction(Action): 1157 1158 def __init__(self, name, aliases, help): 1159 metavar = dest = name 1160 if aliases: 1161 metavar += ' (%s)' % ', '.join(aliases) 1162 sup = super(_SubParsersAction._ChoicesPseudoAction, self) 1163 sup.__init__(option_strings=[], dest=dest, help=help, 1164 metavar=metavar) 1165 1166 def __init__(self, 1167 option_strings, 1168 prog, 1169 parser_class, 1170 dest=SUPPRESS, 1171 required=False, 1172 help=None, 1173 metavar=None): 1174 1175 self._prog_prefix = prog 1176 self._parser_class = parser_class 1177 self._name_parser_map = {} 1178 self._choices_actions = [] 1179 self._deprecated = set() 1180 1181 super(_SubParsersAction, self).__init__( 1182 option_strings=option_strings, 1183 dest=dest, 1184 nargs=PARSER, 1185 choices=self._name_parser_map, 1186 required=required, 1187 help=help, 1188 metavar=metavar) 1189 1190 def add_parser(self, name, *, deprecated=False, **kwargs): 1191 # set prog from the existing prefix 1192 if kwargs.get('prog') is None: 1193 kwargs['prog'] = '%s %s' % (self._prog_prefix, name) 1194 1195 aliases = kwargs.pop('aliases', ()) 1196 1197 if name in self._name_parser_map: 1198 raise ArgumentError(self, _('conflicting subparser: %s') % name) 1199 for alias in aliases: 1200 if alias in self._name_parser_map: 1201 raise ArgumentError( 1202 self, _('conflicting subparser alias: %s') % alias) 1203 1204 # create a pseudo-action to hold the choice help 1205 if 'help' in kwargs: 1206 help = kwargs.pop('help') 1207 choice_action = self._ChoicesPseudoAction(name, aliases, help) 1208 self._choices_actions.append(choice_action) 1209 1210 # create the parser and add it to the map 1211 parser = self._parser_class(**kwargs) 1212 self._name_parser_map[name] = parser 1213 1214 # make parser available under aliases also 1215 for alias in aliases: 1216 self._name_parser_map[alias] = parser 1217 1218 if deprecated: 1219 self._deprecated.add(name) 1220 self._deprecated.update(aliases) 1221 1222 return parser 1223 1224 def _get_subactions(self): 1225 return self._choices_actions 1226 1227 def __call__(self, parser, namespace, values, option_string=None): 1228 parser_name = values[0] 1229 arg_strings = values[1:] 1230 1231 # set the parser name if requested 1232 if self.dest is not SUPPRESS: 1233 setattr(namespace, self.dest, parser_name) 1234 1235 # select the parser 1236 try: 1237 subparser = self._name_parser_map[parser_name] 1238 except KeyError: 1239 args = {'parser_name': parser_name, 1240 'choices': ', '.join(self._name_parser_map)} 1241 msg = _('unknown parser %(parser_name)r (choices: %(choices)s)') % args 1242 raise ArgumentError(self, msg) 1243 1244 if parser_name in self._deprecated: 1245 parser._warning(_("command '%(parser_name)s' is deprecated") % 1246 {'parser_name': parser_name}) 1247 1248 # parse all the remaining options into the namespace 1249 # store any unrecognized options on the object, so that the top 1250 # level parser can decide what to do with them 1251 1252 # In case this subparser defines new defaults, we parse them 1253 # in a new namespace object and then update the original 1254 # namespace for the relevant parts. 1255 subnamespace, arg_strings = subparser.parse_known_args(arg_strings, None) 1256 for key, value in vars(subnamespace).items(): 1257 setattr(namespace, key, value) 1258 1259 if arg_strings: 1260 if not hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR): 1261 setattr(namespace, _UNRECOGNIZED_ARGS_ATTR, []) 1262 getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).extend(arg_strings) 1263 1264class _ExtendAction(_AppendAction): 1265 def __call__(self, parser, namespace, values, option_string=None): 1266 items = getattr(namespace, self.dest, None) 1267 items = _copy_items(items) 1268 items.extend(values) 1269 setattr(namespace, self.dest, items) 1270 1271# ============== 1272# Type classes 1273# ============== 1274 1275class FileType(object): 1276 """Factory for creating file object types 1277 1278 Instances of FileType are typically passed as type= arguments to the 1279 ArgumentParser add_argument() method. 1280 1281 Keyword Arguments: 1282 - mode -- A string indicating how the file is to be opened. Accepts the 1283 same values as the builtin open() function. 1284 - bufsize -- The file's desired buffer size. Accepts the same values as 1285 the builtin open() function. 1286 - encoding -- The file's encoding. Accepts the same values as the 1287 builtin open() function. 1288 - errors -- A string indicating how encoding and decoding errors are to 1289 be handled. Accepts the same value as the builtin open() function. 1290 """ 1291 1292 def __init__(self, mode='r', bufsize=-1, encoding=None, errors=None): 1293 self._mode = mode 1294 self._bufsize = bufsize 1295 self._encoding = encoding 1296 self._errors = errors 1297 1298 def __call__(self, string): 1299 # the special argument "-" means sys.std{in,out} 1300 if string == '-': 1301 if 'r' in self._mode: 1302 return _sys.stdin.buffer if 'b' in self._mode else _sys.stdin 1303 elif any(c in self._mode for c in 'wax'): 1304 return _sys.stdout.buffer if 'b' in self._mode else _sys.stdout 1305 else: 1306 msg = _('argument "-" with mode %r') % self._mode 1307 raise ValueError(msg) 1308 1309 # all other arguments are used as file names 1310 try: 1311 return open(string, self._mode, self._bufsize, self._encoding, 1312 self._errors) 1313 except OSError as e: 1314 args = {'filename': string, 'error': e} 1315 message = _("can't open '%(filename)s': %(error)s") 1316 raise ArgumentTypeError(message % args) 1317 1318 def __repr__(self): 1319 args = self._mode, self._bufsize 1320 kwargs = [('encoding', self._encoding), ('errors', self._errors)] 1321 args_str = ', '.join([repr(arg) for arg in args if arg != -1] + 1322 ['%s=%r' % (kw, arg) for kw, arg in kwargs 1323 if arg is not None]) 1324 return '%s(%s)' % (type(self).__name__, args_str) 1325 1326# =========================== 1327# Optional and Positional Parsing 1328# =========================== 1329 1330class Namespace(_AttributeHolder): 1331 """Simple object for storing attributes. 1332 1333 Implements equality by attribute names and values, and provides a simple 1334 string representation. 1335 """ 1336 1337 def __init__(self, **kwargs): 1338 for name in kwargs: 1339 setattr(self, name, kwargs[name]) 1340 1341 def __eq__(self, other): 1342 if not isinstance(other, Namespace): 1343 return NotImplemented 1344 return vars(self) == vars(other) 1345 1346 def __contains__(self, key): 1347 return key in self.__dict__ 1348 1349 1350class _ActionsContainer(object): 1351 1352 def __init__(self, 1353 description, 1354 prefix_chars, 1355 argument_default, 1356 conflict_handler): 1357 super(_ActionsContainer, self).__init__() 1358 1359 self.description = description 1360 self.argument_default = argument_default 1361 self.prefix_chars = prefix_chars 1362 self.conflict_handler = conflict_handler 1363 1364 # set up registries 1365 self._registries = {} 1366 1367 # register actions 1368 self.register('action', None, _StoreAction) 1369 self.register('action', 'store', _StoreAction) 1370 self.register('action', 'store_const', _StoreConstAction) 1371 self.register('action', 'store_true', _StoreTrueAction) 1372 self.register('action', 'store_false', _StoreFalseAction) 1373 self.register('action', 'append', _AppendAction) 1374 self.register('action', 'append_const', _AppendConstAction) 1375 self.register('action', 'count', _CountAction) 1376 self.register('action', 'help', _HelpAction) 1377 self.register('action', 'version', _VersionAction) 1378 self.register('action', 'parsers', _SubParsersAction) 1379 self.register('action', 'extend', _ExtendAction) 1380 1381 # raise an exception if the conflict handler is invalid 1382 self._get_handler() 1383 1384 # action storage 1385 self._actions = [] 1386 self._option_string_actions = {} 1387 1388 # groups 1389 self._action_groups = [] 1390 self._mutually_exclusive_groups = [] 1391 1392 # defaults storage 1393 self._defaults = {} 1394 1395 # determines whether an "option" looks like a negative number 1396 self._negative_number_matcher = _re.compile(r'^-\d+$|^-\d*\.\d+$') 1397 1398 # whether or not there are any optionals that look like negative 1399 # numbers -- uses a list so it can be shared and edited 1400 self._has_negative_number_optionals = [] 1401 1402 # ==================== 1403 # Registration methods 1404 # ==================== 1405 def register(self, registry_name, value, object): 1406 registry = self._registries.setdefault(registry_name, {}) 1407 registry[value] = object 1408 1409 def _registry_get(self, registry_name, value, default=None): 1410 return self._registries[registry_name].get(value, default) 1411 1412 # ================================== 1413 # Namespace default accessor methods 1414 # ================================== 1415 def set_defaults(self, **kwargs): 1416 self._defaults.update(kwargs) 1417 1418 # if these defaults match any existing arguments, replace 1419 # the previous default on the object with the new one 1420 for action in self._actions: 1421 if action.dest in kwargs: 1422 action.default = kwargs[action.dest] 1423 1424 def get_default(self, dest): 1425 for action in self._actions: 1426 if action.dest == dest and action.default is not None: 1427 return action.default 1428 return self._defaults.get(dest, None) 1429 1430 1431 # ======================= 1432 # Adding argument actions 1433 # ======================= 1434 def add_argument(self, *args, **kwargs): 1435 """ 1436 add_argument(dest, ..., name=value, ...) 1437 add_argument(option_string, option_string, ..., name=value, ...) 1438 """ 1439 1440 # if no positional args are supplied or only one is supplied and 1441 # it doesn't look like an option string, parse a positional 1442 # argument 1443 chars = self.prefix_chars 1444 if not args or len(args) == 1 and args[0][0] not in chars: 1445 if args and 'dest' in kwargs: 1446 raise ValueError('dest supplied twice for positional argument') 1447 kwargs = self._get_positional_kwargs(*args, **kwargs) 1448 1449 # otherwise, we're adding an optional argument 1450 else: 1451 kwargs = self._get_optional_kwargs(*args, **kwargs) 1452 1453 # if no default was supplied, use the parser-level default 1454 if 'default' not in kwargs: 1455 dest = kwargs['dest'] 1456 if dest in self._defaults: 1457 kwargs['default'] = self._defaults[dest] 1458 elif self.argument_default is not None: 1459 kwargs['default'] = self.argument_default 1460 1461 # create the action object, and add it to the parser 1462 action_class = self._pop_action_class(kwargs) 1463 if not callable(action_class): 1464 raise ValueError('unknown action "%s"' % (action_class,)) 1465 action = action_class(**kwargs) 1466 1467 # raise an error if the action type is not callable 1468 type_func = self._registry_get('type', action.type, action.type) 1469 if not callable(type_func): 1470 raise ValueError('%r is not callable' % (type_func,)) 1471 1472 if type_func is FileType: 1473 raise ValueError('%r is a FileType class object, instance of it' 1474 ' must be passed' % (type_func,)) 1475 1476 # raise an error if the metavar does not match the type 1477 if hasattr(self, "_get_formatter"): 1478 try: 1479 self._get_formatter()._format_args(action, None) 1480 except TypeError: 1481 raise ValueError("length of metavar tuple does not match nargs") 1482 1483 return self._add_action(action) 1484 1485 def add_argument_group(self, *args, **kwargs): 1486 group = _ArgumentGroup(self, *args, **kwargs) 1487 self._action_groups.append(group) 1488 return group 1489 1490 def add_mutually_exclusive_group(self, **kwargs): 1491 group = _MutuallyExclusiveGroup(self, **kwargs) 1492 self._mutually_exclusive_groups.append(group) 1493 return group 1494 1495 def _add_action(self, action): 1496 # resolve any conflicts 1497 self._check_conflict(action) 1498 1499 # add to actions list 1500 self._actions.append(action) 1501 action.container = self 1502 1503 # index the action by any option strings it has 1504 for option_string in action.option_strings: 1505 self._option_string_actions[option_string] = action 1506 1507 # set the flag if any option strings look like negative numbers 1508 for option_string in action.option_strings: 1509 if self._negative_number_matcher.match(option_string): 1510 if not self._has_negative_number_optionals: 1511 self._has_negative_number_optionals.append(True) 1512 1513 # return the created action 1514 return action 1515 1516 def _remove_action(self, action): 1517 self._actions.remove(action) 1518 1519 def _add_container_actions(self, container): 1520 # collect groups by titles 1521 title_group_map = {} 1522 for group in self._action_groups: 1523 if group.title in title_group_map: 1524 # This branch could happen if a derived class added 1525 # groups with duplicated titles in __init__ 1526 msg = _('cannot merge actions - two groups are named %r') 1527 raise ValueError(msg % (group.title)) 1528 title_group_map[group.title] = group 1529 1530 # map each action to its group 1531 group_map = {} 1532 for group in container._action_groups: 1533 1534 # if a group with the title exists, use that, otherwise 1535 # create a new group matching the container's group 1536 if group.title not in title_group_map: 1537 title_group_map[group.title] = self.add_argument_group( 1538 title=group.title, 1539 description=group.description, 1540 conflict_handler=group.conflict_handler) 1541 1542 # map the actions to their new group 1543 for action in group._group_actions: 1544 group_map[action] = title_group_map[group.title] 1545 1546 # add container's mutually exclusive groups 1547 # NOTE: if add_mutually_exclusive_group ever gains title= and 1548 # description= then this code will need to be expanded as above 1549 for group in container._mutually_exclusive_groups: 1550 if group._container is container: 1551 cont = self 1552 else: 1553 cont = title_group_map[group._container.title] 1554 mutex_group = cont.add_mutually_exclusive_group( 1555 required=group.required) 1556 1557 # map the actions to their new mutex group 1558 for action in group._group_actions: 1559 group_map[action] = mutex_group 1560 1561 # add all actions to this container or their group 1562 for action in container._actions: 1563 group_map.get(action, self)._add_action(action) 1564 1565 def _get_positional_kwargs(self, dest, **kwargs): 1566 # make sure required is not specified 1567 if 'required' in kwargs: 1568 msg = _("'required' is an invalid argument for positionals") 1569 raise TypeError(msg) 1570 1571 # mark positional arguments as required if at least one is 1572 # always required 1573 nargs = kwargs.get('nargs') 1574 if nargs not in [OPTIONAL, ZERO_OR_MORE, REMAINDER, SUPPRESS, 0]: 1575 kwargs['required'] = True 1576 1577 # return the keyword arguments with no option strings 1578 return dict(kwargs, dest=dest, option_strings=[]) 1579 1580 def _get_optional_kwargs(self, *args, **kwargs): 1581 # determine short and long option strings 1582 option_strings = [] 1583 long_option_strings = [] 1584 for option_string in args: 1585 # error on strings that don't start with an appropriate prefix 1586 if not option_string[0] in self.prefix_chars: 1587 args = {'option': option_string, 1588 'prefix_chars': self.prefix_chars} 1589 msg = _('invalid option string %(option)r: ' 1590 'must start with a character %(prefix_chars)r') 1591 raise ValueError(msg % args) 1592 1593 # strings starting with two prefix characters are long options 1594 option_strings.append(option_string) 1595 if len(option_string) > 1 and option_string[1] in self.prefix_chars: 1596 long_option_strings.append(option_string) 1597 1598 # infer destination, '--foo-bar' -> 'foo_bar' and '-x' -> 'x' 1599 dest = kwargs.pop('dest', None) 1600 if dest is None: 1601 if long_option_strings: 1602 dest_option_string = long_option_strings[0] 1603 else: 1604 dest_option_string = option_strings[0] 1605 dest = dest_option_string.lstrip(self.prefix_chars) 1606 if not dest: 1607 msg = _('dest= is required for options like %r') 1608 raise ValueError(msg % option_string) 1609 dest = dest.replace('-', '_') 1610 1611 # return the updated keyword arguments 1612 return dict(kwargs, dest=dest, option_strings=option_strings) 1613 1614 def _pop_action_class(self, kwargs, default=None): 1615 action = kwargs.pop('action', default) 1616 return self._registry_get('action', action, action) 1617 1618 def _get_handler(self): 1619 # determine function from conflict handler string 1620 handler_func_name = '_handle_conflict_%s' % self.conflict_handler 1621 try: 1622 return getattr(self, handler_func_name) 1623 except AttributeError: 1624 msg = _('invalid conflict_resolution value: %r') 1625 raise ValueError(msg % self.conflict_handler) 1626 1627 def _check_conflict(self, action): 1628 1629 # find all options that conflict with this option 1630 confl_optionals = [] 1631 for option_string in action.option_strings: 1632 if option_string in self._option_string_actions: 1633 confl_optional = self._option_string_actions[option_string] 1634 confl_optionals.append((option_string, confl_optional)) 1635 1636 # resolve any conflicts 1637 if confl_optionals: 1638 conflict_handler = self._get_handler() 1639 conflict_handler(action, confl_optionals) 1640 1641 def _handle_conflict_error(self, action, conflicting_actions): 1642 message = ngettext('conflicting option string: %s', 1643 'conflicting option strings: %s', 1644 len(conflicting_actions)) 1645 conflict_string = ', '.join([option_string 1646 for option_string, action 1647 in conflicting_actions]) 1648 raise ArgumentError(action, message % conflict_string) 1649 1650 def _handle_conflict_resolve(self, action, conflicting_actions): 1651 1652 # remove all conflicting options 1653 for option_string, action in conflicting_actions: 1654 1655 # remove the conflicting option 1656 action.option_strings.remove(option_string) 1657 self._option_string_actions.pop(option_string, None) 1658 1659 # if the option now has no option string, remove it from the 1660 # container holding it 1661 if not action.option_strings: 1662 action.container._remove_action(action) 1663 1664 1665class _ArgumentGroup(_ActionsContainer): 1666 1667 def __init__(self, container, title=None, description=None, **kwargs): 1668 # add any missing keyword arguments by checking the container 1669 update = kwargs.setdefault 1670 update('conflict_handler', container.conflict_handler) 1671 update('prefix_chars', container.prefix_chars) 1672 update('argument_default', container.argument_default) 1673 super_init = super(_ArgumentGroup, self).__init__ 1674 super_init(description=description, **kwargs) 1675 1676 # group attributes 1677 self.title = title 1678 self._group_actions = [] 1679 1680 # share most attributes with the container 1681 self._registries = container._registries 1682 self._actions = container._actions 1683 self._option_string_actions = container._option_string_actions 1684 self._defaults = container._defaults 1685 self._has_negative_number_optionals = \ 1686 container._has_negative_number_optionals 1687 self._mutually_exclusive_groups = container._mutually_exclusive_groups 1688 1689 def _add_action(self, action): 1690 action = super(_ArgumentGroup, self)._add_action(action) 1691 self._group_actions.append(action) 1692 return action 1693 1694 def _remove_action(self, action): 1695 super(_ArgumentGroup, self)._remove_action(action) 1696 self._group_actions.remove(action) 1697 1698 def add_argument_group(self, *args, **kwargs): 1699 import warnings 1700 warnings.warn( 1701 "Nesting argument groups is deprecated.", 1702 category=DeprecationWarning, 1703 stacklevel=2 1704 ) 1705 return super().add_argument_group(*args, **kwargs) 1706 1707 1708class _MutuallyExclusiveGroup(_ArgumentGroup): 1709 1710 def __init__(self, container, required=False): 1711 super(_MutuallyExclusiveGroup, self).__init__(container) 1712 self.required = required 1713 self._container = container 1714 1715 def _add_action(self, action): 1716 if action.required: 1717 msg = _('mutually exclusive arguments must be optional') 1718 raise ValueError(msg) 1719 action = self._container._add_action(action) 1720 self._group_actions.append(action) 1721 return action 1722 1723 def _remove_action(self, action): 1724 self._container._remove_action(action) 1725 self._group_actions.remove(action) 1726 1727 def add_mutually_exclusive_group(self, *args, **kwargs): 1728 import warnings 1729 warnings.warn( 1730 "Nesting mutually exclusive groups is deprecated.", 1731 category=DeprecationWarning, 1732 stacklevel=2 1733 ) 1734 return super().add_mutually_exclusive_group(*args, **kwargs) 1735 1736 1737class ArgumentParser(_AttributeHolder, _ActionsContainer): 1738 """Object for parsing command line strings into Python objects. 1739 1740 Keyword Arguments: 1741 - prog -- The name of the program (default: 1742 ``os.path.basename(sys.argv[0])``) 1743 - usage -- A usage message (default: auto-generated from arguments) 1744 - description -- A description of what the program does 1745 - epilog -- Text following the argument descriptions 1746 - parents -- Parsers whose arguments should be copied into this one 1747 - formatter_class -- HelpFormatter class for printing help messages 1748 - prefix_chars -- Characters that prefix optional arguments 1749 - fromfile_prefix_chars -- Characters that prefix files containing 1750 additional arguments 1751 - argument_default -- The default value for all arguments 1752 - conflict_handler -- String indicating how to handle conflicts 1753 - add_help -- Add a -h/-help option 1754 - allow_abbrev -- Allow long options to be abbreviated unambiguously 1755 - exit_on_error -- Determines whether or not ArgumentParser exits with 1756 error info when an error occurs 1757 """ 1758 1759 def __init__(self, 1760 prog=None, 1761 usage=None, 1762 description=None, 1763 epilog=None, 1764 parents=[], 1765 formatter_class=HelpFormatter, 1766 prefix_chars='-', 1767 fromfile_prefix_chars=None, 1768 argument_default=None, 1769 conflict_handler='error', 1770 add_help=True, 1771 allow_abbrev=True, 1772 exit_on_error=True): 1773 1774 superinit = super(ArgumentParser, self).__init__ 1775 superinit(description=description, 1776 prefix_chars=prefix_chars, 1777 argument_default=argument_default, 1778 conflict_handler=conflict_handler) 1779 1780 # default setting for prog 1781 if prog is None: 1782 prog = _os.path.basename(_sys.argv[0]) 1783 1784 self.prog = prog 1785 self.usage = usage 1786 self.epilog = epilog 1787 self.formatter_class = formatter_class 1788 self.fromfile_prefix_chars = fromfile_prefix_chars 1789 self.add_help = add_help 1790 self.allow_abbrev = allow_abbrev 1791 self.exit_on_error = exit_on_error 1792 1793 add_group = self.add_argument_group 1794 self._positionals = add_group(_('positional arguments')) 1795 self._optionals = add_group(_('options')) 1796 self._subparsers = None 1797 1798 # register types 1799 def identity(string): 1800 return string 1801 self.register('type', None, identity) 1802 1803 # add help argument if necessary 1804 # (using explicit default to override global argument_default) 1805 default_prefix = '-' if '-' in prefix_chars else prefix_chars[0] 1806 if self.add_help: 1807 self.add_argument( 1808 default_prefix+'h', default_prefix*2+'help', 1809 action='help', default=SUPPRESS, 1810 help=_('show this help message and exit')) 1811 1812 # add parent arguments and defaults 1813 for parent in parents: 1814 if not isinstance(parent, ArgumentParser): 1815 raise TypeError('parents must be a list of ArgumentParser') 1816 self._add_container_actions(parent) 1817 defaults = parent._defaults 1818 self._defaults.update(defaults) 1819 1820 # ======================= 1821 # Pretty __repr__ methods 1822 # ======================= 1823 def _get_kwargs(self): 1824 names = [ 1825 'prog', 1826 'usage', 1827 'description', 1828 'formatter_class', 1829 'conflict_handler', 1830 'add_help', 1831 ] 1832 return [(name, getattr(self, name)) for name in names] 1833 1834 # ================================== 1835 # Optional/Positional adding methods 1836 # ================================== 1837 def add_subparsers(self, **kwargs): 1838 if self._subparsers is not None: 1839 raise ArgumentError(None, _('cannot have multiple subparser arguments')) 1840 1841 # add the parser class to the arguments if it's not present 1842 kwargs.setdefault('parser_class', type(self)) 1843 1844 if 'title' in kwargs or 'description' in kwargs: 1845 title = kwargs.pop('title', _('subcommands')) 1846 description = kwargs.pop('description', None) 1847 self._subparsers = self.add_argument_group(title, description) 1848 else: 1849 self._subparsers = self._positionals 1850 1851 # prog defaults to the usage message of this parser, skipping 1852 # optional arguments and with no "usage:" prefix 1853 if kwargs.get('prog') is None: 1854 formatter = self._get_formatter() 1855 positionals = self._get_positional_actions() 1856 groups = self._mutually_exclusive_groups 1857 formatter.add_usage(self.usage, positionals, groups, '') 1858 kwargs['prog'] = formatter.format_help().strip() 1859 1860 # create the parsers action and add it to the positionals list 1861 parsers_class = self._pop_action_class(kwargs, 'parsers') 1862 action = parsers_class(option_strings=[], **kwargs) 1863 self._subparsers._add_action(action) 1864 1865 # return the created parsers action 1866 return action 1867 1868 def _add_action(self, action): 1869 if action.option_strings: 1870 self._optionals._add_action(action) 1871 else: 1872 self._positionals._add_action(action) 1873 return action 1874 1875 def _get_optional_actions(self): 1876 return [action 1877 for action in self._actions 1878 if action.option_strings] 1879 1880 def _get_positional_actions(self): 1881 return [action 1882 for action in self._actions 1883 if not action.option_strings] 1884 1885 # ===================================== 1886 # Command line argument parsing methods 1887 # ===================================== 1888 def parse_args(self, args=None, namespace=None): 1889 args, argv = self.parse_known_args(args, namespace) 1890 if argv: 1891 msg = _('unrecognized arguments: %s') % ' '.join(argv) 1892 if self.exit_on_error: 1893 self.error(msg) 1894 else: 1895 raise ArgumentError(None, msg) 1896 return args 1897 1898 def parse_known_args(self, args=None, namespace=None): 1899 return self._parse_known_args2(args, namespace, intermixed=False) 1900 1901 def _parse_known_args2(self, args, namespace, intermixed): 1902 if args is None: 1903 # args default to the system args 1904 args = _sys.argv[1:] 1905 else: 1906 # make sure that args are mutable 1907 args = list(args) 1908 1909 # default Namespace built from parser defaults 1910 if namespace is None: 1911 namespace = Namespace() 1912 1913 # add any action defaults that aren't present 1914 for action in self._actions: 1915 if action.dest is not SUPPRESS: 1916 if not hasattr(namespace, action.dest): 1917 if action.default is not SUPPRESS: 1918 setattr(namespace, action.dest, action.default) 1919 1920 # add any parser defaults that aren't present 1921 for dest in self._defaults: 1922 if not hasattr(namespace, dest): 1923 setattr(namespace, dest, self._defaults[dest]) 1924 1925 # parse the arguments and exit if there are any errors 1926 if self.exit_on_error: 1927 try: 1928 namespace, args = self._parse_known_args(args, namespace, intermixed) 1929 except ArgumentError as err: 1930 self.error(str(err)) 1931 else: 1932 namespace, args = self._parse_known_args(args, namespace, intermixed) 1933 1934 if hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR): 1935 args.extend(getattr(namespace, _UNRECOGNIZED_ARGS_ATTR)) 1936 delattr(namespace, _UNRECOGNIZED_ARGS_ATTR) 1937 return namespace, args 1938 1939 def _parse_known_args(self, arg_strings, namespace, intermixed): 1940 # replace arg strings that are file references 1941 if self.fromfile_prefix_chars is not None: 1942 arg_strings = self._read_args_from_files(arg_strings) 1943 1944 # map all mutually exclusive arguments to the other arguments 1945 # they can't occur with 1946 action_conflicts = {} 1947 for mutex_group in self._mutually_exclusive_groups: 1948 group_actions = mutex_group._group_actions 1949 for i, mutex_action in enumerate(mutex_group._group_actions): 1950 conflicts = action_conflicts.setdefault(mutex_action, []) 1951 conflicts.extend(group_actions[:i]) 1952 conflicts.extend(group_actions[i + 1:]) 1953 1954 # find all option indices, and determine the arg_string_pattern 1955 # which has an 'O' if there is an option at an index, 1956 # an 'A' if there is an argument, or a '-' if there is a '--' 1957 option_string_indices = {} 1958 arg_string_pattern_parts = [] 1959 arg_strings_iter = iter(arg_strings) 1960 for i, arg_string in enumerate(arg_strings_iter): 1961 1962 # all args after -- are non-options 1963 if arg_string == '--': 1964 arg_string_pattern_parts.append('-') 1965 for arg_string in arg_strings_iter: 1966 arg_string_pattern_parts.append('A') 1967 1968 # otherwise, add the arg to the arg strings 1969 # and note the index if it was an option 1970 else: 1971 option_tuples = self._parse_optional(arg_string) 1972 if option_tuples is None: 1973 pattern = 'A' 1974 else: 1975 option_string_indices[i] = option_tuples 1976 pattern = 'O' 1977 arg_string_pattern_parts.append(pattern) 1978 1979 # join the pieces together to form the pattern 1980 arg_strings_pattern = ''.join(arg_string_pattern_parts) 1981 1982 # converts arg strings to the appropriate and then takes the action 1983 seen_actions = set() 1984 seen_non_default_actions = set() 1985 warned = set() 1986 1987 def take_action(action, argument_strings, option_string=None): 1988 seen_actions.add(action) 1989 argument_values = self._get_values(action, argument_strings) 1990 1991 # error if this argument is not allowed with other previously 1992 # seen arguments 1993 if action.option_strings or argument_strings: 1994 seen_non_default_actions.add(action) 1995 for conflict_action in action_conflicts.get(action, []): 1996 if conflict_action in seen_non_default_actions: 1997 msg = _('not allowed with argument %s') 1998 action_name = _get_action_name(conflict_action) 1999 raise ArgumentError(action, msg % action_name) 2000 2001 # take the action if we didn't receive a SUPPRESS value 2002 # (e.g. from a default) 2003 if argument_values is not SUPPRESS: 2004 action(self, namespace, argument_values, option_string) 2005 2006 # function to convert arg_strings into an optional action 2007 def consume_optional(start_index): 2008 2009 # get the optional identified at this index 2010 option_tuples = option_string_indices[start_index] 2011 # if multiple actions match, the option string was ambiguous 2012 if len(option_tuples) > 1: 2013 options = ', '.join([option_string 2014 for action, option_string, sep, explicit_arg in option_tuples]) 2015 args = {'option': arg_strings[start_index], 'matches': options} 2016 msg = _('ambiguous option: %(option)s could match %(matches)s') 2017 raise ArgumentError(None, msg % args) 2018 2019 action, option_string, sep, explicit_arg = option_tuples[0] 2020 2021 # identify additional optionals in the same arg string 2022 # (e.g. -xyz is the same as -x -y -z if no args are required) 2023 match_argument = self._match_argument 2024 action_tuples = [] 2025 while True: 2026 2027 # if we found no optional action, skip it 2028 if action is None: 2029 extras.append(arg_strings[start_index]) 2030 extras_pattern.append('O') 2031 return start_index + 1 2032 2033 # if there is an explicit argument, try to match the 2034 # optional's string arguments to only this 2035 if explicit_arg is not None: 2036 arg_count = match_argument(action, 'A') 2037 2038 # if the action is a single-dash option and takes no 2039 # arguments, try to parse more single-dash options out 2040 # of the tail of the option string 2041 chars = self.prefix_chars 2042 if ( 2043 arg_count == 0 2044 and option_string[1] not in chars 2045 and explicit_arg != '' 2046 ): 2047 if sep or explicit_arg[0] in chars: 2048 msg = _('ignored explicit argument %r') 2049 raise ArgumentError(action, msg % explicit_arg) 2050 action_tuples.append((action, [], option_string)) 2051 char = option_string[0] 2052 option_string = char + explicit_arg[0] 2053 optionals_map = self._option_string_actions 2054 if option_string in optionals_map: 2055 action = optionals_map[option_string] 2056 explicit_arg = explicit_arg[1:] 2057 if not explicit_arg: 2058 sep = explicit_arg = None 2059 elif explicit_arg[0] == '=': 2060 sep = '=' 2061 explicit_arg = explicit_arg[1:] 2062 else: 2063 sep = '' 2064 else: 2065 extras.append(char + explicit_arg) 2066 extras_pattern.append('O') 2067 stop = start_index + 1 2068 break 2069 # if the action expect exactly one argument, we've 2070 # successfully matched the option; exit the loop 2071 elif arg_count == 1: 2072 stop = start_index + 1 2073 args = [explicit_arg] 2074 action_tuples.append((action, args, option_string)) 2075 break 2076 2077 # error if a double-dash option did not use the 2078 # explicit argument 2079 else: 2080 msg = _('ignored explicit argument %r') 2081 raise ArgumentError(action, msg % explicit_arg) 2082 2083 # if there is no explicit argument, try to match the 2084 # optional's string arguments with the following strings 2085 # if successful, exit the loop 2086 else: 2087 start = start_index + 1 2088 selected_patterns = arg_strings_pattern[start:] 2089 arg_count = match_argument(action, selected_patterns) 2090 stop = start + arg_count 2091 args = arg_strings[start:stop] 2092 action_tuples.append((action, args, option_string)) 2093 break 2094 2095 # add the Optional to the list and return the index at which 2096 # the Optional's string args stopped 2097 assert action_tuples 2098 for action, args, option_string in action_tuples: 2099 if action.deprecated and option_string not in warned: 2100 self._warning(_("option '%(option)s' is deprecated") % 2101 {'option': option_string}) 2102 warned.add(option_string) 2103 take_action(action, args, option_string) 2104 return stop 2105 2106 # the list of Positionals left to be parsed; this is modified 2107 # by consume_positionals() 2108 positionals = self._get_positional_actions() 2109 2110 # function to convert arg_strings into positional actions 2111 def consume_positionals(start_index): 2112 # match as many Positionals as possible 2113 match_partial = self._match_arguments_partial 2114 selected_pattern = arg_strings_pattern[start_index:] 2115 arg_counts = match_partial(positionals, selected_pattern) 2116 2117 # slice off the appropriate arg strings for each Positional 2118 # and add the Positional and its args to the list 2119 for action, arg_count in zip(positionals, arg_counts): 2120 args = arg_strings[start_index: start_index + arg_count] 2121 # Strip out the first '--' if it is not in REMAINDER arg. 2122 if action.nargs == PARSER: 2123 if arg_strings_pattern[start_index] == '-': 2124 assert args[0] == '--' 2125 args.remove('--') 2126 elif action.nargs != REMAINDER: 2127 if (arg_strings_pattern.find('-', start_index, 2128 start_index + arg_count) >= 0): 2129 args.remove('--') 2130 start_index += arg_count 2131 if args and action.deprecated and action.dest not in warned: 2132 self._warning(_("argument '%(argument_name)s' is deprecated") % 2133 {'argument_name': action.dest}) 2134 warned.add(action.dest) 2135 take_action(action, args) 2136 2137 # slice off the Positionals that we just parsed and return the 2138 # index at which the Positionals' string args stopped 2139 positionals[:] = positionals[len(arg_counts):] 2140 return start_index 2141 2142 # consume Positionals and Optionals alternately, until we have 2143 # passed the last option string 2144 extras = [] 2145 extras_pattern = [] 2146 start_index = 0 2147 if option_string_indices: 2148 max_option_string_index = max(option_string_indices) 2149 else: 2150 max_option_string_index = -1 2151 while start_index <= max_option_string_index: 2152 2153 # consume any Positionals preceding the next option 2154 next_option_string_index = start_index 2155 while next_option_string_index <= max_option_string_index: 2156 if next_option_string_index in option_string_indices: 2157 break 2158 next_option_string_index += 1 2159 if not intermixed and start_index != next_option_string_index: 2160 positionals_end_index = consume_positionals(start_index) 2161 2162 # only try to parse the next optional if we didn't consume 2163 # the option string during the positionals parsing 2164 if positionals_end_index > start_index: 2165 start_index = positionals_end_index 2166 continue 2167 else: 2168 start_index = positionals_end_index 2169 2170 # if we consumed all the positionals we could and we're not 2171 # at the index of an option string, there were extra arguments 2172 if start_index not in option_string_indices: 2173 strings = arg_strings[start_index:next_option_string_index] 2174 extras.extend(strings) 2175 extras_pattern.extend(arg_strings_pattern[start_index:next_option_string_index]) 2176 start_index = next_option_string_index 2177 2178 # consume the next optional and any arguments for it 2179 start_index = consume_optional(start_index) 2180 2181 if not intermixed: 2182 # consume any positionals following the last Optional 2183 stop_index = consume_positionals(start_index) 2184 2185 # if we didn't consume all the argument strings, there were extras 2186 extras.extend(arg_strings[stop_index:]) 2187 else: 2188 extras.extend(arg_strings[start_index:]) 2189 extras_pattern.extend(arg_strings_pattern[start_index:]) 2190 extras_pattern = ''.join(extras_pattern) 2191 assert len(extras_pattern) == len(extras) 2192 # consume all positionals 2193 arg_strings = [s for s, c in zip(extras, extras_pattern) if c != 'O'] 2194 arg_strings_pattern = extras_pattern.replace('O', '') 2195 stop_index = consume_positionals(0) 2196 # leave unknown optionals and non-consumed positionals in extras 2197 for i, c in enumerate(extras_pattern): 2198 if not stop_index: 2199 break 2200 if c != 'O': 2201 stop_index -= 1 2202 extras[i] = None 2203 extras = [s for s in extras if s is not None] 2204 2205 # make sure all required actions were present and also convert 2206 # action defaults which were not given as arguments 2207 required_actions = [] 2208 for action in self._actions: 2209 if action not in seen_actions: 2210 if action.required: 2211 required_actions.append(_get_action_name(action)) 2212 else: 2213 # Convert action default now instead of doing it before 2214 # parsing arguments to avoid calling convert functions 2215 # twice (which may fail) if the argument was given, but 2216 # only if it was defined already in the namespace 2217 if (action.default is not None and 2218 isinstance(action.default, str) and 2219 hasattr(namespace, action.dest) and 2220 action.default is getattr(namespace, action.dest)): 2221 setattr(namespace, action.dest, 2222 self._get_value(action, action.default)) 2223 2224 if required_actions: 2225 raise ArgumentError(None, _('the following arguments are required: %s') % 2226 ', '.join(required_actions)) 2227 2228 # make sure all required groups had one option present 2229 for group in self._mutually_exclusive_groups: 2230 if group.required: 2231 for action in group._group_actions: 2232 if action in seen_non_default_actions: 2233 break 2234 2235 # if no actions were used, report the error 2236 else: 2237 names = [_get_action_name(action) 2238 for action in group._group_actions 2239 if action.help is not SUPPRESS] 2240 msg = _('one of the arguments %s is required') 2241 raise ArgumentError(None, msg % ' '.join(names)) 2242 2243 # return the updated namespace and the extra arguments 2244 return namespace, extras 2245 2246 def _read_args_from_files(self, arg_strings): 2247 # expand arguments referencing files 2248 new_arg_strings = [] 2249 for arg_string in arg_strings: 2250 2251 # for regular arguments, just add them back into the list 2252 if not arg_string or arg_string[0] not in self.fromfile_prefix_chars: 2253 new_arg_strings.append(arg_string) 2254 2255 # replace arguments referencing files with the file content 2256 else: 2257 try: 2258 with open(arg_string[1:], 2259 encoding=_sys.getfilesystemencoding(), 2260 errors=_sys.getfilesystemencodeerrors()) as args_file: 2261 arg_strings = [] 2262 for arg_line in args_file.read().splitlines(): 2263 for arg in self.convert_arg_line_to_args(arg_line): 2264 arg_strings.append(arg) 2265 arg_strings = self._read_args_from_files(arg_strings) 2266 new_arg_strings.extend(arg_strings) 2267 except OSError as err: 2268 raise ArgumentError(None, str(err)) 2269 2270 # return the modified argument list 2271 return new_arg_strings 2272 2273 def convert_arg_line_to_args(self, arg_line): 2274 return [arg_line] 2275 2276 def _match_argument(self, action, arg_strings_pattern): 2277 # match the pattern for this action to the arg strings 2278 nargs_pattern = self._get_nargs_pattern(action) 2279 match = _re.match(nargs_pattern, arg_strings_pattern) 2280 2281 # raise an exception if we weren't able to find a match 2282 if match is None: 2283 nargs_errors = { 2284 None: _('expected one argument'), 2285 OPTIONAL: _('expected at most one argument'), 2286 ONE_OR_MORE: _('expected at least one argument'), 2287 } 2288 msg = nargs_errors.get(action.nargs) 2289 if msg is None: 2290 msg = ngettext('expected %s argument', 2291 'expected %s arguments', 2292 action.nargs) % action.nargs 2293 raise ArgumentError(action, msg) 2294 2295 # return the number of arguments matched 2296 return len(match.group(1)) 2297 2298 def _match_arguments_partial(self, actions, arg_strings_pattern): 2299 # progressively shorten the actions list by slicing off the 2300 # final actions until we find a match 2301 for i in range(len(actions), 0, -1): 2302 actions_slice = actions[:i] 2303 pattern = ''.join([self._get_nargs_pattern(action) 2304 for action in actions_slice]) 2305 match = _re.match(pattern, arg_strings_pattern) 2306 if match is not None: 2307 result = [len(string) for string in match.groups()] 2308 if (match.end() < len(arg_strings_pattern) 2309 and arg_strings_pattern[match.end()] == 'O'): 2310 while result and not result[-1]: 2311 del result[-1] 2312 return result 2313 return [] 2314 2315 def _parse_optional(self, arg_string): 2316 # if it's an empty string, it was meant to be a positional 2317 if not arg_string: 2318 return None 2319 2320 # if it doesn't start with a prefix, it was meant to be positional 2321 if not arg_string[0] in self.prefix_chars: 2322 return None 2323 2324 # if the option string is present in the parser, return the action 2325 if arg_string in self._option_string_actions: 2326 action = self._option_string_actions[arg_string] 2327 return [(action, arg_string, None, None)] 2328 2329 # if it's just a single character, it was meant to be positional 2330 if len(arg_string) == 1: 2331 return None 2332 2333 # if the option string before the "=" is present, return the action 2334 option_string, sep, explicit_arg = arg_string.partition('=') 2335 if sep and option_string in self._option_string_actions: 2336 action = self._option_string_actions[option_string] 2337 return [(action, option_string, sep, explicit_arg)] 2338 2339 # search through all possible prefixes of the option string 2340 # and all actions in the parser for possible interpretations 2341 option_tuples = self._get_option_tuples(arg_string) 2342 2343 if option_tuples: 2344 return option_tuples 2345 2346 # if it was not found as an option, but it looks like a negative 2347 # number, it was meant to be positional 2348 # unless there are negative-number-like options 2349 if self._negative_number_matcher.match(arg_string): 2350 if not self._has_negative_number_optionals: 2351 return None 2352 2353 # if it contains a space, it was meant to be a positional 2354 if ' ' in arg_string: 2355 return None 2356 2357 # it was meant to be an optional but there is no such option 2358 # in this parser (though it might be a valid option in a subparser) 2359 return [(None, arg_string, None, None)] 2360 2361 def _get_option_tuples(self, option_string): 2362 result = [] 2363 2364 # option strings starting with two prefix characters are only 2365 # split at the '=' 2366 chars = self.prefix_chars 2367 if option_string[0] in chars and option_string[1] in chars: 2368 if self.allow_abbrev: 2369 option_prefix, sep, explicit_arg = option_string.partition('=') 2370 if not sep: 2371 sep = explicit_arg = None 2372 for option_string in self._option_string_actions: 2373 if option_string.startswith(option_prefix): 2374 action = self._option_string_actions[option_string] 2375 tup = action, option_string, sep, explicit_arg 2376 result.append(tup) 2377 2378 # single character options can be concatenated with their arguments 2379 # but multiple character options always have to have their argument 2380 # separate 2381 elif option_string[0] in chars and option_string[1] not in chars: 2382 option_prefix, sep, explicit_arg = option_string.partition('=') 2383 if not sep: 2384 sep = explicit_arg = None 2385 short_option_prefix = option_string[:2] 2386 short_explicit_arg = option_string[2:] 2387 2388 for option_string in self._option_string_actions: 2389 if option_string == short_option_prefix: 2390 action = self._option_string_actions[option_string] 2391 tup = action, option_string, '', short_explicit_arg 2392 result.append(tup) 2393 elif self.allow_abbrev and option_string.startswith(option_prefix): 2394 action = self._option_string_actions[option_string] 2395 tup = action, option_string, sep, explicit_arg 2396 result.append(tup) 2397 2398 # shouldn't ever get here 2399 else: 2400 raise ArgumentError(None, _('unexpected option string: %s') % option_string) 2401 2402 # return the collected option tuples 2403 return result 2404 2405 def _get_nargs_pattern(self, action): 2406 # in all examples below, we have to allow for '--' args 2407 # which are represented as '-' in the pattern 2408 nargs = action.nargs 2409 # if this is an optional action, -- is not allowed 2410 option = action.option_strings 2411 2412 # the default (None) is assumed to be a single argument 2413 if nargs is None: 2414 nargs_pattern = '([A])' if option else '(-*A-*)' 2415 2416 # allow zero or one arguments 2417 elif nargs == OPTIONAL: 2418 nargs_pattern = '(A?)' if option else '(-*A?-*)' 2419 2420 # allow zero or more arguments 2421 elif nargs == ZERO_OR_MORE: 2422 nargs_pattern = '(A*)' if option else '(-*[A-]*)' 2423 2424 # allow one or more arguments 2425 elif nargs == ONE_OR_MORE: 2426 nargs_pattern = '(A+)' if option else '(-*A[A-]*)' 2427 2428 # allow any number of options or arguments 2429 elif nargs == REMAINDER: 2430 nargs_pattern = '([AO]*)' if option else '(.*)' 2431 2432 # allow one argument followed by any number of options or arguments 2433 elif nargs == PARSER: 2434 nargs_pattern = '(A[AO]*)' if option else '(-*A[-AO]*)' 2435 2436 # suppress action, like nargs=0 2437 elif nargs == SUPPRESS: 2438 nargs_pattern = '()' if option else '(-*)' 2439 2440 # all others should be integers 2441 else: 2442 nargs_pattern = '([AO]{%d})' % nargs if option else '((?:-*A){%d}-*)' % nargs 2443 2444 # return the pattern 2445 return nargs_pattern 2446 2447 # ======================== 2448 # Alt command line argument parsing, allowing free intermix 2449 # ======================== 2450 2451 def parse_intermixed_args(self, args=None, namespace=None): 2452 args, argv = self.parse_known_intermixed_args(args, namespace) 2453 if argv: 2454 msg = _('unrecognized arguments: %s') % ' '.join(argv) 2455 if self.exit_on_error: 2456 self.error(msg) 2457 else: 2458 raise ArgumentError(None, msg) 2459 return args 2460 2461 def parse_known_intermixed_args(self, args=None, namespace=None): 2462 # returns a namespace and list of extras 2463 # 2464 # positional can be freely intermixed with optionals. optionals are 2465 # first parsed with all positional arguments deactivated. The 'extras' 2466 # are then parsed. If the parser definition is incompatible with the 2467 # intermixed assumptions (e.g. use of REMAINDER, subparsers) a 2468 # TypeError is raised. 2469 2470 positionals = self._get_positional_actions() 2471 a = [action for action in positionals 2472 if action.nargs in [PARSER, REMAINDER]] 2473 if a: 2474 raise TypeError('parse_intermixed_args: positional arg' 2475 ' with nargs=%s'%a[0].nargs) 2476 2477 return self._parse_known_args2(args, namespace, intermixed=True) 2478 2479 # ======================== 2480 # Value conversion methods 2481 # ======================== 2482 def _get_values(self, action, arg_strings): 2483 # optional argument produces a default when not present 2484 if not arg_strings and action.nargs == OPTIONAL: 2485 if action.option_strings: 2486 value = action.const 2487 else: 2488 value = action.default 2489 if isinstance(value, str) and value is not SUPPRESS: 2490 value = self._get_value(action, value) 2491 self._check_value(action, value) 2492 2493 # when nargs='*' on a positional, if there were no command-line 2494 # args, use the default if it is anything other than None 2495 elif (not arg_strings and action.nargs == ZERO_OR_MORE and 2496 not action.option_strings): 2497 if action.default is not None: 2498 value = action.default 2499 self._check_value(action, value) 2500 else: 2501 # since arg_strings is always [] at this point 2502 # there is no need to use self._check_value(action, value) 2503 value = arg_strings 2504 2505 # single argument or optional argument produces a single value 2506 elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]: 2507 arg_string, = arg_strings 2508 value = self._get_value(action, arg_string) 2509 self._check_value(action, value) 2510 2511 # REMAINDER arguments convert all values, checking none 2512 elif action.nargs == REMAINDER: 2513 value = [self._get_value(action, v) for v in arg_strings] 2514 2515 # PARSER arguments convert all values, but check only the first 2516 elif action.nargs == PARSER: 2517 value = [self._get_value(action, v) for v in arg_strings] 2518 self._check_value(action, value[0]) 2519 2520 # SUPPRESS argument does not put anything in the namespace 2521 elif action.nargs == SUPPRESS: 2522 value = SUPPRESS 2523 2524 # all other types of nargs produce a list 2525 else: 2526 value = [self._get_value(action, v) for v in arg_strings] 2527 for v in value: 2528 self._check_value(action, v) 2529 2530 # return the converted value 2531 return value 2532 2533 def _get_value(self, action, arg_string): 2534 type_func = self._registry_get('type', action.type, action.type) 2535 if not callable(type_func): 2536 msg = _('%r is not callable') 2537 raise ArgumentError(action, msg % type_func) 2538 2539 # convert the value to the appropriate type 2540 try: 2541 result = type_func(arg_string) 2542 2543 # ArgumentTypeErrors indicate errors 2544 except ArgumentTypeError as err: 2545 msg = str(err) 2546 raise ArgumentError(action, msg) 2547 2548 # TypeErrors or ValueErrors also indicate errors 2549 except (TypeError, ValueError): 2550 name = getattr(action.type, '__name__', repr(action.type)) 2551 args = {'type': name, 'value': arg_string} 2552 msg = _('invalid %(type)s value: %(value)r') 2553 raise ArgumentError(action, msg % args) 2554 2555 # return the converted value 2556 return result 2557 2558 def _check_value(self, action, value): 2559 # converted value must be one of the choices (if specified) 2560 choices = action.choices 2561 if choices is not None: 2562 if isinstance(choices, str): 2563 choices = iter(choices) 2564 if value not in choices: 2565 args = {'value': str(value), 2566 'choices': ', '.join(map(str, action.choices))} 2567 msg = _('invalid choice: %(value)r (choose from %(choices)s)') 2568 raise ArgumentError(action, msg % args) 2569 2570 # ======================= 2571 # Help-formatting methods 2572 # ======================= 2573 def format_usage(self): 2574 formatter = self._get_formatter() 2575 formatter.add_usage(self.usage, self._actions, 2576 self._mutually_exclusive_groups) 2577 return formatter.format_help() 2578 2579 def format_help(self): 2580 formatter = self._get_formatter() 2581 2582 # usage 2583 formatter.add_usage(self.usage, self._actions, 2584 self._mutually_exclusive_groups) 2585 2586 # description 2587 formatter.add_text(self.description) 2588 2589 # positionals, optionals and user-defined groups 2590 for action_group in self._action_groups: 2591 formatter.start_section(action_group.title) 2592 formatter.add_text(action_group.description) 2593 formatter.add_arguments(action_group._group_actions) 2594 formatter.end_section() 2595 2596 # epilog 2597 formatter.add_text(self.epilog) 2598 2599 # determine help from format above 2600 return formatter.format_help() 2601 2602 def _get_formatter(self): 2603 return self.formatter_class(prog=self.prog) 2604 2605 # ===================== 2606 # Help-printing methods 2607 # ===================== 2608 def print_usage(self, file=None): 2609 if file is None: 2610 file = _sys.stdout 2611 self._print_message(self.format_usage(), file) 2612 2613 def print_help(self, file=None): 2614 if file is None: 2615 file = _sys.stdout 2616 self._print_message(self.format_help(), file) 2617 2618 def _print_message(self, message, file=None): 2619 if message: 2620 file = file or _sys.stderr 2621 try: 2622 file.write(message) 2623 except (AttributeError, OSError): 2624 pass 2625 2626 # =============== 2627 # Exiting methods 2628 # =============== 2629 def exit(self, status=0, message=None): 2630 if message: 2631 self._print_message(message, _sys.stderr) 2632 _sys.exit(status) 2633 2634 def error(self, message): 2635 """error(message: string) 2636 2637 Prints a usage message incorporating the message to stderr and 2638 exits. 2639 2640 If you override this in a subclass, it should not return -- it 2641 should either exit or raise an exception. 2642 """ 2643 self.print_usage(_sys.stderr) 2644 args = {'prog': self.prog, 'message': message} 2645 self.exit(2, _('%(prog)s: error: %(message)s\n') % args) 2646 2647 def _warning(self, message): 2648 args = {'prog': self.prog, 'message': message} 2649 self._print_message(_('%(prog)s: warning: %(message)s\n') % args, _sys.stderr) 2650