bpo-14191 Add parse_intermixed_args. (#3319) · python/cpython@0f6b9d2 (original) (raw)

`@@ -4804,6 +4804,93 @@ def test_mixed(self):

`

4804

4804

`self.assertEqual(NS(v=3, spam=True, badger="B"), args)

`

4805

4805

`self.assertEqual(["C", "--foo", "4"], extras)

`

4806

4806

``

``

4807

`+

===========================

`

``

4808

`+

parse_intermixed_args tests

`

``

4809

`+

===========================

`

``

4810

+

``

4811

`+

class TestIntermixedArgs(TestCase):

`

``

4812

`+

def test_basic(self):

`

``

4813

`+

test parsing intermixed optionals and positionals

`

``

4814

`+

parser = argparse.ArgumentParser(prog='PROG')

`

``

4815

`+

parser.add_argument('--foo', dest='foo')

`

``

4816

`+

bar = parser.add_argument('--bar', dest='bar', required=True)

`

``

4817

`+

parser.add_argument('cmd')

`

``

4818

`+

parser.add_argument('rest', nargs='*', type=int)

`

``

4819

`+

argv = 'cmd --foo x 1 --bar y 2 3'.split()

`

``

4820

`+

args = parser.parse_intermixed_args(argv)

`

``

4821

`+

rest gets [1,2,3] despite the foo and bar strings

`

``

4822

`+

self.assertEqual(NS(bar='y', cmd='cmd', foo='x', rest=[1, 2, 3]), args)

`

``

4823

+

``

4824

`+

args, extras = parser.parse_known_args(argv)

`

``

4825

`+

cannot parse the '1,2,3'

`

``

4826

`+

self.assertEqual(NS(bar='y', cmd='cmd', foo='x', rest=[]), args)

`

``

4827

`+

self.assertEqual(["1", "2", "3"], extras)

`

``

4828

+

``

4829

`+

argv = 'cmd --foo x 1 --error 2 --bar y 3'.split()

`

``

4830

`+

args, extras = parser.parse_known_intermixed_args(argv)

`

``

4831

`+

unknown optionals go into extras

`

``

4832

`+

self.assertEqual(NS(bar='y', cmd='cmd', foo='x', rest=[1]), args)

`

``

4833

`+

self.assertEqual(['--error', '2', '3'], extras)

`

``

4834

+

``

4835

`+

restores attributes that were temporarily changed

`

``

4836

`+

self.assertIsNone(parser.usage)

`

``

4837

`+

self.assertEqual(bar.required, True)

`

``

4838

+

``

4839

`+

def test_remainder(self):

`

``

4840

`+

Intermixed and remainder are incompatible

`

``

4841

`+

parser = ErrorRaisingArgumentParser(prog='PROG')

`

``

4842

`+

parser.add_argument('-z')

`

``

4843

`+

parser.add_argument('x')

`

``

4844

`+

parser.add_argument('y', nargs='...')

`

``

4845

`+

argv = 'X A B -z Z'.split()

`

``

4846

`+

intermixed fails with '...' (also 'A...')

`

``

4847

`+

self.assertRaises(TypeError, parser.parse_intermixed_args, argv)

`

``

4848

`+

with self.assertRaises(TypeError) as cm:

`

``

4849

`+

parser.parse_intermixed_args(argv)

`

``

4850

`+

self.assertRegex(str(cm.exception), r'...')

`

``

4851

+

``

4852

`+

def test_exclusive(self):

`

``

4853

`+

mutually exclusive group; intermixed works fine

`

``

4854

`+

parser = ErrorRaisingArgumentParser(prog='PROG')

`

``

4855

`+

group = parser.add_mutually_exclusive_group(required=True)

`

``

4856

`+

group.add_argument('--foo', action='store_true', help='FOO')

`

``

4857

`+

group.add_argument('--spam', help='SPAM')

`

``

4858

`+

parser.add_argument('badger', nargs='*', default='X', help='BADGER')

`

``

4859

`+

args = parser.parse_intermixed_args('1 --foo 2'.split())

`

``

4860

`+

self.assertEqual(NS(badger=['1', '2'], foo=True, spam=None), args)

`

``

4861

`+

self.assertRaises(ArgumentParserError, parser.parse_intermixed_args, '1 2'.split())

`

``

4862

`+

self.assertEqual(group.required, True)

`

``

4863

+

``

4864

`+

def test_exclusive_incompatible(self):

`

``

4865

`+

mutually exclusive group including positional - fail

`

``

4866

`+

parser = ErrorRaisingArgumentParser(prog='PROG')

`

``

4867

`+

group = parser.add_mutually_exclusive_group(required=True)

`

``

4868

`+

group.add_argument('--foo', action='store_true', help='FOO')

`

``

4869

`+

group.add_argument('--spam', help='SPAM')

`

``

4870

`+

group.add_argument('badger', nargs='*', default='X', help='BADGER')

`

``

4871

`+

self.assertRaises(TypeError, parser.parse_intermixed_args, [])

`

``

4872

`+

self.assertEqual(group.required, True)

`

``

4873

+

``

4874

`+

class TestIntermixedMessageContentError(TestCase):

`

``

4875

`+

case where Intermixed gives different error message

`

``

4876

`+

error is raised by 1st parsing step

`

``

4877

`+

def test_missing_argument_name_in_message(self):

`

``

4878

`+

parser = ErrorRaisingArgumentParser(prog='PROG', usage='')

`

``

4879

`+

parser.add_argument('req_pos', type=str)

`

``

4880

`+

parser.add_argument('-req_opt', type=int, required=True)

`

``

4881

+

``

4882

`+

with self.assertRaises(ArgumentParserError) as cm:

`

``

4883

`+

parser.parse_args([])

`

``

4884

`+

msg = str(cm.exception)

`

``

4885

`+

self.assertRegex(msg, 'req_pos')

`

``

4886

`+

self.assertRegex(msg, 'req_opt')

`

``

4887

+

``

4888

`+

with self.assertRaises(ArgumentParserError) as cm:

`

``

4889

`+

parser.parse_intermixed_args([])

`

``

4890

`+

msg = str(cm.exception)

`

``

4891

`+

self.assertNotRegex(msg, 'req_pos')

`

``

4892

`+

self.assertRegex(msg, 'req_opt')

`

``

4893

+

4807

4894

`# ==========================

`

4808

4895

`# add_argument metavar tests

`

4809

4896

`# ==========================

`