How options in my programs conflict, and where argparse falls short

April 6, 2016

In my recent entry on argparse I mentioned that it didn't have really top notch handling of conflicting options; instead it only has relatively basic support for this. You might reasonably wonder what it's missing, and thus what top notch argument conflict handling is.

My programs tend to wind up with three sorts of options (command line switches):

  • general switches that affect almost everything
  • mode-selection switches that pick a major mode of operation
  • mode-modifying switches that change how one or more particular major modes work

General switches sometimes conflict with each other (eg --quiet versus --verbose), but apart from that they're applicable all or almost all the time. This is easily represented in argparse with a mutually exclusive group.

Mode selection switches conflict with each other because it normally only makes sense to pick one mode of operation. Some people would make them sub-commands instead (so instead of 'program -L ...' and 'program -Z ...' you'd have 'program op1 ...' and 'program op2 ...'), but I'm a Unix traditionalist and I mostly don't like that approach. Also, often my programs have a default mode where it is just 'program ...'. You can relatively easily represent this in argparse, again with a mutually exclusive group.

(You can't easily handle the case where a general switch happens to be inapplicable to a particular mode, though.)

Mode modifying switches go with one particular mode (or sometimes a couple) and don't make sense without that mode being picked. These logically group with their mode selection switch so that it should be an error to specify them without it. You can't represent this in argparse today; instead you have to check manually, or more likely just allow but silently ignore those switches (because the code paths the program will use doesn't even look at their values).

(And of course you can have nested situations, where some mode modifying switches conflict with each other or spawn sub-modes or whatever.)

It's not hard to see why argparse punts on this. The general case is clearly pretty complicated; you basically need to be able to form multiple arbitrary groups of conflicting arguments and 'these options require this one' sets, and options can be present in multiple groups. Then argparse would have to evaluate all of these constraints to detect conflicts and ideally produce sensible messages about them, which is probably much harder than it looks if there are multiple conflicts.

If I really care about this, I should probably get used to the now fairly common sub-commands approach. Since you can only specify one sub-command you naturally avoid conflicts between them, and argparse can set things up so each sub-command has its own set of options and so on.

Written on 06 April 2016.
« Some notes on Go's expvar package
What is behind Unix's 'Text file is busy' error »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Wed Apr 6 01:06:50 2016
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.