Broke type conversion out into hooke.util.convert and expanded its use.
authorW. Trevor King <wking@drexel.edu>
Tue, 3 Aug 2010 20:26:37 +0000 (16:26 -0400)
committerW. Trevor King <wking@drexel.edu>
Tue, 3 Aug 2010 20:26:37 +0000 (16:26 -0400)
hooke/config.py
hooke/plugin/curve.py
hooke/plugin/playlist.py
hooke/plugin/playlists.py
hooke/plugin/vclamp.py
hooke/ui/commandline.py
hooke/util/convert.py [new file with mode: 0644]

index c1776c8eee6367056490269c1e54a0dc0d6b8fe7..1c5c4874d53d4191078b599f8fb5aa6e91e8e380 100644 (file)
@@ -26,6 +26,7 @@ import textwrap
 import unittest
 
 from .compat.odict import odict as OrderedDict
+from .util.convert import to_string, from_string
 
 
 DEFAULT_PATHS = [
@@ -39,24 +40,6 @@ specific user files, so the user can override the sysadmin who
 in turn overrides the developer defaults.
 """
 
-CONVERT_FROM_STRING = {
-    'string': lambda x: x,
-    'bool': lambda x: x == 'True',
-    'int': lambda x: int(x),
-    'float': lambda x: float(x),
-    }
-"""Functions converting strings to values, keyed by type.
-"""
-
-CONVERT_TO_STRING = {
-    'string': lambda x: x,
-    'bool': lambda x: str(x),
-    'int': lambda x: str(x),
-    'float': lambda x: str(x),
-    }
-"""Functions converting values to strings, keyed by type.
-"""
-
 class Setting (object):
     """An entry (section or option) in HookeConfigParser.
     """
@@ -64,7 +47,7 @@ class Setting (object):
                  help=None, wrap=True):
         self.section = section
         self.option = option
-        self.value = CONVERT_TO_STRING[type](value)
+        self.value = to_string(value=value, type=type)
         self.type = type
         self.help = help
         self.wrap = wrap
@@ -316,13 +299,13 @@ class HookeConfigParser (configparser.RawConfigParser):
         for i,kv in enumerate(items):
             key,value = kv
             setting = self._default_settings_dict[(section, key)]
-            items[i] = (key, CONVERT_FROM_STRING[setting.type](value))
+            items[i] = (key, from_string(value=value, type=setting.type))
         return items
 
     def set(self, section, option, value):
         """Set an option."""
         setting = self._default_settings_dict[(section, option)]
-        value = CONVERT_TO_STRING[setting.type](value)
+        value = to_string(value=value, type=setting.type)
         # Can't use super() because RawConfigParser is a classic class
         #return super(HookeConfigParser, self).set(section, option, value)
         configparser.RawConfigParser.set(self, section, option, value)
index 7621fc79d2b2a899a7ac4f91e070722e79bcccfb..6221dbe0d4055fac0e1b80bad252a078dfcf7192 100644 (file)
@@ -163,7 +163,7 @@ True if you want the column-naming header line.
             help=self.__doc__, plugin=plugin)
 
     def _run(self, hooke, inqueue, outqueue, params):
-        data = params['curve'].data[int(params['block'])] # HACK, int() should be handled by ui
+        data = params['curve'].data[params['block']]
 
         f = open(params['output'], 'w')
         if params['header'] == True:
index 73fd5a3ec04e0a388fbdb4d75e1587c109a217a0..dccc572ff86d12aa5c834709c810cda30761d754 100644 (file)
@@ -117,7 +117,7 @@ Index of target curve.
             help=self.__doc__, plugin=plugin)
 
     def _run(self, hooke, inqueue, outqueue, params):
-       params['playlist'].jump(int(params['index'])) # HACK, int() should be handled by ui
+       params['playlist'].jump(params['index'])
 
 class IndexCommand (Command):
     """Print the index of the current curve.
index 44bbe923074eb75c1672ea39aa995b518d0d8c75..2ba4ecfe342cab3ec6c27af3ac5748ff4e33fc77 100644 (file)
@@ -71,7 +71,7 @@ Index of target curve.
             help=self.__doc__, plugin=plugin)
 
     def _run(self, hooke, inqueue, outqueue, params):
-       hooke.playlists.jump(int(params['index'])) # HACK, int() should be handled by ui
+       hooke.playlists.jump(params['index'])
 
 class IndexCommand (Command):
     """Print the index of the current playlist.
index 5751d3808ee6f94c98b939e8ec856c65f750b9cd..2365122aaff8a278397e62439ff845cda15e1fb0 100644 (file)
@@ -246,7 +246,7 @@ selects the retracting curve.
             help=self.__doc__, plugin=plugin)
 
     def _run(self, hooke, inqueue, outqueue, params):
-        data = params['curve'].data[int(params['block'])] # HACK, int() should be handled by ui
+        data = params['curve'].data[params['block']]
         # HACK? rely on params['curve'] being bound to the local hooke
         # playlist (i.e. not a copy, as you would get by passing a
         # curve through the queue).  Ugh.  Stupid queues.  As an
@@ -267,8 +267,8 @@ selects the retracting curve.
         new.info['surface detection parameters'] = ps
         new[:,-2] = z_data - surface_offset
         new[:,-1] = d_data - deflection_offset
-        data = params['curve'].data[int(params['block'])] # HACK, int() should be handled by ui
-        params['curve'].data[int(params['block'])] = new # HACK, int() should be handled by ui
+        data = params['curve'].data[params['block']]
+        params['curve'].data[params['block']] = new
 
     def find_contact_point(self, curve, z_data, d_data, outqueue=None):
         """Railyard for the `find_contact_point_*` family.
