mirror of
https://github.com/python/cpython.git
synced 2025-08-30 21:48:47 +00:00
gh-126068: Fix exceptions in the argparse module (GH-126069)
* Only error messages for ArgumentError and ArgumentTypeError are now translated. * ArgumentError is now only used for command line errors, not for logical errors in the program. * TypeError is now raised instead of ValueError for some logical errors.
This commit is contained in:
parent
1f16df4bfe
commit
cc9a183993
4 changed files with 72 additions and 58 deletions
|
@ -2055,7 +2055,7 @@ class TestFileTypeMissingInitialization(TestCase):
|
|||
|
||||
def test(self):
|
||||
parser = argparse.ArgumentParser()
|
||||
with self.assertRaises(ValueError) as cm:
|
||||
with self.assertRaises(TypeError) as cm:
|
||||
parser.add_argument('-x', type=argparse.FileType)
|
||||
|
||||
self.assertEqual(
|
||||
|
@ -2377,11 +2377,24 @@ class TestInvalidAction(TestCase):
|
|||
self.assertRaises(NotImplementedError, parser.parse_args, ['--foo', 'bar'])
|
||||
|
||||
def test_modified_invalid_action(self):
|
||||
parser = ErrorRaisingArgumentParser()
|
||||
parser = argparse.ArgumentParser(exit_on_error=False)
|
||||
action = parser.add_argument('--foo')
|
||||
# Someone got crazy and did this
|
||||
action.type = 1
|
||||
self.assertRaises(ArgumentParserError, parser.parse_args, ['--foo', 'bar'])
|
||||
self.assertRaisesRegex(TypeError, '1 is not callable',
|
||||
parser.parse_args, ['--foo', 'bar'])
|
||||
action.type = ()
|
||||
self.assertRaisesRegex(TypeError, r'\(\) is not callable',
|
||||
parser.parse_args, ['--foo', 'bar'])
|
||||
# It is impossible to distinguish a TypeError raised due to a mismatch
|
||||
# of the required function arguments from a TypeError raised for an incorrect
|
||||
# argument value, and using the heavy inspection machinery is not worthwhile
|
||||
# as it does not reliably work in all cases.
|
||||
# Therefore, a generic ArgumentError is raised to handle this logical error.
|
||||
action.type = pow
|
||||
self.assertRaisesRegex(argparse.ArgumentError,
|
||||
"argument --foo: invalid pow value: 'bar'",
|
||||
parser.parse_args, ['--foo', 'bar'])
|
||||
|
||||
|
||||
# ================
|
||||
|
@ -2418,7 +2431,7 @@ class TestAddSubparsers(TestCase):
|
|||
else:
|
||||
subparsers_kwargs['help'] = 'command help'
|
||||
subparsers = parser.add_subparsers(**subparsers_kwargs)
|
||||
self.assertRaisesRegex(argparse.ArgumentError,
|
||||
self.assertRaisesRegex(ValueError,
|
||||
'cannot have multiple subparser arguments',
|
||||
parser.add_subparsers)
|
||||
|
||||
|
@ -5534,20 +5547,27 @@ class TestInvalidArgumentConstructors(TestCase):
|
|||
self.assertTypeError(action=action)
|
||||
|
||||
def test_invalid_option_strings(self):
|
||||
self.assertValueError('--')
|
||||
self.assertValueError('---')
|
||||
self.assertTypeError('-', errmsg='dest= is required')
|
||||
self.assertTypeError('--', errmsg='dest= is required')
|
||||
self.assertTypeError('---', errmsg='dest= is required')
|
||||
|
||||
def test_invalid_prefix(self):
|
||||
self.assertValueError('--foo', '+foo')
|
||||
self.assertValueError('--foo', '+foo',
|
||||
errmsg='must start with a character')
|
||||
|
||||
def test_invalid_type(self):
|
||||
self.assertValueError('--foo', type='int')
|
||||
self.assertValueError('--foo', type=(int, float))
|
||||
self.assertTypeError('--foo', type='int',
|
||||
errmsg="'int' is not callable")
|
||||
self.assertTypeError('--foo', type=(int, float),
|
||||
errmsg='is not callable')
|
||||
|
||||
def test_invalid_action(self):
|
||||
self.assertValueError('-x', action='foo')
|
||||
self.assertValueError('foo', action='baz')
|
||||
self.assertValueError('--foo', action=('store', 'append'))
|
||||
self.assertValueError('-x', action='foo',
|
||||
errmsg='unknown action')
|
||||
self.assertValueError('foo', action='baz',
|
||||
errmsg='unknown action')
|
||||
self.assertValueError('--foo', action=('store', 'append'),
|
||||
errmsg='unknown action')
|
||||
self.assertValueError('--foo', action="store-true",
|
||||
errmsg='unknown action')
|
||||
|
||||
|
@ -5562,7 +5582,7 @@ class TestInvalidArgumentConstructors(TestCase):
|
|||
def test_multiple_dest(self):
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(dest='foo')
|
||||
with self.assertRaises(ValueError) as cm:
|
||||
with self.assertRaises(TypeError) as cm:
|
||||
parser.add_argument('bar', dest='baz')
|
||||
self.assertIn('dest supplied twice for positional argument,'
|
||||
' did you mean metavar?',
|
||||
|
@ -5733,14 +5753,18 @@ class TestConflictHandling(TestCase):
|
|||
parser = argparse.ArgumentParser()
|
||||
sp = parser.add_subparsers()
|
||||
sp.add_parser('fullname', aliases=['alias'])
|
||||
self.assertRaises(argparse.ArgumentError,
|
||||
sp.add_parser, 'fullname')
|
||||
self.assertRaises(argparse.ArgumentError,
|
||||
sp.add_parser, 'alias')
|
||||
self.assertRaises(argparse.ArgumentError,
|
||||
sp.add_parser, 'other', aliases=['fullname'])
|
||||
self.assertRaises(argparse.ArgumentError,
|
||||
sp.add_parser, 'other', aliases=['alias'])
|
||||
self.assertRaisesRegex(ValueError,
|
||||
'conflicting subparser: fullname',
|
||||
sp.add_parser, 'fullname')
|
||||
self.assertRaisesRegex(ValueError,
|
||||
'conflicting subparser: alias',
|
||||
sp.add_parser, 'alias')
|
||||
self.assertRaisesRegex(ValueError,
|
||||
'conflicting subparser alias: fullname',
|
||||
sp.add_parser, 'other', aliases=['fullname'])
|
||||
self.assertRaisesRegex(ValueError,
|
||||
'conflicting subparser alias: alias',
|
||||
sp.add_parser, 'other', aliases=['alias'])
|
||||
|
||||
|
||||
# =============================
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue