bpo-42572: Improve argparse docs for the type parameter. (GH-23849)
This commit is contained in:
parent
a44ce6c9f7
commit
b0398a4b7f
|
@ -1050,63 +1050,70 @@ command-line argument was not present::
|
||||||
type
|
type
|
||||||
^^^^
|
^^^^
|
||||||
|
|
||||||
By default, :class:`ArgumentParser` objects read command-line arguments in as simple
|
By default, the parser reads command-line arguments in as simple
|
||||||
strings. However, quite often the command-line string should instead be
|
strings. However, quite often the command-line string should instead be
|
||||||
interpreted as another type, like a :class:`float` or :class:`int`. The
|
interpreted as another type, such as a :class:`float` or :class:`int`. The
|
||||||
``type`` keyword argument of :meth:`~ArgumentParser.add_argument` allows any
|
``type`` keyword for :meth:`~ArgumentParser.add_argument` allows any
|
||||||
necessary type-checking and type conversions to be performed. Common built-in
|
necessary type-checking and type conversions to be performed.
|
||||||
types and functions can be used directly as the value of the ``type`` argument::
|
|
||||||
|
|
||||||
>>> parser = argparse.ArgumentParser()
|
If the type_ keyword is used with the default_ keyword, the type converter
|
||||||
>>> parser.add_argument('foo', type=int)
|
is only applied if the default is a string.
|
||||||
>>> parser.add_argument('bar', type=open)
|
|
||||||
>>> parser.parse_args('2 temp.txt'.split())
|
|
||||||
Namespace(bar=<_io.TextIOWrapper name='temp.txt' encoding='UTF-8'>, foo=2)
|
|
||||||
|
|
||||||
See the section on the default_ keyword argument for information on when the
|
The argument to ``type`` can be any callable that accepts a single string.
|
||||||
``type`` argument is applied to default arguments.
|
If the function raises :exc:`ArgumentTypeError`, :exc:`TypeError`, or
|
||||||
|
:exc:`ValueError`, the exception is caught and a nicely formatted error
|
||||||
|
message is displayed. No other exception types are handled.
|
||||||
|
|
||||||
To ease the use of various types of files, the argparse module provides the
|
Common built-in types and functions can be used as type converters:
|
||||||
factory FileType which takes the ``mode=``, ``bufsize=``, ``encoding=`` and
|
|
||||||
``errors=`` arguments of the :func:`open` function. For example,
|
|
||||||
``FileType('w')`` can be used to create a writable file::
|
|
||||||
|
|
||||||
>>> parser = argparse.ArgumentParser()
|
.. testcode::
|
||||||
>>> parser.add_argument('bar', type=argparse.FileType('w'))
|
|
||||||
>>> parser.parse_args(['out.txt'])
|
|
||||||
Namespace(bar=<_io.TextIOWrapper name='out.txt' encoding='UTF-8'>)
|
|
||||||
|
|
||||||
``type=`` can take any callable that takes a single string argument and returns
|
import argparse
|
||||||
the converted value::
|
import pathlib
|
||||||
|
|
||||||
>>> def perfect_square(string):
|
parser = argparse.ArgumentParser()
|
||||||
... value = int(string)
|
parser.add_argument('count', type=int)
|
||||||
... sqrt = math.sqrt(value)
|
parser.add_argument('distance', type=float)
|
||||||
... if sqrt != int(sqrt):
|
parser.add_argument('street', type=ascii)
|
||||||
... msg = "%r is not a perfect square" % string
|
parser.add_argument('code_point', type=ord)
|
||||||
... raise argparse.ArgumentTypeError(msg)
|
parser.add_argument('source_file', type=open)
|
||||||
... return value
|
parser.add_argument('dest_file', type=argparse.FileType('w', encoding='latin-1'))
|
||||||
|
parser.add_argument('datapath', type=pathlib.Path)
|
||||||
|
|
||||||
|
User defined functions can be used as well:
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
|
||||||
|
>>> def hyphenated(string):
|
||||||
|
... return '-'.join([word[:4] for word in string.casefold().split()])
|
||||||
...
|
...
|
||||||
>>> parser = argparse.ArgumentParser(prog='PROG')
|
>>> parser = argparse.ArgumentParser()
|
||||||
>>> parser.add_argument('foo', type=perfect_square)
|
>>> _ = parser.add_argument('short_title', type=hyphenated)
|
||||||
>>> parser.parse_args(['9'])
|
>>> parser.parse_args(['"The Tale of Two Cities"'])
|
||||||
Namespace(foo=9)
|
Namespace(short_title='"the-tale-of-two-citi')
|
||||||
>>> parser.parse_args(['7'])
|
|
||||||
usage: PROG [-h] foo
|
|
||||||
PROG: error: argument foo: '7' is not a perfect square
|
|
||||||
|
|
||||||
The choices_ keyword argument may be more convenient for type checkers that
|
The :func:`bool` function is not recommended as a type converter. All it does
|
||||||
simply check against a range of values::
|
is convert empty strings to ``False`` and non-empty strings to ``True``.
|
||||||
|
This is usually not what is desired.
|
||||||
|
|
||||||
>>> parser = argparse.ArgumentParser(prog='PROG')
|
In general, the ``type`` keyword is a convenience that should only be used for
|
||||||
>>> parser.add_argument('foo', type=int, choices=range(5, 10))
|
simple conversions that can only raise one of the three supported exceptions.
|
||||||
>>> parser.parse_args(['7'])
|
Anything with more interesting error-handling or resource management should be
|
||||||
Namespace(foo=7)
|
done downstream after the arguments are parsed.
|
||||||
>>> parser.parse_args(['11'])
|
|
||||||
usage: PROG [-h] {5,6,7,8,9}
|
|
||||||
PROG: error: argument foo: invalid choice: 11 (choose from 5, 6, 7, 8, 9)
|
|
||||||
|
|
||||||
See the choices_ section for more details.
|
For example, JSON or YAML conversions have complex error cases that require
|
||||||
|
better reporting than can be given by the ``type`` keyword. An
|
||||||
|
:exc:`~json.JSONDecodeError` would not be well formatted and a
|
||||||
|
:exc:`FileNotFound` exception would not be handled at all.
|
||||||
|
|
||||||
|
Even :class:`~argparse.FileType` has its limitations for use with the ``type``
|
||||||
|
keyword. If one argument uses *FileType* and then a subsequent argument fails,
|
||||||
|
an error is reported but the file is not automatically closed. In this case, it
|
||||||
|
would be better to wait until after the parser has run and then use the
|
||||||
|
:keyword:`with`-statement to manage the files.
|
||||||
|
|
||||||
|
For type checkers that simply check against a fixed set of values, consider
|
||||||
|
using the choices_ keyword instead.
|
||||||
|
|
||||||
|
|
||||||
choices
|
choices
|
||||||
|
|
Loading…
Reference in New Issue