[getopt-sig] Documentation, functionality, options, syncing

Greg Ward gward@python.net
Wed, 20 Feb 2002 21:41:47 -0500


On 20 February 2002, A.T. Hofkamp said:
> - I believe that it is not possible to get really good quality documentation
>   from a number of one-liners that are part of an option. Especially, when
>   talking about man-page size (or bigger).
>   We should extend pydoc for such stuff.

I completely agree.  What you get from "foo --help" is a brief summary
of what's available.  If you already know how foo works and what it
does, it's a useful memory aid.  If you're completely new to foo, it
might be useful to you -- or it might not.  There *must* be a man page
(or similar) to fall back on.  That's not a technical problem, that's a
social problem.

>   Even with lesser size, I'd like to be in control of the order in which
>   help-text for options are printed (to allow grouping of similar options in
>   the help), and have proper line-break routines for instance.

Optik prints the help in the same order you add options to your
OptionParser, so you have control over the order.  It also uses a good,
solid line-wrapping routine (distutils.fancy_getopt.wrap_text() -- which
will have to move if distutils.fancy_getopt is removed!) to generate
pretty good-looking output.

For example, here's a snippet of the "--help" output from a CD ripping
script I wrote; naturally, it uses Optik for the option-parsing:

usage: ripoff [options]

options:
  -h, --help            show this help message and exit
  --version             show program's version number and exit
  -v                    increase verbosity level
  --verbose=V           set verbosity level to V
  -q, --quiet           run silently (verbosity = 0)
  -dDEVICE, --device=DEVICE
                        device file to open (default: /dev/cdrom on this
                        platform)
  -bDIR, --output-base=DIR
                        base output dir (default: /music/ogg)
  -tTRACKS, --tracks=TRACKS
                        tracks to rip (default: all) (example: 1,2-5,8)
  -p, --use-pipes, --synchronous
                        use named pipes for intermediate output (uses less
                        temporary disk space, works great if encoding is
                        faster than ripping) [default]
  -f, --use-files, --asynchronous
                        use real files for intermediate output (uses more
                        temporary disk space, but should be more reliable if
                        ripping is faster than encoding, and will free up your
                        CD-ROM drive sooner)
  [...]

Note that lines are nicely wrapped to 80 columns.  (Actually it's 78,
and yes it is hard-coded -- despite getting some useful answers on
c.l.py, I haven't gotten around to actually coding any of the 14
different ways to find out how big the terminal is.)  (You can see the
source for this script is at
  http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/ripoff/ripoff/ripoff?rev=1.42&content-type=text/vnd.viewcvs-markup
-- the option list is near the bottom, in main().)

The main thing missing from Optik is the ability to group options
thematically.  It's on my to-do list.

> - I also believe that it is a mistake to learn new Pythonists that writing a
>   one-liner for an option is documentation.  I'd rather have no
>   documentation (so it is glaring obvious there is none) than to have
>   a one-liner that means nothing to anyone except the author.

I quite disagree!  Any documentation is better than none at all.  And a
programmer who is incapable of writing decent per-option help -- ie. 95%
of programmers -- is probably also incapable of writing a decent man
page.

Again, this is a social problem, not a technical problem.  The Python
standard library can and should provide good tools, but it cannot turn
programmers into good documentors.

> - Please don't abuse pydoc strings for anything else than
>   documentation of the implementation.

+1

> - The argument of having to keep documentation and options in sync did not
>   convince me that having help as part of the option, and having an option
>   parser having to deal with help-output is good.
> 
>   On the other hand, I can understand the concern of keeping
>   everything in sync. There fore, I'd like to propose two different
>   approaches to the matter.  Quite likely, others (with more
>   experience in this field of keeping stuff in sync) can improve
>   and/or propose entirely new approaches.
> 
>   * The first approach is to create the help text, while adding options to the
>     parser, i.e. something like
> 
>     parser.AddOption('-h')
>     helptext.append('-h get this helptext')

If you're proposing a separate class whose sole responsibility is
formatting help, that's a good idea.  That's a large and hairy chunk of
my OptionParser class, and factoring it out to a new class might be a
good idea.  (Especially if we want to put in hooks for customizing help
output.)  But there's no good reason why we have to expose that
implementation detail to the programmer; what's wrong with spelling that

  parser.add_option('-h', help="get this help text")

anyways?  Under the hood, the OptionParser could be updating a
HelpFormatter, but that's irrelevant to the API.  Yes, it ties you to
having your help in the same order as your options are defined.  I think
that's a feature: it ties documentation clarity to code clarity; as one
increases (decreases), so does the other.  Can you think of an example
where you would want to define options in a different order than you
would document them?

        Greg
-- 
Greg Ward - geek-at-large                               gward@python.net
http://starship.python.net/~gward/
Don't hate yourself in the morning -- sleep till noon.