<br><br><div class="gmail_quote">On 31 July 2012 12:03, Benoist Laurent <span dir="ltr"><<a href="mailto:benoist@ibpc.fr" target="_blank">benoist@ibpc.fr</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div style="word-wrap:break-word">Finally.<div><br></div><div>The code I proposed doesn't work in this case: if you add any positional argument to one of the subparsers, then the parsing doesn't work anymore.</div>
<div>The reason seems to be that argparse thinks the last argument of the first parser is the last but one argument.</div><div>Hence, if a subparser takes some arguments, it fails.</div><div><br></div><div>Example: if the "-n" argument of the foo parser is set mandatory (so becomes "n" instead of "-n")</div>
<div><div><br></div><div><div>python toto.py foo.txt bar.txt foo 10</div><div>usage: toto.py [-h] [fname [fname ...]] command ...</div><div>toto.py: error: argument command: invalid choice: '10' (choose from 'foo', 'bar')</div>
</div></div></div></blockquote><div><br></div><div>What about:</div><div><br></div><div>$ python toto.py foo.txt bar.txt foo -n 10</div><div><br></div><div>Note that contrary to what you said above, your program does not work like a "standard unix tool". A standard command line program to do what you want would normally look like</div>
<div><br></div><div>$ python toto.py foo -n 10 foo.txt bar.txt</div><div><br></div><div>or perhaps</div><div><br></div><div><div>$ python toto.py foo foo.txt bar.txt -n 10</div></div><div><br></div><div>so that the algorithm for differentiating the command 'foo' from the filenames is well defined. How do you propose that your user enters a filename 'foo'?</div>
<div><br></div><div>Oscar.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div><br></div><div><br></div><div>
Any solution?</div><div><br></div><div>Cheers,</div><div>Ben</div><div><br></div><div><br></div><div><br><div><div>Le Jul 31, 2012 à 12:37 PM, Benoist Laurent a écrit :</div><div><div class="h5"><br><blockquote type="cite">
<div style="word-wrap:break-word">Really sorry about that.<div><br></div><div>So, for the community, below is the full code for a tool that behaves like a Unix standard tool.</div><div>It takes in argument the files to process and a command.</div>
<div><br></div><div><div>"""Just to setup a command-line parser that acts just like a unix</div><div>standard tool."""</div><div><br></div><div>import argparse</div><div>import sys</div><div>
<br></div><div>def define_options():</div><div>    parser = argparse.ArgumentParser()</div><div>    parser.add_argument("fname", help="input file", nargs="*")</div><div><br></div><div>    # create subparsers</div>
<div>    subparsers = parser.add_subparsers(dest="cmd", metavar="command")</div><div><br></div><div>    # create the parser for the "foo" command</div><div>    get_parser = subparsers.add_parser("foo", help="foo help")</div>
<div>    get_parser.add_argument("-n", help="number of foo to print", </div><div>                            type=int, default=10)</div><div><br></div><div>    # create the parser for the "bar" command</div>
<div>    sum_parser = subparsers.add_parser("bar", help="bar help")</div><div>    </div><div>    return parser</div><div><br></div><div><br></div><div>if __name__ == '__main__':</div><div>    args = define_options().parse_args()</div>
<div><br></div><div>    if not args.fname:</div><div>        content = sys.stdin.read()</div><div>        # do something</div><div>    else:</div><div>        for fname in args.fname:</div><div>            with(open(fname, "rt")) as f:</div>
<div>                content = f.read()</div><div>            # do somet</div></div><div><br></div><div><br></div><div>Benoist</div><div><br></div><div><br></div><div><br><div><div>Le Jul 31, 2012 à 11:55 AM, Oscar Benjamin a écrit :</div>
<br><blockquote type="cite"><p><br>
On Jul 31, 2012 10:32 AM, "Benoist Laurent" <<a href="mailto:benoist@ibpc.fr" target="_blank">benoist@ibpc.fr</a>> wrote:<br>
><br>
> Well sorry about that but it seems I was wrong.<br>
> It was Friday evening and I guess I've not been careful.<br>
><br>
> Actually when you specify nargs="?",  the doc says "One argument will be consumed from the command line if possible, and produced as a single item".<br>
> So you can't pass several arguments to the program.</p><p>Right below that in the docs it explains about using nargs='*' and nargs='+'. One of those will do what you want.</p><p>Oscar.</p><p>><br>

