Skip to content

Commit

Permalink
Change some ValueError to TypeError.
Browse files Browse the repository at this point in the history
  • Loading branch information
serhiy-storchaka committed Oct 30, 2024
1 parent 27964f7 commit fccf382
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 21 deletions.
16 changes: 8 additions & 8 deletions Lib/argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -1429,8 +1429,8 @@ def add_argument(self, *args, **kwargs):
chars = self.prefix_chars
if not args or len(args) == 1 and args[0][0] not in chars:
if args and 'dest' in kwargs:
raise ValueError('dest supplied twice for positional argument,'
' did you mean metavar?')
raise TypeError('dest supplied twice for positional argument,'
' did you mean metavar?')
kwargs = self._get_positional_kwargs(*args, **kwargs)

# otherwise, we're adding an optional argument
Expand All @@ -1449,7 +1449,7 @@ def add_argument(self, *args, **kwargs):
action_name = kwargs.get('action')
action_class = self._pop_action_class(kwargs)
if not callable(action_class):
raise ValueError('unknown action "%s"' % (action_class,))
raise ValueError('unknown action {action_class!r}')
action = action_class(**kwargs)

# raise an error if action for positional argument does not
Expand All @@ -1460,11 +1460,11 @@ def add_argument(self, *args, **kwargs):
# raise an error if the action type is not callable
type_func = self._registry_get('type', action.type, action.type)
if not callable(type_func):
raise ValueError('%r is not callable' % (type_func,))
raise TypeError(f'{type_func!r} is not callable')

if type_func is FileType:
raise ValueError('%r is a FileType class object, instance of it'
' must be passed' % (type_func,))
raise TypeError(f'{type_func!r} is a FileType class object, '
f'instance of it must be passed')

# raise an error if the metavar does not match the type
if hasattr(self, "_get_formatter"):
Expand Down Expand Up @@ -1599,7 +1599,7 @@ def _get_optional_kwargs(self, *args, **kwargs):
dest = dest_option_string.lstrip(self.prefix_chars)
if not dest:
msg = f'dest= is required for options like {option_string!r}'
raise ValueError(msg)
raise TypeError(msg)
dest = dest.replace('-', '_')

# return the updated keyword arguments
Expand Down Expand Up @@ -2562,7 +2562,7 @@ def _get_values(self, action, arg_strings):
def _get_value(self, action, arg_string):
type_func = self._registry_get('type', action.type, action.type)
if not callable(type_func):
raise RuntimeError('%r is not callable' % (type_func,))
raise TypeError(f'{type_func!r} is not callable')

# convert the value to the appropriate type
try:
Expand Down
31 changes: 19 additions & 12 deletions Lib/test/test_argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -2381,10 +2381,10 @@ def test_modified_invalid_action(self):
action = parser.add_argument('--foo')
# Someone got crazy and did this
action.type = 1
self.assertRaisesRegex(RuntimeError, '1 is not callable',
self.assertRaisesRegex(TypeError, '1 is not callable',
parser.parse_args, ['--foo', 'bar'])
action.type = ()
self.assertRaisesRegex(RuntimeError, r'\(\) is not callable',
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
Expand Down Expand Up @@ -5547,20 +5547,27 @@ def test_missing_destination(self):
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')

Expand All @@ -5575,7 +5582,7 @@ def test_invalid_help(self):
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?',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Fix exceptions in the :mod:`argparse` module so that 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.
errors in the program. TypeError is now raised instead of ValueError for
some logical errors.

0 comments on commit fccf382

Please sign in to comment.