From b2913b6ae2248318090b13b1f2ccfe7e9781e244 2010-01-10 17:39:14
From: Fernando Perez <Fernando.Perez@berkeley.edu>
Date: 2010-01-10 17:39:14
Subject: [PATCH] Apply argparse code simplification to all kernel scripts.

---

diff --git a/IPython/config/loader.py b/IPython/config/loader.py
index a5ce5df..9198c37 100644
--- a/IPython/config/loader.py
+++ b/IPython/config/loader.py
@@ -362,6 +362,7 @@ class ArgParseConfigLoader(CommandLineConfigLoader):
             self.parser.add_argument(*argument[0],**argument[1])
 
     def _add_other_arguments(self):
+        """Meant for subclasses to add their own arguments."""
         pass
 
     def _parse_args(self, args):
diff --git a/IPython/kernel/clusterdir.py b/IPython/kernel/clusterdir.py
old mode 100644
new mode 100755
index 677d93e..ad8239f
--- a/IPython/kernel/clusterdir.py
+++ b/IPython/kernel/clusterdir.py
@@ -27,7 +27,6 @@ from IPython.core import release
 from IPython.config.loader import PyFileConfigLoader
 from IPython.core.application import Application
 from IPython.core.component import Component
-from IPython.config.loader import ArgParseConfigLoader, NoConfigDefault
 from IPython.utils.traitlets import Unicode, Bool
 from IPython.utils import genutils
 
@@ -219,54 +218,37 @@ class ClusterDir(Component):
         return ClusterDir(cluster_dir)
 
 
-class AppWithClusterDirArgParseConfigLoader(ArgParseConfigLoader):
-    """Default command line options for IPython cluster applications."""
-
-    def _add_other_arguments(self):
-        self.parser.add_argument('--ipython-dir', 
-            dest='Global.ipython_dir',type=unicode,
-            help='Set to override default location of Global.ipython_dir.',
-            default=NoConfigDefault,
-            metavar='Global.ipython_dir'
-        )
-        self.parser.add_argument('-p', '--profile',
-            dest='Global.profile',type=unicode,
-            help='The string name of the profile to be used. This determines '
-            'the name of the cluster dir as: cluster_<profile>. The default profile '
-            'is named "default".  The cluster directory is resolve this way '
-            'if the --cluster-dir option is not used.',
-            default=NoConfigDefault,
-            metavar='Global.profile'
-        )
-        self.parser.add_argument('--log-level',
-            dest="Global.log_level",type=int,
-            help='Set the log level (0,10,20,30,40,50).  Default is 30.',
-            default=NoConfigDefault,
-            metavar="Global.log_level"
-        )
-        self.parser.add_argument('--cluster-dir',
-            dest='Global.cluster_dir',type=unicode,
-            help='Set the cluster dir. This overrides the logic used by the '
-            '--profile option.',
-            default=NoConfigDefault,
-            metavar='Global.cluster_dir'
-        ),
-        self.parser.add_argument('--work-dir',
-            dest='Global.work_dir',type=unicode,
-            help='Set the working dir for the process.',
-            default=NoConfigDefault,
-            metavar='Global.work_dir'
-        )
-        self.parser.add_argument('--clean-logs',
-            dest='Global.clean_logs', action='store_true',
-            help='Delete old log flies before starting.',
-            default=NoConfigDefault
-        )
-        self.parser.add_argument('--no-clean-logs',
-            dest='Global.clean_logs', action='store_false',
-            help="Don't Delete old log flies before starting.",
-            default=NoConfigDefault
-        )
+# Default command line options for IPython cluster applications.
+cl_args = (
+    (('--ipython-dir',), dict(
+        dest='Global.ipython_dir',type=unicode,
+        help='Set to override default location of Global.ipython_dir.',
+        metavar='Global.ipython_dir') ),
+    (('-p', '--profile',), dict(
+        dest='Global.profile',type=unicode,
+        help=
+        """The string name of the profile to be used. This determines the name
+        of the cluster dir as: cluster_<profile>. The default profile is named
+        'default'.  The cluster directory is resolve this way if the
+        --cluster-dir option is not used.""",
+        metavar='Global.profile') ),
+    (('--cluster-dir',), dict(
+        dest='Global.cluster_dir',type=unicode,
+        help="""Set the cluster dir. This overrides the logic used by the
+        --profile option.""",
+        metavar='Global.cluster_dir') ),
+    (('--work-dir',), dict(
+      dest='Global.work_dir',type=unicode,
+      help='Set the working dir for the process.',
+      metavar='Global.work_dir') ),
+    (('--clean-logs',), dict(
+      dest='Global.clean_logs', action='store_true',
+      help='Delete old log flies before starting.') ),
+    (('--no-clean-logs',), dict(
+      dest='Global.clean_logs', action='store_false',
+      help="Don't Delete old log flies before starting.") ),
+    )
+
 
 class ApplicationWithClusterDir(Application):
     """An application that puts everything into a cluster directory.
@@ -289,6 +271,8 @@ class ApplicationWithClusterDir(Application):
 
     auto_create_cluster_dir = True
 
+    cl_arguments = Application.cl_arguments + cl_args
+
     def create_default_config(self):
         super(ApplicationWithClusterDir, self).create_default_config()
         self.default_config.Global.profile = u'default'
@@ -297,13 +281,6 @@ class ApplicationWithClusterDir(Application):
         self.default_config.Global.log_to_file = False
         self.default_config.Global.clean_logs = False
 
-    def create_command_line_config(self):
-        """Create and return a command line config loader."""
-        return AppWithClusterDirArgParseConfigLoader(
-            description=self.description, 
-            version=release.version
-        )
-
     def find_resources(self):
         """This resolves the cluster directory.
 
