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

Preserving order of options and nonoption arguments in gnu_getopt() #126390

Closed
serhiy-storchaka opened this issue Nov 4, 2024 · 0 comments
Closed
Assignees
Labels
stdlib Python modules in the Lib dir type-feature A feature request or enhancement

Comments

@serhiy-storchaka
Copy link
Member

serhiy-storchaka commented Nov 4, 2024

Feature or enhancement

by default GNU getopt() permutes the contents of argv as it scans, so that eventually all the nonoptions are at the end. It supports two other scanning modes -- one compatible with Posix getopt() (stop at first nonoption argument), and other allows to return options and nonoption arguments in order.

getopt.gnu_getopt() returns two lists -- the list of option-and-value pairs and the list of nonoption arguments. Thus, the relative order of options and nonoption arguments is lost.

I propose to add support for the missed feature. If the first character of the option string is minus ('-'), non-option arguments that are followed by options will be 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. Non-option arguments that follow the last option will be returned as the second element of the gnu_getopt() result.

For example:

>>> 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']

I considered also alternative options:

  • Returning each nonoption argument as a separate (None, value) tuple instead of (None, list). But if you need a list of consequent arguments, it will be less convenient to build it from separate argument. And if you need separate arguments, you can simply iterate the list.
  • Returning the last portion of nonoption arguments also as a (None, list) pair. This makes handling nonoption arguments followed and not followed by options in user code uniform. But then the second element of the gnu_getopt() result will always be an empty list. I am not sure about this.
  • Add the third function (gnu_getopt_iter()?) which is a generator function and emits (option, value) or (None, list) pairs.

Linked PRs

@serhiy-storchaka serhiy-storchaka added type-feature A feature request or enhancement 3.14 new features, bugs and security fixes labels Nov 4, 2024
@serhiy-storchaka serhiy-storchaka self-assigned this Nov 4, 2024
serhiy-storchaka added a commit to serhiy-storchaka/cpython that referenced this issue Nov 4, 2024
@erlend-aasland erlend-aasland added the stdlib Python modules in the Lib dir label Nov 4, 2024
@picnixz picnixz removed the 3.14 new features, bugs and security fixes label Nov 6, 2024
serhiy-storchaka added a commit to serhiy-storchaka/cpython that referenced this issue Nov 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stdlib Python modules in the Lib dir type-feature A feature request or enhancement
Projects
None yet
Development

No branches or pull requests

3 participants