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

feature request: defopt.run add append option #95

Open
ickc opened this issue Dec 3, 2021 · 5 comments
Open

feature request: defopt.run add append option #95

ickc opened this issue Dec 3, 2021 · 5 comments

Comments

@ickc
Copy link

ickc commented Dec 3, 2021

See https://docs.python.org/3/library/argparse.html#action:

'append' - This stores a list, and appends each argument value to the list. This is useful to allow an option to be specified multiple times. Example usage:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='append')
>>> parser.parse_args('--foo 1 --foo 2'.split())
Namespace(foo=['1', '2'])

This feature request is to add an option to defopt.run s.t. parser.add_argument(..., action='append') behavior can be toggled.

@anntzer
Copy link
Owner

anntzer commented Dec 5, 2021

This and #96 both seem reasonable to me, but adding a global option to defopt.run seems unsatisfying because sooner or later someone will request to be able to specify this only for some of the parameters, perhaps in some deeply nested subcommands hierarchy on top of that...

Off the top of my head, a possibly(?) better solution could be to exploit typing.Annotated here, e.g. Annotated[list[int], defopt.APPEND] here and Annotated[list[int], defopt.VARARGS] for #96. (Note that for the case here, the underlying type annotation should be list[int], not int, because that's what the type of foo would ultimately be in the program.) A PR would be welcome :-) It should also clarify how these options interact with cli_options, as introduced by #92 (which is generalizing strict_kwonly).

@Spectre5
Copy link
Contributor

I wonder if it makes more sense to use the annotated method as suggested here or to provide a dictionary to defopt.run to indicate non-default behavior for certain parameters. This would be similar to how alternative parsers are provided as well as custom short cli arguments. It would also stick with the defopt philosophy of not changing the cli function itself, even if the Annotated solution is only in the type hint.

One potentially tricky issue to the dictionary method I've suggested is if the same argument could be passed to multiple commands with different behavior.

@anntzer
Copy link
Owner

anntzer commented Jan 22, 2022

My preference would be to use Annotated. I agree with your point about not changing the CLI function itself, but Annotated is spefically designed to include "context-specific metadata" (that's what its docs say), and CLI info seems suitable there.
I am indeed worried about people requesting different customizations for identically-named args being passed to multiple functions (especially now that you added nested subcommands, which suggest that rather complex CLIs are being built).

Your point about the parsers kwarg is well-taken, but that actually predates my involvement in defopt and my personal preference is rather to use the implicitly-constructible-from-str approach whenever possible (see StrWrapper at https://defopt.readthedocs.io/en/stable/features.html#parsers).

@Spectre5
Copy link
Contributor

Spectre5 commented Jan 22, 2022

Ok, so to implement this, I guess the first step is adding the functionality to properly handle Annotated. Then it seems that it could be used to solve this issue, #96, and #102. So it seems that it has a bit of value in it.

Annotated is only available in Python 3.9+.

@anntzer
Copy link
Owner

anntzer commented Jan 22, 2022

We depend indirectly on typing_extensions (via typing_inspect), which brings in support for Annotated on older Pythons (in fact, we already (briefly) use Annotated internally, in defopt.signature).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants