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