From a560986a7f8cb3c0095bfb77d04d4cbaad0e2034 Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan <ncoghlan@gmail.com> Date: Thu, 31 Oct 2024 15:32:05 +1000 Subject: [PATCH 01/18] Remove getopt and optparse deprecation notices --- Doc/library/allos.rst | 5 --- Doc/library/argparse.rst | 8 +++++ Doc/library/cmdlinelibs.rst | 19 ++++++++++ Doc/library/getopt.rst | 5 --- Doc/library/index.rst | 1 + Doc/library/optparse.rst | 36 ++++++++++++++++--- Doc/library/superseded.rst | 8 ++--- Doc/whatsnew/3.13.rst | 20 ++++++----- ...-10-31-14-31-36.gh-issue-126225.vTxGXm.rst | 6 ++++ 9 files changed, 80 insertions(+), 28 deletions(-) create mode 100644 Doc/library/cmdlinelibs.rst create mode 100644 Misc/NEWS.d/next/Library/2024-10-31-14-31-36.gh-issue-126225.vTxGXm.rst diff --git a/Doc/library/allos.rst b/Doc/library/allos.rst index 0223c1054ea5d8..1aed340b2527ac 100644 --- a/Doc/library/allos.rst +++ b/Doc/library/allos.rst @@ -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 diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index 7638798ca2552f..952b3b4cb790c1 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -11,6 +11,14 @@ **Source code:** :source:`Lib/argparse.py` +.. note:: + + While :mod:`argparse` is the recommended standard library module for + *implementing* command line applications, authors of third party + command line argument processing libraries may find that the + simpler :mod:`optparse` module serves as a better foundation for + that use case. + -------------- .. sidebar:: Tutorial diff --git a/Doc/library/cmdlinelibs.rst b/Doc/library/cmdlinelibs.rst new file mode 100644 index 00000000000000..9e304478e04336 --- /dev/null +++ b/Doc/library/cmdlinelibs.rst @@ -0,0 +1,19 @@ +.. _cmdlinelibs: + +************************************** +Command Line Implementation Libraries +************************************** + +The modules described in this chapter provide interfaces that assist with +implementing command line applications. Here's an overview: + +.. toctree:: + :maxdepth: 1 + + argparse.rst + optparse.rst + getopt.rst + getpass.rst + curses.rst + curses.ascii.rst + curses.panel.rst diff --git a/Doc/library/getopt.rst b/Doc/library/getopt.rst index d43d3250732306..ecddc5019a78f5 100644 --- a/Doc/library/getopt.rst +++ b/Doc/library/getopt.rst @@ -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:: The :mod:`getopt` module is a parser for command line options whose API is diff --git a/Doc/library/index.rst b/Doc/library/index.rst index 0b348ae6f5c8c0..8ef6a3aadf24ac 100644 --- a/Doc/library/index.rst +++ b/Doc/library/index.rst @@ -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 diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst index 74a49a8fb33666..a06e0b9e6ea5ca 100644 --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -10,10 +10,38 @@ **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 will work in practice is sometimes unpredictable) + * 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. -------------- diff --git a/Doc/library/superseded.rst b/Doc/library/superseded.rst index 17bfa66f043302..2192122553283b 100644 --- a/Doc/library/superseded.rst +++ b/Doc/library/superseded.rst @@ -7,9 +7,5 @@ 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. - -.. toctree:: - :maxdepth: 1 - - getopt.rst - optparse.rst +With the removal of various obsolete modules through :pep:`594`, there are currently no modules +in this category. diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index de4c7fd4c0486b..3f5c980093c0fd 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -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 + means ``optparse`` may provide a better foundation for *writing* + argument processing libraries. + (Contributed by Alyssa Coghlan in :gh:`126225`.) + + pathlib ------- @@ -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 diff --git a/Misc/NEWS.d/next/Library/2024-10-31-14-31-36.gh-issue-126225.vTxGXm.rst b/Misc/NEWS.d/next/Library/2024-10-31-14-31-36.gh-issue-126225.vTxGXm.rst new file mode 100644 index 00000000000000..cfa9eddaa068d4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-31-14-31-36.gh-issue-126225.vTxGXm.rst @@ -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 module documentation applies. From 0a568f145f44148873ce7bf3a57b24cad3efbb02 Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan <ncoghlan@gmail.com> Date: Thu, 31 Oct 2024 15:41:09 +1000 Subject: [PATCH 02/18] Wording tweaks --- Doc/howto/argparse.rst | 2 +- Doc/library/argparse.rst | 2 +- Doc/whatsnew/3.13.rst | 4 ++-- .../Library/2024-10-31-14-31-36.gh-issue-126225.vTxGXm.rst | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/howto/argparse.rst b/Doc/howto/argparse.rst index 1efbee64d60bb3..4bca472d822262 100644 --- a/Doc/howto/argparse.rst +++ b/Doc/howto/argparse.rst @@ -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. Note also that :mod:`argparse` is based on :mod:`optparse`, and therefore very similar in terms of usage. diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index 952b3b4cb790c1..b2763cfaf3e31a 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -16,7 +16,7 @@ While :mod:`argparse` is the recommended standard library module for *implementing* command line applications, authors of third party command line argument processing libraries may find that the - simpler :mod:`optparse` module serves as a better foundation for + lower level :mod:`optparse` module serves as a better foundation for that use case. -------------- diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index 3f5c980093c0fd..95eb756c9b0106 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -1655,8 +1655,8 @@ optparse 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 - means ``optparse`` may provide a better foundation for *writing* - argument processing libraries. + means the lower level ``optparse`` module may provide a better + foundation for *writing* argument processing libraries. (Contributed by Alyssa Coghlan in :gh:`126225`.) diff --git a/Misc/NEWS.d/next/Library/2024-10-31-14-31-36.gh-issue-126225.vTxGXm.rst b/Misc/NEWS.d/next/Library/2024-10-31-14-31-36.gh-issue-126225.vTxGXm.rst index cfa9eddaa068d4..13a1f213c7a58e 100644 --- a/Misc/NEWS.d/next/Library/2024-10-31-14-31-36.gh-issue-126225.vTxGXm.rst +++ b/Misc/NEWS.d/next/Library/2024-10-31-14-31-36.gh-issue-126225.vTxGXm.rst @@ -3,4 +3,4 @@ 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 module documentation applies. +the ``optparse`` module documentation applies. From 55b72155bc4d623e37b41a1b3397c3618f588dc9 Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan <ncoghlan@gmail.com> Date: Thu, 31 Oct 2024 16:14:09 +1000 Subject: [PATCH 03/18] Incorporate improvements from Serhiy's PR Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> --- Doc/library/argparse.rst | 8 ++++++-- Doc/library/getopt.rst | 27 +++++++++++++++++++++++---- Doc/library/optparse.rst | 9 +++++---- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index b2763cfaf3e31a..522d1572c89178 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -14,10 +14,14 @@ .. note:: While :mod:`argparse` is the recommended standard library module for - *implementing* command line applications, authors of third party + *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. + 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. -------------- diff --git a/Doc/library/getopt.rst b/Doc/library/getopt.rst index ecddc5019a78f5..e3f88df74a1d3b 100644 --- a/Doc/library/getopt.rst +++ b/Doc/library/getopt.rst @@ -139,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 +by using the :mod:`argparse` module:: import argparse @@ -157,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 .. +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 ``-``. + .. 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. diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst index a06e0b9e6ea5ca..35c49b9fb5fc22 100644 --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -46,10 +46,11 @@ -------------- :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. +: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:: From 09717805f9428206a90e1f604cb430ee74be546b Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan <ncoghlan@gmail.com> Date: Thu, 31 Oct 2024 16:22:46 +1000 Subject: [PATCH 04/18] Grammar fix --- Doc/whatsnew/3.13.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index 95eb756c9b0106..2167e4b66a619c 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -1655,7 +1655,7 @@ optparse 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 - means the lower level ``optparse`` module may provide a better + mean the lower level ``optparse`` module may provide a better foundation for *writing* argument processing libraries. (Contributed by Alyssa Coghlan in :gh:`126225`.) From 09b023798639d8a1e93010c9bbdfab2963364959 Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan <ncoghlan@gmail.com> Date: Thu, 31 Oct 2024 16:23:33 +1000 Subject: [PATCH 05/18] Fix issue number reference --- Doc/whatsnew/3.13.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index 2167e4b66a619c..8b0cbd9904aaae 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -1657,7 +1657,7 @@ optparse 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:`126225`.) + (Contributed by Alyssa Coghlan in :gh:`126180`.) pathlib From 4cdebdeea6d32b3a86698f61c2fd92ffb8053678 Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan <ncoghlan@gmail.com> Date: Thu, 31 Oct 2024 16:26:05 +1000 Subject: [PATCH 06/18] Another wording tweak --- Doc/library/optparse.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst index 35c49b9fb5fc22..ea5fb5c01fd1fb 100644 --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -21,7 +21,7 @@ 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 will work in practice is sometimes unpredictable) + 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). From 693a979aedf50c74f2a3db706ef0c2a340ecb3ea Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan <ncoghlan@gmail.com> Date: Thu, 31 Oct 2024 16:33:24 +1000 Subject: [PATCH 07/18] Update heading and description for new chapter --- Doc/library/cmdlinelibs.rst | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Doc/library/cmdlinelibs.rst b/Doc/library/cmdlinelibs.rst index 9e304478e04336..a691035b3e5c8f 100644 --- a/Doc/library/cmdlinelibs.rst +++ b/Doc/library/cmdlinelibs.rst @@ -1,11 +1,13 @@ .. _cmdlinelibs: -************************************** -Command Line Implementation Libraries -************************************** +******************************** +Command Line Interface Libraries +******************************** The modules described in this chapter provide interfaces that assist with -implementing command line applications. Here's an overview: +implementing command line and terminal interfaces for applications. + +Here's an overview: .. toctree:: :maxdepth: 1 From 50d1ee4d91a5d30ff4ae06d889d30103cd5fe7c7 Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan <ncoghlan@gmail.com> Date: Thu, 31 Oct 2024 16:35:23 +1000 Subject: [PATCH 08/18] fileinput belongs in the new chapter --- Doc/library/cmdlinelibs.rst | 1 + Doc/library/filesys.rst | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/cmdlinelibs.rst b/Doc/library/cmdlinelibs.rst index a691035b3e5c8f..93ea0b1a1bdbd9 100644 --- a/Doc/library/cmdlinelibs.rst +++ b/Doc/library/cmdlinelibs.rst @@ -16,6 +16,7 @@ Here's an overview: optparse.rst getopt.rst getpass.rst + fileinput.rst curses.rst curses.ascii.rst curses.panel.rst diff --git a/Doc/library/filesys.rst b/Doc/library/filesys.rst index 0ccf2b7bf59a0f..f1ea4761af7cb1 100644 --- a/Doc/library/filesys.rst +++ b/Doc/library/filesys.rst @@ -14,7 +14,6 @@ in this chapter is: pathlib.rst os.path.rst - fileinput.rst stat.rst filecmp.rst tempfile.rst From 4e50c74ba908c12f36b0e4ce78e21b72fb57b3fe Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan <ncoghlan@gmail.com> Date: Thu, 31 Oct 2024 17:16:08 +1000 Subject: [PATCH 09/18] Move getopt back to the superseded section --- Doc/library/cmdlinelibs.rst | 1 - Doc/library/superseded.rst | 20 ++++++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/Doc/library/cmdlinelibs.rst b/Doc/library/cmdlinelibs.rst index 93ea0b1a1bdbd9..c526bbe72c3f38 100644 --- a/Doc/library/cmdlinelibs.rst +++ b/Doc/library/cmdlinelibs.rst @@ -14,7 +14,6 @@ Here's an overview: argparse.rst optparse.rst - getopt.rst getpass.rst fileinput.rst curses.rst diff --git a/Doc/library/superseded.rst b/Doc/library/superseded.rst index 2192122553283b..fcef3193c8d8f6 100644 --- a/Doc/library/superseded.rst +++ b/Doc/library/superseded.rst @@ -4,8 +4,20 @@ 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. -With the removal of various obsolete modules through :pep:`594`, there are currently no modules -in this category. +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`). + +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 From 0db2c888c72d46ffa55c120fcb5c8521a98d3613 Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan <ncoghlan@gmail.com> Date: Thu, 31 Oct 2024 17:20:56 +1000 Subject: [PATCH 10/18] Reword superseded chapter intro --- Doc/library/superseded.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Doc/library/superseded.rst b/Doc/library/superseded.rst index fcef3193c8d8f6..d120c6acf621e3 100644 --- a/Doc/library/superseded.rst +++ b/Doc/library/superseded.rst @@ -9,7 +9,10 @@ for most use cases, and are retained primarily to preserve backwards compatibili 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`). +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 From e474e77f95fb1648e8a2a3c411d45528d9d6519a Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan <ncoghlan@gmail.com> Date: Thu, 31 Oct 2024 18:08:28 +1000 Subject: [PATCH 11/18] Simplify wording --- Doc/library/cmdlinelibs.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/cmdlinelibs.rst b/Doc/library/cmdlinelibs.rst index c526bbe72c3f38..085d31af7bca1f 100644 --- a/Doc/library/cmdlinelibs.rst +++ b/Doc/library/cmdlinelibs.rst @@ -4,8 +4,8 @@ Command Line Interface Libraries ******************************** -The modules described in this chapter provide interfaces that assist with -implementing command line and terminal interfaces for applications. +The modules described in this chapter assist with implementing +command line and terminal interfaces for applications. Here's an overview: From 93d7161893a84656403365098a2d04f0d1434a36 Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan <ncoghlan@gmail.com> Date: Sat, 2 Nov 2024 22:53:59 +1000 Subject: [PATCH 12/18] Updates based on Serhiy's feedback --- Doc/howto/argparse-optparse.rst | 18 ++++---- Doc/howto/argparse.rst | 14 ++++-- Doc/library/argparse.rst | 8 ++-- Doc/library/getopt.rst | 82 ++++++++++++++++++++++----------- Doc/library/optparse.rst | 30 +++++++----- 5 files changed, 95 insertions(+), 57 deletions(-) diff --git a/Doc/howto/argparse-optparse.rst b/Doc/howto/argparse-optparse.rst index cef2d893b28a62..fc20586c91561c 100644 --- a/Doc/howto/argparse-optparse.rst +++ b/Doc/howto/argparse-optparse.rst @@ -6,15 +6,8 @@ Upgrading optparse code ========================== -Originally, the :mod:`argparse` module had attempted to maintain compatibility -with :mod:`optparse`. However, :mod:`optparse` was difficult to extend -transparently, particularly with the changes required to support -``nargs=`` specifiers and better usage messages. When most everything in -:mod:`optparse` had either been copy-pasted over or monkey-patched, it no -longer seemed practical to try to maintain the backwards compatibility. - -The :mod:`argparse` module improves on the :mod:`optparse` -module in a number of ways including: +The :mod:`argparse` module offers several higher level features not natively +provided by the :mod:`optparse` module, including: * Handling positional arguments. * Supporting subcommands. @@ -23,6 +16,13 @@ module in a number of ways including: * Producing more informative usage messages. * Providing a much simpler interface for custom ``type`` and ``action``. +Originally, the :mod:`argparse` module attempted to maintain compatibility +with :mod:`optparse`. However, :mod:`optparse` was difficult to extend +transparently, particularly with the changes required to support +``nargs=`` specifiers and better usage messages. When most everything in +:mod:`optparse` had either been copy-pasted over or monkey-patched, it no +longer seemed practical to try to maintain the backwards compatibility. + A partial upgrade path from :mod:`optparse` to :mod:`argparse`: * Replace all :meth:`optparse.OptionParser.add_option` calls with diff --git a/Doc/howto/argparse.rst b/Doc/howto/argparse.rst index 4bca472d822262..3332d789032bd8 100644 --- a/Doc/howto/argparse.rst +++ b/Doc/howto/argparse.rst @@ -13,11 +13,15 @@ recommended command-line parsing module in the Python standard library. .. note:: - There are two other modules that fulfill the same task, namely - :mod:`getopt` (an equivalent for ``getopt()`` from the C - language) and the lower level :mod:`optparse` module. - Note also that :mod:`argparse` is based on :mod:`optparse`, - and therefore very similar in terms of usage. + The standard library includes two other libraries directly related + to command-line parameter processing: the lower level :mod:`optparse` + module (which may require more code to configure for a given application, + but also allows an application to request behaviors that ``argparse`` + doesn't support), and the very low level :mod:`getopt` (which specifically + serves as an equivalent to ``getopt()`` from the C language). + While neither of those modules is covered directly in this guide, many of + the core concepts in ``argparse`` first originated in ``optparse``, so + some aspects of this tutorial will also be relevant to ``optparse`` users. Concepts diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index 522d1572c89178..13221f331afa87 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -19,9 +19,11 @@ 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. + ``argparse`` doesn't support behaviors that the application requires + (such as entirely disabling support for interspersed options and + positional arguments, or stricter adherence to common Unix and Linux + command line interface conventions related to the handling of option + parameter values that start with ``-``). -------------- diff --git a/Doc/library/getopt.rst b/Doc/library/getopt.rst index e3f88df74a1d3b..88053015cf9851 100644 --- a/Doc/library/getopt.rst +++ b/Doc/library/getopt.rst @@ -9,11 +9,11 @@ .. note:: - The :mod:`getopt` module is a parser for command line options whose API is - designed to be familiar to users of the C :c:func:`!getopt` function. Users who - are unfamiliar with the C :c:func:`!getopt` function or who would like to write - less code and get better help and error messages should consider using the - :mod:`argparse` module instead. + This module is considered feature complete. A more object-oriented and + extensible alternative to this API is provided in the :mod:`optparse` + module. Further functional enhancements for command line parameter + processing are provided either as third party modules on PyPI, + or else as features in the :mod:`argparse` module. -------------- @@ -23,6 +23,12 @@ the special meanings of arguments of the form '``-``' and '``--``'). Long options similar to those supported by GNU software may be used as well via an optional third argument. +Users who are unfamiliar with the Unix :c:func:`!getopt` function should consider +using the :mod:`argparse` module instead. Users who are familiar with the Unix +:c:func:`!getopt` function, but would like to get equivalent behavior while +writing less code and getting better help and error messages should consider +using the :mod:`optparse` module. + This module provides two functions and an exception: @@ -150,29 +156,49 @@ 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 -by using the :mod:`argparse` module:: - - import argparse - - if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('-o', '--output') - parser.add_argument('-v', dest='verbose', action='store_true') - args = parser.parse_args() - # ... do something with args.output ... - # ... do something with 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 ``-``. + 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) + +A roughly equivalent command line interface for this case can also be +produced by using the :mod:`argparse` module:: + +import argparse + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('-o', '--output') + parser.add_argument('-v', dest='verbose', action='store_true') + parser.add_argument('rest', nargs='*') + args = parser.parse_args() + process(args.rest, output=args.output, verbose=args.verbose) + +However, unlike the ``optparse`` example, this ``argparse`` example will +handle some parameter combinations differently from the way the ``getopt`` +version would handle them. For example (amongst other differences): + +* supplying ``-o -v`` gives ``output="-v"`` and ``verbose=False`` + for both ``getopt`` and ``optparse``, + but a usage error with ``argparse`` + (complaining that no value has been supplied for ``-o/--output``, + since ``-v`` is interpreted as meaning the verbosity flag) +* similarly, supplying ``-o --`` gives ``output="--"`` and ``args=()`` + for both ``getopt`` and ``optparse``, + but a usage error with ``argparse`` + (also complaining that no value has been supplied for ``-o/--output``, + since ``--`` is interpreted as terminating the option processing + and treating all remaining values as positional arguments) +* supplying ``-o=foo`` gives ``output="=foo"`` + for both ``getopt`` and ``optparse``, + but gives ``output="foo"`` with ``argparse`` + (since ``=`` is special cased as an alternative separator for + option parameter values) + +Whether these differing behaviors in the ``argparse`` version are +considered desirable or a problem will depend on the specific command line +application use case. .. seealso:: diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst index ea5fb5c01fd1fb..d60e9a23cc140f 100644 --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -12,8 +12,14 @@ .. note:: - :mod:`argparse` (rather than this module) is the recommended standard - library module for implementing command line applications unless one + This module is considered feature complete. Further functional enhancements for + command line parameter processing are provided either as third party modules on + PyPI, or else as features in the :mod:`argparse` module. + +.. note:: + + The higher level :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 @@ -24,7 +30,10 @@ 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). + options to be passed to invoked subprocesses) + * the application requires some other command line parameter processing + behavior which ``argparse`` does not support, but which can be implemented + in terms of the lower level interface offered by ``optparse`` These ``argparse`` caveats also mean that :mod:`optparse` is likely to provide a better foundation for library authors *writing* third party @@ -32,16 +41,13 @@ .. 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:: + :pypi:`click` is a third party argument processing library (originally + based on ``optparse``), which allows command line applications to be + developed as a set of decorated command implementation functions. - 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. + Other third party libraries, such as :pypi:`typer` or :pypi:`msgspec-click`, + allow command line interfaces to be specified in ways that effectively + integrate with static checking of Python type annotations. -------------- From bb91b529dac8c886c457b9e21711d3757a10b82d Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan <ncoghlan@gmail.com> Date: Sat, 2 Nov 2024 23:04:42 +1000 Subject: [PATCH 13/18] Also reword What's New entry --- Doc/whatsnew/3.13.rst | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index 8b0cbd9904aaae..7792733c2f4c77 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -1656,8 +1656,12 @@ optparse 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`.) + foundation for *writing* argument processing libraries, and + for implementing command line applications which adhere more + strictly than ``argparse`` does to various Unix command line + processing conventions that originate in the behaviour of the + C :c:func:`getopt` function . + (Contributed by Alyssa Coghlan and Serhiy Storchaka in :gh:`126180`.) pathlib From 7cc72ada98bea5c83bfe1ce59ec8e0d14590b3d5 Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan <ncoghlan@gmail.com> Date: Sat, 2 Nov 2024 23:06:42 +1000 Subject: [PATCH 14/18] Consistent getopt markup --- Doc/howto/argparse.rst | 2 +- Doc/whatsnew/3.13.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/howto/argparse.rst b/Doc/howto/argparse.rst index 3332d789032bd8..dcc516754fa89c 100644 --- a/Doc/howto/argparse.rst +++ b/Doc/howto/argparse.rst @@ -18,7 +18,7 @@ recommended command-line parsing module in the Python standard library. module (which may require more code to configure for a given application, but also allows an application to request behaviors that ``argparse`` doesn't support), and the very low level :mod:`getopt` (which specifically - serves as an equivalent to ``getopt()`` from the C language). + serves as an equivalent to :c:func:`!getopt` from the C language). While neither of those modules is covered directly in this guide, many of the core concepts in ``argparse`` first originated in ``optparse``, so some aspects of this tutorial will also be relevant to ``optparse`` users. diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index 7792733c2f4c77..6a412730072d7b 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -1660,7 +1660,7 @@ optparse for implementing command line applications which adhere more strictly than ``argparse`` does to various Unix command line processing conventions that originate in the behaviour of the - C :c:func:`getopt` function . + C :c:func:`!getopt` function . (Contributed by Alyssa Coghlan and Serhiy Storchaka in :gh:`126180`.) From 5d86774f59be52a9fe9c850075666c7e7996d7cc Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan <ncoghlan@gmail.com> Date: Sun, 8 Dec 2024 15:54:22 +1000 Subject: [PATCH 15/18] Updates based on review feedback --- Doc/howto/argparse-optparse.rst | 28 +++++-- Doc/howto/argparse.rst | 3 +- Doc/library/argparse.rst | 20 ++--- Doc/library/getopt.rst | 60 +++++-------- Doc/library/optparse.rst | 144 ++++++++++++++++++++++++-------- 5 files changed, 161 insertions(+), 94 deletions(-) diff --git a/Doc/howto/argparse-optparse.rst b/Doc/howto/argparse-optparse.rst index fc20586c91561c..b684619885b4c7 100644 --- a/Doc/howto/argparse-optparse.rst +++ b/Doc/howto/argparse-optparse.rst @@ -1,10 +1,11 @@ .. currentmodule:: argparse .. _upgrading-optparse-code: +.. _migrating-optparse-code: -========================== -Upgrading optparse code -========================== +============================================ +Migrating ``optparse`` code to ``argparse`` +============================================ The :mod:`argparse` module offers several higher level features not natively provided by the :mod:`optparse` module, including: @@ -17,13 +18,22 @@ provided by the :mod:`optparse` module, including: * Providing a much simpler interface for custom ``type`` and ``action``. Originally, the :mod:`argparse` module attempted to maintain compatibility -with :mod:`optparse`. However, :mod:`optparse` was difficult to extend -transparently, particularly with the changes required to support -``nargs=`` specifiers and better usage messages. When most everything in -:mod:`optparse` had either been copy-pasted over or monkey-patched, it no -longer seemed practical to try to maintain the backwards compatibility. +with :mod:`optparse`. However, the fundamental design differences between +supporting declarative command line option processing (while leaving positional +argument processing to application code), and supporting both named options +and positional arguments in the declarative interface mean that the +API has diverged from that of ``optparse`` over time. -A partial upgrade path from :mod:`optparse` to :mod:`argparse`: +As described in :ref:`choosing-an-argument-parser`, applications that are +currently using :mod:`optparse` and are happy with the way it works can +just continue to use ``optparse``. + +Application developers that are considering migrating should also review +the list of intrinsic behavioural differences described in that section +before deciding whether or not migration is desirable. + +For applications that do choose to migrate from :mod:`optparse` to :mod:`argparse`, +the following suggestions should be helpful: * Replace all :meth:`optparse.OptionParser.add_option` calls with :meth:`ArgumentParser.add_argument` calls. diff --git a/Doc/howto/argparse.rst b/Doc/howto/argparse.rst index dcc516754fa89c..902c50de00803c 100644 --- a/Doc/howto/argparse.rst +++ b/Doc/howto/argparse.rst @@ -18,7 +18,8 @@ recommended command-line parsing module in the Python standard library. module (which may require more code to configure for a given application, but also allows an application to request behaviors that ``argparse`` doesn't support), and the very low level :mod:`getopt` (which specifically - serves as an equivalent to :c:func:`!getopt` from the C language). + serves as an equivalent to the :c:func:`!getopt` family of functions + available to C programmers). While neither of those modules is covered directly in this guide, many of the core concepts in ``argparse`` first originated in ``optparse``, so some aspects of this tutorial will also be relevant to ``optparse`` users. diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index fa715dc513fc59..8d0116d8c060b8 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -13,17 +13,15 @@ .. note:: - While :mod:`argparse` is the recommended standard library module for - *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 - ``argparse`` doesn't support behaviors that the application requires - (such as entirely disabling support for interspersed options and - positional arguments, or stricter adherence to common Unix and Linux - command line interface conventions related to the handling of option - parameter values that start with ``-``). + While :mod:`argparse` is the default recommended standard library module + for implementing basic command line applications, authors with more + exacting requirements for exactly how their command line applications + behave may find it doesn't provide the necessary level of control. + Refer to :ref:`choosing-an-argument-parser` for alternatives to + consider when ``argparse`` doesn't support behaviors that the application + requires (such as entirely disabling support for interspersed options and + positional arguments, or accepting option parameter values that start + with ``-`` even when they correspond to another defined option). -------------- diff --git a/Doc/library/getopt.rst b/Doc/library/getopt.rst index b4f28de7b53aa2..6239e9b3008135 100644 --- a/Doc/library/getopt.rst +++ b/Doc/library/getopt.rst @@ -9,7 +9,7 @@ .. note:: - This module is considered feature complete. A more object-oriented and + This module is considered feature complete. A more declarative and extensible alternative to this API is provided in the :mod:`optparse` module. Further functional enhancements for command line parameter processing are provided either as third party modules on PyPI, @@ -27,7 +27,8 @@ Users who are unfamiliar with the Unix :c:func:`!getopt` function should conside using the :mod:`argparse` module instead. Users who are familiar with the Unix :c:func:`!getopt` function, but would like to get equivalent behavior while writing less code and getting better help and error messages should consider -using the :mod:`optparse` module. +using the :mod:`optparse` module. See :ref:`choosing-an-argument-parser` for +additional details. This module provides two functions and an exception: @@ -215,47 +216,28 @@ and more informative help and error messages by using the :mod:`optparse` module process(args, output=opts.output, verbose=opts.verbose) A roughly equivalent command line interface for this case can also be -produced by using the :mod:`argparse` module:: - -import argparse - -if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('-o', '--output') - parser.add_argument('-v', dest='verbose', action='store_true') - parser.add_argument('rest', nargs='*') - args = parser.parse_args() - process(args.rest, output=args.output, verbose=args.verbose) - -However, unlike the ``optparse`` example, this ``argparse`` example will -handle some parameter combinations differently from the way the ``getopt`` -version would handle them. For example (amongst other differences): - -* supplying ``-o -v`` gives ``output="-v"`` and ``verbose=False`` - for both ``getopt`` and ``optparse``, - but a usage error with ``argparse`` - (complaining that no value has been supplied for ``-o/--output``, - since ``-v`` is interpreted as meaning the verbosity flag) -* similarly, supplying ``-o --`` gives ``output="--"`` and ``args=()`` - for both ``getopt`` and ``optparse``, - but a usage error with ``argparse`` - (also complaining that no value has been supplied for ``-o/--output``, - since ``--`` is interpreted as terminating the option processing - and treating all remaining values as positional arguments) -* supplying ``-o=foo`` gives ``output="=foo"`` - for both ``getopt`` and ``optparse``, - but gives ``output="foo"`` with ``argparse`` - (since ``=`` is special cased as an alternative separator for - option parameter values) - -Whether these differing behaviors in the ``argparse`` version are -considered desirable or a problem will depend on the specific command line -application use case. +produced by using the :mod:`argparse` module: + +.. testcode:: + + import argparse + + if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('-o', '--output') + parser.add_argument('-v', dest='verbose', action='store_true') + parser.add_argument('rest', nargs='*') + args = parser.parse_args() + process(args.rest, output=args.output, verbose=args.verbose) + +See :ref:`choosing-an-argument-parser` for details on how the ``argparse`` +version of this code differs in behaviour from the ``optparse`` (and +``getopt``) version. .. seealso:: Module :mod:`optparse` - More object-oriented command line option parsing. + Declarative command line option parsing. Module :mod:`argparse` More opinionated command line option and argument parsing library. diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst index d60e9a23cc140f..c3e2074bb985fd 100644 --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -3,41 +3,114 @@ .. module:: optparse :synopsis: Command-line option parsing library. - :deprecated: .. moduleauthor:: Greg Ward <gward@python.net> .. sectionauthor:: Greg Ward <gward@python.net> **Source code:** :source:`Lib/optparse.py` -.. note:: - - This module is considered feature complete. Further functional enhancements for - command line parameter processing are provided either as third party modules on - PyPI, or else as features in the :mod:`argparse` module. - -.. note:: - - The higher level :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) - * the application requires some other command line parameter processing - behavior which ``argparse`` does not support, but which can be implemented - in terms of the lower level interface offered by ``optparse`` +-------------- - 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. +.. _choosing-an-argument-parser: + +Choosing an argument parsing library +------------------------------------ + +The standard library includes three argument parsing libraries: + +* :mod:`getopt`: a module that closely mirrors the procedural C ``getopt`` API. + Included in the standard library since before the initial Python 1.0 release. +* :mod:`optparse`: a declarative replacement for ``getopt`` that + provides equivalent functionality without requiring each application + to implement its own procedural option parsing logic. First included + in the standard library since the Python 2.3 release. +* :mod:`argparse`: a more opinionated alternative to ``optparse`` that + provides more functionality by default, at the expense of reduced application + flexibility in controlling exactly how arguments are processed. Included in + the standard library since the Python 2.7 and Python 3.2 releases. + +In the absence of more specific argument parsing design constraints, :mod:`argparse` +is the recommended choice for implementing command line applications, as it offers +the highest level of baseline functionality with the least application level code. + +:mod:`getopt` is retained almost entirely for backwards compatibility reasons. +However, it also serves a niche use case as a tool for prototyping and testing +command line argument handling in ``getopt``-based C applications. + +:mod:`optparse` should be considered as an alternative to :mod:`argparse` in the +following cases: + +* an application is already using :mod:`optparse` and doesn't want to risk the + subtle behavioural changes that may arise when migrating to :mod:`argparse` +* 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) +* the application requires some other command line parameter processing + behavior which ``argparse`` does not support, but which can be implemented + in terms of the lower level interface offered by ``optparse`` + +These considerations also mean that :mod:`optparse` is likely to provide a +better foundation for library authors writing third party command line +argument processing libraries. + +As a concrete example, consider the following two command line argument +parsing configurations, the first using ``optparse``, and the second +using ``argparse``: + +.. testcode:: + + 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) + +.. testcode:: + + import argparse + + if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('-o', '--output') + parser.add_argument('-v', dest='verbose', action='store_true') + parser.add_argument('rest', nargs='*') + args = parser.parse_args() + process(args.rest, output=args.output, verbose=args.verbose) + +The most obvious difference is that in the ``optparse`` version, the non-option +arguments are processed separately by the application after the option processing +is complete. In the ``argparse`` version, positional arguments are declared and +processed in the same way as the named options. + +However, the ``argparse`` version will also handle some parameter combination +differently from the way the ``optparse`` version would handle them. +For example (amongst other differences): + +* supplying ``-o -v`` gives ``output="-v"`` and ``verbose=False`` + when using ``optparse``, but a usage error with ``argparse`` + (complaining that no value has been supplied for ``-o/--output``, + since ``-v`` is interpreted as meaning the verbosity flag) +* similarly, supplying ``-o --`` gives ``output="--"`` and ``args=()`` + when using ``optparse``, but a usage error with ``argparse`` + (also complaining that no value has been supplied for ``-o/--output``, + since ``--`` is interpreted as terminating the option processing + and treating all remaining values as positional arguments) +* supplying ``-o=foo`` gives ``output="=foo"`` when using ``optparse``, + but gives ``output="foo"`` with ``argparse`` (since ``=`` is special + cased as an alternative separator for option parameter values) + +Whether these differing behaviors in the ``argparse`` version are +considered desirable or a problem will depend on the specific command line +application use case. .. seealso:: @@ -46,10 +119,12 @@ developed as a set of decorated command implementation functions. Other third party libraries, such as :pypi:`typer` or :pypi:`msgspec-click`, - allow command line interfaces to be specified in ways that effectively + allow command line interfaces to be specified in ways that more effectively integrate with static checking of Python type annotations. --------------- + +Introduction +------------ :mod:`optparse` is a more convenient, flexible, and powerful library for parsing command-line options than the minimalist :mod:`getopt` module. @@ -117,10 +192,11 @@ Background ---------- :mod:`optparse` was explicitly designed to encourage the creation of programs -with straightforward, conventional command-line interfaces. To that end, it -supports only the most common command-line syntax and semantics conventionally -used under Unix. If you are unfamiliar with these conventions, read this -section to acquaint yourself with them. +with straightforward command-line interfaces that follow the conventions +established by the :c:func`!getopt` family of functions available to C developers. +To that end, it supports only the most common command-line syntax and semantics +conventionally used under Unix. If you are unfamiliar with these conventions, +reading this section will allow you to acquaint yourself with them. .. _optparse-terminology: From c2ae2936a3aaca26d0896fc3f5cbc708ad67f30e Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan <ncoghlan@gmail.com> Date: Sun, 8 Dec 2024 22:24:43 +1000 Subject: [PATCH 16/18] Syntax fix --- Doc/library/optparse.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst index c3e2074bb985fd..5bef475893cacd 100644 --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -193,7 +193,7 @@ Background :mod:`optparse` was explicitly designed to encourage the creation of programs with straightforward command-line interfaces that follow the conventions -established by the :c:func`!getopt` family of functions available to C developers. +established by the :c:func:`!getopt` family of functions available to C developers. To that end, it supports only the most common command-line syntax and semantics conventionally used under Unix. If you are unfamiliar with these conventions, reading this section will allow you to acquaint yourself with them. From 5e2fcd9ee6dd05f58577bba04936f5e75ca1e153 Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan <ncoghlan@gmail.com> Date: Tue, 17 Dec 2024 22:12:10 +1000 Subject: [PATCH 17/18] Fix excess indentation in examples --- Doc/library/getopt.rst | 22 +++++++++++----------- Doc/library/optparse.rst | 22 +++++++++++----------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Doc/library/getopt.rst b/Doc/library/getopt.rst index 6239e9b3008135..5c63009e22d58c 100644 --- a/Doc/library/getopt.rst +++ b/Doc/library/getopt.rst @@ -209,11 +209,11 @@ 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) + 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) A roughly equivalent command line interface for this case can also be produced by using the :mod:`argparse` module: @@ -223,12 +223,12 @@ produced by using the :mod:`argparse` module: import argparse if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('-o', '--output') - parser.add_argument('-v', dest='verbose', action='store_true') - parser.add_argument('rest', nargs='*') - args = parser.parse_args() - process(args.rest, output=args.output, verbose=args.verbose) + parser = argparse.ArgumentParser() + parser.add_argument('-o', '--output') + parser.add_argument('-v', dest='verbose', action='store_true') + parser.add_argument('rest', nargs='*') + args = parser.parse_args() + process(args.rest, output=args.output, verbose=args.verbose) See :ref:`choosing-an-argument-parser` for details on how the ``argparse`` version of this code differs in behaviour from the ``optparse`` (and diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst index 5bef475893cacd..425a00f3628d16 100644 --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -68,23 +68,23 @@ using ``argparse``: 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) + 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) .. testcode:: import argparse if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('-o', '--output') - parser.add_argument('-v', dest='verbose', action='store_true') - parser.add_argument('rest', nargs='*') - args = parser.parse_args() - process(args.rest, output=args.output, verbose=args.verbose) + parser = argparse.ArgumentParser() + parser.add_argument('-o', '--output') + parser.add_argument('-v', dest='verbose', action='store_true') + parser.add_argument('rest', nargs='*') + args = parser.parse_args() + process(args.rest, output=args.output, verbose=args.verbose) The most obvious difference is that in the ``optparse`` version, the non-option arguments are processed separately by the application after the option processing From 457ee88d6f883fb5a9a05b38b1e04cde1c04f638 Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan <ncoghlan@gmail.com> Date: Tue, 17 Dec 2024 22:15:38 +1000 Subject: [PATCH 18/18] Phrasing tweak --- Doc/library/optparse.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst index 425a00f3628d16..ff327cf9162a8c 100644 --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -22,7 +22,7 @@ The standard library includes three argument parsing libraries: Included in the standard library since before the initial Python 1.0 release. * :mod:`optparse`: a declarative replacement for ``getopt`` that provides equivalent functionality without requiring each application - to implement its own procedural option parsing logic. First included + to implement its own procedural option parsing logic. Included in the standard library since the Python 2.3 release. * :mod:`argparse`: a more opinionated alternative to ``optparse`` that provides more functionality by default, at the expense of reduced application