# and add the Positional and its args to the list
for action, arg_count in zip(positionals, arg_counts):
args = arg_strings[start_index: start_index + arg_count]
- # Strip out the first '--' if it is not in PARSER or REMAINDER arg.
- if (action.nargs not in [PARSER, REMAINDER]
- and arg_strings_pattern.find('-', start_index,
+ # Strip out the first '--' if it is not in REMAINDER arg.
+ if action.nargs == PARSER:
+ if arg_strings_pattern[start_index] == '-':
+ assert args[0] == '--'
+ args.remove('--')
+ elif action.nargs != REMAINDER:
+ if (arg_strings_pattern.find('-', start_index,
start_index + arg_count) >= 0):
- args.remove('--')
+ args.remove('--')
start_index += arg_count
if args and action.deprecated and action.dest not in warned:
self._warning(_("argument '%(argument_name)s' is deprecated") %
"invalid choice: '--'",
parser.parse_args, ['--', 'x', '--', 'run', 'a', 'b'])
+ def test_subparser_after_multiple_argument_option(self):
+ parser = argparse.ArgumentParser(exit_on_error=False)
+ parser.add_argument('--foo', nargs='*')
+ subparsers = parser.add_subparsers()
+ parser1 = subparsers.add_parser('run')
+ parser1.add_argument('-f')
+ parser1.add_argument('bar', nargs='*')
+
+ args = parser.parse_args(['--foo', 'x', 'y', '--', 'run', 'a', 'b', '-f', 'c'])
+ self.assertEqual(NS(foo=['x', 'y'], f='c', bar=['a', 'b']), args)
+ self.assertRaisesRegex(argparse.ArgumentError,
+ "invalid choice: '--'",
+ parser.parse_args, ['--foo', 'x', '--', '--', 'run', 'a', 'b'])
+
# ===========================
# parse_intermixed_args tests