Skip to content

Commit 831b6de

Browse files
pythongh-126180: Remove getopt and optparse deprecation notices (pythonGH-126227)
* Remove getopt and optparse deprecation notices * Add new docs sections for command line app helper libraries * Add guidance on choosing a CLI parsing library to the optparse docs * Link to the new guidance from the argparse and getopt docs * Reword intro in docs section for superseded stdlib modules * Reframe the optparse->argparse guide as a migration guide rather than as an upgrade guide --------- Co-authored-by: Serhiy Storchaka <[email protected]>
1 parent 9d3a8f4 commit 831b6de

12 files changed

+266
-65
lines changed

Doc/howto/argparse-optparse.rst

+23-13
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
11
.. currentmodule:: argparse
22

33
.. _upgrading-optparse-code:
4+
.. _migrating-optparse-code:
45

5-
==========================
6-
Upgrading optparse code
7-
==========================
6+
============================================
7+
Migrating ``optparse`` code to ``argparse``
8+
============================================
89

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:
10+
The :mod:`argparse` module offers several higher level features not natively
11+
provided by the :mod:`optparse` module, including:
1812

1913
* Handling positional arguments.
2014
* Supporting subcommands.
@@ -23,7 +17,23 @@ module in a number of ways including:
2317
* Producing more informative usage messages.
2418
* Providing a much simpler interface for custom ``type`` and ``action``.
2519

26-
A partial upgrade path from :mod:`optparse` to :mod:`argparse`:
20+
Originally, the :mod:`argparse` module attempted to maintain compatibility
21+
with :mod:`optparse`. However, the fundamental design differences between
22+
supporting declarative command line option processing (while leaving positional
23+
argument processing to application code), and supporting both named options
24+
and positional arguments in the declarative interface mean that the
25+
API has diverged from that of ``optparse`` over time.
26+
27+
As described in :ref:`choosing-an-argument-parser`, applications that are
28+
currently using :mod:`optparse` and are happy with the way it works can
29+
just continue to use ``optparse``.
30+
31+
Application developers that are considering migrating should also review
32+
the list of intrinsic behavioural differences described in that section
33+
before deciding whether or not migration is desirable.
34+
35+
For applications that do choose to migrate from :mod:`optparse` to :mod:`argparse`,
36+
the following suggestions should be helpful:
2737

2838
* Replace all :meth:`optparse.OptionParser.add_option` calls with
2939
:meth:`ArgumentParser.add_argument` calls.

Doc/howto/argparse.rst

+10-5
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,16 @@ 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 deprecated :mod:`optparse`.
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 the :c:func:`!getopt` family of functions
22+
available to C programmers).
23+
While neither of those modules is covered directly in this guide, many of
24+
the core concepts in ``argparse`` first originated in ``optparse``, so
25+
some aspects of this tutorial will also be relevant to ``optparse`` users.
2126

2227

2328
Concepts

Doc/library/allos.rst

-5
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,9 @@ but they are available on most other systems as well. Here's an overview:
1515
os.rst
1616
io.rst
1717
time.rst
18-
argparse.rst
1918
logging.rst
2019
logging.config.rst
2120
logging.handlers.rst
22-
getpass.rst
23-
curses.rst
24-
curses.ascii.rst
25-
curses.panel.rst
2621
platform.rst
2722
errno.rst
2823
ctypes.rst

Doc/library/argparse.rst

+12
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,18 @@
1111

1212
**Source code:** :source:`Lib/argparse.py`
1313

14+
.. note::
15+
16+
While :mod:`argparse` is the default recommended standard library module
17+
for implementing basic command line applications, authors with more
18+
exacting requirements for exactly how their command line applications
19+
behave may find it doesn't provide the necessary level of control.
20+
Refer to :ref:`choosing-an-argument-parser` for alternatives to
21+
consider when ``argparse`` doesn't support behaviors that the application
22+
requires (such as entirely disabling support for interspersed options and
23+
positional arguments, or accepting option parameter values that start
24+
with ``-`` even when they correspond to another defined option).
25+
1426
--------------
1527

1628
.. sidebar:: Tutorial

Doc/library/cmdlinelibs.rst

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
.. _cmdlinelibs:
2+
3+
********************************
4+
Command Line Interface Libraries
5+
********************************
6+
7+
The modules described in this chapter assist with implementing
8+
command line and terminal interfaces for applications.
9+
10+
Here's an overview:
11+
12+
.. toctree::
13+
:maxdepth: 1
14+
15+
argparse.rst
16+
optparse.rst
17+
getpass.rst
18+
fileinput.rst
19+
curses.rst
20+
curses.ascii.rst
21+
curses.panel.rst

Doc/library/filesys.rst

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ in this chapter is:
1414

1515
pathlib.rst
1616
os.path.rst
17-
fileinput.rst
1817
stat.rst
1918
filecmp.rst
2019
tempfile.rst

Doc/library/getopt.rst

+38-16
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,13 @@
77

88
**Source code:** :source:`Lib/getopt.py`
99

10-
.. deprecated:: 3.13
11-
The :mod:`getopt` module is :term:`soft deprecated` and will not be
12-
developed further; development will continue with the :mod:`argparse`
13-
module.
14-
1510
.. note::
1611

