mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +00:00
gh-126390: Support for preserving order of options and nonoption arguments in gnu_getopt() (GH-126393)
This commit is contained in:
parent
12ca7e622f
commit
35010b8cf2
5 changed files with 48 additions and 5 deletions
|
@ -85,6 +85,16 @@ exception:
|
||||||
variable :envvar:`!POSIXLY_CORRECT` is set, then option processing stops as
|
variable :envvar:`!POSIXLY_CORRECT` is set, then option processing stops as
|
||||||
soon as a non-option argument is encountered.
|
soon as a non-option argument is encountered.
|
||||||
|
|
||||||
|
If the first character of the option string is ``'-'``, non-option arguments
|
||||||
|
that are followed by options are added to the list of option-and-value pairs
|
||||||
|
as a pair that has ``None`` as its first element and the list of non-option
|
||||||
|
arguments as its second element.
|
||||||
|
The second element of the :func:`!gnu_getopt` result is a list of
|
||||||
|
program arguments after the last option.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.14
|
||||||
|
Support for returning intermixed options and non-option arguments in order.
|
||||||
|
|
||||||
|
|
||||||
.. exception:: GetoptError
|
.. exception:: GetoptError
|
||||||
|
|
||||||
|
@ -144,6 +154,20 @@ Optional arguments should be specified explicitly:
|
||||||
>>> args
|
>>> args
|
||||||
['a1', 'a2']
|
['a1', 'a2']
|
||||||
|
|
||||||
|
The order of options and non-option arguments can be preserved:
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
|
||||||
|
>>> s = 'a1 -x a2 a3 a4 --long a5 a6'
|
||||||
|
>>> args = s.split()
|
||||||
|
>>> args
|
||||||
|
['a1', '-x', 'a2', 'a3', 'a4', '--long', 'a5', 'a6']
|
||||||
|
>>> optlist, args = getopt.gnu_getopt(args, '-x:', ['long='])
|
||||||
|
>>> optlist
|
||||||
|
[(None, ['a1']), ('-x', 'a2'), (None, ['a3', 'a4']), ('--long', 'a5')]
|
||||||
|
>>> args
|
||||||
|
['a6']
|
||||||
|
|
||||||
In a script, typical usage is something like this:
|
In a script, typical usage is something like this:
|
||||||
|
|
||||||
.. testcode::
|
.. testcode::
|
||||||
|
|
|
@ -331,6 +331,9 @@ getopt
|
||||||
* Add support for options with optional arguments.
|
* Add support for options with optional arguments.
|
||||||
(Contributed by Serhiy Storchaka in :gh:`126374`.)
|
(Contributed by Serhiy Storchaka in :gh:`126374`.)
|
||||||
|
|
||||||
|
* Add support for returning intermixed options and non-option arguments in order.
|
||||||
|
(Contributed by Serhiy Storchaka in :gh:`126390`.)
|
||||||
|
|
||||||
http
|
http
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
|
@ -24,9 +24,6 @@ option involved with the exception.
|
||||||
# TODO for gnu_getopt():
|
# TODO for gnu_getopt():
|
||||||
#
|
#
|
||||||
# - GNU getopt_long_only mechanism
|
# - GNU getopt_long_only mechanism
|
||||||
# - allow the caller to specify ordering
|
|
||||||
# - RETURN_IN_ORDER option
|
|
||||||
# - GNU extension with '-' as first character of option string
|
|
||||||
# - an option string with a W followed by semicolon should
|
# - an option string with a W followed by semicolon should
|
||||||
# treat "-W foo" as "--foo"
|
# treat "-W foo" as "--foo"
|
||||||
|
|
||||||
|
@ -63,7 +60,7 @@ def getopt(args, shortopts, longopts = []):
|
||||||
long options which should be supported. The leading '--'
|
long options which should be supported. The leading '--'
|
||||||
characters should not be included in the option name. Options
|
characters should not be included in the option name. Options
|
||||||
which require an argument should be followed by an equal sign
|
which require an argument should be followed by an equal sign
|
||||||
('='). Options which acept an optional argument should be
|
('='). Options which accept an optional argument should be
|
||||||
followed by an equal sign and question mark ('=?').
|
followed by an equal sign and question mark ('=?').
|
||||||
|
|
||||||
The return value consists of two elements: the first is a list of
|
The return value consists of two elements: the first is a list of
|
||||||
|
@ -116,8 +113,13 @@ def gnu_getopt(args, shortopts, longopts = []):
|
||||||
else:
|
else:
|
||||||
longopts = list(longopts)
|
longopts = list(longopts)
|
||||||
|
|
||||||
|
return_in_order = False
|
||||||
|
if shortopts.startswith('-'):
|
||||||
|
shortopts = shortopts[1:]
|
||||||
|
all_options_first = False
|
||||||
|
return_in_order = True
|
||||||
# Allow options after non-option arguments?
|
# Allow options after non-option arguments?
|
||||||
if shortopts.startswith('+'):
|
elif shortopts.startswith('+'):
|
||||||
shortopts = shortopts[1:]
|
shortopts = shortopts[1:]
|
||||||
all_options_first = True
|
all_options_first = True
|
||||||
elif os.environ.get("POSIXLY_CORRECT"):
|
elif os.environ.get("POSIXLY_CORRECT"):
|
||||||
|
@ -131,8 +133,14 @@ def gnu_getopt(args, shortopts, longopts = []):
|
||||||
break
|
break
|
||||||
|
|
||||||
if args[0][:2] == '--':
|
if args[0][:2] == '--':
|
||||||
|
if return_in_order and prog_args:
|
||||||
|
opts.append((None, prog_args))
|
||||||
|
prog_args = []
|
||||||
opts, args = do_longs(opts, args[0][2:], longopts, args[1:])
|
opts, args = do_longs(opts, args[0][2:], longopts, args[1:])
|
||||||
elif args[0][:1] == '-' and args[0] != '-':
|
elif args[0][:1] == '-' and args[0] != '-':
|
||||||
|
if return_in_order and prog_args:
|
||||||
|
opts.append((None, prog_args))
|
||||||
|
prog_args = []
|
||||||
opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:])
|
opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:])
|
||||||
else:
|
else:
|
||||||
if all_options_first:
|
if all_options_first:
|
||||||
|
|
|
@ -173,6 +173,12 @@ class GetoptTests(unittest.TestCase):
|
||||||
self.assertEqual(args, ['-'])
|
self.assertEqual(args, ['-'])
|
||||||
self.assertEqual(opts, [('-a', ''), ('-b', '-')])
|
self.assertEqual(opts, [('-a', ''), ('-b', '-')])
|
||||||
|
|
||||||
|
# Return positional arguments intermixed with options.
|
||||||
|
opts, args = getopt.gnu_getopt(cmdline, '-ab:', ['alpha', 'beta='])
|
||||||
|
self.assertEqual(args, ['arg2'])
|
||||||
|
self.assertEqual(opts, [('-a', ''), (None, ['arg1']), ('-b', '1'), ('--alpha', ''),
|
||||||
|
('--beta', '2'), ('--beta', '3')])
|
||||||
|
|
||||||
# Posix style via +
|
# Posix style via +
|
||||||
opts, args = getopt.gnu_getopt(cmdline, '+ab:', ['alpha', 'beta='])
|
opts, args = getopt.gnu_getopt(cmdline, '+ab:', ['alpha', 'beta='])
|
||||||
self.assertEqual(opts, [('-a', '')])
|
self.assertEqual(opts, [('-a', '')])
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Add support for returning intermixed options and non-option arguments in
|
||||||
|
order in :func:`getopt.gnu_getopt`.
|
Loading…
Add table
Add a link
Reference in a new issue