-
Notifications
You must be signed in to change notification settings - Fork 34
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
Support choices provided via the complete attribute #136
Conversation
@casperdcl could you please take a look at this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Srry for the delay; thanks for this PR!
Just for clarification, why not use
action = parser.add_argument(..., choices=["false", "true", "null"])
instead of action.complete = ["false", "true", "null"]
?
See the beginning of #68 for the motivation: "many shtab features would work out-of-the-box, avoiding the need for them to implement boilerplate". Making the users provide choices would be boilerplate. Take for instance a more complex case: parser.add_argument("--options", type=Optional[Union[EnumA, EnumB, bool]]) Should users need to manually create an array of possible inputs and set Also I think there could be some undesired side effects. Setting argument choices restricts the input to those values. For example in the case |
Note that If there's a boolean option, there are no choices to be selected, doesn't make much sense to combine those. The With |
Certainly. This feature does not limit anything related to
The motivation comes from action = parser.add_argument("--arg", type=str)
action.complete = shtab.custom_choices("prefix1_", "prefix2_", "prefix3_") Could be argued that there should be a specific completer for prefixes, so not applicable to
Not sure what you mean.
Note that there is a different proposal for other kinds of types #70. |
Thanks for the feedback.
That's I was trying to get at, as @casperdcl mentioned above. action = parser.add_argument(..., choices=["false", "true", "null"]) In this common situation, why not use the argparse choices argument already? Why repeat this in a special argument? I agree that the special argument |
Hmm I think I have a meta-gripe. IIUC, this PR solves 2 different problems:
I'd prefer a different approach:
WDYT? |
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## main #136 +/- ##
==========================================
+ Coverage 91.06% 91.48% +0.42%
==========================================
Files 3 3
Lines 347 376 +29
==========================================
+ Hits 316 344 +28
- Misses 31 32 +1
☔ View full report in Codecov by Sentry. |
As I explained before,
The main motivation is parser.add_argument("--bool", type=Optional[bool]) # custom_choices are automatically set
# no need to set choices either A second example with even less duplication is adding arguments from a function signature. The function already has type hints, so there is no reason to duplicate these to create a parser: parser.add_function_arguments(func_many_params) # adds many arguments, custom_choices automatic if applicable For this to be possible to implement in Apart from
Just for reference. If this is not enough motivation to justify adding a feature in |
I think I have come up with a viable alternative using |
Oh do you mean something like this? class Custom:
def __init__(self):
self.preamble_bash = ""
def choice(*choices):
assert all(isinstance(c, str) for c in choices)
choices_str = "('" + "' '".join(choices) + "')"
func_bash = f"_{hash(choices_str)}"
self.preamble_bash += f"""\
{func_bash}_choices={choices_str}
{func_bash}(){
compgen -W "${{{func_bash}_choices[*]}}" -- $1
}
"""
return {"bash": func_bash, "zsh": choices_str, "tcsh": choices_str} With the use case: custom = Custom()
parser.add_argument("--bool", type=Optional[bool]).complete = custom.choice("yes", "no", "null")
parser.add_argument(...).complete = custom.choice(...)
shtab.add_argument_to(parser, preamble={"bash": custom.preamble_bash}) |
No, what I had in mind is to have a wrapper to Regarding your idea, what I don't particularly like is that every developer would have to implement that class in their code. Common completion use cases should become functions/classes part of For the custom choices, if the only likely potential user is |
That's true for both
Ok, makes sense. |
I am interested in implementing #68. It is my first time looking at the shtab source code so do need some guidance. This pull request only implements the option to do like
Later I might also want to implement support the following, which could be relevant for discussing how to change the code now and later on.
For the moment I have only implemented the support in optional actions. I will wait for some feedback before doing it for positionals.