changeset 0:3081763b099b

initial commit of ConfigOptionParser
author Jeff Hammel <jhammel@mozilla.com>
date Thu, 20 May 2010 08:47:35 -0700
parents
children 3148ccbd82de
files configoptionparser/__init__.py example.ini example.py setup.py
diffstat 4 files changed, 162 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configoptionparser/__init__.py	Thu May 20 08:47:35 2010 -0700
@@ -0,0 +1,93 @@
+from optparse import OptionParser
+from ConfigParser import ConfigParser
+
+### duplicate/extend ConfigParser functions as we can't use them directly :(
+
+def getlist(string, separator=','):
+  """returns a list from a string given a separator"""
+  string = string.strip()
+  if not string:
+    return []
+  return [i.strip() for i in string.split(separator)]
+
+def getboolean(string):
+  return string.lower() == 'true'
+
+
+class Undefined(object):
+  def __init__(self, default):
+    self.default=default
+
+class ConfigOptionParser(OptionParser):
+  def __init__(self, defaults_section='DEFAULTS', dict_section=None,
+               variables=None, **kwargs):
+    """
+    - defaults_section: section of .ini to look for configuration variables
+    - dict_section: section of .ini to return as a dictionary
+    - variables: attr on returned options to parse dictionary from command line
+    """
+    self.defaults_section = defaults_section
+    self.dict_section = dict_section
+    self.variables = variables
+    if self.dict_section and not self.variables:
+      self.variables = dict_section
+    OptionParser.__init__(self, **kwargs)
+    OptionParser.add_option(self,
+                            '-c', '--config', dest='config', action='append',
+                            help='ini file to read from')
+
+  def add_option(self, *args, **kwargs):
+    kwargs['default'] = Undefined(kwargs.get('default'))
+    OptionParser.add_option(self, *args, **kwargs)
+
+  def parse_args(self, args=None, values=None):
+    options, args = OptionParser.parse_args(self, args, values)
+
+    # get defaults from the configuration parser
+    defaults = {}
+    config = ConfigParser()
+    if options.config:
+      config.read(options.config)
+      if self.defaults_section in config.sections():
+        defaults = dict(config.items(self.defaults_section, raw=True))
+
+    # option dict
+    option_dict = dict([(i.dest, i) for i in self.option_list
+                        if i.dest not in ('config', 'help')])
+
+    # conversion functions for .ini data
+    conversions = { 'store_true': getboolean,
+                    'store_false': getboolean,
+                    'append': getlist }
+
+    # fill in the defaults not set from the command line
+    for key, value in options.__dict__.items():
+      
+      # don't override command line arguments! they win!
+      if isinstance(value, Undefined):
+
+        if key in defaults and key in option_dict:
+          # fill in options from .ini files
+
+          option = option_dict[key]
+          
+          # converstion function
+          function = conversions.get(option.action, lambda x: x)
+          
+          setattr(options, key, function(defaults[key]))
+        else:
+          # set from option defaults
+          setattr(options, key, value.default)
+
+    # get variables from dict_section and command line arguments
+    # TODO: could do this first then interpolate the config file from these
+    variables = {}
+    if self.dict_section in config.sections():
+      variables.update(dict(config.items(self.dict_section, raw=True)))
+    if self.variables:
+      variables.update(dict([i.split('=',1) for i in args if '=' in i]))
+      args = [i for i in args if '=' not in i]
+      setattr(options, self.variables, variables)
+    
+    return (options, args)
+      
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/example.ini	Thu May 20 08:47:35 2010 -0700
@@ -0,0 +1,9 @@
+[DEFAULTS]
+foo = bar
+bar = baz
+fleem = blah
+list = foo, bar, baz
+verbose = True
+
+[variables]
+blah = w00t
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/example.py	Thu May 20 08:47:35 2010 -0700
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+
+"""
+Example script to illustrate ConfigOptionParser.
+Run from the command line and give some arguments to see how this works.
+
+Read values from .ini file:
+ python example.py -c example.ini
+
+Read values from .ini file but override the setting for the foo
+ python example.py -c example.ini -f blah
+
+Override/add variables from the command line:
+ python example.py -c example.ini blah=bleem fargo=bah -f blah
+"""
+
+import sys
+from configoptionparser import ConfigOptionParser
+
+parser = ConfigOptionParser(dict_section='variables')
+parser.add_option('-f', dest='foo')
+parser.add_option('--baz', default='the baz default string')
+parser.add_option('--fleem')
+parser.add_option('--list', dest='list', action='append')
+parser.add_option('--verbose', dest='verbose', action='store_true',
+                  default=False)
+
+def main(args=sys.argv[1:]):
+  options, args = parser.parse_args(args)
+  for key in sorted(options.__dict__):
+    print '%s: %s' % (key, options.__dict__[key])
+  print 'args: %s' % args
+
+if __name__ == '__main__':
+  main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/setup.py	Thu May 20 08:47:35 2010 -0700
@@ -0,0 +1,25 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='ConfigOptionParser',
+      version=version,
+      description="a version of OptionParser that allows parsing from .ini files",
+      long_description="""\
+""",
+      classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
+      keywords='ini cli',
+      author='Jeff Hammel',
+      author_email='jhammel@mozilla.com',
+      url='http://k0s.org',
+      license='MPL',
+      packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=[
+          # -*- Extra requirements: -*-
+      ],
+      entry_points="""
+      # -*- Entry points: -*-
+      """,
+      )