@@ -433,7 +433,7 @@ selects the retracting curve.
             help=self.__doc__, plugin=plugin)
 
     def _run(self, hooke, inqueue, outqueue, params):
-        data = params['curve'].data[int(params['block'])] # HACK, int() should be handled by ui
+        data = params['curve'].data[params['block']]
         # HACK? rely on params['curve'] being bound to the local hooke
         # playlist (i.e. not a copy, as you would get by passing a
         # curve through the queue).  Ugh.  Stupid queues.  As an
@@ -445,7 +445,7 @@ selects the retracting curve.
         new.info['columns'].append('deflection (N)')
         d_data = data[:,data.info['columns'].index('surface adjusted deflection (m)')]
         new[:,-1] = d_data * data.info['spring constant (N/m)']
-        params['curve'].data[int(params['block'])] = new # HACK, int() should be handled by ui
+        params['curve'].data[params['block']] = new
 
 
 class generalvclampCommands(object):
index 132d65785cefa3850a4a9e1cd6e5984d6e427b8e..4baaf851fdd57f54b4fb301f909bc81de520f15a 100644 (file)
@@ -29,6 +29,7 @@ import shlex
 from ..command import CommandExit, Exit, Command, Argument, StoreValue
 from ..interaction import Request, BooleanRequest, ReloadUserInterfaceConfig
 from ..ui import UserInterface, CommandMessage
+from ..util.convert import from_string
 from ..util.encoding import get_input_encoding, get_output_encoding
 
 
@@ -53,8 +54,27 @@ class CommandLineParser (optparse.OptionParser):
                 continue # 'help' is a default OptionParser option
             if a.optional == True:
                 name = name_fn(a.name)
+                type = a.type
+                if type == 'bool':
+                    if a.default == True:
+                        self.add_option(
+                            '--disable-%s' % name, dest=name, default=Default,
+                            action='store_false')
+                        self.command_opts.append(a)
+                        continue
+                    elif a.default == False:
+                        self.add_option(
+                            '--enable-%s' % name, dest=name, default=Default,
+                            action='store_true')
+                        self.command_opts.append(a)
+                        continue
+                    else:
+                        type = 'string'
+                elif type not in ['string', 'int', 'long', 'choice', 'float',
+                                  'complex']:
+                    type = 'string'
                 self.add_option(
-                    '--%s' % name, dest=name, default=Default)
+                    '--%s' % name, dest=name, type=type, default=Default)
                 self.command_opts.append(a)
             else:
                 self.command_args.append(a)
@@ -102,6 +122,7 @@ class DoCommand (CommandMethod):
             self.cmd.stdout.write(str(e).lstrip()+'\n')
             self.cmd.stdout.write('Failure\n')
             return
+        print args
         self.cmd.inqueue.put(CommandMessage(self.command, args))
         while True:
             msg = self.cmd.outqueue.get()
@@ -130,12 +151,15 @@ class DoCommand (CommandMethod):
         arg_index = 0
         for argument in self.parser.command_args:
             if argument.count == 1:
-                params[argument.name] = args[arg_index]
+                params[argument.name] = from_string(args[arg_index],
+                                                    argument.type)
             elif argument.count > 1:
-                params[argument.name] = \
-                    args[arg_index:arg_index+argument.count]
+                params[argument.name] = [
+                    from_string(a, argument.type)
+                    for a in args[arg_index:arg_index+argument.count]]
             else: # argument.count == -1:
-                params[argument.name] = args[arg_index:]
+                params[argument.name] = [
+                    from_string(a, argument.type) for a in args[arg_index:]]
             arg_index += argument.count
         return params
 
diff --git a/hooke/util/convert.py b/hooke/util/convert.py
new file mode 100644 (file)
index 0000000..92e6b64
--- /dev/null
@@ -0,0 +1,63 @@
+# Copyright
+
+"""Type conversion utilities.
+"""
+
+CONVERT_FROM_STRING = {
+    'string': lambda x: x,
+    'bool': lambda x: x == 'True',
+    'int': lambda x: int(x),
+    'float': lambda x: float(x),
+    }
+"""Functions converting strings to values, keyed by type.
+"""
+
+ANALOGS = {
+    'file': 'string',
+    'point': 'int',
+    }
+"""Types that may be treated as other types.
+
+These types may have optional special handling on the UI end
+(e.g. file picker dialogs), but it is not required.
+"""
+
+RAW_TYPES = [
+    'curve',
+    'dict',
+    'driver',
+    'function',
+    'object',
+    'playlist',
+    ]
+"""List of types that should not be converted.
+"""
+
+def to_string(value, type):
+    """Convert `value` from `type` to a unicode string.
+    """
+    type = ANALOGS.get(type, type)
+    if type in RAW_TYPES:
+        return value
+    return unicode(value)
+
+def from_string(value, type):
+    """Convert `value` from a string to `type`.
+    """
+    type = ANALOGS.get(type, type)
+    if type in RAW_TYPES:
+        return value
+    fn = globals()['_string_to_%s' % type]
+    return fn(value)
+
+def _string_to_string(value):
+    return unicode(value)
+
+def _string_to_bool(value):
+    return value == 'True'
+
+def _string_to_int(value):
+    return int(value)
+
+def _string_to_float(value):
+    return float(value)