-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Behaviour of fire for variadic arguments #169
Comments
|
Thanks for the quick reply @dbieber. par1 and par2 will still not be visible in fire help area, I want user to know about these par1 and par2 flags. Moreover any other workaround ? |
For a flag to appear in the help text, it has to appear as an argument in the function: For example: def special(par1, par2):
print(par1)
print(par2) You could also mention par1 and par2 in the docstring, which will be shown with the help text. |
Actually I have two flags in my original code, one with nargs as '+' and other as '*' and now I want to create my function in best possible way to cover these aspects. What do you think can be the best way ? |
If you use quotes, it won't be shell dependent. If you share your original code, I can better tell you how to write it with Fire. Please share not just the argparse code, but also the lines where the arguments get used, as this is the most important part for informing how to translate your CLI to Fire. |
Actually I am working on deepmind's kapitan https://github.com/deepmind/kapitan, and the main cli file containing logic for argparse is https://github.com/deepmind/kapitan/blob/master/kapitan/cli.py |
I hope the following is helpful - here's what I put together for translating cli.py to use Fire: So, currently it looks like this:
As a first step, I recommend moving that to a structure more like:
And you don't even need to define lint, because it's already available as So you just need to define write functions for eval, compile, inventory, and secrets. I'll do eval here as an example. Here's the current implementation:
Here's how you would modify it for fire:
You could also modify the signature to be: In that case, you can even remove the splitting logic: Once you have eval, compile, inventory, and secrets defined, you can do something like this: fire.Fire({'eval': eval, 'compile': compile, 'inventory': inventory, 'searchvar': searchvar, 'lint': start_lint, 'init': initialise_skeleton, 'secrets': secrets}) Or if you want greater flexibility (but a messier CLI since it will pick up extra objects beyond the ones you want to expose), you can simply do If you use python cli.py jsonfile yaml --search-paths="[path1,path2]" --vars="['var1=val1','var2=val2']" (This is obviously messy and error prone; if you take this route I recommend making vars just a string, rather than a list, and parsing it yourself. You're already doing some of the parsing yourself anyway with the line "ext_vars = dict(var.split('=') for var in vars)"). If you use python cli.py jsonfile yaml path1 path2 --var1=val1 --var2=val2. I think this last line is what you were asking about. It sounds like you want to combine the approaches, so can specify |
My recommendation is to just accept a string (using signature |
Thanks a lot @dbieber for such elaborate analysis. Much appreciated. I would discuss there as well and then finally migrate it to python-fire. I also think your recommended way is much cleaner. |
While using |
You can use decorators.SetParseFn to force it to be a string, but 1) that API isn't guaranteed stable in future versions, and 2) don't you want it as a tuple anyway? In Fire, you generally don't require or declare a specific type for a specific arg. Instead, the value provided by the user determines the type. So, if users are likely to pass in both strings and tuples, then your code should be written to handle both strings and tuples. |
When I passed |
The parsing logic is here https://github.com/google/python-fire/blob/master/fire/parser.py#L57. It converts bare words to strings and then uses Python's literal eval. This is to give you the flexibility of using any of Python's primitive types without requiring you to use quotes for strings. If the arg doesn't parse in this way, it is kept as a string. Determining types directly from the values is one of Fire's strengths but can also be a pain point when it gives unexpected behavior, like you're seeing now. |
Thanks @dbieber. I have now wrapped parsing stuff inside a function, just a bit more help about displaying basic project summary. I mean we have PROJECT_NAME, DESCRIPTION, VERSION etc, so are they also needed to be wrapped inside a function and then fired or is there some other way as well ? |
I'm not sure I understand what you're asking. Are PROJECT_NAME, DESCRIPTION, VERSION values to be set by the user, or are they part of kapitan? |
They are part of kapitan. Just to be displayed. Project name is kapitan, and project description is kapitan defined in one line.
These are in fact displayed when we just type kapitan. How we can create an equivalent behavior in Fire ? Moreover after constructing all functions in fire is there some way to show the docstring of each function on |
For description and version, you can wrap your functions in a class rather than a dict
And for showing all the docstrings on |
Hey @dbieber , as mentioned in #108 , shorthand notation is indeed added in fire. But when I try to use
as Is the shorthand ability added for all types or only boolean ? According to logic defined here Line 840 in d15fa28
|
Yes, it will work in the next release. That improvement wasn't available yet in 0.0.3. |
When are you planning for next release ? |
I'm not able to make a reliable time estimate atm - but the main thing we want to finish before the release is switching from helputils to helptext, the latter of which is still a work in progress. |
The release should be going out later today (July 26, 2019). |
I have some codebase which uses argparse and wanted to migrate into python-fire. Now there I have option of specifying nargs as different flags to get required arguments. Now say I have one flag which uses '+' and one uses '*' to get arguments. How can I wrap all this stuff in a function so that fire converts into desired cli automatically. Actually I want to get variable size list for different flags.
Consider this testfire.py
python testfire.py special --par1 haha --par2 a b c
produces:
I would like to achieve is that to be able to have these name of par1 and par2 integrated and for par2 I want to get a, b, c in list.
Thanks
The text was updated successfully, but these errors were encountered: