Skip to content

Commit 93d7161

Browse files
committed
Updates based on Serhiy's feedback
1 parent 43234de commit 93d7161

File tree

5 files changed

+95
-57
lines changed

5 files changed

+95
-57
lines changed

Doc/howto/argparse-optparse.rst

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,8 @@
66
Upgrading optparse code
77
==========================
88

9-
Originally, the :mod:`argparse` module had attempted to maintain compatibility
10-
with :mod:`optparse`. However, :mod:`optparse` was difficult to extend
11-
transparently, particularly with the changes required to support
12-
``nargs=`` specifiers and better usage messages. When most everything in
13-
:mod:`optparse` had either been copy-pasted over or monkey-patched, it no
14-
longer seemed practical to try to maintain the backwards compatibility.
15-
16-
The :mod:`argparse` module improves on the :mod:`optparse`
17-
module in a number of ways including:
9+
The :mod:`argparse` module offers several higher level features not natively
10+
provided by the :mod:`optparse` module, including:
1811

1912
* Handling positional arguments.
2013
* Supporting subcommands.
@@ -23,6 +16,13 @@ module in a number of ways including:
2316
* Producing more informative usage messages.
2417
* Providing a much simpler interface for custom ``type`` and ``action``.
2518

19+
Originally, the :mod:`argparse` module attempted to maintain compatibility
20+
with :mod:`optparse`. However, :mod:`optparse` was difficult to extend
21+
transparently, particularly with the changes required to support
22+
``nargs=`` specifiers and better usage messages. When most everything in
23+
:mod:`optparse` had either been copy-pasted over or monkey-patched, it no
24+
longer seemed practical to try to maintain the backwards compatibility.
25+
2626
A partial upgrade path from :mod:`optparse` to :mod:`argparse`:
2727

2828
* Replace all :meth:`optparse.OptionParser.add_option` calls with

Doc/howto/argparse.rst

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,15 @@ recommended command-line parsing module in the Python standard library.
1313

1414
.. note::
1515

16-
There are two other modules that fulfill the same task, namely
17-
:mod:`getopt` (an equivalent for ``getopt()`` from the C
18-
language) and the lower level :mod:`optparse` module.
19-
Note also that :mod:`argparse` is based on :mod:`optparse`,
20-
and therefore very similar in terms of usage.
16+
The standard library includes two other libraries directly related
17+
to command-line parameter processing: the lower level :mod:`optparse`
18+
module (which may require more code to configure for a given application,
19+
but also allows an application to request behaviors that ``argparse``
20+
doesn't support), and the very low level :mod:`getopt` (which specifically
21+
serves as an equivalent to ``getopt()`` from the C language).
22+
While neither of those modules is covered directly in this guide, many of
23+
the core concepts in ``argparse`` first originated in ``optparse``, so
24+
some aspects of this tutorial will also be relevant to ``optparse`` users.
2125

2226

2327
Concepts

Doc/library/argparse.rst

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@
1919
lower level :mod:`optparse` module serves as a better foundation for
2020
that use case. ``optparse`` (or one of the third party libraries
2121
based on it) may also be worth considering for applications where
22-
stricter adherence to common Unix and Linux command line interface
23-
conventions around the handling of option parameter values that start
24-
with ``-`` is desired.
22+
``argparse`` doesn't support behaviors that the application requires
23+
(such as entirely disabling support for interspersed options and
24+
positional arguments, or stricter adherence to common Unix and Linux
25+
command line interface conventions related to the handling of option
26+
parameter values that start with ``-``).
2527

2628
--------------
2729

Doc/library/getopt.rst

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99

1010
.. note::
1111

12-
The :mod:`getopt` module is a parser for command line options whose API is
13-
designed to be familiar to users of the C :c:func:`!getopt` function. Users who
14-
are unfamiliar with the C :c:func:`!getopt` function or who would like to write
15-
less code and get better help and error messages should consider using the
16-
:mod:`argparse` module instead.
12+
This module is considered feature complete. A more object-oriented and
13+
extensible alternative to this API is provided in the :mod:`optparse`
14+
module. Further functional enhancements for command line parameter
15+
processing are provided either as third party modules on PyPI,
16+
or else as features in the :mod:`argparse` module.
1717

1818
--------------
1919

@@ -23,6 +23,12 @@ the special meanings of arguments of the form '``-``' and '``--``'). Long
2323
options similar to those supported by GNU software may be used as well via an
2424
optional third argument.
2525

26+
Users who are unfamiliar with the Unix :c:func:`!getopt` function should consider
27+
using the :mod:`argparse` module instead. Users who are familiar with the Unix
28+
:c:func:`!getopt` function, but would like to get equivalent behavior while
29+
writing less code and getting better help and error messages should consider
30+
using the :mod:`optparse` module.
31+
2632
This module provides two functions and an
2733
exception:
2834

@@ -150,29 +156,49 @@ and more informative help and error messages by using the :mod:`optparse` module
150156
import optparse
151157

