Reputation: 103
I would like to use a variable number of arguments in a task for pyinvoke. Like so:
from invoke import task
@task(help={'out_file:': 'Name of the output file.',
'in_files': 'List of the input files.'})
def pdf_combine(out_file, *in_files):
print( "out = %s" % out_file)
print( "in = %s" % list(in_files))
The above is only one of many variations I tried out but it seems pyinvoke can't handle a variable number of arguments. Is this true?
The above code results in
$ invoke pdf_combine -o binder.pdf -i test.pdf test1.pdf
No idea what '-i' is!
Similar, if I define pdf_combine(out_file, in_file), without the asterisk before in_file
$ invoke pdf_combine -o binder.pdf -i test.pdf test1.pdf
No idea what 'test1.pdf' is!
If I invoke the task with only one in_file like below it run OK.
$ invoke pdf_combine -o binder.pdf -i test.pdf
out = binder.pdf
in = ['t', 'e', 's', 't', '.', 'p', 'd', 'f']
What I would like to see is
$ invoke pdf_combine -o binder.pdf test.pdf test1.pdf test2.pdf
out = binder.pdf
in = [test.pdf test1.pdf test2.pdf]
I could not find anything like that in the documentation of pyinvoke, though I cannot imagine that other users of this library do not have the need for calling a task with a variable number of arguments...
Upvotes: 10
Views: 2664
Reputation: 5518
As of version 0.21.0 you can use iterable flag values:
@task(
help={
'out-file': 'Name of the output file.', # `out-file` NOT `out_file`
'in-files': 'List of the input files.'},
iterable=['in_files'],
)
def pdf_combine(out_file, in_files):
for item in in_files:
print(f"file: {item}")
NOTE help
using the dash converted key and iterable
using the non-converted underscore key
NOTE I understand the above note is kinda odd, so I submitted a PR since the author is pretty awesome and might take the suggestion into consideration
Using it in this way allows for this type of cli:
$ invoke pdf-combine -o spam -i eggs -i ham
file: eggs
file: ham
$ invoke --help pdf-combine
Usage: inv[oke] [--core-opts] pdf-combine [--options] [other tasks here ...]
Docstring:
none
Options:
-i, --in-files List of the input files
-o STRING, --out-file=STRING Name of the output file.
NOTE pdf_combine
task is called with inv pdf-combine
from the CLI
Upvotes: 1
Reputation: 6844
You can do something like this:
from invoke import task
@task
def pdf_combine(out_file, in_files):
print( "out = %s" % out_file)
print( "in = %s" % in_files)
in_file_list = in_files.split(',') # insert as many args as you want separated by comma
>> out = binder.pdf
>> in = test.pdf,test1.pdf,test2.pdf
Where the invoke
command is:
invoke pdf_combine -o binder.pdf -i test.pdf,test1.pdf,test2.pdf
I couldn't find another way to do this reading the pyinvoke
documentation.
Upvotes: 4