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