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') 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