def someFunc(someArg, someFlag = False): print "Flag value =", someFlag print "Arg value =", someArg from cmdline import Command command = Command(someFunc, "An example to show usage of command line", "Email bug reports to firstname.lastname@example.org") command.add_flag('s', 'setflag', 'Set the flag', 'someFlag') command.add_argument('SOMEARG', 'Some float argument', 'someArg', float) command.invoke()
This is can now be used from the command line in the fashion of standard unix command line utilities;
$ python test.py 3 Flag value = False Arg value = 3.0
Flags can be set
$ python test.py -s 5.3 Flag value = True Arg value = 5.3
Help can be called
$ python test.py --help Usage: test.py [OPTIONS] SOMEARG An example to show usage of command line Arguments SOMEARG Some float argument Mandatory arguments to long flags are mandatory for short options too -h, --help Show this help page -s, --setflag Set the flag Email bug reports to email@example.com
Setting configuration trees
Sometimes it isn't appropriate to call a function, especially when the number of configuration options grows. That's why it is also possible to set values in an arbitrary object;
# For some python object... config.general.verbose = False config.general.filename = "" config.i386.bounds_checks = False config.i386.overflow_checks = False from cmdline import ConfigSetter command = ConfigSetter(config, "An example command line app") command.add_flag('v', 'verbose', 'Verbose logging', 'general.verbose') command.add_flag(None, 'bounds-checks', 'Debugging bounds checks', 'i386.bounds_checks') command.add_flag(None, 'overflow-checks', 'Debugging overflow checks', 'i386.overflow_checks') command.add_argument('FILENAME', 'Filename to compile', 'general.filename') command.invoke() print "filename:", config.general.filename print "bounds checks:", config.i386.bounds_checks
$ python test.py --bounds-checks somefile.txt filename: somefile.txt bounds checks: True
So why should you use this instead of optparse? I actually wrote this before becoming aware of optparse, and once I noticed it, was a little annoyed. That said,
- I believe this is quicker, easier and cleaner to implement in code, while giving a full command line interface.
- Help (usage) option for free. This help is in the format of standard unix command line tools
- It also has the advantage of completely seperating the command line interface from actual functionality.
- It uses the well tested getopt module, so actual command line parsing is well tested.
- Lots of validating user input; If you want an int, either you get an int, or the user gets an error that they didn't enter an int.
- The code that checks for correct format uses a simple user provided callable object (eg: int, float, str...). This can be easily customised to parse user defined types (simply write a method to parse an object from a string)
- Checks for correctness of arguments, something getopt doesn't do (it is outside of it's functional spec). eg: if the user enters too many, not enough, or the wrong sort of argument, they get an error.
- When usage is printed, long strings are wrapped correctly at the end of the line
- When usage is printed, flags are sorted alphabetically
- No optional arguments to flags (difficult, as getopt doesn't seem to support them).
- At the moment, no support for repeated flags (all repeated flags converge into one)
The command line module is written in python, and uses the getopt library for parsing the command line.
While the examples show a unix type shell, it also works correctly in Microsoft Windows.
Release 0.20, 30 Jan 2007
Update the library to be more like a standard module (naming conventions, etc), plus general code improvements. Added a 'config' style backend, where flags can be set in a configuration tree (instead of invoking a function).
Release 0.10, 14 March 2005
Initial release of cmdline module