> So, to rephrase the question, how can I get a argument parser that parses the command-line just as Unix grep would do?<br>
> i.e.<br>
><br>
> $ echo 42 > foo.txt<br>
> $ echo 172 >> foo.txt<br>
> $ cp foo.txt bar.txt<br>
> $<br>
> $ grep 42 foo.txt<br>
> 42<br>
> $ grep 42 foo.txt bar.txt<br>
> foo.txt:42<br>
> bar.txt:42<br>
> $ cat foo.txt | grep 42<br>
> 42<br>
> $ grep -c 42 foo.txt<br>
> 1<br>
><br>
><br>
> Cheers,<br>
> Ben<br>
><br>
><br>
><br>
><br>
> Le Jul 27, 2012 à 7:08 PM, Benoist Laurent a écrit :<br>
><br>
>><br>
>><br>
>> Yes basically looks like you get it.<br>
>> I have to further test it but my first impression is that it's correct.<br>
>><br>
>> So actually the point was to use nargs="?".<br>
>><br>
>> Thank you very much.<br>
>> Ben<br>
>><br>
>><br>
>><br>
>> Le Jul 27, 2012 à 5:44 PM, Peter Otten a écrit :<br>
>><br>
>>> Benoist Laurent wrote:<br>
>>><br>
>>>> I'm impletting a tool in Python.<br>
>>>><br>
>>>> I'd like this tool to behave like a standard unix tool, as grep for<br>
>>>><br>
>>>> exemple. I chose to use the argparse module to parse the command line and<br>
>>>><br>
>>>> I think I'm getting into several limitations of this module.<br>
>>>><br>
>>>><br>
>>>>> First Question.<br>
>>>><br>
>>>> How can I configure the the ArgumentParser to allow the user to give<br>
>>>><br>
>>>> either an input file or to pipe the output from another program?<br>
>>>><br>
>>>><br>
>>>> $ mytool.py file.txt<br>
>>>><br>
>>>> $ cat file.txt | mytool.py<br>
>>><br>
>>><br>
>>> $ echo alpha > in.txt<br>
>>> $ cat in.txt | ./mytool.py <br>
>>> ALPHA<br>
>>> $ cat in.txt | ./mytool.py - out.txt<br>
>>> $ cat out.txt <br>
>>> ALPHA<br>
>>> $ ./mytool.py in.txt <br>
>>> ALPHA<br>
>>> $ ./mytool.py in.txt out2.txt<br>
>>> $ cat out2.txt <br>
>>> ALPHA<br>
>>> $ cat ./mytool.py<br>
>>> #!/usr/bin/env python<br>
>>> assert __name__ == "__main__"<br>
>>><br>
>>> import argparse<br>
>>> import sys<br>
>>><br>
>>> parser = argparse.ArgumentParser()<br>
>>> parser.add_argument("infile", nargs="?", type=argparse.FileType("r"), <br>
>>> default=sys.stdin)<br>
>>> parser.add_argument("outfile", nargs="?", type=argparse.FileType("w"), <br>
>>> default=sys.stdout)<br>
>>> args = parser.parse_args()<br>
>>><br>
>>> args.outfile.writelines(line.upper() for line in args.infile)<br>
>>><br>
>>> Is that good enough?<br>
>>><br>
>>><br>
>>> -- <br>
>>> <a href="http://mail.python.org/mailman/listinfo/python-list" target="_blank">http://mail.python.org/mailman/listinfo/python-list</a><br>
>>><br>
>><br>
>> -- <br>
>> Benoist Laurent<br>
>> Laboratoire de Biochimie Theorique / CNRS UPR 9080<br>
>> Institut de Biologie Physico-Chimique<br>
>> 13, rue Pierre et Marie Curie<br>
>> F-75005 Paris<br>
>> Tel. <a href="tel:%2B33%20%5B0%5D1%2058%2041%2051%2067" value="+33158415167" target="_blank">+33 [0]1 58 41 51 67</a> or <a href="tel:%2B33%C2%A0%5B0%5D6%2021%2064%2050%C2%A056" value="+33621645056" target="_blank">+33 [0]6 21 64 50 56</a><br>

>><br>
>> -- <br>
>> <a href="http://mail.python.org/mailman/listinfo/python-list" target="_blank">http://mail.python.org/mailman/listinfo/python-list</a><br>
><br>
><br>
> -- <br>
> Benoist Laurent<br>
> Laboratoire de Biochimie Theorique / CNRS UPR 9080<br>
> Institut de Biologie Physico-Chimique<br>
> 13, rue Pierre et Marie Curie<br>
> F-75005 Paris<br>
> Tel. <a href="tel:%2B33%20%5B0%5D1%2058%2041%2051%2067" value="+33158415167" target="_blank">+33 [0]1 58 41 51 67</a> or <a href="tel:%2B33%C2%A0%5B0%5D6%2021%2064%2050%C2%A056" value="+33621645056" target="_blank">+33 [0]6 21 64 50 56</a><br>

><br>
><br>
> --<br>
> <a href="http://mail.python.org/mailman/listinfo/python-list" target="_blank">http://mail.python.org/mailman/listinfo/python-list</a><br>
><br>
</p>
</blockquote></div><br><div>
-- <br>Benoist Laurent<br>Laboratoire de Biochimie Theorique / CNRS UPR 9080<br>Institut de Biologie Physico-Chimique<br>13, rue Pierre et Marie Curie<br>F-75005 Paris<br>Tel. <a href="tel:%2B33%20%5B0%5D1%2058%2041%2051%2067" value="+33158415167" target="_blank">+33 [0]1 58 41 51 67</a> or <a href="tel:%2B33%C2%A0%5B0%5D6%2021%2064%2050%C2%A056" value="+33621645056" target="_blank">+33 [0]6 21 64 50 56</a>
</div>
<br></div></div>-- <br><a href="http://mail.python.org/mailman/listinfo/python-list" target="_blank">http://mail.python.org/mailman/listinfo/python-list</a><br></blockquote></div></div></div><div><div class="h5"><br><div>

-- <br>Benoist Laurent<br>Laboratoire de Biochimie Theorique / CNRS UPR 9080<br>Institut de Biologie Physico-Chimique<br>13, rue Pierre et Marie Curie<br>F-75005 Paris<br>Tel. <a href="tel:%2B33%20%5B0%5D1%2058%2041%2051%2067" value="+33158415167" target="_blank">+33 [0]1 58 41 51 67</a> or <a href="tel:%2B33%C2%A0%5B0%5D6%2021%2064%2050%C2%A056" value="+33621645056" target="_blank">+33 [0]6 21 64 50 56</a>
</div>
<br></div></div></div></div></div></blockquote></div><br>