diff --git a/Lib/argparse.py b/Lib/argparse.py index ddfd772c1126d2..0696e01a31efca 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -1959,6 +1959,9 @@ def consume_positionals(start_index): for action, arg_count in zip(positionals, arg_counts): args = arg_strings[start_index: start_index + arg_count] start_index += arg_count + if action.nargs not in [PARSER, REMAINDER]: + if '--' in args: + args.remove('--') take_action(action, args) # slice off the Positionals that we just parsed and return the @@ -2352,13 +2355,6 @@ def parse_known_intermixed_args(self, args=None, namespace=None): # Value conversion methods # ======================== def _get_values(self, action, arg_strings): - # for everything but PARSER, REMAINDER args, strip out first '--' - if action.nargs not in [PARSER, REMAINDER]: - try: - arg_strings.remove('--') - except ValueError: - pass - # optional argument produces a default when not present if not arg_strings and action.nargs == OPTIONAL: if action.option_strings: diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 86ec6cca51acc4..29ac9ccc548cb2 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -5262,6 +5262,47 @@ def test_help_with_metavar(self): ''')) +class TestDoubleDashRemoval(ParserTestCase): + """Test actions with multiple -- values""" + + """argparse removed all '--' + a 3-2012 patch removed just the 1st -- of each positional group + this new patch removes just the 1st -- + this change is most valuable when passing arg strings to another process""" + + argument_signatures = [ + Sig('-f', '--foo', help='an optional'), + Sig('cmd', help='a command'), + Sig('rest', nargs='*', help='zero or more args'), + ] + failures = ['cmd --foo bar 1 2 3', 'cmd -f1 2 3'] + successes = [ + ('-f1 1 -- 2 3', NS(cmd='1', foo='1', rest=['2', '3'])), + ('cmd -- --foo bar', NS(cmd='cmd', foo=None, rest=['--foo', 'bar'])), + ('cmd -- --foo -- -f2', NS(cmd='cmd', foo=None, rest=['--foo', '-f2'])), + ('-- --foo -- --bar 2', NS(cmd='--foo', foo=None, rest=['--bar', '2'])), + ('-f1 -- -- 1 -- 2', NS(cmd='--', foo='1', rest=['1', '2'])), + ('-- cmd -- -- --foo', NS(cmd='cmd', foo=None, rest=['--', '--foo'])), + ('cmd test --foo=--', NS(cmd='cmd', foo='--', rest=['test'])) + ] + + +class TestDoubleDashRemoval1(ParserTestCase): + """Test actions with multiple -- values, with '+' positional""" + + argument_signatures = [ + Sig('-f', '--foo', help='an optional'), + Sig('cmd', help='a command'), + Sig('rest', nargs='+', help='1 or more args'), + ] + failures = ['cmd -f1', '-f1 -- cmd', '-f1 cmd --'] + successes = [ + ('cmd -f1 2 3', NS(cmd='cmd', foo='1', rest=['2', '3'])), + ('cmd -f1 -- 2 3', NS(cmd='cmd', foo='1', rest=['2', '3'])), + ('-f1 -- cmd -- -f2 3', NS(cmd='cmd', foo='1', rest=['-f2', '3'])) + ] + + def test_main(): support.run_unittest(__name__) # Remove global references to avoid looking like we have refleaks. diff --git a/Misc/NEWS.d/next/Library/2019-09-06-06-16-35.bpo-14364.eEtNMR.rst b/Misc/NEWS.d/next/Library/2019-09-06-06-16-35.bpo-14364.eEtNMR.rst new file mode 100644 index 00000000000000..dce024d1a43ecb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-09-06-06-16-35.bpo-14364.eEtNMR.rst @@ -0,0 +1,2 @@ +'--' should be treated as other characters when '--' is +a part of argument.