Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(29271)

Delta Between Two Patch Sets: Lib/argparse.py

Issue 9253: argparse: optional subparsers
Left Patch Set: Created 7 years, 8 months ago
Right Patch Set: Created 6 years, 5 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Doc/library/argparse.rst ('k') | Lib/test/test_argparse.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 # Author: Steven J. Bethard <steven.bethard@gmail.com>. 1 # Author: Steven J. Bethard <steven.bethard@gmail.com>.
2 2
3 """Command-line parsing library 3 """Command-line parsing library
4 4
5 This module is an optparse-inspired command-line parsing library that: 5 This module is an optparse-inspired command-line parsing library that:
6 6
7 - handles both optional and positional arguments 7 - handles both optional and positional arguments
8 - produces highly informative usage messages 8 - produces highly informative usage messages
9 - supports parsers that dispatch to sub-parsers 9 - supports parsers that dispatch to sub-parsers
10 10
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 92
93 from gettext import gettext as _, ngettext 93 from gettext import gettext as _, ngettext
94 94
95 95
96 SUPPRESS = '==SUPPRESS==' 96 SUPPRESS = '==SUPPRESS=='
97 97
98 OPTIONAL = '?' 98 OPTIONAL = '?'
99 ZERO_OR_MORE = '*' 99 ZERO_OR_MORE = '*'
100 ONE_OR_MORE = '+' 100 ONE_OR_MORE = '+'
101 PARSER = 'A...' 101 PARSER = 'A...'
102 _OPTIONAL_PARSER = 'A...?'
103 REMAINDER = '...' 102 REMAINDER = '...'
104 _UNRECOGNIZED_ARGS_ATTR = '_unrecognized_args' 103 _UNRECOGNIZED_ARGS_ATTR = '_unrecognized_args'
105 104
106 # ============================= 105 # =============================
107 # Utility functions and classes 106 # Utility functions and classes
108 # ============================= 107 # =============================
109 108
110 class _AttributeHolder(object): 109 class _AttributeHolder(object):
111 """Abstract base class that provides __repr__. 110 """Abstract base class that provides __repr__.
112 111
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 if action.nargs is None: 572 if action.nargs is None:
574 result = '%s' % get_metavar(1) 573 result = '%s' % get_metavar(1)
575 elif action.nargs == OPTIONAL: 574 elif action.nargs == OPTIONAL:
576 result = '[%s]' % get_metavar(1) 575 result = '[%s]' % get_metavar(1)
577 elif action.nargs == ZERO_OR_MORE: 576 elif action.nargs == ZERO_OR_MORE:
578 result = '[%s [%s ...]]' % get_metavar(2) 577 result = '[%s [%s ...]]' % get_metavar(2)
579 elif action.nargs == ONE_OR_MORE: 578 elif action.nargs == ONE_OR_MORE:
580 result = '%s [%s ...]' % get_metavar(2) 579 result = '%s [%s ...]' % get_metavar(2)
581 elif action.nargs == REMAINDER: 580 elif action.nargs == REMAINDER:
582 result = '...' 581 result = '...'
583 elif action.nargs in [ PARSER, _OPTIONAL_PARSER ]: 582 elif action.nargs == PARSER:
584 result = '%s ...' % get_metavar(1) 583 result = '%s ...' % get_metavar(1)
585 else: 584 else:
586 formats = ['%s' for _ in range(action.nargs)] 585 formats = ['%s' for _ in range(action.nargs)]
587 result = ' '.join(formats) % get_metavar(action.nargs) 586 result = ' '.join(formats) % get_metavar(action.nargs)
588 return result 587 return result
589 588
590 def _expand_help(self, action): 589 def _expand_help(self, action):
591 params = dict(vars(action), prog=self._prog) 590 params = dict(vars(action), prog=self._prog)
592 for name in list(params): 591 for name in list(params):
593 if params[name] is SUPPRESS: 592 if params[name] is SUPPRESS:
594 del params[name] 593 del params[name]
595 for name in list(params): 594 for name in list(params):
596 if hasattr(params[name], '__name__'): 595 if hasattr(params[name], '__name__'):
597 params[name] = params[name].__name__ 596 params[name] = params[name].__name__
598 if params.get('choices') is not None: 597 if params.get('choices') is not None:
599 choices_str = ', '.join([str(c) for c in params['choices']]) 598 choices_str = ', '.join([str(c) for c in params['choices']])
600 params['choices'] = choices_str 599 params['choices'] = choices_str
601 return self._get_help_string(action) % params 600 return self._get_help_string(action) % params
602 601
603 def _iter_indented_subactions(self, action): 602 def _iter_indented_subactions(self, action):
604 try: 603 try:
605 get_subactions = action._get_subactions 604 get_subactions = action._get_subactions
606 except AttributeError: 605 except AttributeError:
607 pass 606 pass
608 else: 607 else:
609 self._indent() 608 self._indent()
610 for subaction in get_subactions(): 609 yield from get_subactions()
611 yield subaction
612 self._dedent() 610 self._dedent()
613 611
614 def _split_lines(self, text, width): 612 def _split_lines(self, text, width):
615 text = self._whitespace_matcher.sub(' ', text).strip() 613 text = self._whitespace_matcher.sub(' ', text).strip()
616 return _textwrap.wrap(text, width) 614 return _textwrap.wrap(text, width)
617 615
618 def _fill_text(self, text, width, indent): 616 def _fill_text(self, text, width, indent):
619 text = self._whitespace_matcher.sub(' ', text).strip() 617 text = self._whitespace_matcher.sub(' ', text).strip()
620 return _textwrap.fill(text, width, initial_indent=indent, 618 return _textwrap.fill(text, width, initial_indent=indent,
621 subsequent_indent=indent) 619 subsequent_indent=indent)
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
691 689
692 def _get_action_name(argument): 690 def _get_action_name(argument):
693 if argument is None: 691 if argument is None:
694 return None 692 return None
695 elif argument.option_strings: 693 elif argument.option_strings:
696 return '/'.join(argument.option_strings) 694 return '/'.join(argument.option_strings)
697 elif argument.metavar not in (None, SUPPRESS): 695 elif argument.metavar not in (None, SUPPRESS):
698 return argument.metavar 696 return argument.metavar
699 elif argument.dest not in (None, SUPPRESS): 697 elif argument.dest not in (None, SUPPRESS):
700 return argument.dest 698 return argument.dest
699 elif hasattr(argument, 'name'):
700 return argument.name()
701 else: 701 else:
702 return None 702 return None
703 703
704 704
705 class ArgumentError(Exception): 705 class ArgumentError(Exception):
706 """An error from creating or using an argument (optional or positional). 706 """An error from creating or using an argument (optional or positional).
707 707
708 The string value of this exception is the message, augmented with 708 The string value of this exception is the message, augmented with
709 information about the argument that caused it. 709 information about the argument that caused it.
710 """ 710 """
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 - '+' consumes one or more arguments (and produces a list) 755 - '+' consumes one or more arguments (and produces a list)
756 Note that the difference between the default and nargs=1 is that 756 Note that the difference between the default and nargs=1 is that
757 with the default, a single value will be produced, while with 757 with the default, a single value will be produced, while with
758 nargs=1, a list containing a single value will be produced. 758 nargs=1, a list containing a single value will be produced.
759 759
760 - const -- The value to be produced if the option is specified and the 760 - const -- The value to be produced if the option is specified and the
761 option uses an action that takes no values. 761 option uses an action that takes no values.
762 762
763 - default -- The value to be produced if the option is not specified. 763 - default -- The value to be produced if the option is not specified.
764 764
765 - type -- The type which the command-line arguments should be converted 765 - type -- A callable that accepts a single string argument, and
766 to, should be one of 'string', 'int', 'float', 'complex' or a 766 returns the converted value. The standard Python types str, int,
767 callable object that accepts a single string argument. If None, 767 float, and complex are useful examples of such callables. If None,
768 'string' is assumed. 768 str is used.
769 769
770 - choices -- A container of values that should be allowed. If not None, 770 - choices -- A container of values that should be allowed. If not None,
771 after a command-line argument has been converted to the appropriate 771 after a command-line argument has been converted to the appropriate
772 type, an exception will be raised if it is not a member of this 772 type, an exception will be raised if it is not a member of this
773 collection. 773 collection.
774 774
775 - required -- True if the action must always be specified at the 775 - required -- True if the action must always be specified at the
776 command line. This is only meaningful for optional command-line 776 command line. This is only meaningful for optional command-line
777 arguments. 777 arguments.
778 778
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
1052 metavar += ' (%s)' % ', '.join(aliases) 1052 metavar += ' (%s)' % ', '.join(aliases)
1053 sup = super(_SubParsersAction._ChoicesPseudoAction, self) 1053 sup = super(_SubParsersAction._ChoicesPseudoAction, self)
1054 sup.__init__(option_strings=[], dest=dest, help=help, 1054 sup.__init__(option_strings=[], dest=dest, help=help,
1055 metavar=metavar) 1055 metavar=metavar)
1056 1056
1057 def __init__(self, 1057 def __init__(self,
1058 option_strings, 1058 option_strings,
1059 prog, 1059 prog,
1060 parser_class, 1060 parser_class,
1061 dest=SUPPRESS, 1061 dest=SUPPRESS,
1062 required=True,
1062 help=None, 1063 help=None,
1063 default=None,
1064 metavar=None): 1064 metavar=None):
1065 1065
1066 self._prog_prefix = prog 1066 self._prog_prefix = prog
1067 self._parser_class = parser_class 1067 self._parser_class = parser_class
1068 self._name_parser_map = _collections.OrderedDict() 1068 self._name_parser_map = _collections.OrderedDict()
1069 self._choices_actions = [] 1069 self._choices_actions = []
1070 1070
1071 nargs = PARSER
1072 if default is not None:
1073 nargs = _OPTIONAL_PARSER
1074
1075 super(_SubParsersAction, self).__init__( 1071 super(_SubParsersAction, self).__init__(
1076 option_strings=option_strings, 1072 option_strings=option_strings,
1077 dest=dest, 1073 dest=dest,
1078 nargs=nargs, 1074 nargs=PARSER,
1079 default=default,
1080 choices=self._name_parser_map, 1075 choices=self._name_parser_map,
1076 required=required,
1081 help=help, 1077 help=help,
1082 metavar=metavar) 1078 metavar=metavar)
1083 1079
1084 def add_parser(self, name, **kwargs): 1080 def add_parser(self, name, **kwargs):
1085 # set prog from the existing prefix 1081 # set prog from the existing prefix
1086 if kwargs.get('prog') is None: 1082 if kwargs.get('prog') is None:
1087 kwargs['prog'] = '%s %s' % (self._prog_prefix, name) 1083 kwargs['prog'] = '%s %s' % (self._prog_prefix, name)
1088 1084
1089 aliases = kwargs.pop('aliases', ()) 1085 aliases = kwargs.pop('aliases', ())
1090 1086
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1125 raise ArgumentError(self, msg) 1121 raise ArgumentError(self, msg)
1126 1122
1127 # parse all the remaining options into the namespace 1123 # parse all the remaining options into the namespace
1128 # store any unrecognized options on the object, so that the top 1124 # store any unrecognized options on the object, so that the top
1129 # level parser can decide what to do with them 1125 # level parser can decide what to do with them
1130 namespace, arg_strings = parser.parse_known_args(arg_strings, namespace) 1126 namespace, arg_strings = parser.parse_known_args(arg_strings, namespace)
1131 if arg_strings: 1127 if arg_strings:
1132 vars(namespace).setdefault(_UNRECOGNIZED_ARGS_ATTR, []) 1128 vars(namespace).setdefault(_UNRECOGNIZED_ARGS_ATTR, [])
1133 getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).extend(arg_strings) 1129 getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).extend(arg_strings)
1134 1130
1131 def name(self):
1132 # custom name for _get_action_name()
1133 return "{%s}"%','.join(self._name_parser_map)
1135 1134
1136 # ============== 1135 # ==============
1137 # Type classes 1136 # Type classes
1138 # ============== 1137 # ==============
1139 1138
1140 class FileType(object): 1139 class FileType(object):
1141 """Factory for creating file object types 1140 """Factory for creating file object types
1142 1141
1143 Instances of FileType are typically passed as type= arguments to the 1142 Instances of FileType are typically passed as type= arguments to the
1144 ArgumentParser add_argument() method. 1143 ArgumentParser add_argument() method.
1145 1144
1146 Keyword Arguments: 1145 Keyword Arguments:
1147 - mode -- A string indicating how the file is to be opened. Accepts the 1146 - mode -- A string indicating how the file is to be opened. Accepts the
1148 same values as the builtin open() function. 1147 same values as the builtin open() function.
1149 - bufsize -- The file's desired buffer size. Accepts the same values as 1148 - bufsize -- The file's desired buffer size. Accepts the same values as
1150 the builtin open() function. 1149 the builtin open() function.
1150 - encoding -- The file's encoding. Accepts the same values as the
1151 builtin open() function.
1152 - errors -- A string indicating how encoding and decoding errors are to
1153 be handled. Accepts the same value as the builtin open() function.
1151 """ 1154 """
1152 1155
1153 def __init__(self, mode='r', bufsize=-1): 1156 def __init__(self, mode='r', bufsize=-1, encoding=None, errors=None):
1154 self._mode = mode 1157 self._mode = mode
1155 self._bufsize = bufsize 1158 self._bufsize = bufsize
1159 self._encoding = encoding
1160 self._errors = errors
1156 1161
1157 def __call__(self, string): 1162 def __call__(self, string):
1158 # the special argument "-" means sys.std{in,out} 1163 # the special argument "-" means sys.std{in,out}
1159 if string == '-': 1164 if string == '-':
1160 if 'r' in self._mode: 1165 if 'r' in self._mode:
1161 return _sys.stdin 1166 return _sys.stdin
1162 elif 'w' in self._mode: 1167 elif 'w' in self._mode:
1163 return _sys.stdout 1168 return _sys.stdout
1164 else: 1169 else:
1165 msg = _('argument "-" with mode %r') % self._mode 1170 msg = _('argument "-" with mode %r') % self._mode
1166 raise ValueError(msg) 1171 raise ValueError(msg)
1167 1172
1168 # all other arguments are used as file names 1173 # all other arguments are used as file names
1169 try: 1174 try:
1170 return open(string, self._mode, self._bufsize) 1175 return open(string, self._mode, self._bufsize, self._encoding,
1171 except IOError as e: 1176 self._errors)
1177 except OSError as e:
1172 message = _("can't open '%s': %s") 1178 message = _("can't open '%s': %s")
1173 raise ArgumentTypeError(message % (string, e)) 1179 raise ArgumentTypeError(message % (string, e))
1174 1180
1175 def __repr__(self): 1181 def __repr__(self):
1176 args = self._mode, self._bufsize 1182 args = self._mode, self._bufsize
1177 args_str = ', '.join(repr(arg) for arg in args if arg != -1) 1183 kwargs = [('encoding', self._encoding), ('errors', self._errors)]
1184 args_str = ', '.join([repr(arg) for arg in args if arg != -1] +
1185 ['%s=%r' % (kw, arg) for kw, arg in kwargs
1186 if arg is not None])
1178 return '%s(%s)' % (type(self).__name__, args_str) 1187 return '%s(%s)' % (type(self).__name__, args_str)
1179 1188
1180 # =========================== 1189 # ===========================
1181 # Optional and Positional Parsing 1190 # Optional and Positional Parsing
1182 # =========================== 1191 # ===========================
1183 1192
1184 class Namespace(_AttributeHolder): 1193 class Namespace(_AttributeHolder):
1185 """Simple object for storing attributes. 1194 """Simple object for storing attributes.
1186 1195
1187 Implements equality by attribute names and values, and provides a simple 1196 Implements equality by attribute names and values, and provides a simple
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
1579 - argument_default -- The default value for all arguments 1588 - argument_default -- The default value for all arguments
1580 - conflict_handler -- String indicating how to handle conflicts 1589 - conflict_handler -- String indicating how to handle conflicts
1581 - add_help -- Add a -h/-help option 1590 - add_help -- Add a -h/-help option
1582 """ 1591 """
1583 1592
1584 def __init__(self, 1593 def __init__(self,
1585 prog=None, 1594 prog=None,
1586 usage=None, 1595 usage=None,
1587 description=None, 1596 description=None,
1588 epilog=None, 1597 epilog=None,
1589 version=None,
1590 parents=[], 1598 parents=[],
1591 formatter_class=HelpFormatter, 1599 formatter_class=HelpFormatter,
1592 prefix_chars='-', 1600 prefix_chars='-',
1593 fromfile_prefix_chars=None, 1601 fromfile_prefix_chars=None,
1594 argument_default=None, 1602 argument_default=None,
1595 conflict_handler='error', 1603 conflict_handler='error',
1596 add_help=True): 1604 add_help=True):
1597 1605
1598 if version is not None:
1599 import warnings
1600 warnings.warn(
1601 """The "version" argument to ArgumentParser is deprecated. """
1602 """Please use """
1603 """"add_argument(..., action='version', version="N", ...)" """
1604 """instead""", DeprecationWarning)
1605
1606 superinit = super(ArgumentParser, self).__init__ 1606 superinit = super(ArgumentParser, self).__init__
1607 superinit(description=description, 1607 superinit(description=description,
1608 prefix_chars=prefix_chars, 1608 prefix_chars=prefix_chars,
1609 argument_default=argument_default, 1609 argument_default=argument_default,
1610 conflict_handler=conflict_handler) 1610 conflict_handler=conflict_handler)
1611 1611
1612 # default setting for prog 1612 # default setting for prog
1613 if prog is None: 1613 if prog is None:
1614 prog = _os.path.basename(_sys.argv[0]) 1614 prog = _os.path.basename(_sys.argv[0])
1615 1615
1616 self.prog = prog 1616 self.prog = prog
1617 self.usage = usage 1617 self.usage = usage
1618 self.epilog = epilog 1618 self.epilog = epilog
1619 self.version = version
1620 self.formatter_class = formatter_class 1619 self.formatter_class = formatter_class
1621 self.fromfile_prefix_chars = fromfile_prefix_chars 1620 self.fromfile_prefix_chars = fromfile_prefix_chars
1622 self.add_help = add_help 1621 self.add_help = add_help
1623 1622
1624 add_group = self.add_argument_group 1623 add_group = self.add_argument_group
1625 self._positionals = add_group(_('positional arguments')) 1624 self._positionals = add_group(_('positional arguments'))
1626 self._optionals = add_group(_('optional arguments')) 1625 self._optionals = add_group(_('optional arguments'))
1627 self._subparsers = None 1626 self._subparsers = None
1628 1627
1629 # register types 1628 # register types
1630 def identity(string): 1629 def identity(string):
1631 return string 1630 return string
1632 self.register('type', None, identity) 1631 self.register('type', None, identity)
1633 1632
1634 # add help and version arguments if necessary 1633 # add help argument if necessary
1635 # (using explicit default to override global argument_default) 1634 # (using explicit default to override global argument_default)
1636 default_prefix = '-' if '-' in prefix_chars else prefix_chars[0] 1635 default_prefix = '-' if '-' in prefix_chars else prefix_chars[0]
1637 if self.add_help: 1636 if self.add_help:
1638 self.add_argument( 1637 self.add_argument(
1639 default_prefix+'h', default_prefix*2+'help', 1638 default_prefix+'h', default_prefix*2+'help',
1640 action='help', default=SUPPRESS, 1639 action='help', default=SUPPRESS,
1641 help=_('show this help message and exit')) 1640 help=_('show this help message and exit'))
1642 if self.version:
1643 self.add_argument(
1644 default_prefix+'v', default_prefix*2+'version',
1645 action='version', default=SUPPRESS,
1646 version=self.version,
1647 help=_("show program's version number and exit"))
1648 1641
1649 # add parent arguments and defaults 1642 # add parent arguments and defaults
1650 for parent in parents: 1643 for parent in parents:
1651 self._add_container_actions(parent) 1644 self._add_container_actions(parent)
1652 try: 1645 try:
1653 defaults = parent._defaults 1646 defaults = parent._defaults
1654 except AttributeError: 1647 except AttributeError:
1655 pass 1648 pass
1656 else: 1649 else:
1657 self._defaults.update(defaults) 1650 self._defaults.update(defaults)
1658 1651
1659 # ======================= 1652 # =======================
1660 # Pretty __repr__ methods 1653 # Pretty __repr__ methods
1661 # ======================= 1654 # =======================
1662 def _get_kwargs(self): 1655 def _get_kwargs(self):
1663 names = [ 1656 names = [
1664 'prog', 1657 'prog',
1665 'usage', 1658 'usage',
1666 'description', 1659 'description',
1667 'version',
1668 'formatter_class', 1660 'formatter_class',
1669 'conflict_handler', 1661 'conflict_handler',
1670 'add_help', 1662 'add_help',
1671 ] 1663 ]
1672 return [(name, getattr(self, name)) for name in names] 1664 return [(name, getattr(self, name)) for name in names]
1673 1665
1674 # ================================== 1666 # ==================================
1675 # Optional/Positional adding methods 1667 # Optional/Positional adding methods
1676 # ================================== 1668 # ==================================
1677 def add_subparsers(self, **kwargs): 1669 def add_subparsers(self, **kwargs):
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1726 # Command line argument parsing methods 1718 # Command line argument parsing methods
1727 # ===================================== 1719 # =====================================
1728 def parse_args(self, args=None, namespace=None): 1720 def parse_args(self, args=None, namespace=None):
1729 args, argv = self.parse_known_args(args, namespace) 1721 args, argv = self.parse_known_args(args, namespace)
1730 if argv: 1722 if argv:
1731 msg = _('unrecognized arguments: %s') 1723 msg = _('unrecognized arguments: %s')
1732 self.error(msg % ' '.join(argv)) 1724 self.error(msg % ' '.join(argv))
1733 return args 1725 return args
1734 1726
1735 def parse_known_args(self, args=None, namespace=None): 1727 def parse_known_args(self, args=None, namespace=None):
1736 # args default to the system args
1737 if args is None: 1728 if args is None:
1729 # args default to the system args
1738 args = _sys.argv[1:] 1730 args = _sys.argv[1:]
1731 else:
1732 # make sure that args are mutable
1733 args = list(args)
1739 1734
1740 # default Namespace built from parser defaults 1735 # default Namespace built from parser defaults
1741 if namespace is None: 1736 if namespace is None:
1742 namespace = Namespace() 1737 namespace = Namespace()
1743 1738
1744 # add any action defaults that aren't present 1739 # add any action defaults that aren't present
1745 for action in self._actions: 1740 for action in self._actions:
1746 if action.dest is not SUPPRESS: 1741 if action.dest is not SUPPRESS:
1747 if not hasattr(namespace, action.dest): 1742 if not hasattr(namespace, action.dest):
1748 if action.default is not SUPPRESS: 1743 if action.default is not SUPPRESS:
1749 default = action.default 1744 setattr(namespace, action.dest, action.default)
1750 if isinstance(action.default, str):
1751 default = self._get_value(action, default)
1752 setattr(namespace, action.dest, default)
1753 1745
1754 # add any parser defaults that aren't present 1746 # add any parser defaults that aren't present
1755 for dest in self._defaults: 1747 for dest in self._defaults:
1756 if not hasattr(namespace, dest): 1748 if not hasattr(namespace, dest):
1757 setattr(namespace, dest, self._defaults[dest]) 1749 setattr(namespace, dest, self._defaults[dest])
1758 1750
1759 # parse the arguments and exit if there are any errors 1751 # parse the arguments and exit if there are any errors
1760 try: 1752 try:
1761 namespace, args = self._parse_known_args(args, namespace) 1753 namespace, args = self._parse_known_args(args, namespace)
1762 if hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR): 1754 if hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR):
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
1965 1957
1966 # consume the next optional and any arguments for it 1958 # consume the next optional and any arguments for it
1967 start_index = consume_optional(start_index) 1959 start_index = consume_optional(start_index)
1968 1960
1969 # consume any positionals following the last Optional 1961 # consume any positionals following the last Optional
1970 stop_index = consume_positionals(start_index) 1962 stop_index = consume_positionals(start_index)
1971 1963
1972 # if we didn't consume all the argument strings, there were extras 1964 # if we didn't consume all the argument strings, there were extras
1973 extras.extend(arg_strings[stop_index:]) 1965 extras.extend(arg_strings[stop_index:])
1974 1966
1975 # make sure all required actions were present 1967 # make sure all required actions were present and also convert
1976 required_actions = [_get_action_name(action) for action in self._actions 1968 # action defaults which were not given as arguments
1977 if action.required and action not in seen_actions] 1969 required_actions = []
1970 for action in self._actions:
1971 if action not in seen_actions:
1972 if action.required:
1973 required_actions.append(_get_action_name(action))
1974 else:
1975 # Convert action default now instead of doing it before
1976 # parsing arguments to avoid calling convert functions
1977 # twice (which may fail) if the argument was given, but
1978 # only if it was defined already in the namespace
1979 if (action.default is not None and
1980 isinstance(action.default, str) and
1981 hasattr(namespace, action.dest) and
1982 action.default is getattr(namespace, action.dest)):
1983 setattr(namespace, action.dest,
1984 self._get_value(action, action.default))
1985
1978 if required_actions: 1986 if required_actions:
1987 required_actions = ['%s'%name for name in required_actions]
1979 self.error(_('the following arguments are required: %s') % 1988 self.error(_('the following arguments are required: %s') %
1980 ', '.join(required_actions)) 1989 ', '.join(required_actions))
1981 1990
1982 # make sure all required groups had one option present 1991 # make sure all required groups had one option present
1983 for group in self._mutually_exclusive_groups: 1992 for group in self._mutually_exclusive_groups:
1984 if group.required: 1993 if group.required:
1985 for action in group._group_actions: 1994 for action in group._group_actions:
1986 if action in seen_non_default_actions: 1995 if action in seen_non_default_actions:
1987 break 1996 break
1988 1997
1989 # if no actions were used, report the error 1998 # if no actions were used, report the error
1990 else: 1999 else:
1991 names = [_get_action_name(action) 2000 names = [_get_action_name(action)
1992 for action in group._group_actions 2001 for action in group._group_actions
1993 if action.help is not SUPPRESS] 2002 if action.help is not SUPPRESS]
2003 names = ['%s'%name for name in names]
1994 msg = _('one of the arguments %s is required') 2004 msg = _('one of the arguments %s is required')
1995 self.error(msg % ' '.join(names)) 2005 self.error(msg % ' '.join(names))
1996 2006
1997 # return the updated namespace and the extra arguments 2007 # return the updated namespace and the extra arguments
1998 return namespace, extras 2008 return namespace, extras
1999 2009
2000 def _read_args_from_files(self, arg_strings): 2010 def _read_args_from_files(self, arg_strings):
2001 # expand arguments referencing files 2011 # expand arguments referencing files
2002 new_arg_strings = [] 2012 new_arg_strings = []
2003 for arg_string in arg_strings: 2013 for arg_string in arg_strings:
2004 2014
2005 # for regular arguments, just add them back into the list 2015 # for regular arguments, just add them back into the list
2006 if arg_string[0] not in self.fromfile_prefix_chars: 2016 if not arg_string or arg_string[0] not in self.fromfile_prefix_chars :
2007 new_arg_strings.append(arg_string) 2017 new_arg_strings.append(arg_string)
2008 2018
2009 # replace arguments referencing files with the file content 2019 # replace arguments referencing files with the file content
2010 else: 2020 else:
2011 try: 2021 try:
2012 args_file = open(arg_string[1:]) 2022 with open(arg_string[1:]) as args_file:
2013 try:
2014 arg_strings = [] 2023 arg_strings = []
2015 for arg_line in args_file.read().splitlines(): 2024 for arg_line in args_file.read().splitlines():
2016 for arg in self.convert_arg_line_to_args(arg_line): 2025 for arg in self.convert_arg_line_to_args(arg_line):
2017 arg_strings.append(arg) 2026 arg_strings.append(arg)
2018 arg_strings = self._read_args_from_files(arg_strings) 2027 arg_strings = self._read_args_from_files(arg_strings)
2019 new_arg_strings.extend(arg_strings) 2028 new_arg_strings.extend(arg_strings)
2020 finally: 2029 except OSError:
2021 args_file.close()
2022 except IOError:
2023 err = _sys.exc_info()[1] 2030 err = _sys.exc_info()[1]
2024 self.error(str(err)) 2031 self.error(str(err))
2025 2032
2026 # return the modified argument list 2033 # return the modified argument list
2027 return new_arg_strings 2034 return new_arg_strings
2028 2035
2029 def convert_arg_line_to_args(self, arg_line): 2036 def convert_arg_line_to_args(self, arg_line):
2030 return [arg_line] 2037 return [arg_line]
2031 2038
2032 def _match_argument(self, action, arg_strings_pattern): 2039 def _match_argument(self, action, arg_strings_pattern):
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
2190 nargs_pattern = '(-*A[A-]*)' 2197 nargs_pattern = '(-*A[A-]*)'
2191 2198
2192 # allow any number of options or arguments 2199 # allow any number of options or arguments
2193 elif nargs == REMAINDER: 2200 elif nargs == REMAINDER:
2194 nargs_pattern = '([-AO]*)' 2201 nargs_pattern = '([-AO]*)'
2195 2202
2196 # allow one argument followed by any number of options or arguments 2203 # allow one argument followed by any number of options or arguments
2197 elif nargs == PARSER: 2204 elif nargs == PARSER:
2198 nargs_pattern = '(-*A[-AO]*)' 2205 nargs_pattern = '(-*A[-AO]*)'
2199 2206
2200 # allow one optional argument followed by any number of options or
2201 # arguments
2202 elif nargs == _OPTIONAL_PARSER:
2203 nargs_pattern = '(-*A?[-AO]*)?'
2204
2205 # all others should be integers 2207 # all others should be integers
2206 else: 2208 else:
2207 nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs) 2209 nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs)
2208 2210
2209 # if this is an optional action, -- is not allowed 2211 # if this is an optional action, -- is not allowed
2210 if action.option_strings: 2212 if action.option_strings:
2211 nargs_pattern = nargs_pattern.replace('-*', '') 2213 nargs_pattern = nargs_pattern.replace('-*', '')
2212 nargs_pattern = nargs_pattern.replace('-', '') 2214 nargs_pattern = nargs_pattern.replace('-', '')
2213 2215
2214 # return the pattern 2216 # return the pattern
2215 return nargs_pattern 2217 return nargs_pattern
2216 2218
2217 # ======================== 2219 # ========================
2218 # Value conversion methods 2220 # Value conversion methods
2219 # ======================== 2221 # ========================
2220 def _get_values(self, action, arg_strings): 2222 def _get_values(self, action, arg_strings):
2221 # for everything but PARSER args, strip out '--' 2223 # for everything but PARSER, REMAINDER args, strip out first '--'
2222 #if action.nargs not in [PARSER, REMAINDER]: 2224 if action.nargs not in [PARSER, REMAINDER]:
2223 if action.nargs not in [_OPTIONAL_PARSER, PARSER, REMAINDER]: 2225 try:
2224 arg_strings = [s for s in arg_strings if s != '--'] 2226 arg_strings.remove('--')
2227 except ValueError:
2228 pass
2225 2229
2226 # optional argument produces a default when not present 2230 # optional argument produces a default when not present
2227 if not arg_strings and action.nargs == OPTIONAL: 2231 if not arg_strings and action.nargs == OPTIONAL:
2228 if action.option_strings: 2232 if action.option_strings:
2229 value = action.const 2233 value = action.const
2230 else: 2234 else:
2231 value = action.default 2235 value = action.default
2232 if isinstance(value, str): 2236 if isinstance(value, str):
2233 value = self._get_value(action, value) 2237 value = self._get_value(action, value)
2234 self._check_value(action, value) 2238 self._check_value(action, value)
2239
2235 # when nargs='*' on a positional, if there were no command-line 2240 # when nargs='*' on a positional, if there were no command-line
2236 # args, use the default if it is anything other than None 2241 # args, use the default if it is anything other than None
2237 elif (not arg_strings and action.nargs == ZERO_OR_MORE and 2242 elif (not arg_strings and action.nargs == ZERO_OR_MORE and
2238 not action.option_strings): 2243 not action.option_strings):
2239 if action.default is not None: 2244 if action.default is not None:
2240 value = action.default 2245 value = action.default
2241 else: 2246 else:
2242 value = arg_strings 2247 value = arg_strings
2243 self._check_value(action, value) 2248 self._check_value(action, value)
2244 2249
2245 # single argument or optional argument produces a single value 2250 # single argument or optional argument produces a single value
2246 elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]: 2251 elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]:
2247 arg_string, = arg_strings 2252 arg_string, = arg_strings
2248 value = self._get_value(action, arg_string) 2253 value = self._get_value(action, arg_string)
2249 self._check_value(action, value) 2254 self._check_value(action, value)
2250 2255
2251 # REMAINDER arguments convert all values, checking none 2256 # REMAINDER arguments convert all values, checking none
2252 elif action.nargs == REMAINDER: 2257 elif action.nargs == REMAINDER:
2253 value = [self._get_value(action, v) for v in arg_strings] 2258 value = [self._get_value(action, v) for v in arg_strings]
2254 2259
2255 # PARSER arguments convert all values, but check only the first 2260 # PARSER arguments convert all values, but check only the first
2256 elif action.nargs in [ PARSER, _OPTIONAL_PARSER ]: 2261 elif action.nargs == PARSER:
2257 value = [self._get_value(action, v) for v in arg_strings] 2262 value = [self._get_value(action, v) for v in arg_strings]
2258 if (not arg_strings and action.default is not None
2259 and action.nargs == _OPTIONAL_PARSER):
2260 value = [action.default]
2261 self._check_value(action, value[0]) 2263 self._check_value(action, value[0])
2262 2264
2263 # all other types of nargs produce a list 2265 # all other types of nargs produce a list
2264 else: 2266 else:
2265 value = [self._get_value(action, v) for v in arg_strings] 2267 value = [self._get_value(action, v) for v in arg_strings]
2266 for v in value: 2268 for v in value:
2267 self._check_value(action, v) 2269 self._check_value(action, v)
2268 2270
2269 # return the converted value 2271 # return the converted value
2270 return value 2272 return value
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2328 formatter.add_text(action_group.description) 2330 formatter.add_text(action_group.description)
2329 formatter.add_arguments(action_group._group_actions) 2331 formatter.add_arguments(action_group._group_actions)
2330 formatter.end_section() 2332 formatter.end_section()
2331 2333
2332 # epilog 2334 # epilog
2333 formatter.add_text(self.epilog) 2335 formatter.add_text(self.epilog)
2334 2336
2335 # determine help from format above 2337 # determine help from format above
2336 return formatter.format_help() 2338 return formatter.format_help()
2337 2339
2338 def format_version(self):
2339 import warnings
2340 warnings.warn(
2341 'The format_version method is deprecated -- the "version" '
2342 'argument to ArgumentParser is no longer supported.',
2343 DeprecationWarning)
2344 formatter = self._get_formatter()
2345 formatter.add_text(self.version)
2346 return formatter.format_help()
2347
2348 def _get_formatter(self): 2340 def _get_formatter(self):
2349 return self.formatter_class(prog=self.prog) 2341 return self.formatter_class(prog=self.prog)
2350 2342
2351 # ===================== 2343 # =====================
2352 # Help-printing methods 2344 # Help-printing methods
2353 # ===================== 2345 # =====================
2354 def print_usage(self, file=None): 2346 def print_usage(self, file=None):
2355 if file is None: 2347 if file is None:
2356 file = _sys.stdout 2348 file = _sys.stdout
2357 self._print_message(self.format_usage(), file) 2349 self._print_message(self.format_usage(), file)
2358 2350
2359 def print_help(self, file=None): 2351 def print_help(self, file=None):
2360 if file is None: 2352 if file is None:
2361 file = _sys.stdout 2353 file = _sys.stdout
2362 self._print_message(self.format_help(), file) 2354 self._print_message(self.format_help(), file)
2363 2355
2364 def print_version(self, file=None):
2365 import warnings
2366 warnings.warn(
2367 'The print_version method is deprecated -- the "version" '
2368 'argument to ArgumentParser is no longer supported.',
2369 DeprecationWarning)
2370 self._print_message(self.format_version(), file)
2371
2372 def _print_message(self, message, file=None): 2356 def _print_message(self, message, file=None):
2373 if message: 2357 if message:
2374 if file is None: 2358 if file is None:
2375 file = _sys.stderr 2359 file = _sys.stderr
2376 file.write(message) 2360 file.write(message)
2377 2361
2378 # =============== 2362 # ===============
2379 # Exiting methods 2363 # Exiting methods
2380 # =============== 2364 # ===============
2381 def exit(self, status=0, message=None): 2365 def exit(self, status=0, message=None):
2382 if message: 2366 if message:
2383 self._print_message(message, _sys.stderr) 2367 self._print_message(message, _sys.stderr)
2384 _sys.exit(status) 2368 _sys.exit(status)
2385 2369
2386 def error(self, message): 2370 def error(self, message):
2387 """error(message: string) 2371 """error(message: string)
2388 2372
2389 Prints a usage message incorporating the message to stderr and 2373 Prints a usage message incorporating the message to stderr and
2390 exits. 2374 exits.
2391 2375
2392 If you override this in a subclass, it should not return -- it 2376 If you override this in a subclass, it should not return -- it
2393 should either exit or raise an exception. 2377 should either exit or raise an exception.
2394 """ 2378 """
2395 self.print_usage(_sys.stderr) 2379 self.print_usage(_sys.stderr)
2396 args = {'prog': self.prog, 'message': message} 2380 args = {'prog': self.prog, 'message': message}
2397 self.exit(2, _('%(prog)s: error: %(message)s\n') % args) 2381 self.exit(2, _('%(prog)s: error: %(message)s\n') % args)
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+