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

Delta Between Two Patch Sets: Lib/argparse.py

Issue 14191: argparse: nargs='*' doesn't get out-of-order positional parameters
Left Patch Set: Created 8 years ago
Right Patch Set: Created 6 years, 10 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 563 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 elif action.nargs == OPTIONAL: 574 elif action.nargs == OPTIONAL:
575 result = '[%s]' % get_metavar(1) 575 result = '[%s]' % get_metavar(1)
576 elif action.nargs == ZERO_OR_MORE: 576 elif action.nargs == ZERO_OR_MORE:
577 result = '[%s [%s ...]]' % get_metavar(2) 577 result = '[%s [%s ...]]' % get_metavar(2)
578 elif action.nargs == ONE_OR_MORE: 578 elif action.nargs == ONE_OR_MORE:
579 result = '%s [%s ...]' % get_metavar(2) 579 result = '%s [%s ...]' % get_metavar(2)
580 elif action.nargs == REMAINDER: 580 elif action.nargs == REMAINDER:
581 result = '...' 581 result = '...'
582 elif action.nargs == PARSER: 582 elif action.nargs == PARSER:
583 result = '%s ...' % get_metavar(1) 583 result = '%s ...' % get_metavar(1)
584 elif action.nargs == SUPPRESS:
585 result = ''
584 else: 586 else:
585 formats = ['%s' for _ in range(action.nargs)] 587 formats = ['%s' for _ in range(action.nargs)]
586 result = ' '.join(formats) % get_metavar(action.nargs) 588 result = ' '.join(formats) % get_metavar(action.nargs)
587 return result 589 return result
588 590
589 def _expand_help(self, action): 591 def _expand_help(self, action):
590 params = dict(vars(action), prog=self._prog) 592 params = dict(vars(action), prog=self._prog)
591 for name in list(params): 593 for name in list(params):
592 if params[name] is SUPPRESS: 594 if params[name] is SUPPRESS:
593 del params[name] 595 del params[name]
594 for name in list(params): 596 for name in list(params):
595 if hasattr(params[name], '__name__'): 597 if hasattr(params[name], '__name__'):
596 params[name] = params[name].__name__ 598 params[name] = params[name].__name__
597 if params.get('choices') is not None: 599 if params.get('choices') is not None:
598 choices_str = ', '.join([str(c) for c in params['choices']]) 600 choices_str = ', '.join([str(c) for c in params['choices']])
599 params['choices'] = choices_str 601 params['choices'] = choices_str
600 return self._get_help_string(action) % params 602 return self._get_help_string(action) % params
601 603
602 def _iter_indented_subactions(self, action): 604 def _iter_indented_subactions(self, action):
603 try: 605 try:
604 get_subactions = action._get_subactions 606 get_subactions = action._get_subactions
605 except AttributeError: 607 except AttributeError:
606 pass 608 pass
607 else: 609 else:
608 self._indent() 610 self._indent()
609 for subaction in get_subactions(): 611 yield from get_subactions()
610 yield subaction
611 self._dedent() 612 self._dedent()
612 613
613 def _split_lines(self, text, width): 614 def _split_lines(self, text, width):
614 text = self._whitespace_matcher.sub(' ', text).strip() 615 text = self._whitespace_matcher.sub(' ', text).strip()
615 return _textwrap.wrap(text, width) 616 return _textwrap.wrap(text, width)
616 617
617 def _fill_text(self, text, width, indent): 618 def _fill_text(self, text, width, indent):
618 text = self._whitespace_matcher.sub(' ', text).strip() 619 text = self._whitespace_matcher.sub(' ', text).strip()
619 return _textwrap.fill(text, width, initial_indent=indent, 620 return _textwrap.fill(text, width, initial_indent=indent,
620 subsequent_indent=indent) 621 subsequent_indent=indent)
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 - '+' consumes one or more arguments (and produces a list) 755 - '+' consumes one or more arguments (and produces a list)
755 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
756 with the default, a single value will be produced, while with 757 with the default, a single value will be produced, while with
757 nargs=1, a list containing a single value will be produced. 758 nargs=1, a list containing a single value will be produced.
758 759
759 - 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
760 option uses an action that takes no values. 761 option uses an action that takes no values.
761 762
762 - 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.
763 764
764 - type -- The type which the command-line arguments should be converted 765 - type -- A callable that accepts a single string argument, and
765 to, should be one of 'string', 'int', 'float', 'complex' or a 766 returns the converted value. The standard Python types str, int,
766 callable object that accepts a single string argument. If None, 767 float, and complex are useful examples of such callables. If None,
767 'string' is assumed. 768 str is used.
768 769
769 - 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,
770 after a command-line argument has been converted to the appropriate 771 after a command-line argument has been converted to the appropriate
771 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
772 collection. 773 collection.
773 774
774 - required -- True if the action must always be specified at the 775 - required -- True if the action must always be specified at the
775 command line. This is only meaningful for optional command-line 776 command line. This is only meaningful for optional command-line
776 arguments. 777 arguments.
777 778
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
845 dest=dest, 846 dest=dest,
846 nargs=nargs, 847 nargs=nargs,
847 const=const, 848 const=const,
848 default=default, 849 default=default,
849 type=type, 850 type=type,
850 choices=choices, 851 choices=choices,
851 required=required, 852 required=required,
852 help=help, 853 help=help,
853 metavar=metavar) 854 metavar=metavar)
854 855
855 # has this action been called yet?
856 self.called = False
857
858 def __call__(self, parser, namespace, values, option_string=None): 856 def __call__(self, parser, namespace, values, option_string=None):
859 # if this action has nargs = "*" and is greedy, we need to override
860 # the default value (if any) that comes with the namespace in the first
861 # call, and append new values on successive calls
862 if self.nargs == ZERO_OR_MORE and parser.greedy_star and self.called:
863 previous = getattr(namespace, self.dest, None)
864
865 if previous is None:
866 previous = []
867 elif not isinstance(previous, list):
868 previous = [previous]
869
870 if isinstance(values, list):
871 values = previous + values
872 else:
873 values = previous + [values]
874
875 self.called = True
876 setattr(namespace, self.dest, values) 857 setattr(namespace, self.dest, values)
877 858
878 859
879 class _StoreConstAction(Action): 860 class _StoreConstAction(Action):
880 861
881 def __init__(self, 862 def __init__(self,
882 option_strings, 863 option_strings,
883 dest, 864 dest,
884 const, 865 const,
885 default=None, 866 default=None,
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
1154 """Factory for creating file object types 1135 """Factory for creating file object types
1155 1136
1156 Instances of FileType are typically passed as type= arguments to the 1137 Instances of FileType are typically passed as type= arguments to the
1157 ArgumentParser add_argument() method. 1138 ArgumentParser add_argument() method.
1158 1139
1159 Keyword Arguments: 1140 Keyword Arguments:
1160 - mode -- A string indicating how the file is to be opened. Accepts the 1141 - mode -- A string indicating how the file is to be opened. Accepts the
1161 same values as the builtin open() function. 1142 same values as the builtin open() function.
1162 - bufsize -- The file's desired buffer size. Accepts the same values as 1143 - bufsize -- The file's desired buffer size. Accepts the same values as
1163 the builtin open() function. 1144 the builtin open() function.
1145 - encoding -- The file's encoding. Accepts the same values as the
1146 builtin open() function.
1147 - errors -- A string indicating how encoding and decoding errors are to
1148 be handled. Accepts the same value as the builtin open() function.
1164 """ 1149 """
1165 1150
1166 def __init__(self, mode='r', bufsize=-1): 1151 def __init__(self, mode='r', bufsize=-1, encoding=None, errors=None):
1167 self._mode = mode 1152 self._mode = mode
1168 self._bufsize = bufsize 1153 self._bufsize = bufsize
1154 self._encoding = encoding
1155 self._errors = errors
1169 1156
1170 def __call__(self, string): 1157 def __call__(self, string):
1171 # the special argument "-" means sys.std{in,out} 1158 # the special argument "-" means sys.std{in,out}
1172 if string == '-': 1159 if string == '-':
1173 if 'r' in self._mode: 1160 if 'r' in self._mode:
1174 return _sys.stdin 1161 return _sys.stdin
1175 elif 'w' in self._mode: 1162 elif 'w' in self._mode:
1176 return _sys.stdout 1163 return _sys.stdout
1177 else: 1164 else:
1178 msg = _('argument "-" with mode %r') % self._mode 1165 msg = _('argument "-" with mode %r') % self._mode
1179 raise ValueError(msg) 1166 raise ValueError(msg)
1180 1167
1181 # all other arguments are used as file names 1168 # all other arguments are used as file names
1182 try: 1169 try:
1183 return open(string, self._mode, self._bufsize) 1170 return open(string, self._mode, self._bufsize, self._encoding,
1184 except IOError as e: 1171 self._errors)
1172 except OSError as e:
1185 message = _("can't open '%s': %s") 1173 message = _("can't open '%s': %s")
1186 raise ArgumentTypeError(message % (string, e)) 1174 raise ArgumentTypeError(message % (string, e))
1187 1175
1188 def __repr__(self): 1176 def __repr__(self):
1189 args = self._mode, self._bufsize 1177 args = self._mode, self._bufsize
1190 args_str = ', '.join(repr(arg) for arg in args if arg != -1) 1178 kwargs = [('encoding', self._encoding), ('errors', self._errors)]
1179 args_str = ', '.join([repr(arg) for arg in args if arg != -1] +
1180 ['%s=%r' % (kw, arg) for kw, arg in kwargs
1181 if arg is not None])
1191 return '%s(%s)' % (type(self).__name__, args_str) 1182 return '%s(%s)' % (type(self).__name__, args_str)
1192 1183
1193 # =========================== 1184 # ===========================
1194 # Optional and Positional Parsing 1185 # Optional and Positional Parsing
1195 # =========================== 1186 # ===========================
1196 1187
1197 class Namespace(_AttributeHolder): 1188 class Namespace(_AttributeHolder):
1198 """Simple object for storing attributes. 1189 """Simple object for storing attributes.
1199 1190
1200 Implements equality by attribute names and values, and provides a simple 1191 Implements equality by attribute names and values, and provides a simple
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
1592 - argument_default -- The default value for all arguments 1583 - argument_default -- The default value for all arguments
1593 - conflict_handler -- String indicating how to handle conflicts 1584 - conflict_handler -- String indicating how to handle conflicts
1594 - add_help -- Add a -h/-help option 1585 - add_help -- Add a -h/-help option
1595 """ 1586 """
1596 1587
1597 def __init__(self, 1588 def __init__(self,
1598 prog=None, 1589 prog=None,
1599 usage=None, 1590 usage=None,
1600 description=None, 1591 description=None,
1601 epilog=None, 1592 epilog=None,
1602 version=None,
1603 parents=[], 1593 parents=[],
1604 formatter_class=HelpFormatter, 1594 formatter_class=HelpFormatter,
1605 prefix_chars='-', 1595 prefix_chars='-',
1606 fromfile_prefix_chars=None, 1596 fromfile_prefix_chars=None,
1607 argument_default=None, 1597 argument_default=None,
1608 conflict_handler='error', 1598 conflict_handler='error',
1609 add_help=True, 1599 add_help=True):
1610 greedy_star=False):
1611
1612 if version is not None:
1613 import warnings
1614 warnings.warn(
1615 """The "version" argument to ArgumentParser is deprecated. """
1616 """Please use """
1617 """"add_argument(..., action='version', version="N", ...)" """
1618 """instead""", DeprecationWarning)
1619 1600
1620 superinit = super(ArgumentParser, self).__init__ 1601 superinit = super(ArgumentParser, self).__init__
1621 superinit(description=description, 1602 superinit(description=description,
1622 prefix_chars=prefix_chars, 1603 prefix_chars=prefix_chars,
1623 argument_default=argument_default, 1604 argument_default=argument_default,
1624 conflict_handler=conflict_handler) 1605 conflict_handler=conflict_handler)
1625 1606
1626 # default setting for prog 1607 # default setting for prog
1627 if prog is None: 1608 if prog is None:
1628 prog = _os.path.basename(_sys.argv[0]) 1609 prog = _os.path.basename(_sys.argv[0])
1629 1610
1630 self.prog = prog 1611 self.prog = prog
1631 self.usage = usage 1612 self.usage = usage
1632 self.epilog = epilog 1613 self.epilog = epilog
1633 self.version = version
1634 self.formatter_class = formatter_class 1614 self.formatter_class = formatter_class
1635 self.fromfile_prefix_chars = fromfile_prefix_chars 1615 self.fromfile_prefix_chars = fromfile_prefix_chars
1636 self.add_help = add_help 1616 self.add_help = add_help
1637 self.greedy_star = greedy_star
1638 1617
1639 add_group = self.add_argument_group 1618 add_group = self.add_argument_group
1640 self._positionals = add_group(_('positional arguments')) 1619 self._positionals = add_group(_('positional arguments'))
1641 self._optionals = add_group(_('optional arguments')) 1620 self._optionals = add_group(_('optional arguments'))
1642 self._subparsers = None 1621 self._subparsers = None
1643 1622
1644 # register types 1623 # register types
1645 def identity(string): 1624 def identity(string):
1646 return string 1625 return string
1647 self.register('type', None, identity) 1626 self.register('type', None, identity)
1648 1627
1649 # add help and version arguments if necessary 1628 # add help argument if necessary
1650 # (using explicit default to override global argument_default) 1629 # (using explicit default to override global argument_default)
1651 default_prefix = '-' if '-' in prefix_chars else prefix_chars[0] 1630 default_prefix = '-' if '-' in prefix_chars else prefix_chars[0]
1652 if self.add_help: 1631 if self.add_help:
1653 self.add_argument( 1632 self.add_argument(
1654 default_prefix+'h', default_prefix*2+'help', 1633 default_prefix+'h', default_prefix*2+'help',
1655 action='help', default=SUPPRESS, 1634 action='help', default=SUPPRESS,
1656 help=_('show this help message and exit')) 1635 help=_('show this help message and exit'))
1657 if self.version:
1658 self.add_argument(
1659 default_prefix+'v', default_prefix*2+'version',
1660 action='version', default=SUPPRESS,
1661 version=self.version,
1662 help=_("show program's version number and exit"))
1663 1636
1664 # add parent arguments and defaults 1637 # add parent arguments and defaults
1665 for parent in parents: 1638 for parent in parents:
1666 self._add_container_actions(parent) 1639 self._add_container_actions(parent)
1667 try: 1640 try:
1668 defaults = parent._defaults 1641 defaults = parent._defaults
1669 except AttributeError: 1642 except AttributeError:
1670 pass 1643 pass
1671 else: 1644 else:
1672 self._defaults.update(defaults) 1645 self._defaults.update(defaults)
1673 1646
1674 # ======================= 1647 # =======================
1675 # Pretty __repr__ methods 1648 # Pretty __repr__ methods
1676 # ======================= 1649 # =======================
1677 def _get_kwargs(self): 1650 def _get_kwargs(self):
1678 names = [ 1651 names = [
1679 'prog', 1652 'prog',
1680 'usage', 1653 'usage',
1681 'description', 1654 'description',
1682 'version',
1683 'formatter_class', 1655 'formatter_class',
1684 'conflict_handler', 1656 'conflict_handler',
1685 'add_help', 1657 'add_help',
1686 ] 1658 ]
1687 return [(name, getattr(self, name)) for name in names] 1659 return [(name, getattr(self, name)) for name in names]
1688 1660
1689 # ================================== 1661 # ==================================
1690 # Optional/Positional adding methods 1662 # Optional/Positional adding methods
1691 # ================================== 1663 # ==================================
1692 def add_subparsers(self, **kwargs): 1664 def add_subparsers(self, **kwargs):
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1741 # Command line argument parsing methods 1713 # Command line argument parsing methods
1742 # ===================================== 1714 # =====================================
1743 def parse_args(self, args=None, namespace=None): 1715 def parse_args(self, args=None, namespace=None):
1744 args, argv = self.parse_known_args(args, namespace) 1716 args, argv = self.parse_known_args(args, namespace)
1745 if argv: 1717 if argv:
1746 msg = _('unrecognized arguments: %s') 1718 msg = _('unrecognized arguments: %s')
1747 self.error(msg % ' '.join(argv)) 1719 self.error(msg % ' '.join(argv))
1748 return args 1720 return args
1749 1721
1750 def parse_known_args(self, args=None, namespace=None): 1722 def parse_known_args(self, args=None, namespace=None):
1751 # args default to the system args
1752 if args is None: 1723 if args is None:
1724 # args default to the system args
1753 args = _sys.argv[1:] 1725 args = _sys.argv[1:]
1726 else:
1727 # make sure that args are mutable
1728 args = list(args)
1754 1729
1755 # default Namespace built from parser defaults 1730 # default Namespace built from parser defaults
1756 if namespace is None: 1731 if namespace is None:
1757 namespace = Namespace() 1732 namespace = Namespace()
1758 1733
1759 # add any action defaults that aren't present 1734 # add any action defaults that aren't present
1760 for action in self._actions: 1735 for action in self._actions:
1761 if action.dest is not SUPPRESS: 1736 if action.dest is not SUPPRESS:
1762 if not hasattr(namespace, action.dest): 1737 if not hasattr(namespace, action.dest):
1763 if action.default is not SUPPRESS: 1738 if action.default is not SUPPRESS:
1764 default = action.default 1739 setattr(namespace, action.dest, action.default)
1765 if isinstance(action.default, str):
1766 default = self._get_value(action, default)
1767 setattr(namespace, action.dest, default)
1768 1740
1769 # add any parser defaults that aren't present 1741 # add any parser defaults that aren't present
1770 for dest in self._defaults: 1742 for dest in self._defaults:
1771 if not hasattr(namespace, dest): 1743 if not hasattr(namespace, dest):
1772 setattr(namespace, dest, self._defaults[dest]) 1744 setattr(namespace, dest, self._defaults[dest])
1773 1745
1774 # parse the arguments and exit if there are any errors 1746 # parse the arguments and exit if there are any errors
1775 try: 1747 try:
1776 namespace, args = self._parse_known_args(args, namespace) 1748 namespace, args = self._parse_known_args(args, namespace)
1777 if hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR): 1749 if hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR):
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1935 1907
1936 # slice off the appropriate arg strings for each Positional 1908 # slice off the appropriate arg strings for each Positional
1937 # and add the Positional and its args to the list 1909 # and add the Positional and its args to the list
1938 for action, arg_count in zip(positionals, arg_counts): 1910 for action, arg_count in zip(positionals, arg_counts):
1939 args = arg_strings[start_index: start_index + arg_count] 1911 args = arg_strings[start_index: start_index + arg_count]
1940 start_index += arg_count 1912 start_index += arg_count
1941 take_action(action, args) 1913 take_action(action, args)
1942 1914
1943 # slice off the Positionals that we just parsed and return the 1915 # slice off the Positionals that we just parsed and return the
1944 # index at which the Positionals' string args stopped 1916 # index at which the Positionals' string args stopped
1945 # keep positionals that take zero or more arguments if they are 1917 positionals[:] = positionals[len(arg_counts):]
1946 # greedy so we can reuse them
1947 if not self.greedy_star:
1948 positionals[:] = positionals[len(arg_counts):]
1949 else:
1950 positionals[:len(arg_counts)] = [
1951 p
1952 for p in positionals[:len(arg_counts)]
1953 if p.nargs == ZERO_OR_MORE
1954 ]
1955
1956 return start_index 1918 return start_index
1957 1919
1958 # consume Positionals and Optionals alternately, until we have 1920 # consume Positionals and Optionals alternately, until we have
1959 # passed the last option string 1921 # passed the last option string
1960 extras = [] 1922 extras = []
1961 start_index = 0 1923 start_index = 0
1962 if option_string_indices: 1924 if option_string_indices:
1963 max_option_string_index = max(option_string_indices) 1925 max_option_string_index = max(option_string_indices)
1964 else: 1926 else:
1965 max_option_string_index = -1 1927 max_option_string_index = -1
(...skipping 24 matching lines...) Expand all
1990 1952
1991 # consume the next optional and any arguments for it 1953 # consume the next optional and any arguments for it
1992 start_index = consume_optional(start_index) 1954 start_index = consume_optional(start_index)
1993 1955
1994 # consume any positionals following the last Optional 1956 # consume any positionals following the last Optional
1995 stop_index = consume_positionals(start_index) 1957 stop_index = consume_positionals(start_index)
1996 1958
1997 # if we didn't consume all the argument strings, there were extras 1959 # if we didn't consume all the argument strings, there were extras
1998 extras.extend(arg_strings[stop_index:]) 1960 extras.extend(arg_strings[stop_index:])
1999 1961
2000 # make sure all required actions were present 1962 # make sure all required actions were present and also convert
2001 required_actions = [_get_action_name(action) for action in self._actions 1963 # action defaults which were not given as arguments
2002 if action.required and action not in seen_actions] 1964 required_actions = []
1965 for action in self._actions:
1966 if action not in seen_actions:
1967 if action.required:
1968 required_actions.append(_get_action_name(action))
1969 else:
1970 # Convert action default now instead of doing it before
1971 # parsing arguments to avoid calling convert functions
1972 # twice (which may fail) if the argument was given, but
1973 # only if it was defined already in the namespace
1974 if (action.default is not None and
1975 isinstance(action.default, str) and
1976 hasattr(namespace, action.dest) and
1977 action.default is getattr(namespace, action.dest)):
1978 setattr(namespace, action.dest,
1979 self._get_value(action, action.default))
1980
2003 if required_actions: 1981 if required_actions:
2004 self.error(_('the following arguments are required: %s') % 1982 self.error(_('the following arguments are required: %s') %
2005 ', '.join(required_actions)) 1983 ', '.join(required_actions))
2006 1984
2007 # make sure all required groups had one option present 1985 # make sure all required groups had one option present
2008 for group in self._mutually_exclusive_groups: 1986 for group in self._mutually_exclusive_groups:
2009 if group.required: 1987 if group.required:
2010 for action in group._group_actions: 1988 for action in group._group_actions:
2011 if action in seen_non_default_actions: 1989 if action in seen_non_default_actions:
2012 break 1990 break
2013 1991
2014 # if no actions were used, report the error 1992 # if no actions were used, report the error
2015 else: 1993 else:
2016 names = [_get_action_name(action) 1994 names = [_get_action_name(action)
2017 for action in group._group_actions 1995 for action in group._group_actions
2018 if action.help is not SUPPRESS] 1996 if action.help is not SUPPRESS]
2019 msg = _('one of the arguments %s is required') 1997 msg = _('one of the arguments %s is required')
2020 self.error(msg % ' '.join(names)) 1998 self.error(msg % ' '.join(names))
2021 1999
2022 # return the updated namespace and the extra arguments 2000 # return the updated namespace and the extra arguments
2023 return namespace, extras 2001 return namespace, extras
2024 2002
2025 def _read_args_from_files(self, arg_strings): 2003 def _read_args_from_files(self, arg_strings):
2026 # expand arguments referencing files 2004 # expand arguments referencing files
2027 new_arg_strings = [] 2005 new_arg_strings = []
2028 for arg_string in arg_strings: 2006 for arg_string in arg_strings:
2029 2007
2030 # for regular arguments, just add them back into the list 2008 # for regular arguments, just add them back into the list
2031 if arg_string[0] not in self.fromfile_prefix_chars: 2009 if not arg_string or arg_string[0] not in self.fromfile_prefix_chars :
2032 new_arg_strings.append(arg_string) 2010 new_arg_strings.append(arg_string)
2033 2011
2034 # replace arguments referencing files with the file content 2012 # replace arguments referencing files with the file content
2035 else: 2013 else:
2036 try: 2014 try:
2037 args_file = open(arg_string[1:]) 2015 with open(arg_string[1:]) as args_file:
2038 try:
2039 arg_strings = [] 2016 arg_strings = []
2040 for arg_line in args_file.read().splitlines(): 2017 for arg_line in args_file.read().splitlines():
2041 for arg in self.convert_arg_line_to_args(arg_line): 2018 for arg in self.convert_arg_line_to_args(arg_line):
2042 arg_strings.append(arg) 2019 arg_strings.append(arg)
2043 arg_strings = self._read_args_from_files(arg_strings) 2020 arg_strings = self._read_args_from_files(arg_strings)
2044 new_arg_strings.extend(arg_strings) 2021 new_arg_strings.extend(arg_strings)
2045 finally: 2022 except OSError:
2046 args_file.close()
2047 except IOError:
2048 err = _sys.exc_info()[1] 2023 err = _sys.exc_info()[1]
2049 self.error(str(err)) 2024 self.error(str(err))
2050 2025
2051 # return the modified argument list 2026 # return the modified argument list
2052 return new_arg_strings 2027 return new_arg_strings
2053 2028
2054 def convert_arg_line_to_args(self, arg_line): 2029 def convert_arg_line_to_args(self, arg_line):
2055 return [arg_line] 2030 return [arg_line]
2056 2031
2057 def _match_argument(self, action, arg_strings_pattern): 2032 def _match_argument(self, action, arg_strings_pattern):
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
2215 nargs_pattern = '(-*A[A-]*)' 2190 nargs_pattern = '(-*A[A-]*)'
2216 2191
2217 # allow any number of options or arguments 2192 # allow any number of options or arguments
2218 elif nargs == REMAINDER: 2193 elif nargs == REMAINDER:
2219 nargs_pattern = '([-AO]*)' 2194 nargs_pattern = '([-AO]*)'
2220 2195
2221 # allow one argument followed by any number of options or arguments 2196 # allow one argument followed by any number of options or arguments
2222 elif nargs == PARSER: 2197 elif nargs == PARSER:
2223 nargs_pattern = '(-*A[-AO]*)' 2198 nargs_pattern = '(-*A[-AO]*)'
2224 2199
2200 # suppress action, like nargs=0
2201 elif nargs == SUPPRESS:
2202 nargs_pattern = '(-*-*)'
2203
2225 # all others should be integers 2204 # all others should be integers
2226 else: 2205 else:
2227 nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs) 2206 nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs)
2228 2207
2229 # if this is an optional action, -- is not allowed 2208 # if this is an optional action, -- is not allowed
2230 if action.option_strings: 2209 if action.option_strings:
2231 nargs_pattern = nargs_pattern.replace('-*', '') 2210 nargs_pattern = nargs_pattern.replace('-*', '')
2232 nargs_pattern = nargs_pattern.replace('-', '') 2211 nargs_pattern = nargs_pattern.replace('-', '')
2233 2212
2234 # return the pattern 2213 # return the pattern
2235 return nargs_pattern 2214 return nargs_pattern
2236 2215
2237 # ======================== 2216 # ========================
2217 # Alt command line argument parsing, allowing free intermix
2218 # ========================
2219
2220 def parse_intermixed_args(self, args=None, namespace=None):
2221 args, argv = self.parse_known_intermixed_args(args, namespace)
2222 if argv:
2223 msg = _('unrecognized arguments: %s')
2224 self.error(msg % ' '.join(argv))
2225 return args
2226
2227 def parse_known_intermixed_args(self, args=None, namespace=None):
2228 # self - argparse parser
2229 # args, namespace - as used by parse_known_args
2230 # returns a namespace and list of extras
2231
2232 # positional can be freely intermixed with optionals
2233 # optionals are first parsed with all positional arguments deactivated
2234 # the 'extras' are then parsed
2235 # if parser definition is incompatible with the intermixed assumptions
2236 # returns a TypeError (e.g. use of REMAINDER, subparsers)
2237
2238 # positionals are 'deactivated' by setting nargs and default to SUPPRESS .
2239 # This blocks the addition of that positional to the namespace
2240
2241 positionals = self._get_positional_actions()
2242 a = [action for action in positionals if action.nargs in [PARSER, REMAIN DER]]
2243 if a:
2244 raise TypeError('parse_intermixed_args: positional arg with nargs=%s '%a[0].nargs)
2245
2246 if [action.dest for group in self._mutually_exclusive_groups
2247 for action in group._group_actions if action in positionals]:
2248 raise TypeError('parse_intermixed_args: positional in mutuallyExclus iveGroup')
2249
2250 save_usage = self.usage
2251 try:
2252 if self.usage is None:
2253 # capture the full usage for use in error messages
2254 self.usage = self.format_usage()[7:]
2255 for action in positionals:
2256 # deactivate positionals
2257 action.save_nargs = action.nargs
2258 # action.nargs = 0
2259 action.nargs = SUPPRESS
2260 action.save_default = action.default
2261 action.default = SUPPRESS
2262 try:
2263 namespace, remaining_args = self.parse_known_args(args, namespac e)
2264 for action in positionals:
2265 # remove the empty positional values from namespace
2266 if hasattr(namespace, action.dest) and getattr(namespace, ac tion.dest)==[]:
2267 from warnings import warn
2268 warn('Do not expect %s in %s'%(action.dest,namespace))
2269 delattr(namespace, action.dest)
2270 finally:
2271 # restore nargs and usage before exiting
2272 for action in positionals:
2273 action.nargs = action.save_nargs
2274 action.default = action.save_default
2275 # parse positionals
2276 # optionals aren't normally required, but just in case, turn that of f
2277 optionals = self._get_optional_actions()
2278 for action in optionals:
2279 action.save_required = action.required
2280 action.required = False
2281 for group in self._mutually_exclusive_groups:
2282 group.save_required = group.required
2283 group.required = False
2284 try:
2285 namespace, extras = self.parse_known_args(remaining_args, namesp ace)
2286 finally:
2287 # restore parser values before exiting
2288 for action in optionals:
2289 action.required = action.save_required
2290 for group in self._mutually_exclusive_groups:
2291 group.required = group.save_required
2292 finally:
2293 self.usage = save_usage
2294 return namespace, extras
2295
2296 # ========================
2238 # Value conversion methods 2297 # Value conversion methods
2239 # ======================== 2298 # ========================
2240 def _get_values(self, action, arg_strings): 2299 def _get_values(self, action, arg_strings):
2241 # for everything but PARSER args, strip out '--' 2300 # for everything but PARSER, REMAINDER args, strip out first '--'
2242 if action.nargs not in [PARSER, REMAINDER]: 2301 if action.nargs not in [PARSER, REMAINDER]:
2243 arg_strings = [s for s in arg_strings if s != '--'] 2302 try:
2303 arg_strings.remove('--')
2304 except ValueError:
2305 pass
2244 2306
2245 # optional argument produces a default when not present 2307 # optional argument produces a default when not present
2246 if not arg_strings and action.nargs == OPTIONAL: 2308 if not arg_strings and action.nargs == OPTIONAL:
2247 if action.option_strings: 2309 if action.option_strings:
2248 value = action.const 2310 value = action.const
2249 else: 2311 else:
2250 value = action.default 2312 value = action.default
2251 if isinstance(value, str): 2313 if isinstance(value, str):
2252 value = self._get_value(action, value) 2314 value = self._get_value(action, value)
2253 self._check_value(action, value) 2315 self._check_value(action, value)
(...skipping 16 matching lines...) Expand all
2270 2332
2271 # REMAINDER arguments convert all values, checking none 2333 # REMAINDER arguments convert all values, checking none
2272 elif action.nargs == REMAINDER: 2334 elif action.nargs == REMAINDER:
2273 value = [self._get_value(action, v) for v in arg_strings] 2335 value = [self._get_value(action, v) for v in arg_strings]
2274 2336
2275 # PARSER arguments convert all values, but check only the first 2337 # PARSER arguments convert all values, but check only the first
2276 elif action.nargs == PARSER: 2338 elif action.nargs == PARSER:
2277 value = [self._get_value(action, v) for v in arg_strings] 2339 value = [self._get_value(action, v) for v in arg_strings]
2278 self._check_value(action, value[0]) 2340 self._check_value(action, value[0])
2279 2341
2342 # SUPPRESS argument does not put anything in the namespace
2343 elif action.nargs == SUPPRESS:
2344 value = SUPPRESS
2345
2280 # all other types of nargs produce a list 2346 # all other types of nargs produce a list
2281 else: 2347 else:
2282 value = [self._get_value(action, v) for v in arg_strings] 2348 value = [self._get_value(action, v) for v in arg_strings]
2283 for v in value: 2349 for v in value:
2284 self._check_value(action, v) 2350 self._check_value(action, v)
2285 2351
2286 # return the converted value 2352 # return the converted value
2287 return value 2353 return value
2288 2354
2289 def _get_value(self, action, arg_string): 2355 def _get_value(self, action, arg_string):
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2345 formatter.add_text(action_group.description) 2411 formatter.add_text(action_group.description)
2346 formatter.add_arguments(action_group._group_actions) 2412 formatter.add_arguments(action_group._group_actions)
2347 formatter.end_section() 2413 formatter.end_section()
2348 2414
2349 # epilog 2415 # epilog
2350 formatter.add_text(self.epilog) 2416 formatter.add_text(self.epilog)
2351 2417
2352 # determine help from format above 2418 # determine help from format above
2353 return formatter.format_help() 2419 return formatter.format_help()
2354 2420
2355 def format_version(self):
2356 import warnings
2357 warnings.warn(
2358 'The format_version method is deprecated -- the "version" '
2359 'argument to ArgumentParser is no longer supported.',
2360 DeprecationWarning)
2361 formatter = self._get_formatter()
2362 formatter.add_text(self.version)
2363 return formatter.format_help()
2364
2365 def _get_formatter(self): 2421 def _get_formatter(self):
2366 return self.formatter_class(prog=self.prog) 2422 return self.formatter_class(prog=self.prog)
2367 2423
2368 # ===================== 2424 # =====================
2369 # Help-printing methods 2425 # Help-printing methods
2370 # ===================== 2426 # =====================
2371 def print_usage(self, file=None): 2427 def print_usage(self, file=None):
2372 if file is None: 2428 if file is None:
2373 file = _sys.stdout 2429 file = _sys.stdout
2374 self._print_message(self.format_usage(), file) 2430 self._print_message(self.format_usage(), file)
2375 2431
2376 def print_help(self, file=None): 2432 def print_help(self, file=None):
2377 if file is None: 2433 if file is None:
2378 file = _sys.stdout 2434 file = _sys.stdout
2379 self._print_message(self.format_help(), file) 2435 self._print_message(self.format_help(), file)
2380 2436
2381 def print_version(self, file=None):
2382 import warnings
2383 warnings.warn(
2384 'The print_version method is deprecated -- the "version" '
2385 'argument to ArgumentParser is no longer supported.',
2386 DeprecationWarning)
2387 self._print_message(self.format_version(), file)
2388
2389 def _print_message(self, message, file=None): 2437 def _print_message(self, message, file=None):
2390 if message: 2438 if message:
2391 if file is None: 2439 if file is None:
2392 file = _sys.stderr 2440 file = _sys.stderr
2393 file.write(message) 2441 file.write(message)
2394 2442
2395 # =============== 2443 # ===============
2396 # Exiting methods 2444 # Exiting methods
2397 # =============== 2445 # ===============
2398 def exit(self, status=0, message=None): 2446 def exit(self, status=0, message=None):
2399 if message: 2447 if message:
2400 self._print_message(message, _sys.stderr) 2448 self._print_message(message, _sys.stderr)
2401 _sys.exit(status) 2449 _sys.exit(status)
2402 2450
2403 def error(self, message): 2451 def error(self, message):
2404 """error(message: string) 2452 """error(message: string)
2405 2453
2406 Prints a usage message incorporating the message to stderr and 2454 Prints a usage message incorporating the message to stderr and
2407 exits. 2455 exits.
2408 2456
2409 If you override this in a subclass, it should not return -- it 2457 If you override this in a subclass, it should not return -- it
2410 should either exit or raise an exception. 2458 should either exit or raise an exception.
2411 """ 2459 """
2412 self.print_usage(_sys.stderr) 2460 self.print_usage(_sys.stderr)
2413 args = {'prog': self.prog, 'message': message} 2461 args = {'prog': self.prog, 'message': message}
2414 self.exit(2, _('%(prog)s: error: %(message)s\n') % args) 2462 self.exit(2, _('%(prog)s: error: %(message)s\n') % args)
LEFTRIGHT

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