17-
The :mod:`getopt` module is a parser for command line options whose API is
18-
designed to be familiar to users of the C :c:func:`!getopt` function. Users who
19-
are unfamiliar with the C :c:func:`!getopt` function or who would like to write
20-
less code and get better help and error messages should consider using the
21-
:mod:`argparse` module instead.
12+
This module is considered feature complete. A more declarative 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.
2217

2318
--------------
2419

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

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. See :ref:`choosing-an-argument-parser` for
31+
additional details.
32+
3133
This module provides two functions and an
3234
exception:
3335

@@ -194,13 +196,27 @@ In a script, typical usage is something like this:
194196
output = a
195197
else:
196198
assert False, "unhandled option"
197-
# ...
199+
process(args, output=output, verbose=verbose)
198200

199201
if __name__ == "__main__":
200202
main()
201203

202204
Note that an equivalent command line interface could be produced with less code
203-
and more informative help and error messages by using the :mod:`argparse` module:
205+
and more informative help and error messages by using the :mod:`optparse` module:
206+
207+
.. testcode::
208+
209+
import optparse
210+
211+
if __name__ == '__main__':
212+
parser = optparse.OptionParser()
213+
parser.add_option('-o', '--output')
214+
parser.add_option('-v', dest='verbose', action='store_true')
215+
opts, args = parser.parse_args()
216+
process(args, output=opts.output, verbose=opts.verbose)
217+
218+
A roughly equivalent command line interface for this case can also be
219+
produced by using the :mod:`argparse` module:
204220

205221
.. testcode::
206222

@@ -210,12 +226,18 @@ and more informative help and error messages by using the :mod:`argparse` module
210226
parser = argparse.ArgumentParser()
211227
parser.add_argument('-o', '--output')
212228
parser.add_argument('-v', dest='verbose', action='store_true')
229+
parser.add_argument('rest', nargs='*')
213230
args = parser.parse_args()
214-
# ... do something with args.output ...
215-
# ... do something with args.verbose ..
231+
process(args.rest, output=args.output, verbose=args.verbose)
232+
233+
See :ref:`choosing-an-argument-parser` for details on how the ``argparse``
234+
version of this code differs in behaviour from the ``optparse`` (and
235+
``getopt``) version.
216236

217237
.. seealso::
218238

219-
Module :mod:`argparse`
220-
Alternative command line option and argument parsing library.
239+
Module :mod:`optparse`
240+
Declarative command line option parsing.
221241

242+
Module :mod:`argparse`
243+
More opinionated command line option and argument parsing library.

Doc/library/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ the `Python Package Index <https://pypi.org>`_.
5555
fileformats.rst
5656
crypto.rst
5757
allos.rst
58+
cmdlinelibs.rst
5859
concurrency.rst
5960
ipc.rst
6061
netdata.rst

Doc/library/optparse.rst

+125-14
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,135 @@
33

44
.. module:: optparse
55
:synopsis: Command-line option parsing library.
6-
:deprecated:
76

87
.. moduleauthor:: Greg Ward <[email protected]>
98
.. sectionauthor:: Greg Ward <[email protected]>
109

1110
**Source code:** :source:`Lib/optparse.py`
1211

13-
.. deprecated:: 3.2
14-
The :mod:`optparse` module is :term:`soft deprecated` and will not be
15-
developed further; development will continue with the :mod:`argparse`
16-
module.
17-
1812
--------------
1913

