diff --git a/Lib/argparse.py b/Lib/argparse.py index 100ef9f55cd2f7..99806d848443a7 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -2470,12 +2470,17 @@ 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 not action.option_strings and action.nargs not in [PARSER, REMAINDER]: - try: - arg_strings.remove('--') - except ValueError: - pass + if ((action.nargs in [ZERO_OR_MORE, ONE_OR_MORE] or + (isinstance(action.nargs, int) and action.nargs > 1)) and + action.type is None): + if arg_strings and arg_strings[0] == '--': + arg_strings = arg_strings[1:] + else: + try: + arg_strings.remove('--') + except ValueError: + pass # optional argument produces a default when not present if not arg_strings and action.nargs == OPTIONAL: diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index fd111be18aed6e..7da0da8ec5a32e 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -5716,6 +5716,27 @@ def test_double_dash(self): args = parser.parse_args(['--foo', 'a', 'b', '--', 'c', 'd']) self.assertEqual(NS(foo=['a', 'b'], bar=['c', 'd']), args) + parser2 = argparse.ArgumentParser() + parser2.add_argument('foo') + parser2.add_argument('bar', nargs='*') + + args = parser2.parse_args(['foo', '--', '--bar', '--', 'com']) + self.assertEqual(NS(foo='foo', bar=['--bar', '--', 'com']), args) + + parser3 = argparse.ArgumentParser() + parser3.add_argument('foo') + parser3.add_argument('bar', nargs='+') + + args = parser3.parse_args(['foo', '--', '--bar', '--', 'com']) + self.assertEqual(NS(foo='foo', bar=['--bar', '--', 'com']), args) + + parser4 = argparse.ArgumentParser() + parser4.add_argument('foo') + parser4.add_argument('bar', nargs=3) + + args = parser4.parse_args(['foo', '--', '--bar', '--', 'com']) + self.assertEqual(NS(foo='foo', bar=['--bar', '--', 'com']), args) + # =========================== # parse_intermixed_args tests diff --git a/Misc/NEWS.d/next/Library/2024-09-16-22-26-43.gh-issue-95468.L1bRag.rst b/Misc/NEWS.d/next/Library/2024-09-16-22-26-43.gh-issue-95468.L1bRag.rst new file mode 100644 index 00000000000000..1beeaaa7211e99 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-09-16-22-26-43.gh-issue-95468.L1bRag.rst @@ -0,0 +1 @@ +Fix a bug where :mod:`argparse` would remove "--" in cases where it delineates positional arguments in nargs.