On 31 July 2012 12:03, Benoist Laurent <beno...@ibpc.fr> wrote: > Finally. > > 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. > The reason seems to be that argparse thinks the last argument of the first > parser is the last but one argument. > Hence, if a subparser takes some arguments, it fails. > > Example: if the "-n" argument of the foo parser is set mandatory (so > becomes "n" instead of "-n") > > python toto.py foo.txt bar.txt foo 10 > usage: toto.py [-h] [fname [fname ...]] command ... > toto.py: error: argument command: invalid choice: '10' (choose from 'foo', > 'bar') >
What about: $ python toto.py foo.txt bar.txt foo -n 10 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 $ python toto.py foo -n 10 foo.txt bar.txt or perhaps $ python toto.py foo foo.txt bar.txt -n 10 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'? Oscar. > > Any solution? > > Cheers, > Ben > > > > Le Jul 31, 2012 à 12:37 PM, Benoist Laurent a écrit : > > Really sorry about that. > > So, for the community, below is the full code for a tool that behaves like > a Unix standard tool. > It takes in argument the files to process and a command. > > """Just to setup a command-line parser that acts just like a unix > standard tool.""" > > import argparse > import sys > > def define_options(): > parser = argparse.ArgumentParser() > parser.add_argument("fname", help="input file", nargs="*") > > # create subparsers > subparsers = parser.add_subparsers(dest="cmd", metavar="command") > > # create the parser for the "foo" command > get_parser = subparsers.add_parser("foo", help="foo help") > get_parser.add_argument("-n", help="number of foo to print", > type=int, default=10) > > # create the parser for the "bar" command > sum_parser = subparsers.add_parser("bar", help="bar help") > > return parser > > > if __name__ == '__main__': > args = define_options().parse_args() > > if not args.fname: > content = sys.stdin.read() > # do something > else: > for fname in args.fname: > with(open(fname, "rt")) as f: > content = f.read() > # do somet > > > Benoist > > > > Le Jul 31, 2012 à 11:55 AM, Oscar Benjamin a écrit : > > > On Jul 31, 2012 10:32 AM, "Benoist Laurent" <beno...@ibpc.fr> wrote: > > > > Well sorry about that but it seems I was wrong. > > It was Friday evening and I guess I've not been careful. > > > > 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". > > So you can't pass several arguments to the program. > > Right below that in the docs it explains about using nargs='*' and > nargs='+'. One of those will do what you want. > > Oscar. > > > > > So, to rephrase the question, how can I get a argument parser that > parses the command-line just as Unix grep would do? > > i.e. > > > > $ echo 42 > foo.txt > > $ echo 172 >> foo.txt > > $ cp foo.txt bar.txt > > $ > > $ grep 42 foo.txt > > 42 > > $ grep 42 foo.txt bar.txt > > foo.txt:42 > > bar.txt:42 > > $ cat foo.txt | grep 42 > > 42 > > $ grep -c 42 foo.txt > > 1 > > > > > > Cheers, > > Ben > > > > > > > > > > Le Jul 27, 2012 à 7:08 PM, Benoist Laurent a écrit : > > > >> > >> > >> Yes basically looks like you get it. > >> I have to further test it but my first impression is that it's correct. > >> > >> So actually the point was to use nargs="?". > >> > >> Thank you very much. > >> Ben > >> > >> > >> > >> Le Jul 27, 2012 à 5:44 PM, Peter Otten a écrit : > >> > >>> Benoist Laurent wrote: > >>> > >>>> I'm impletting a tool in Python. > >>>> > >>>> I'd like this tool to behave like a standard unix tool, as grep for > >>>> > >>>> exemple. I chose to use the argparse module to parse the command line > and > >>>> > >>>> I think I'm getting into several limitations of this module. > >>>> > >>>> > >>>>> First Question. > >>>> > >>>> How can I configure the the ArgumentParser to allow the user to give > >>>> > >>>> either an input file or to pipe the output from another program? > >>>> > >>>> > >>>> $ mytool.py file.txt > >>>> > >>>> $ cat file.txt | mytool.py > >>> > >>> > >>> $ echo alpha > in.txt > >>> $ cat in.txt | ./mytool.py > >>> ALPHA > >>> $ cat in.txt | ./mytool.py - out.txt > >>> $ cat out.txt > >>> ALPHA > >>> $ ./mytool.py in.txt > >>> ALPHA > >>> $ ./mytool.py in.txt out2.txt > >>> $ cat out2.txt > >>> ALPHA > >>> $ cat ./mytool.py > >>> #!/usr/bin/env python > >>> assert __name__ == "__main__" > >>> > >>> import argparse > >>> import sys > >>> > >>> parser = argparse.ArgumentParser() > >>> parser.add_argument("infile", nargs="?", type=argparse.FileType("r"), > >>> default=sys.stdin) > >>> parser.add_argument("outfile", nargs="?", type=argparse.FileType("w"), > >>> default=sys.stdout) > >>> args = parser.parse_args() > >>> > >>> args.outfile.writelines(line.upper() for line in args.infile) > >>> > >>> Is that good enough? > >>> > >>> > >>> -- > >>> http://mail.python.org/mailman/listinfo/python-list > >>> > >> > >> -- > >> Benoist Laurent > >> Laboratoire de Biochimie Theorique / CNRS UPR 9080 > >> Institut de Biologie Physico-Chimique > >> 13, rue Pierre et Marie Curie > >> F-75005 Paris > >> Tel. +33 [0]1 58 41 51 67 or +33 [0]6 21 64 50 56 > >> > >> -- > >> http://mail.python.org/mailman/listinfo/python-list > > > > > > -- > > Benoist Laurent > > Laboratoire de Biochimie Theorique / CNRS UPR 9080 > > Institut de Biologie Physico-Chimique > > 13, rue Pierre et Marie Curie > > F-75005 Paris > > Tel. +33 [0]1 58 41 51 67 or +33 [0]6 21 64 50 56 > > > > > > -- > > http://mail.python.org/mailman/listinfo/python-list > > > > > -- > Benoist Laurent > Laboratoire de Biochimie Theorique / CNRS UPR 9080 > Institut de Biologie Physico-Chimique > 13, rue Pierre et Marie Curie > F-75005 Paris > Tel. +33 [0]1 58 41 51 67 or +33 [0]6 21 64 50 56 > > -- > http://mail.python.org/mailman/listinfo/python-list > > > -- > Benoist Laurent > Laboratoire de Biochimie Theorique / CNRS UPR 9080 > Institut de Biologie Physico-Chimique > 13, rue Pierre et Marie Curie > F-75005 Paris > Tel. +33 [0]1 58 41 51 67 or +33 [0]6 21 64 50 56 > >
-- http://mail.python.org/mailman/listinfo/python-list