@@ -471,5 +448,3 @@ class ApplicationWithClusterDir(Application):
                 return pid
         else:
             raise PIDFileError('pid file not found: %s' % pid_file)
-
-
diff --git a/IPython/kernel/ipclusterapp.py b/IPython/kernel/ipclusterapp.py
old mode 100644
new mode 100755
index fe74e83..f30a882
--- a/IPython/kernel/ipclusterapp.py
+++ b/IPython/kernel/ipclusterapp.py
@@ -18,13 +18,12 @@ The ipcluster application.
 import logging
 import os
 import signal
-import sys
 
 if os.name=='posix':
     from twisted.scripts._twistd_unix import daemonize
 
 from IPython.core import release
-from IPython.external import argparse
+from IPython.external.argparse import ArgumentParser
 from IPython.config.loader import ArgParseConfigLoader, NoConfigDefault
 from IPython.utils.importstring import import_item
 
@@ -54,44 +53,40 @@ ALREADY_STOPPED = 11
 
 class IPClusterCLLoader(ArgParseConfigLoader):
 
-    def _add_arguments(self):
+    def _add_other_arguments(self):
         # This has all the common options that all subcommands use
-        parent_parser1 = argparse.ArgumentParser(add_help=False)
+        parent_parser1 = ArgumentParser(add_help=False,
+                                        argument_default=NoConfigDefault)
         parent_parser1.add_argument('--ipython-dir', 
             dest='Global.ipython_dir',type=unicode,
             help='Set to override default location of Global.ipython_dir.',
-            default=NoConfigDefault,
             metavar='Global.ipython_dir')
         parent_parser1.add_argument('--log-level',
             dest="Global.log_level",type=int,
             help='Set the log level (0,10,20,30,40,50).  Default is 30.',
-            default=NoConfigDefault,
             metavar='Global.log_level')
 
         # This has all the common options that other subcommands use
