--- /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()