fancyopts option parser, first iteration
authorAlexander Solovyov <piranha@piranha.org.ua>
Sun, 31 May 2009 15:04:40 +0300
changeset 0 cbb132cade5c
child 1 64bd6c430858
fancyopts option parser, first iteration
fancyopts.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fancyopts.py	Sun May 31 15:04:40 2009 +0300
@@ -0,0 +1,62 @@
+# (c) Alexander Solovyov, 2009, under terms of the new BSD License
+'''Fancy option parser
+'''
+
+import getopt, types
+
+def fancyopts(args, options):
+    '''
+    >>> opts = [('l', 'listen', 'localhost',
+    ...          'ip to listen on (default: localhost)'),
+    ...         ('p', 'port', 8000,
+    ...          'port to listen on (default: 8000)'),
+    ...         ('d', 'daemonize', False,
+    ...          'daemonize process'),
+    ...         ('', 'pid-file', '',
+    ...          'name of file to write process ID to')]
+    >>> print fancyopts(['-l', '0.0.0.0', '--pi', 'test', 'all'], opts)
+    ({'pid_file': 'test', 'daemonize': False, 'port': 8000, 'listen': '0.0.0.0'}, ['all'])
+
+    '''
+    argmap = {}
+    state = {}
+    shortlist = ''
+    namelist = []
+
+    for short, oname, default, comment in options:
+        # change name to match Python styling
+        name = oname.replace('-', '_')
+        argmap['-' + short] = argmap['--' + oname] = name
+        state[name] = default
+
+        # it takes a parameter
+        if default not in (None, True, False):
+            if short: short += ':'
+            if oname: oname += '='
+        if short:
+            shortlist += short
+        if name:
+            namelist.append(oname)
+
+    opts, args = getopt.gnu_getopt(args, shortlist, namelist)
+
+    # transfer result to state
+    for opt, val in opts:
+        name = argmap[opt]
+        t = type(state[name])
+        if t is types.FunctionType:
+            state[name] = state[name](val)
+        elif t is types.IntType:
+            state[name] = int(val)
+        elif t is types.StringType:
+            state[name] = val
+        elif t is types.ListType:
+            state[name].append(val)
+        elif t in (types.NoneType, types.BooleanType):
+            state[name] = not state[name]
+
+    return state, args
+
+if __name__ == '__main__':
+    import doctest
+    doctest.testmod()