152158
if __name__ == '__main__':
153-
parser = optparse.OptionParser()
154-
parser.add_option('-o', '--output')
155-
parser.add_option('-v', dest='verbose', action='store_true')
156-
opts, args = parser.parse_args()
157-
process(args, output=opts.output, verbose=opts.verbose)
158-
159-
An equivalent command line interface for this simple case can also be produced
160-
by using the :mod:`argparse` module::
161-
162-
import argparse
163-
164-
if __name__ == '__main__':
165-
parser = argparse.ArgumentParser()
166-
parser.add_argument('-o', '--output')
167-
parser.add_argument('-v', dest='verbose', action='store_true')
168-
args = parser.parse_args()
169-
# ... do something with args.output ...
170-
# ... do something with args.verbose ..
171-
172-
In more complex cases (such as options which accept values), the behaviour
173-
of the ``argparse`` version may diverge from that of the ``getopt`` and
174-
``optparse`` versions due to the way ``argparse`` handles parameter
175-
values that start with ``-``.
159+
parser = optparse.OptionParser()
160+
parser.add_option('-o', '--output')
161+
parser.add_option('-v', dest='verbose', action='store_true')
162+
opts, args = parser.parse_args()
163+
process(args, output=opts.output, verbose=opts.verbose)
164+
165+
A roughly equivalent command line interface for this case can also be
166+
produced by using the :mod:`argparse` module::
167+
168+
import argparse
169+
170+
if __name__ == '__main__':
171+
parser = argparse.ArgumentParser()
172+
parser.add_argument('-o', '--output')
173+
parser.add_argument('-v', dest='verbose', action='store_true')
174+
parser.add_argument('rest', nargs='*')
175+
args = parser.parse_args()
176+
process(args.rest, output=args.output, verbose=args.verbose)
177+
178+
However, unlike the ``optparse`` example, this ``argparse`` example will
179+
handle some parameter combinations differently from the way the ``getopt``
180+
version would handle them. For example (amongst other differences):
181+
182+
* supplying ``-o -v`` gives ``output="-v"`` and ``verbose=False``
183+
for both ``getopt`` and ``optparse``,
184+
but a usage error with ``argparse``
185+
(complaining that no value has been supplied for ``-o/--output``,
186+
since ``-v`` is interpreted as meaning the verbosity flag)
187+
* similarly, supplying ``-o --`` gives ``output="--"`` and ``args=()``
188+
for both ``getopt`` and ``optparse``,
189+
but a usage error with ``argparse``
190+
(also complaining that no value has been supplied for ``-o/--output``,
191+
since ``--`` is interpreted as terminating the option processing
192+
and treating all remaining values as positional arguments)
193+
* supplying ``-o=foo`` gives ``output="=foo"``
194+
for both ``getopt`` and ``optparse``,
195+
but gives ``output="foo"`` with ``argparse``
196+
(since ``=`` is special cased as an alternative separator for
197+
option parameter values)
198+
199+
Whether these differing behaviors in the ``argparse`` version are
200+
considered desirable or a problem will depend on the specific command line
201+
application use case.
176202

177203
.. seealso::
178204

Doc/library/optparse.rst

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,14 @@
1212

1313
.. note::
1414

15-
:mod:`argparse` (rather than this module) is the recommended standard
16-
library module for implementing command line applications unless one
15+
This module is considered feature complete. Further functional enhancements for
16+
command line parameter processing are provided either as third party modules on
17+
PyPI, or else as features in the :mod:`argparse` module.
18+
19+
.. note::
20+
21+
The higher level :mod:`argparse` (rather than this module) is the recommended
22+
standard library module for implementing command line applications unless one
1723
of the following caveats applies:
1824

1925
* the application requires additional control over the way options and
@@ -24,24 +30,24 @@
2430
exact way it works in practice is undesirable for some use cases)
2531
* the application requires additional control over the handling of options
2632
which accept parameter values that may start with ``-`` (such as delegated
27-
options to be passed to invoked subprocesses).
33+
options to be passed to invoked subprocesses)
34+
* the application requires some other command line parameter processing
35+
behavior which ``argparse`` does not support, but which can be implemented
36+
in terms of the lower level interface offered by ``optparse``
2837

2938
These ``argparse`` caveats also mean that :mod:`optparse` is likely to
3039
provide a better foundation for library authors *writing* third party
3140
command line argument processing libraries.
3241

3342
.. seealso::
3443

35-
The :pypi:`"click" package <click>` is an ``optparse`` based third party
36-
argument processing library which allows command line applications to be
37-
developed as a set of appropriately decorated command implementation
38-
functions.
39-
40-
.. seealso::
44+
:pypi:`click` is a third party argument processing library (originally
45+
based on ``optparse``), which allows command line applications to be
46+
developed as a set of decorated command implementation functions.
4147

42-
The :pypi:`"Typer" package <click>` is a ``click`` based third party
43-
argument processing library which allows the use of annotated Python
44-
type hints to define an application's command line interface.
48+
Other third party libraries, such as :pypi:`typer` or :pypi:`msgspec-click`,
49+
allow command line interfaces to be specified in ways that effectively
50+
integrate with static checking of Python type annotations.
4551

4652
--------------
4753

0 commit comments

Comments
 (0)