Friday, April 29, 2011

Combining ConfigParser and argparse with parse_known_args()

Edited to add: The best place to discuss this topic is on my original answer on StackOverflow.

I'm a fan of both the ConfigParser and argparse modules in my Python scripts and I've always thought it would be great to have a way to combine them. In other words allow the user of a script to provide a command line option that specified a configuration file that specified defaults for the command line options.

Recently I discovered the parse_known_args() method, which allows one to do just that.

Here's the script p.py that demonstrates this:


Here's a configuration file and a demonstration of how it works:


So this is what I was looking for, the caller can specify a configuration file with defaults, but override those defaults with more command line options.

There's only one problem, the help option only shows the configuration file option:


That's because the '-h' is processed by the parse_known_args() instead of the final parse_args(). The way to fix this is to create two ArgumentParsers and use the add_help parameter when creating first to suppress it from parsing -h:


Now help works like you would expect:

5 comments:

Lester Cheung said...

I always wondered about this one. Thanks for the example!

Lester Cheung said...

I always wonder about this one but never looked into it. Thanks for the example!

Petri Savolainen said...

Thanks for making the effort of writing this up. Very useful, helped me simplify some code. I would probably have not come up with this technique without your article. Thanks again!

Kumar McMillan said...

Fantastic, thanks. This should be in the argparse docs but your blog came up first in a search. I also got this to work with sub commands but it's a little weird because if you have two sub-arguments with the same name, only one wins in the config file. There could be another way to do it.

Kumar McMillan said...

Fantastic, thanks. This should be in the argparse docs but your blog came up first in a search. I also got this to work with sub commands but it's a little weird because if you have two sub-arguments with the same name, only one wins in the config file. There could be another way to do it.