Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-126180: Remove getopt and optparse deprecation notices #126227

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
2 changes: 1 addition & 1 deletion Doc/howto/argparse.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ recommended command-line parsing module in the Python standard library.

There are two other modules that fulfill the same task, namely
:mod:`getopt` (an equivalent for ``getopt()`` from the C
language) and the deprecated :mod:`optparse`.
language) and the lower level :mod:`optparse` module.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may create an impression that optparse is lower level than getopt.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll reorder it to make it clear the "lower level" comparison is relative to argparse

Note also that :mod:`argparse` is based on :mod:`optparse`,
and therefore very similar in terms of usage.

Expand Down
5 changes: 0 additions & 5 deletions Doc/library/allos.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,9 @@ but they are available on most other systems as well. Here's an overview:
os.rst
io.rst
time.rst
argparse.rst
logging.rst
logging.config.rst
logging.handlers.rst
getpass.rst
curses.rst
curses.ascii.rst
curses.panel.rst
platform.rst
errno.rst
ctypes.rst
12 changes: 12 additions & 0 deletions Doc/library/argparse.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@

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

.. note::

While :mod:`argparse` is the recommended standard library module for
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not recommend it for now. You can use it on your own risk. optparse may need more work, but it works as expected. I would recommend it for beginners, which cannot distinguish their own errors from peculiarities of the library.

Copy link
Contributor Author

@ncoghlan ncoghlan Oct 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this PR, I'd like to stick with the status quo as far as recommendations go (that is, only taking the step back from "argparse is the only non-deprecated argument processing option in the standard library").

Taking the extra step to saying "argparse is not recommended over optparse anymore, even for end user applications" would then be a separate follow up question.

*implementing* basic command line applications, authors of third party
command line argument processing libraries may find that the
lower level :mod:`optparse` module serves as a better foundation for
that use case. ``optparse`` (or one of the third party libraries
based on it) may also be worth considering for applications where
stricter adherence to common Unix and Linux command line interface
conventions around the handling of option parameter values that start
with ``-`` is desired.
Comment on lines +23 to +24
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not only this. There are other peculiarities that make implementation of compatible interface with argparse impossible (unlike to getopt and optparse).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I had gotten the impression from the Discourse thread that this was the primary quirk, but I can reword these caveats to be less specific to that one issue.


--------------

.. sidebar:: Tutorial
Expand Down
21 changes: 21 additions & 0 deletions Doc/library/cmdlinelibs.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.. _cmdlinelibs:

********************************
Command Line Interface Libraries
********************************

The modules described in this chapter assist with implementing
command line and terminal interfaces for applications.

Here's an overview:

.. toctree::
:maxdepth: 1

argparse.rst
optparse.rst
Comment on lines +15 to +16
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would place optparse above argparse.

getpass.rst
fileinput.rst
curses.rst
curses.ascii.rst
curses.panel.rst
1 change: 0 additions & 1 deletion Doc/library/filesys.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ in this chapter is:

pathlib.rst
os.path.rst
fileinput.rst
stat.rst
filecmp.rst
tempfile.rst
Expand Down
32 changes: 23 additions & 9 deletions Doc/library/getopt.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@

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

.. deprecated:: 3.13
The :mod:`getopt` module is :term:`soft deprecated` and will not be
developed further; development will continue with the :mod:`argparse`
module.

.. note::
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would convert the note in normal paragraph. Also, it should refer to optparse as an object-oriented and extensible alternative, not only to argparse (which is not an equivalent).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ended up moving this page back to the "Superseded" section of the docs, as it really is a niche use case when anyone should be reaching for this. The use of the note syntax here reflects that "You almost certainly don't want this module" status.

I agree about referring readers to optparse in the note, though.


The :mod:`getopt` module is a parser for command line options whose API is
Expand Down Expand Up @@ -144,13 +139,25 @@ In a script, typical usage is something like this::
output = a
else:
assert False, "unhandled option"
# ...
process(args, output=output, verbose=verbose)

if __name__ == "__main__":
main()

Note that an equivalent command line interface could be produced with less code
and more informative help and error messages by using the :mod:`argparse` module::
and more informative help and error messages by using the :mod:`optparse` module::

import optparse

if __name__ == '__main__':
parser = optparse.OptionParser()
parser.add_option('-o', '--output')
parser.add_option('-v', dest='verbose', action='store_true')
opts, args = parser.parse_args()
process(args, output=opts.output, verbose=opts.verbose)

An equivalent command line interface for this simple case can also be produced
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even in this simple example this is not an exact equivalent. For example, -o -v and -o -- do not work, -o=foo works differently, you cannot interleave options and positional arguments. I said this is "a roughly equivalent".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if we elaborate on the discrepancies here, it may help lay the foundation for weakening the current recommendation to use argparse in a future PR. I'll incorporate more of your notes here tomorrow.

by using the :mod:`argparse` module::

import argparse

Expand All @@ -162,8 +169,15 @@ and more informative help and error messages by using the :mod:`argparse` module
# ... do something with args.output ...
# ... do something with args.verbose ..
Comment on lines 169 to 170
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this to show the difference in the API between three modules

       parser.add_argument('rest', nargs='*')
       args = parser.parse_args()
       process(args.rest, output=args.output, verbose=args.verbose)


