Le Jul 31, 2012 à 1:45 PM, Oscar Benjamin a écrit : > > > 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
You're right. But then, using argparse, I would have to add the same argument to all my subparsers since argparse does the work sequentially: once it recognized the start of a subparser, everything that follows have to be an argument of this subparser. Hence, arguments (therefore options) from the main parser are not recognized anymore. > > $ python toto.py foo -n 10 foo.txt bar.txt Same remark as above: if I want the command line to look like this, then I would have setup each subparser with all the main program options. > > 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'? Well I guess it is a intrinsec limitation: I think it's quite natural that the user can't enter a filename named as a command. > > 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 > > -- 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