Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(50)

Delta Between Two Patch Sets: Lib/test/test_argparse.py

Issue 14191: argparse: nargs='*' doesn't get out-of-order positional parameters
Left Patch Set: Created 8 years ago
Right Patch Set: Created 6 years, 10 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « Lib/argparse.py ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 # Author: Steven J. Bethard <steven.bethard@gmail.com>. 1 # Author: Steven J. Bethard <steven.bethard@gmail.com>.
2 2
3 import codecs 3 import codecs
4 import inspect 4 import inspect
5 import os 5 import os
6 import shutil 6 import shutil
7 import stat 7 import stat
8 import sys 8 import sys
9 import textwrap 9 import textwrap
10 import tempfile 10 import tempfile
(...skipping 4696 matching lines...) Expand 10 before | Expand all | Expand 10 after
4707 parser = argparse.ArgumentParser() 4707 parser = argparse.ArgumentParser()
4708 parser.add_argument('-v', nargs='?', const=1, type=int) 4708 parser.add_argument('-v', nargs='?', const=1, type=int)
4709 parser.add_argument('--spam', action='store_false') 4709 parser.add_argument('--spam', action='store_false')
4710 parser.add_argument('badger') 4710 parser.add_argument('badger')
4711 4711
4712 argv = ["B", "C", "--foo", "-v", "3", "4"] 4712 argv = ["B", "C", "--foo", "-v", "3", "4"]
4713 args, extras = parser.parse_known_args(argv) 4713 args, extras = parser.parse_known_args(argv)
4714 self.assertEqual(NS(v=3, spam=True, badger="B"), args) 4714 self.assertEqual(NS(v=3, spam=True, badger="B"), args)
4715 self.assertEqual(["C", "--foo", "4"], extras) 4715 self.assertEqual(["C", "--foo", "4"], extras)
4716 4716
4717 # ===========================
4718 # parse_intermixed_args tests
4719 # ===========================
4720
4721 class TestIntermixedArgs(TestCase):
4722 def test_basic(self):
4723 # test parsing intermixed optionals and positionals
4724 parser = argparse.ArgumentParser(prog='PROG')
4725 parser.add_argument('--foo', dest='foo')
4726 bar = parser.add_argument('--bar', dest='bar', required=True)
4727 parser.add_argument('cmd')
4728 parser.add_argument('rest', nargs='*', type=int)
4729 argv = 'cmd --foo x 1 --bar y 2 3'.split()
4730 args = parser.parse_intermixed_args(argv)
4731 # rest gets [1,2,3] despite the foo and bar strings
4732 self.assertEqual(NS(bar='y', cmd='cmd', foo='x', rest=[1, 2, 3]), args)
4733
4734 args, extras = parser.parse_known_args(argv)
4735 # cannot parse the '1,2,3'
4736 self.assertEqual(NS(bar='y', cmd='cmd', foo='x', rest=[]), args)
4737 self.assertEqual(["1", "2", "3"], extras)
4738
4739 argv = 'cmd --foo x 1 --error 2 --bar y 3'.split()
4740 args, extras = parser.parse_known_intermixed_args(argv)
4741 # unknown optionals go into extras
4742 self.assertEqual(NS(bar='y', cmd='cmd', foo='x', rest=[1]), args)
4743 self.assertEqual(['--error', '2', '3'], extras)
4744
4745 # restores attributes that were temporarily changed
4746 self.assertIsNone(parser.usage)
4747 self.assertEqual(bar.required, True)
4748
4749 def test_remainder(self):
4750 # Intermixed and remainder are incompatible
4751 parser = ErrorRaisingArgumentParser(prog='PROG')
4752 parser.add_argument('-z')
4753 parser.add_argument('x')
4754 parser.add_argument('y', nargs='...')
4755 argv = 'X A B -z Z'.split()
4756 # intermixed fails with '...' (also 'A...')
4757 # self.assertRaises(TypeError, parser.parse_intermixed_args, argv)
4758 with self.assertRaises(TypeError) as cm:
4759 parser.parse_intermixed_args(argv)
4760 self.assertRegex(str(cm.exception), '\.\.\.')
4761
4762 def test_exclusive(self):
4763 # mutually exclusive group; intermixed works fine
4764 parser = ErrorRaisingArgumentParser(prog='PROG')
4765 group = parser.add_mutually_exclusive_group(required=True)
4766 group.add_argument('--foo', action='store_true', help='FOO')
4767 group.add_argument('--spam', help='SPAM')
4768 parser.add_argument('badger', nargs='*', default='X', help='BADGER')
4769 args = parser.parse_intermixed_args('1 --foo 2'.split())
4770 self.assertEqual(NS(badger=['1', '2'], foo=True, spam=None), args)
4771 self.assertRaises(ArgumentParserError, parser.parse_intermixed_args, '1 2'.split())
4772 self.assertEqual(group.required, True)
4773
4774 def test_exclusive_incompatible(self):
4775 # mutually exclusive group including positional - fail
4776 parser = ErrorRaisingArgumentParser(prog='PROG')
4777 group = parser.add_mutually_exclusive_group(required=True)
4778 group.add_argument('--foo', action='store_true', help='FOO')
4779 group.add_argument('--spam', help='SPAM')
4780 group.add_argument('badger', nargs='*', default='X', help='BADGER')
4781 self.assertRaises(TypeError, parser.parse_intermixed_args, [])
4782 self.assertEqual(group.required, True)
4783
4784 class TestIntermixedMessageContentError(TestCase):
4785 # case where Intermixed gives different error message
4786 # error is raised by 1st parsing step
4787 def test_missing_argument_name_in_message(self):
4788 parser = ErrorRaisingArgumentParser(prog='PROG', usage='')
4789 parser.add_argument('req_pos', type=str)
4790 parser.add_argument('-req_opt', type=int, required=True)
4791
4792 with self.assertRaises(ArgumentParserError) as cm:
4793 parser.parse_args([])
4794 msg = str(cm.exception)
4795 self.assertRegex(msg, 'req_pos')
4796 self.assertRegex(msg, 'req_opt')
4797
4798 with self.assertRaises(ArgumentParserError) as cm:
4799 parser.parse_intermixed_args([])
4800 msg = str(cm.exception)
4801 self.assertNotRegex(msg, 'req_pos')
4802 self.assertRegex(msg, 'req_opt')
4803
4717 # ========================== 4804 # ==========================
4718 # add_argument metavar tests 4805 # add_argument metavar tests
4719 # ========================== 4806 # ==========================
4720 4807
4721 class TestAddArgumentMetavar(TestCase): 4808 class TestAddArgumentMetavar(TestCase):
4722 4809
4723 EXPECTED_MESSAGE = "length of metavar tuple does not match nargs" 4810 EXPECTED_MESSAGE = "length of metavar tuple does not match nargs"
4724 4811
4725 def do_test_no_exception(self, nargs, metavar): 4812 def do_test_no_exception(self, nargs, metavar):
4726 parser = argparse.ArgumentParser() 4813 parser = argparse.ArgumentParser()
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
4907 def test_main(): 4994 def test_main():
4908 support.run_unittest(__name__) 4995 support.run_unittest(__name__)
4909 # Remove global references to avoid looking like we have refleaks. 4996 # Remove global references to avoid looking like we have refleaks.
4910 RFile.seen = {} 4997 RFile.seen = {}
4911 WFile.seen = set() 4998 WFile.seen = set()
4912 4999
4913 5000
4914 5001
4915 if __name__ == '__main__': 5002 if __name__ == '__main__':
4916 test_main() 5003 test_main()
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+