variable :envvar:`!POSIXLY_CORRECT` is set, then option processing stops as
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
>>> args
['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:
.. testcode::
* Add support for options with optional arguments.
(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
----
# TODO for gnu_getopt():
#
# - 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
# treat "-W foo" as "--foo"
long options which should be supported. The leading '--'
characters should not be included in the option name. Options
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 ('=?').
The return value consists of two elements: the first is a list of
else:
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?
- if shortopts.startswith('+'):
+ elif shortopts.startswith('+'):
shortopts = shortopts[1:]
all_options_first = True
elif os.environ.get("POSIXLY_CORRECT"):
break
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:])
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:])
else:
if all_options_first:
self.assertEqual(args, ['-'])
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 +
opts, args = getopt.gnu_getopt(cmdline, '+ab:', ['alpha', 'beta='])
self.assertEqual(opts, [('-a', '')])
--- /dev/null
+Add support for returning intermixed options and non-option arguments in
+order in :func:`getopt.gnu_getopt`.