@@ -1050,63 +1050,70 @@ command-line argument was not present::
10501050type
10511051^^^^
10521052
1053- By default, :class: ` ArgumentParser ` objects read command-line arguments in as simple
1053+ By default, the parser reads command-line arguments in as simple
10541054strings. However, quite often the command-line string should instead be
1055- interpreted as another type, like a :class: `float ` or :class: `int `. The
1056- ``type `` keyword argument of :meth: `~ArgumentParser.add_argument ` allows any
1057- necessary type-checking and type conversions to be performed. Common built-in
1058- types and functions can be used directly as the value of the ``type `` argument::
1055+ interpreted as another type, such as a :class: `float ` or :class: `int `. The
1056+ ``type `` keyword for :meth: `~ArgumentParser.add_argument ` allows any
1057+ necessary type-checking and type conversions to be performed.
10591058
1060- >>> parser = argparse.ArgumentParser()
1061- >>> parser.add_argument('foo', type=int)
1062- >>> parser.add_argument('bar', type=open)
1063- >>> parser.parse_args('2 temp.txt'.split())
1064- Namespace(bar=<_io.TextIOWrapper name='temp.txt' encoding='UTF-8'>, foo=2)
1059+ If the type _ keyword is used with the default _ keyword, the type converter
1060+ is only applied if the default is a string.
10651061
1066- See the section on the default _ keyword argument for information on when the
1067- ``type `` argument is applied to default arguments.
1062+ The argument to ``type `` can be any callable that accepts a single string.
1063+ If the function raises :exc: `ArgumentTypeError `, :exc: `TypeError `, or
1064+ :exc: `ValueError `, the exception is caught and a nicely formatted error
1065+ message is displayed. No other exception types are handled.
10681066
1069- To ease the use of various types of files, the argparse module provides the
1070- factory FileType which takes the ``mode= ``, ``bufsize= ``, ``encoding= `` and
1071- ``errors= `` arguments of the :func: `open ` function. For example,
1072- ``FileType('w') `` can be used to create a writable file::
1067+ Common built-in types and functions can be used as type converters:
10731068
1074- >>> parser = argparse.ArgumentParser()
1075- >>> parser.add_argument('bar', type=argparse.FileType('w'))
1076- >>> parser.parse_args(['out.txt'])
1077- Namespace(bar=<_io.TextIOWrapper name='out.txt' encoding='UTF-8'>)
1078-
1079- ``type= `` can take any callable that takes a single string argument and returns
1080- the converted value::
1081-
1082- >>> def perfect_square(string):
1083- ... value = int(string)
1084- ... sqrt = math.sqrt(value)
1085- ... if sqrt != int(sqrt):
1086- ... msg = "%r is not a perfect square" % string
1087- ... raise argparse.ArgumentTypeError(msg)
1088- ... return value
1089- ...
1090- >>> parser = argparse.ArgumentParser(prog='PROG')
1091- >>> parser.add_argument('foo', type=perfect_square)
1092- >>> parser.parse_args(['9'])
1093- Namespace(foo=9)
1094- >>> parser.parse_args(['7'])
1095- usage: PROG [-h] foo
1096- PROG: error: argument foo: '7' is not a perfect square
1069+ .. testcode ::
10971070
1098- The choices _ keyword argument may be more convenient for type checkers that
1099- simply check against a range of values::
1071+ import argparse
1072+ import pathlib
11001073
1101- >>> parser = argparse.ArgumentParser(prog='PROG')
1102- >>> parser.add_argument('foo', type=int, choices=range(5, 10))
1103- >>> parser.parse_args(['7'])
1104- Namespace(foo=7)
1105- >>> parser.parse_args(['11'])
1106- usage: PROG [-h] {5,6,7,8,9}
1107- PROG: error: argument foo: invalid choice: 11 (choose from 5, 6, 7, 8, 9)
1108-
1109- See the choices _ section for more details.
1074+ parser = argparse.ArgumentParser()
1075+ parser.add_argument('count', type=int)
1076+ parser.add_argument('distance', type=float)
1077+ parser.add_argument('street', type=ascii)
1078+ parser.add_argument('code_point', type=ord)
1079+ parser.add_argument('source_file', type=open)
1080+ parser.add_argument('dest_file', type=argparse.FileType('w', encoding='latin-1'))
1081+ parser.add_argument('datapath', type=pathlib.Path)
1082+
1083+ User defined functions can be used as well:
1084+
1085+ .. doctest ::
1086+
1087+ >>> def hyphenated (string ):
1088+ ... return ' -' .join([word[:4 ] for word in string.casefold().split()])
1089+ ...
1090+ >>> parser = argparse.ArgumentParser()
1091+ >>> _ = parser.add_argument(' short_title' , type = hyphenated)
1092+ >>> parser.parse_args([' "The Tale of Two Cities"' ])
1093+ Namespace(short_title='"the-tale-of-two-citi')
1094+
1095+ The :func: `bool ` function is not recommended as a type converter. All it does
1096+ is convert empty strings to ``False `` and non-empty strings to ``True ``.
1097+ This is usually not what is desired.
1098+
1099+ In general, the ``type `` keyword is a convenience that should only be used for
1100+ simple conversions that can only raise one of the three supported exceptions.
1101+ Anything with more interesting error-handling or resource management should be
1102+ done downstream after the arguments are parsed.
1103+
1104+ For example, JSON or YAML conversions have complex error cases that require
1105+ better reporting than can be given by the ``type `` keyword. An
1106+ :exc: `~json.JSONDecodeError ` would not be well formatted and a
1107+ :exc: `FileNotFound ` exception would not be handled at all.
1108+
1109+ Even :class: `~argparse.FileType ` has its limitations for use with the ``type ``
1110+ keyword. If one argument uses *FileType * and then a subsequent argument fails,
1111+ an error is reported but the file is not automatically closed. In this case, it
1112+ would be better to wait until after the parser has run and then use the
1113+ :keyword: `with `-statement to manage the files.
1114+
1115+ For type checkers that simply check against a fixed set of values, consider
1116+ using the choices _ keyword instead.
11101117
11111118
11121119choices
0 commit comments