diff -r 8630fa732cf6 Lib/argparse.py --- a/Lib/argparse.py Thu Jan 17 17:07:17 2013 +0100 +++ b/Lib/argparse.py Thu Jan 17 21:27:42 2013 +0100 @@ -581,9 +581,11 @@ result = '...' elif action.nargs == PARSER: result = '%s ...' % get_metavar(1) - else: + elif isinstance(action.nargs, int): formats = ['%s' for _ in range(action.nargs)] result = ' '.join(formats) % get_metavar(action.nargs) + else: + raise ValueError("invalid value for nargs") return result def _expand_help(self, action): @@ -833,7 +835,7 @@ required=False, help=None, metavar=None): - if nargs == 0: + if isinstance(nargs, int) and nargs <= 0: raise ValueError('nargs for store actions must be > 0; if you ' 'have nothing to store, actions such as store ' 'true or store const may be more appropriate') @@ -925,7 +927,7 @@ required=False, help=None, metavar=None): - if nargs == 0: + if isinstance(nargs, int) and nargs <= 0: raise ValueError('nargs for append actions must be > 0; if arg ' 'strings are not supplying the value to append, ' 'the append const action may be more appropriate') diff -r 8630fa732cf6 Lib/test/test_argparse.py --- a/Lib/test/test_argparse.py Thu Jan 17 17:07:17 2013 +0100 +++ b/Lib/test/test_argparse.py Thu Jan 17 21:27:42 2013 +0100 @@ -4089,7 +4089,6 @@ class TestHelpMetavarTypeFormatter(HelpTestCase): - """""" def custom_type(string): return string @@ -4198,9 +4197,11 @@ def test_more_than_one_argument_actions(self): for action in ['store', 'append']: - # nargs=0 is disallowed + # nargs<=0 is disallowed self.assertValueError('-x', nargs=0, action=action) self.assertValueError('spam', nargs=0, action=action) + self.assertValueError('-x', nargs=-1, action=action) + self.assertValueError('spam', nargs=-1, action=action) # const is disallowed with non-optional arguments for nargs in [1, '*', '+']: @@ -4885,6 +4886,38 @@ def test_nargs_3_metavar_length3(self): self.do_test_no_exception(nargs=3, metavar=("1", "2", "3")) + +class TestInvalidNargs(TestCase): + + EXPECTED_INVALID_MESSAGE = "invalid value for nargs" + EXPECTED_RANGE_MESSAGE = "nargs for store actions must be > 0; if you " \ + "have nothing to store, actions such as store " \ + "true or store const may be more appropriate" + + def do_test_range_exception(self, nargs): + parser = argparse.ArgumentParser() + with self.assertRaises(ValueError) as cm: + parser.add_argument("--foo", nargs=nargs) + self.assertEqual(cm.exception.args[0], self.EXPECTED_RANGE_MESSAGE) + + def do_test_invalid_exception(self, nargs): + parser = argparse.ArgumentParser() + with self.assertRaises(ValueError) as cm: + parser.add_argument("--foo", nargs=nargs) + self.assertEqual(cm.exception.args[0], self.EXPECTED_INVALID_MESSAGE) + + # Unit tests for different values of nargs + + def test_nargs_alphabetic(self): + self.do_test_invalid_exception(nargs='a') + self.do_test_invalid_exception(nargs="abcd") + + def test_nargs_zero(self): + self.do_test_range_exception(nargs=0) + + def test_nargs_negative(self): + self.do_test_range_exception(nargs=-1) + # ============================ # from argparse import * tests # ============================