14+
.. _choosing-an-argument-parser:
15+
16+
Choosing an argument parsing library
17+
------------------------------------
18+
19+
The standard library includes three argument parsing libraries:
20+
21+
* :mod:`getopt`: a module that closely mirrors the procedural C ``getopt`` API.
22+
Included in the standard library since before the initial Python 1.0 release.
23+
* :mod:`optparse`: a declarative replacement for ``getopt`` that
24+
provides equivalent functionality without requiring each application
25+
to implement its own procedural option parsing logic. Included
26+
in the standard library since the Python 2.3 release.
27+
* :mod:`argparse`: a more opinionated alternative to ``optparse`` that
28+
provides more functionality by default, at the expense of reduced application
29+
flexibility in controlling exactly how arguments are processed. Included in
30+
the standard library since the Python 2.7 and Python 3.2 releases.
31+
32+
In the absence of more specific argument parsing design constraints, :mod:`argparse`
33+
is the recommended choice for implementing command line applications, as it offers
34+
the highest level of baseline functionality with the least application level code.
35+
36+
:mod:`getopt` is retained almost entirely for backwards compatibility reasons.
37+
However, it also serves a niche use case as a tool for prototyping and testing
38+
command line argument handling in ``getopt``-based C applications.
39+
40+
:mod:`optparse` should be considered as an alternative to :mod:`argparse` in the
41+
following cases:
42+
43+
* an application is already using :mod:`optparse` and doesn't want to risk the
44+
subtle behavioural changes that may arise when migrating to :mod:`argparse`
45+
* the application requires additional control over the way options and
46+
positional parameters are interleaved on the command line (including
47+
the ability to disable the interleaving feature completely)
48+
* the application requires additional control over the incremental parsing
49+
of command line elements (while ``argparse`` does support this, the
50+
exact way it works in practice is undesirable for some use cases)
51+
* the application requires additional control over the handling of options
52+
which accept parameter values that may start with ``-`` (such as delegated
53+
options to be passed to invoked subprocesses)
54+
* the application requires some other command line parameter processing
55+
behavior which ``argparse`` does not support, but which can be implemented
56+
in terms of the lower level interface offered by ``optparse``
57+
58+
These considerations also mean that :mod:`optparse` is likely to provide a
59+
better foundation for library authors writing third party command line
60+
argument processing libraries.
61+
62+
As a concrete example, consider the following two command line argument
63+
parsing configurations, the first using ``optparse``, and the second
64+
using ``argparse``:
65+
66+
.. testcode::
67+
68+
import optparse
69+
70+
if __name__ == '__main__':
71+
parser = optparse.OptionParser()
72+
parser.add_option('-o', '--output')
73+
parser.add_option('-v', dest='verbose', action='store_true')
74+
opts, args = parser.parse_args()
75+
process(args, output=opts.output, verbose=opts.verbose)
76+
77+
.. testcode::
78+
79+
import argparse
80+
81+
if __name__ == '__main__':
82+
parser = argparse.ArgumentParser()
83+
parser.add_argument('-o', '--output')
84+
parser.add_argument('-v', dest='verbose', action='store_true')
85+
parser.add_argument('rest', nargs='*')
86+
args = parser.parse_args()
87+
process(args.rest, output=args.output, verbose=args.verbose)
88+
89+
The most obvious difference is that in the ``optparse`` version, the non-option
90+
arguments are processed separately by the application after the option processing
91+
is complete. In the ``argparse`` version, positional arguments are declared and
92+
processed in the same way as the named options.
93+
94+
However, the ``argparse`` version will also handle some parameter combination
95+
differently from the way the ``optparse`` version would handle them.
96+
For example (amongst other differences):
97+
98+
* supplying ``-o -v`` gives ``output="-v"`` and ``verbose=False``
99+
when using ``optparse``, but a usage error with ``argparse``
100+
(complaining that no value has been supplied for ``-o/--output``,
101+
since ``-v`` is interpreted as meaning the verbosity flag)
102+
* similarly, supplying ``-o --`` gives ``output="--"`` and ``args=()``
103+
when using ``optparse``, but a usage error with ``argparse``
104+
(also complaining that no value has been supplied for ``-o/--output``,
105+
since ``--`` is interpreted as terminating the option processing
106+
and treating all remaining values as positional arguments)
107+
* supplying ``-o=foo`` gives ``output="=foo"`` when using ``optparse``,
108+
but gives ``output="foo"`` with ``argparse`` (since ``=`` is special
109+
cased as an alternative separator for option parameter values)
110+
111+
Whether these differing behaviors in the ``argparse`` version are
112+
considered desirable or a problem will depend on the specific command line
113+
application use case.
114+
115+
.. seealso::
116+
117+
:pypi:`click` is a third party argument processing library (originally
118+
based on ``optparse``), which allows command line applications to be
119+
developed as a set of decorated command implementation functions.
120+
121+
Other third party libraries, such as :pypi:`typer` or :pypi:`msgspec-click`,
122+
allow command line interfaces to be specified in ways that more effectively
123+
integrate with static checking of Python type annotations.
124+
125+
126+
Introduction
127+
------------
128+
20129
:mod:`optparse` is a more convenient, flexible, and powerful library for parsing
21-
command-line options than the old :mod:`getopt` module. :mod:`optparse` uses a
22-
more declarative style of command-line parsing: you create an instance of
23-
:class:`OptionParser`, populate it with options, and parse the command
24-
line. :mod:`optparse` allows users to specify options in the conventional
130+
command-line options than the minimalist :mod:`getopt` module.
131+
:mod:`optparse` uses a more declarative style of command-line parsing:
132+
you create an instance of :class:`OptionParser`,
133+
populate it with options, and parse the command line.
134+
:mod:`optparse` allows users to specify options in the conventional
25135
GNU/POSIX syntax, and additionally generates usage and help messages for you.
26136

27137
Here's an example of using :mod:`optparse` in a simple script::
@@ -82,10 +192,11 @@ Background
82192
----------
83193

84194
:mod:`optparse` was explicitly designed to encourage the creation of programs
85-
with straightforward, conventional command-line interfaces. To that end, it
86-
supports only the most common command-line syntax and semantics conventionally
87-
used under Unix. If you are unfamiliar with these conventions, read this
88-
section to acquaint yourself with them.
195+
with straightforward command-line interfaces that follow the conventions
196+
established by the :c:func:`!getopt` family of functions available to C developers.
197+
To that end, it supports only the most common command-line syntax and semantics
198+
conventionally used under Unix. If you are unfamiliar with these conventions,
199+
reading this section will allow you to acquaint yourself with them.
89200

90201

91202
.. _optparse-terminology:

0 commit comments

Comments
 (0)