argparse vs getopt

Ian Bruene ianbruene at gmail.com
Sat Jun 10 05:34:10 UTC 2017


First: I am not considering performance here *whatsoever*, even if there 
were a meaningful difference, which I doubt, option parsing happens once 
during program startup, and ntpq doesn't need high speed anyway.

Advantages of getopt
     getopt is simpler, it only needs argv + some definitions fed into a 
single function and you get parsed options out the other end.
     The definitions are themselves simpler; just a string of the short 
arguments, and a list of strings for the long arguments.
     Because of that, the "setup" such as it is, is very compact.
     getopt results are simpler, just a list of (option, value) pairs 
that are easy to loop through.
     Since getopt does not handle usage notes the usage string will be 
defined in one place, and formatted exactly as the author intends.
     Generally speaking getopt handles basic option parsing and no more. 
This lack of options means there is no need to tell it which bells, 
whistles, and gongs should or should not be used.

Advantages of argparse
     All of the relevant information about an option is defined in the 
same place, this includes both short and long forms, casting, 
repetition, and usage string. This is a clear win for self-documentation 
despite being more verbose.
     argparse can automatically create the usage note from the 
information given to it in the definitions.
     The previous features result in a Single Point of Truth.
     While argparse's setup is far longer it is visually simpler than 
the big bag of bytes that getopt wants.
     argparse can cast and sanity check inputs where relevant.
     argparse can provide default values where relevant.
     argparse returns its results in a form that is more complicated, 
but does not require a loop to find and assign from.
     argparse supports options with optional values. The whole reason 
this thing started.


The general tradeoff between getopt vs argparse would appear to be a 
matter of option complexity: programs with few, simple options should 
use getopt. Programs which have many options, or options with complex 
argument or exclusivity requirements should use argparse as they will 
have lower overall complexity, and will also be easier to read.

TL;DR: if the program is xkcd 1168 compliant use argparse.

As it currently stands I believe that ntpq is small enough to be below 
the complexity crossover point. Of the 14 currently existing options 6 
are switches, 2 are knobs that take ints, 2 are for the auth system one 
taking an int the other a filename, 2 are commands, and 2 are debugs. No 
fancy parsing or exclusion is required, and the total number is low 
enough that there is little need to pull hair out when tinkering with 
the system. Under those circumstances I do not believe the transition 
cost is worth it, unless consistency across the python toolchain is a goal.

However.

The reason this subject is being discussed in the first place is because 
a currently existing snafu with the debug options would be best solved 
by adding separate options to control logging to a file. With getopt 
this requires 2 additional options because it doesn't support optional 
arguments. There is also the possibility of adding an option in the 
future to display the raw packets that are sent and received.

Given /these/ circumstances I believe the conversion to argparse is 
justifiable, with ntpq just coming over the threshold of benefiting from 
the SPOT and self-documenting aspects of argparse more than it loses 
from the increased setup costs. I am weighting the self-doc relatively 
high in this case because ntpq is part of NTPsec.

-- 
In the end; what separates a Man, from a Slave? Money? Power?
No. A Man Chooses, a Slave Obeys. -- Andrew Ryan



More information about the devel mailing list