Back when Python 1.5.4 was hot and new, I wrote a class to serve as a basis for the many command line programs I was working on for myself and my employer. This was long before the Option Parsing Wars that resulted in the addition of optparse to the standard library. If optparse had been around, I probably wouldn’t have written CommandLineApp, but since all I had to work with at the time was getopt, and it operated at such a low level, I hacked together a helper class.

The difference between CommandLineApp and optparse is that CommandLineApp treats your application as an object, just like everything else in the application. The application class is responsible for option processing, although it collaborates with getopt to do the parsing work.

To use it, you subclass CommandLineApp and define option handler methods and a main(). To invoke the program, call run(). The option handlers are identified by name, and used to build the list of supported options. optionHandler_myopt() is called when --myopt is encountered. If the method takes an argument, so does your option. The docstrings for the callback methods are used to create the help output. Support for short-form usage (via -h) and long-form help (via --help) are built-in to the base class.

The old version (released as 1.0), which had not received a substantial rewrite in many years (mostly because it still worked fine and I had more important projects to work on) can run under Python 1.4 through 2.5. It was some of the earliest complex Python code I ever wrote, and that is clear from the code quality (both style and substance). The new version has been tested under Python 2.5. It feels less hack-ish, since it uses inspect instead of scanning the class hierarchy and method signatures directly.

The 2.0 rewrite works in essentially the same way as 1.0, but is much more compact and (I think) the code is cleaner. I called it 2.0 because the class API is different in a few important ways from the earlier version. I still want to add argument validation (for non-option arguments to the program), but that will take a little more time.