From cben@techunix.technion.ac.il Wed Dec 11 13:13:47 2002 From: cben@techunix.technion.ac.il (Beni Cherniavsky) Date: Wed, 11 Dec 2002 15:13:47 +0200 (IST) Subject: [getopt-sig] Ann: argexp - new option parsing library Message-ID: Hi, This is not mature enough yet for use in a real application (help printing not implemented) so I'm only announcing it here for now (if you think somebody does have use for it today, feel free to forward). I withholded releasing it since I felt "just a little bit and I will have a help system and it will be ready for use" but I didn't advance on that part for some time. Also Greg Ward mentioned that the name change optik->optarg could be a good oportunity to even introduce incompatibilities. So I decided to show what I have for possible cross-fertilization of ideas... It's currently availiable at: http://www.technion.ac.il/~cben/argexp/ ``argexp.py`` is the library itself, in one file. It's reasonably documented (rST docstrings all over), in particular the top module docstring gives an overview. It takes quite a different approach from optik in that it provides a full language for specifying the syntax and associated semantics of the command line. The building block is a Matcher object that takes a list of arguments and an associated env dict and returns some extracted information, a new argument list and a new env (or fails with an exception). The aim is to be able to directly handle *all* command-line parsing needs, including positional arguemtns, even for programs like cvs! To this end it's very easily extensible. To get a taste: >>> arglist = ['--fo', '.5', '-d'] >>> Option('--foo').match(arglist, {}) (0, ['.5', '-d'], {}) >>> Function(float).match(*_[1:]) (0.5, ['-d'], {}) >>> Repeat(Switch({ Option('--foo'): Set('foo', Function(float)), Or(Option('--debug'), Option('-d')): Set('debug', Quote(1)) })).match(arglist, {}) ([None, None], [], {'foo': 0.5, 'debug': 1}) A shorter way to describe the last matcher is by using "templates", that give meanings to standalone Python objects (strings, functions, lists, dicts, etc.): ``({'--foo': float, ('--debug', '-d'): 1},)`` :-). For a "real" example see ``ripoff_argexp.py`` - an interface to ripoff using in the context of: http://www.python.org/sigs/getopt-sig/compare.html With 127 lines, 84 of them code, it's smaller than all competitors except optik but it does quite a bit more than optik -- it parses ``-t 1,5-7,2`` into the list [1, 5, 6, 7, 2] and manages all conflicts between dependent options (-p/-f, -R => -k => -f) before they get to the application. The example shows approximately where the help strings will go. I'm still not sure how this will work. Basically the tree will be traversed in some flexible way that will allow to control how much to print (usage, full help, help limited to some part of the tree for big programs, etc.). I expect eventually to reach more help flexibility than possible with e.g. optik -- but as I said I have none yet ;-) -- Beni Cherniavsky What's lower level than machine code? A spreadsheet: not only addresses are numeric and hand-allocated but also all loops are hand-unrolled and all calls hand-inlined... (and macros are unheard of, of course).