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

argparse with option/value like --gpg-options "--homedir=/home/user" errors out but adding binding op works. #118551

Open
kwloafman opened this issue May 3, 2024 · 5 comments
Labels
type-bug An unexpected behavior, bug, or error

Comments

@kwloafman
Copy link

kwloafman commented May 3, 2024

Bug report

Bug description:

--gpg-options is defined as follows:

    gpg_options=dict(
        metavar=_("options"),
        action=SplitOptionsAction,
        help="Verbatim gpg options.  May be supplied multiple times.",
        default=dflt(config.gpg_options),
    ),

This does not work (using space):

prog --gpg-options "--homedir=/home/user"

and gets argument --gpg-options: expected one argument

But this one does (using the binding op):

prog --gpg-options="--homedir=/home/user"

with gpg_options being set correctly.

The deprecated optparse handled this correctly.

See Also:
https://gitlab.com/duplicity/duplicity/-/issues/795
https://gitlab.com/duplicity/duplicity/-/issues/816

CPython versions tested on:

3.8, 3.9, 3.10, 3.11, 3.12

Operating systems tested on:

Linux, macOS

@kwloafman kwloafman added the type-bug An unexpected behavior, bug, or error label May 3, 2024
@vadmium
Copy link
Member

vadmium commented May 4, 2024

You might like to add a clear way to produce the bug. How does the gpg_options dictionary interface with the argparse module?

So far this sounds like the known bug #53580. Unfortunately, the documentation https://docs.python.org/3/library/argparse.html#arguments-containing indicates it is intended that cases like this assume the user made a mistake and an error is reported.

@kwloafman
Copy link
Author

It's a simple case of using a dataclass of dictionaries so that we can do:

    for opt in sorted(all_options):
        var = opt2var(opt)
        names = [opt] + OptionAliases.__dict__.get(var, [])
        parser.add_argument(*names, **OptionKwargs[var])

where OptionKwargs[var] is the dictionary above, one of 109 in duplicity.

So putting it all together it would appear as if expanded to multiple calls:

    parser.add_argument(
        "gpg-options", 
        metavar=_("options"),
        action=SplitOptionsAction,
        help="Verbatim gpg options.  May be supplied multiple times.",
        default=dflt(config.gpg_options),
)

@eli-schwartz
Copy link
Contributor

Note that per the linked ticket, the overall answer here is that optparse has POSIX-compatible semantics and argparse does not, and if you find yourself hitting this argparse bug the answer is to switch (back?) to optparse.

@kwloafman
Copy link
Author

When exactly does optparse get removed? It's been deprecated for years.

@eli-schwartz
Copy link
Contributor

There are no plans to ever remove it.

CPython considers it feature- complete and closed for future development, and also considered less ergonomic than argparse, hence "soft deprecated in the sense that for existing scripts it's fine to keep using it forever".

Note that argparse is also considered feature-complete and no one is really willing to develop it further beyond bugfixes, because it turns out that argument parsing libraries are hard and no one wants to touch them or something. 🤷 Ask most people and they will tell you to give up on the standard library as a bad idea and go use click instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-bug An unexpected behavior, bug, or error
Projects
Status: Bugs
Development

No branches or pull requests

3 participants