python-fire icon indicating copy to clipboard operation
python-fire copied to clipboard

feature request: allow passing unparsed parameters

Open ophiry opened this issue 7 years ago • 6 comments

a common idiom in cli is to have a flag (usually --, but this is taken here) that all text afterwards is passed as is (mostly for passing to other commands)

it could be useful to have a similar feature in fire

for example:

example.py foo --- this is passed as is - --

example.py:

import fire

def hello(name, __unparsed__):
  print(name)
  print(__unparsed__)

if __name__ == '__main__':
  fire.Fire(hello)

will yield:

foo this is passed as is - --

ophiry avatar Apr 17 '18 20:04 ophiry

Thanks for the suggestion. What's your use case? For the example you gave above, you can achieve the desired behavior with quotes.

example.py foo "this is passed as is - --"

dbieber avatar Apr 23 '18 18:04 dbieber

The use case is wrapper scripts that do some kind of preprocessing, and then launch a second script with the rest of the params (similar to docker and ssh where the unparsed parameters are treated as a command to run) quoting will work, but gets ugly when the original parameters contain quotes

ophiry avatar Apr 23 '18 19:04 ophiry

I see. Yes, that's an important use case.

For now you should be able to do this with the experimental decorator @decorators.SetParseFn(str) and *varargs. However, this decorator is an undocumented / experimental feature, and the syntax for it may change in future versions of fire.

dbieber avatar Apr 23 '18 20:04 dbieber

For example, with the current implementation of these decorators you can do this:

import fire
import subprocess

@fire.decorators.SetParseFn(str)
@fire.decorators.SetParseFns(number_of_repeats=int)
def repeat_command(number_of_repeats, *command):
  for _ in range(number_of_repeats):
    subprocess.call(command)

if __name__ == '__main__':
  fire.Fire(repeat_command)

This enables running a command multiple times like so:

example.py 4 echo hello world

dbieber avatar Apr 23 '18 20:04 dbieber

Hi, how can I make this work when the wrapped command has named options? For example, using the code above, if I do: python example.py 4 git --version, I get:

Fire trace:
1. Initial component
2. Called routine "repeat_command" (example.py:4)
3. ('Could not consume arg:', '--version')

I would like the command variable to get the tuple ('git', '--version')

mtikekar avatar Feb 10 '19 09:02 mtikekar

The decorator trick seem not work in this case. I think we still need to have fire to inject some context into the function being executed to enable such feature.

link89 avatar Sep 14 '22 02:09 link89