Introduce intermediate map to handle default values.
authorAlexander Solovyov <piranha@piranha.org.ua>
Mon, 15 Jun 2009 19:23:10 +0300
changeset 10 3aa5407b64e7
parent 9 7fb313fccdeb
child 11 560f5682ce00
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
fancyopts.py
--- 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