Parse config file and command-line arguments, to get a single collection of options
rzed
rzantow at gmail.com
Sat May 28 19:12:04 EDT 2011
Ben Finney <ben at benfinney.id.au> wrote in
news:87k4deaxfc.fsf at benfinney.id.au:
> Howdy all,
>
> Python's standard library has modules for configuration file
> parsing (configparser) and command-line argument parsing
> (optparse, argparse). I want to write a program that does both,
> but also:
>
> * Has a cascade of options: default option values, overridden by
> config
> file options, overridden by command-line options.
>
> * Reads a different, or even additional, configuration file if
> specified
> on the command-line (e.g. --config-file foo.conf) and yet still
> obeys the above cascade.
>
> * Allows a single definition of an option (e.g. logging level) to
> define
> the same option for parsing from configuration files and the
> command line.
>
> * Unifies the parsed options into a single collection for the
> rest of
> the program to access without caring where they came from.
>
> How can I achieve this with minimum deviation from the Python
> standard library?
>
>
> (For anyone interested in gaining StackOverflow points, I'm also
> asking this as a question there so feel free to post answers on
> that site
> <URL:http://stackoverflow.com/questions/6133517/parse-config-file-
> and-command-line-arguments-to-get-a-single-collection-of-optio>.)
>
This seems vaguely similar to a module I wrote and use all the time.
It allows default value specification, categorization of command-line
options, in-line parsing of further spec file[s] and overrides of
values in the the sequence you define, pretty much. It doesn't deal
with the "logging level" item. I'm not sure what that would mean. The
idea of the module is to create a namespace object (though it could
as easily be a dict) that contains whatever values are specified.
in the program it would be invoked like this:
ctx = Cmdline( outfname='test.out', size=(250,400), ... ) (or
whatever).
The command line can contain switches, prefixed by hyphens, spec file
names, prefixed by @, untagged names, or key=value pairs. The values
will be parsed as (tuples), [lists], or {dicts}, ints, floats, or
strings. I did not, I am ashamed to say, resist the temptation to
guess. 'Ctx' will contain the result of all this. Switches, if any
are in a list named ctx._switches, unadorned arguments are in a list
named ctx._vars, and the other stuff is pretty much as you would
expect. It expects configuration files to be in a sort of ini-file
format.
Here's an example:
---------------------------
test.spec:
log=test.log
count=10
size=(400,200)
group1={key=value,a=alpha}
group2={b=beta,name=doogie howser}
#
temp=[1,2,5,11,22]
sub=(al,becky,carl,diane,edwin,fran)
---------------------------
test.py:
from Cmdline import Cmdline
c = Cmdline( count=5, log='pink.tank')
c.show()
---------------------------
>python test.py log=friend.txt @test.spec count=32 name=waldo
... yields:
<type 'int'> count = 32
<type 'tuple'> sub = ('al', 'becky', 'carl', 'diane', 'edwin',
'fran')
<type 'str'> log = 'test.log'
<type 'list'> temp = [1, 2, 5, 11, 22]
<type 'dict'> group1 = {'a': 'alpha', 'key': 'value'}
<type 'dict'> group2 = {'b': 'beta', 'name': 'doogie howser'}
<type 'tuple'> size = (400, 200)
<type 'str'> name = 'waldo'
... while
>python @test.spec count=32 name=waldo temp=Vitalis sub='' dream -k
<type 'int'> count = 32
<type 'list'> _vars = ['dream']
<type 'str'> log = 'test.log'
<type 'str'> temp = 'Vitalis'
<type 'list'> _switches = ['k']
<type 'str'> name = 'waldo'
<type 'dict'> group1 = {'a': 'alpha', 'key': 'value'}
<type 'dict'> group2 = {'b': 'beta', 'name': 'doogie howser'}
<type 'tuple'> size = (400, 200)
<type 'str'> sub = ''
What the program does with the results is up to it, of course.
--
rzed
More information about the Python-list
mailing list