-        parent_parser2 = argparse.ArgumentParser(add_help=False)
+        parent_parser2 = ArgumentParser(add_help=False,
+                                        argument_default=NoConfigDefault)
         parent_parser2.add_argument('-p','--profile',
             dest='Global.profile',type=unicode,
             help='The string name of the profile to be used. This determines '
             'the name of the cluster dir as: cluster_<profile>. The default profile '
             'is named "default".  The cluster directory is resolve this way '
             'if the --cluster-dir option is not used.',
-            default=NoConfigDefault,
             metavar='Global.profile')
         parent_parser2.add_argument('--cluster-dir',
             dest='Global.cluster_dir',type=unicode,
             help='Set the cluster dir. This overrides the logic used by the '
             '--profile option.',
-            default=NoConfigDefault,
             metavar='Global.cluster_dir'),
         parent_parser2.add_argument('--work-dir',
             dest='Global.work_dir',type=unicode,
             help='Set the working dir for the process.',
-            default=NoConfigDefault,
             metavar='Global.work_dir')
         parent_parser2.add_argument('--log-to-file',
             action='store_true', dest='Global.log_to_file', 
-            default=NoConfigDefault,
             help='Log to a file in the log directory (default is stdout)'
         )
 
@@ -130,29 +125,24 @@ class IPClusterCLLoader(ArgParseConfigLoader):
         parser_start.add_argument(
             '-n', '--number',
             type=int, dest='Global.n',
-            default=NoConfigDefault,
             help='The number of engines to start.',
             metavar='Global.n'
         )
         parser_start.add_argument('--clean-logs',
             dest='Global.clean_logs', action='store_true',
             help='Delete old log flies before starting.',
-            default=NoConfigDefault
         )
         parser_start.add_argument('--no-clean-logs',
             dest='Global.clean_logs', action='store_false',
             help="Don't delete old log flies before starting.",
-            default=NoConfigDefault
         )
         parser_start.add_argument('--daemon',
             dest='Global.daemonize', action='store_true',
             help='Daemonize the ipcluster program. This implies --log-to-file',
-            default=NoConfigDefault
         )
         parser_start.add_argument('--no-daemon',
             dest='Global.daemonize', action='store_false',
             help="Dont't daemonize the ipcluster program.",
-            default=NoConfigDefault
         )
 
         parser_start = subparsers.add_parser(
@@ -164,7 +154,6 @@ class IPClusterCLLoader(ArgParseConfigLoader):
             dest='Global.signal', type=int,
             help="The signal number to use in stopping the cluster (default=2).",
             metavar="Global.signal",
-            default=NoConfigDefault
         )
 
 
@@ -372,8 +361,8 @@ class IPClusterApp(ApplicationWithClusterDir):
                 log.msg('Unexpected error in ipcluster:')
                 log.msg(r.getTraceback())
             log.msg("IPython cluster: stopping")
-            d= self.stop_engines()
-            d2 = self.stop_controller()
+            self.stop_engines()
+            self.stop_controller()
             # Wait a few seconds to let things shut down.
             reactor.callLater(4.0, reactor.stop)
 
diff --git a/IPython/kernel/ipcontrollerapp.py b/IPython/kernel/ipcontrollerapp.py
old mode 100644
new mode 100755
index 70ce723..7a2e9d2
--- a/IPython/kernel/ipcontrollerapp.py
+++ b/IPython/kernel/ipcontrollerapp.py
@@ -26,25 +26,17 @@ from twisted.internet import reactor
 from twisted.python import log
 
 from IPython.config.loader import Config, NoConfigDefault
-
-from IPython.kernel.clusterdir import (
-    ApplicationWithClusterDir, 
-    AppWithClusterDirArgParseConfigLoader
-)
-
 from IPython.core import release
-
-from IPython.utils.traitlets import Str, Instance, Unicode
-
+from IPython.core.application import Application
 from IPython.kernel import controllerservice
-
+from IPython.kernel.clusterdir import ApplicationWithClusterDir
 from IPython.kernel.fcutil import FCServiceFactory
+from IPython.utils.traitlets import Str, Instance, Unicode
 
 #-----------------------------------------------------------------------------
 # Default interfaces
 #-----------------------------------------------------------------------------
 
