Index: Lib/argparse.py =================================================================== --- Lib/argparse.py (revision 86616) +++ Lib/argparse.py (working copy) @@ -382,6 +382,9 @@ # find group indices and identify actions in groups group_actions = set() inserts = {} + variable_option_usage = any( + a.nargs in (OPTIONAL, ONE_OR_MORE, ZERO_OR_MORE) + for a in actions if a.option_strings) for group in groups: try: start = actions.index(group._group_actions[0]) @@ -422,6 +425,11 @@ # produce all arg strings elif not action.option_strings: + # add -- before the first argument if needed to be unambiguous + if variable_option_usage: + parts.append("--") + variable_option_usage = False + part = self._format_args(action, action.dest) # if it's in a group, strip the outer [] Index: Lib/test/test_argparse.py =================================================================== --- Lib/test/test_argparse.py (revision 86616) +++ Lib/test/test_argparse.py (working copy) @@ -1238,9 +1238,38 @@ ('a', NS(x=None, y=['a'])), ('a -x', NS(x=[], y=['a'])), ('a -x b', NS(x=['b'], y=['a'])), + ('-x a b', NS(x=['a','b'], y=[])), + ('-x -- a b', NS(x=[], y=['a', 'b'])) ] +class TestNargsZeroOrOne(ParserTestCase): + """Tests specifying an args for an Optional that accepts zero or more""" + + argument_signatures = [Sig('-x', nargs='?'), Sig('y', nargs='?')] + failures = ["-x a b c", "a b -x"] + successes = [ + ('', NS(x=None, y=None)), + ('-x', NS(x=None, y=None)), + ('-x a', NS(x='a', y=None)), + ('-x -- a', NS(x=None, y='a')), + ('a', NS(x=None, y='a')), + ('a -x', NS(x=None, y='a')), + ('a -x b', NS(x='b', y='a')), + ('-x a -- b', NS(x='a', y='b')) + ] + + +class TestNargsOneOrMore(ParserTestCase): + """Tests specifying an args for an Optional that accepts one or more""" + + argument_signatures = [Sig('-x', nargs='+'), Sig('y')] + failures = ['-x a b'] + successes = [ + ('-x a -- b', NS(x=['a'], y='b')), + ('b -x a', NS(x=['a'], y='b')) + ] + class TestNargsRemainder(ParserTestCase): """Tests specifying a positional with nargs=REMAINDER""" @@ -2856,7 +2885,7 @@ Sig('-z', nargs='+', help='Z HELP')]), ] usage = '''\ - usage: PROG [-h] [-v] [-x] [--y Y] [-z Z [Z ...]] foo bar baz + usage: PROG [-h] [-v] [-x] [--y Y] [-z Z [Z ...]] -- foo bar baz ''' help = usage + '''\ @@ -3847,6 +3876,107 @@ ''' version = '' +class TestHelpZeroOrOneOptionalsNoPositionals(HelpTestCase): + """Test lacking of -- seperator if no positional arguments can be supplied + """ + + parser_signature = Sig(prog='PROG') + argument_signatures = [Sig('-x', nargs='?')] + argument_group_signatures = [] + usage = '''\ + usage: PROG [-h] [-x [X]] + ''' + help = usage + '''\ + + optional arguments: + -h, --help show this help message and exit + -x [X] + ''' + version= '' + +class TestHelpOneOrMoreOptionalsNoPositionals(HelpTestCase): + """Test lacking of -- seperator if no positional arguments can be supplied + """ + + parser_signature = Sig(prog='PROG') + argument_signatures = [Sig('-x', nargs='+')] + argument_group_signatures = [] + usage = '''\ + usage: PROG [-h] [-x X [X ...]] + ''' + help = usage + '''\ + + optional arguments: + -h, --help show this help message and exit + -x X [X ...] + ''' + version= '' + +class TestHelpOneOrMoreOptionalsNoPositionals2(HelpTestCase): + """Test lacking of -- seperator if no positional arguments can be supplied + """ + + parser_signature = Sig(prog='PROG') + argument_signatures = [Sig('-x', nargs='+'), Sig('-y')] + argument_group_signatures = [] + usage = '''\ + usage: PROG [-h] [-x X [X ...]] [-y Y] + ''' + help = usage + '''\ + + optional arguments: + -h, --help show this help message and exit + -x X [X ...] + -y Y + ''' + version= '' + +class TestHelpMiscOptionalsWithPositionals(HelpTestCase): + """Test output of -- seperator if some positional arguments follow + optionals with variable length + """ + + parser_signature = Sig(prog='PROG') + argument_signatures = [Sig('-x', nargs='+'), Sig('-y'), Sig("z")] + argument_group_signatures = [] + usage = '''\ + usage: PROG [-h] [-x X [X ...]] [-y Y] -- z + ''' + help = usage + '''\ + + positional arguments: + z + + optional arguments: + -h, --help show this help message and exit + -x X [X ...] + -y Y + ''' + version= '' + +class TestHelpZeroOrOneOptionalWithZeroOrOnePositional(HelpTestCase): + """Test output of -- seperator if some positional arguments follow + optionals with variable length + """ + + parser_signature = Sig(prog='PROG') + argument_signatures = [Sig('-x', nargs='?'), Sig("z", nargs="?")] + argument_group_signatures = [] + usage = '''\ + usage: PROG [-h] [-x [X]] -- [z] + ''' + help = usage + '''\ + + positional arguments: + z + + optional arguments: + -h, --help show this help message and exit + -x [X] + ''' + version= '' + + # ===================================== # Optional/Positional constructor tests # =====================================