Introduce intermediate map to handle default values.
This helps to resolve issues with lists and functions: latest
supplied option should win, which was impossible earlier because
function were replaced with it's return value
--- a/fancyopts.py Mon Jun 15 19:17:33 2009 +0300
+++ b/fancyopts.py Mon Jun 15 19:23:10 2009 +0300
@@ -122,10 +122,8 @@
({'pid_file': 'test', 'daemonize': False, 'port': 8000, 'listen': '0.0.0.0'}, ['all'])
'''
- argmap = {}
- state = {}
- shortlist = ''
- namelist = []
+ argmap, defmap, state = {}, {}, {}
+ shortlist, namelist = '', []
for short, name, default, comment in options:
# change name to match Python styling
@@ -133,6 +131,14 @@
argmap['-' + short] = argmap['--' + name] = pyname
defmap[pyname] = default
+ # copy defaults to state
+ if isinstance(default, list):
+ state[pyname] = default[:]
+ elif hasattr(default, '__call__'):
+ state[pyname] = None
+ else:
+ state[pyname] = default
+
# getopt wants indication that it takes a parameter
if default not in (None, True, False):
if short: short += ':'
@@ -147,9 +153,9 @@
# transfer result to state
for opt, val in opts:
name = argmap[opt]
- t = type(state[name])
+ t = type(defmap[name])
if t is types.FunctionType:
- state[name] = state[name](val)
+ state[name] = defmap[name](val)
elif t is types.IntType:
state[name] = int(val)
elif t is types.StringType:
@@ -157,7 +163,7 @@
elif t is types.ListType:
state[name].append(val)
elif t in (types.NoneType, types.BooleanType):
- state[name] = not state[name]
+ state[name] = not defmap[name]
return state, args