-
 # The default client interfaces for FCClientServiceFactory.interfaces
 default_client_interfaces = Config()
 default_client_interfaces.Task.interface_chain = [
@@ -107,19 +99,19 @@ class FCEngineServiceFactory(FCServiceFactory):
 cl_args = (
     # Client config
     (('--client-ip',), dict(
-        type=str, dest='FCClientServiceFactory.ip', default=NoConfigDefault,
+        type=str, dest='FCClientServiceFactory.ip', 
         help='The IP address or hostname the controller will listen on for '
         'client connections.',
         metavar='FCClientServiceFactory.ip')
     ),
     (('--client-port',), dict(
-        type=int, dest='FCClientServiceFactory.port', default=NoConfigDefault,
+        type=int, dest='FCClientServiceFactory.port', 
         help='The port the controller will listen on for client connections. '
         'The default is to use 0, which will autoselect an open port.',
         metavar='FCClientServiceFactory.port')
     ),
     (('--client-location',), dict(
-        type=str, dest='FCClientServiceFactory.location', default=NoConfigDefault,
+        type=str, dest='FCClientServiceFactory.location',
         help='The hostname or IP that clients should connect to. This does '
         'not control which interface the controller listens on. Instead, this '
         'determines the hostname/IP that is listed in the FURL, which is how '
@@ -129,19 +121,19 @@ cl_args = (
     ),
     # Engine config
     (('--engine-ip',), dict(
-        type=str, dest='FCEngineServiceFactory.ip', default=NoConfigDefault,
+        type=str, dest='FCEngineServiceFactory.ip', 
         help='The IP address or hostname the controller will listen on for '
         'engine connections.',
         metavar='FCEngineServiceFactory.ip')
     ),
     (('--engine-port',), dict(
-        type=int, dest='FCEngineServiceFactory.port', default=NoConfigDefault,
+        type=int, dest='FCEngineServiceFactory.port',
         help='The port the controller will listen on for engine connections. '
         'The default is to use 0, which will autoselect an open port.',
         metavar='FCEngineServiceFactory.port')
     ),
     (('--engine-location',), dict(
-        type=str, dest='FCEngineServiceFactory.location', default=NoConfigDefault,
+        type=str, dest='FCEngineServiceFactory.location',
         help='The hostname or IP that engines should connect to. This does '
         'not control which interface the controller listens on. Instead, this '
         'determines the hostname/IP that is listed in the FURL, which is how '
@@ -151,31 +143,26 @@ cl_args = (
     ),
     # Global config
     (('--log-to-file',), dict(
-        action='store_true', dest='Global.log_to_file', default=NoConfigDefault,
+        action='store_true', dest='Global.log_to_file',
         help='Log to a file in the log directory (default is stdout)')
     ),
     (('-r','--reuse-furls'), dict(
-        action='store_true', dest='Global.reuse_furls', default=NoConfigDefault,
+        action='store_true', dest='Global.reuse_furls',
         help='Try to reuse all FURL files. If this is not set all FURL files '
         'are deleted before the controller starts. This must be set if '
         'specific ports are specified by --engine-port or --client-port.')
     ),
     (('--no-secure',), dict(
-        action='store_false', dest='Global.secure', default=NoConfigDefault,
+        action='store_false', dest='Global.secure',
         help='Turn off SSL encryption for all connections.')
     ),
     (('--secure',), dict(
-        action='store_true', dest='Global.secure', default=NoConfigDefault,
+        action='store_true', dest='Global.secure',
         help='Turn off SSL encryption for all connections.')
     )
 )
 
 
-class IPControllerAppCLConfigLoader(AppWithClusterDirArgParseConfigLoader):
-
-    arguments = cl_args
-
-
 _description = """Start the IPython controller for parallel computing.
 
 The IPython controller provides a gateway between the IPython engines and
@@ -195,6 +182,7 @@ class IPControllerApp(ApplicationWithClusterDir):
     description = _description
     config_file_name = default_config_file_name
     auto_create_cluster_dir = True
+    cl_arguments = Application.cl_arguments + cl_args
 
     def create_default_config(self):
         super(IPControllerApp, self).create_default_config()
@@ -203,13 +191,6 @@ class IPControllerApp(ApplicationWithClusterDir):
         self.default_config.Global.import_statements = []
         self.default_config.Global.clean_logs = True
 
-    def create_command_line_config(self):
-        """Create and return a command line config loader."""
-        return IPControllerAppCLConfigLoader(
-            description=self.description, 
-            version=release.version
-        )
-
     def post_load_command_line_config(self):
         # Now setup reuse_furls
         c = self.command_line_config
@@ -272,4 +253,3 @@ def launch_new_instance():
 
 if __name__ == '__main__':
     launch_new_instance()
-
diff --git a/IPython/kernel/ipengineapp.py b/IPython/kernel/ipengineapp.py
old mode 100644
new mode 100755
index 9edc72b..dbd3e35
--- a/IPython/kernel/ipengineapp.py
+++ b/IPython/kernel/ipengineapp.py
@@ -22,29 +22,21 @@ from twisted.application import service
 from twisted.internet import reactor
 from twisted.python import log
 
-from IPython.config.loader import NoConfigDefault
-
-from IPython.kernel.clusterdir import (
-    ApplicationWithClusterDir, 
-    AppWithClusterDirArgParseConfigLoader
-)
-from IPython.core import release
-
-from IPython.utils.importstring import import_item
-
+from IPython.core.application import Application
+from IPython.kernel.clusterdir import ApplicationWithClusterDir
+from IPython.kernel.engineconnector import EngineConnector
 from IPython.kernel.engineservice import EngineService
 from IPython.kernel.fcutil import Tub
-from IPython.kernel.engineconnector import EngineConnector
+from IPython.utils.importstring import import_item
 
 #-----------------------------------------------------------------------------
 # The main application
 #-----------------------------------------------------------------------------
 
-
 cl_args = (
     # Controller config
     (('--furl-file',), dict(
-        type=unicode, dest='Global.furl_file', default=NoConfigDefault,
+        type=unicode, dest='Global.furl_file',
         help='The full location of the file containing the FURL of the '
         'controller. If this is not given, the FURL file must be in the '
         'security directory of the cluster directory.  This location is '
@@ -53,23 +45,18 @@ cl_args = (
     ),
     # MPI
     (('--mpi',), dict(
-        type=str, dest='MPI.use', default=NoConfigDefault,
+        type=str, dest='MPI.use',
         help='How to enable MPI (mpi4py, pytrilinos, or empty string to disable).',
         metavar='MPI.use')
     ),
     # Global config
     (('--log-to-file',), dict(
-        action='store_true', dest='Global.log_to_file', default=NoConfigDefault,
+        action='store_true', dest='Global.log_to_file',
         help='Log to a file in the log directory (default is stdout)')
     )
 )
 
 
-class IPEngineAppCLConfigLoader(AppWithClusterDirArgParseConfigLoader):
-
-    arguments = cl_args
-
-
 mpi4py_init = """from mpi4py import MPI as mpi
 mpi.size = mpi.COMM_WORLD.Get_size()
 mpi.rank = mpi.COMM_WORLD.Get_rank()
@@ -104,6 +91,7 @@ class IPEngineApp(ApplicationWithClusterDir):
     description = _description
     config_file_name = default_config_file_name
     auto_create_cluster_dir = True
+    cl_arguments = Application.cl_arguments + cl_args
 
     def create_default_config(self):
         super(IPEngineApp, self).create_default_config()
@@ -134,13 +122,6 @@ class IPEngineApp(ApplicationWithClusterDir):
         self.default_config.MPI.mpi4py = mpi4py_init
         self.default_config.MPI.pytrilinos = pytrilinos_init
 
-    def create_command_line_config(self):
-        """Create and return a command line config loader."""
-        return IPEngineAppCLConfigLoader(
-            description=self.description, 
-            version=release.version
-        )
-
     def post_load_command_line_config(self):
         pass