@@ -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
# ==========================
0 commit comments