In more complex cases (such as options which accept values), the behaviour
of the ``argparse`` version may diverge from that of the ``getopt`` and
``optparse`` versions due to the way ``argparse`` handles parameter
values that start with ``-``.
Comment on lines +174 to +175
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The difference is not only in this.


.. seealso::

Module :mod:`argparse`
Alternative command line option and argument parsing library.
Module :mod:`optparse`
More object-oriented command line option parsing.

Module :mod:`argparse`
More opinionated command line option and argument parsing library.
1 change: 1 addition & 0 deletions Doc/library/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ the `Python Package Index <https://pypi.org>`_.
fileformats.rst
crypto.rst
allos.rst
cmdlinelibs.rst
concurrency.rst
ipc.rst
netdata.rst
Expand Down
45 changes: 37 additions & 8 deletions Doc/library/optparse.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,47 @@

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

.. deprecated:: 3.2
The :mod:`optparse` module is :term:`soft deprecated` and will not be
developed further; development will continue with the :mod:`argparse`
module.
.. note::

:mod:`argparse` (rather than this module) is the recommended standard
library module for implementing command line applications unless one
of the following caveats applies:

* the application requires additional control over the way options and
positional parameters are interleaved on the command line (including
the ability to disable the interleaving feature completely)
* the application requires additional control over the incremental parsing
of command line elements (while ``argparse`` does support this, the
exact way it works in practice is undesirable for some use cases)
* the application requires additional control over the handling of options
which accept parameter values that may start with ``-`` (such as delegated
options to be passed to invoked subprocesses).

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

.. seealso::

The :pypi:`"click" package <click>` is an ``optparse`` based third party
argument processing library which allows command line applications to be
developed as a set of appropriately decorated command implementation
functions.

.. seealso::

The :pypi:`"Typer" package <click>` is a ``click`` based third party
argument processing library which allows the use of annotated Python
type hints to define an application's command line interface.
Comment on lines +33 to +44

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might make sense to duplicate these seealso notes in Doc/library/argparse.rst and Doc/howto/argparse.rst.


--------------

:mod:`optparse` is a more convenient, flexible, and powerful library for parsing
command-line options than the old :mod:`getopt` module. :mod:`optparse` uses a
more declarative style of command-line parsing: you create an instance of
:class:`OptionParser`, populate it with options, and parse the command
line. :mod:`optparse` allows users to specify options in the conventional
command-line options than the minimalist :mod:`getopt` module.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replacing old with minimalist is the only actual wording change here (the rest is just reflowing text)

:mod:`optparse` uses a more declarative style of command-line parsing:
you create an instance of :class:`OptionParser`,
populate it with options, and parse the command line.
:mod:`optparse` allows users to specify options in the conventional
GNU/POSIX syntax, and additionally generates usage and help messages for you.

Here's an example of using :mod:`optparse` in a simple script::
Expand Down
17 changes: 14 additions & 3 deletions Doc/library/superseded.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,23 @@
Superseded Modules
******************

The modules described in this chapter are deprecated or :term:`soft deprecated` and only kept for
backwards compatibility. They have been superseded by other modules.
The modules described in this chapter have been superseded by other modules
for most use cases, and are retained primarily to preserve backwards compatibility.

Modules may appear in this chapter because they only cover a limited subset of
a problem space, and a more generally applicable solution is available elsewhere
in the standard library (for example, :mod:`getopt` covers the very specific
task of "mimic the C :c:func:`!getopt` API in Python", rather than the broader
command line option parsing and argument parsing capabilities offered by
:mod:`optparse` and :mod:`argparse`).

Alternatively, modules may appear in this chapter because they are deprecated
outright, and awaiting removal in a future release, or they are
:term:`soft deprecated` and their use is actively discouraged in new projects.
With the removal of various obsolete modules through :pep:`594`, there are
currently no modules in this latter category.

.. toctree::
:maxdepth: 1

getopt.rst
optparse.rst
20 changes: 12 additions & 8 deletions Doc/whatsnew/3.13.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1648,6 +1648,18 @@ opcode
(Contributed by Irit Katriel in :gh:`105481`.)


optparse
--------

* This module is no longer considered :term:`soft deprecated`.
While :mod:`argparse` remains preferred for new projects that
aren't using a third party command line argument processing
library, there are aspects of the way ``argparse`` works that
mean the lower level ``optparse`` module may provide a better
foundation for *writing* argument processing libraries.
(Contributed by Alyssa Coghlan in :gh:`126180`.)


pathlib
-------

Expand Down Expand Up @@ -1787,14 +1799,6 @@ New Deprecations
Check membership in :data:`~dis.hasarg` instead.
(Contributed by Irit Katriel in :gh:`109319`.)

* :mod:`getopt` and :mod:`optparse`:

* Both modules are now :term:`soft deprecated`,
with :mod:`argparse` preferred for new projects.
This is a new soft-deprecation for the :mod:`!getopt` module,
whereas the :mod:`!optparse` module was already *de facto* soft deprecated.
(Contributed by Victor Stinner in :gh:`106535`.)

* :mod:`gettext`:

* Deprecate non-integer numbers as arguments to functions and methods
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
:mod:`getopt` and :mod:`optparse` are no longer marked as deprecated.
There are legitimate reasons to use one of these modules in preference to
:mod:`argparse`, and none of these modules are at risk of being removed
from the standard library. Of the three, ``argparse`` remains the
recommended default choice, *unless* one of the concerns noted at the top of
the ``optparse`` module documentation applies.
Loading