From 7115b61b3080e51e8cdeeb29728293883183f5ed 2011-07-16 15:43:26 From: MinRK Date: 2011-07-16 15:43:26 Subject: [PATCH] command-line pass * profile create does *not* include redundant '--init', inherited from parent app * --init message more verbose * include aliases in items scrubbed from the argv passed to the kernel from the frontend, now that unrecognized aliases throw a warning * remove plain/pure as aliases, leaving only bool flags * make _launcher_class help message more verbose, including example values * engines inherit work_dir from launching ipcluster by default, rather than using profile_dir * unimportable launcher classes won't cause a crash in ipcluster --- diff --git a/IPython/core/application.py b/IPython/core/application.py index 817ffcc..c4596a2 100644 --- a/IPython/core/application.py +++ b/IPython/core/application.py @@ -66,7 +66,9 @@ base_flags = dict( init = ({'BaseIPythonApplication' : { 'copy_config_files' : True, 'auto_create' : True} - }, "Initialize profile with default config files") + }, """Initialize profile with default config files. This is equivalent + to running `ipython profile create ` prior to startup. + """) ) diff --git a/IPython/core/profileapp.py b/IPython/core/profileapp.py index 1c96629..f02e8ef 100644 --- a/IPython/core/profileapp.py +++ b/IPython/core/profileapp.py @@ -136,11 +136,13 @@ class ProfileList(Application): create_flags = {} create_flags.update(base_flags) -create_flags.update(boolean_flag('reset', 'ProfileCreate.overwrite', - "reset config files to defaults", "leave existing config files")) -create_flags.update(boolean_flag('parallel', 'ProfileCreate.parallel', - "Include parallel computing config files", - "Don't include parallel computing config files")) +# don't include '--init' flag, which implies running profile create in other apps +create_flags.pop('init') +create_flags['reset'] = ({'ProfileCreate': {'overwrite' : True}}, + "reset config files in this profile to the defaults.") +create_flags['parallel'] = ({'ProfileCreate': {'parallel' : True}}, + "Include the config files for parallel " + "computing apps (ipengine, ipcontroller, etc.)") class ProfileCreate(BaseIPythonApplication): diff --git a/IPython/frontend/qt/console/qtconsoleapp.py b/IPython/frontend/qt/console/qtconsoleapp.py index ee0bd66..0d767ec 100644 --- a/IPython/frontend/qt/console/qtconsoleapp.py +++ b/IPython/frontend/qt/console/qtconsoleapp.py @@ -176,21 +176,20 @@ class MainWindow(QtGui.QMainWindow): #----------------------------------------------------------------------------- flags = dict(ipkernel_flags) - -flags.update({ +qt_flags = { 'existing' : ({'IPythonQtConsoleApp' : {'existing' : True}}, "Connect to an existing kernel."), 'pure' : ({'IPythonQtConsoleApp' : {'pure' : True}}, "Use a pure Python kernel instead of an IPython kernel."), 'plain' : ({'ConsoleWidget' : {'kind' : 'plain'}}, "Disable rich text support."), -}) -flags.update(boolean_flag( +} +qt_flags.update(boolean_flag( 'gui-completion', 'ConsoleWidget.gui_completion', "use a GUI widget for tab completion", "use plaintext output for completion" )) -flags.update(boolean_flag( +qt_flags.update(boolean_flag( 'confirm-exit', 'IPythonQtConsoleApp.confirm_exit', """Set to display confirmation dialog on exit. You can always use 'exit' or 'quit', to force a direct exit without any confirmation. @@ -199,31 +198,31 @@ flags.update(boolean_flag( if it is owned by the frontend, and leave it alive if it is external. """ )) +flags.update(qt_flags) # the flags that are specific to the frontend # these must be scrubbed before being passed to the kernel, # or it will raise an error on unrecognized flags -qt_flags = ['existing', 'pure', 'plain', 'gui-completion', 'no-gui-completion', - 'confirm-exit', 'no-confirm-exit'] +qt_flags = qt_flags.keys() aliases = dict(ipkernel_aliases) -aliases.update(dict( +qt_aliases = dict( hb = 'IPythonQtConsoleApp.hb_port', shell = 'IPythonQtConsoleApp.shell_port', iopub = 'IPythonQtConsoleApp.iopub_port', stdin = 'IPythonQtConsoleApp.stdin_port', ip = 'IPythonQtConsoleApp.ip', - plain = 'IPythonQtConsoleApp.plain', - pure = 'IPythonQtConsoleApp.pure', style = 'IPythonWidget.syntax_style', stylesheet = 'IPythonQtConsoleApp.stylesheet', colors = 'ZMQInteractiveShell.colors', editor = 'IPythonWidget.editor', paging = 'ConsoleWidget.paging', -)) -aliases['gui-completion'] = 'ConsoleWidget.gui_completion' +) +aliases.update(qt_aliases) +# also scrub aliases from the frontend +qt_flags.extend(qt_aliases.keys()) #----------------------------------------------------------------------------- @@ -316,8 +315,11 @@ class IPythonQtConsoleApp(BaseIPythonApplication): self.kernel_argv.append("--KernelApp.parent_appname='%s'"%self.name) # scrub frontend-specific flags for a in argv: - if a.startswith('-') and a.lstrip('-') in qt_flags: - self.kernel_argv.remove(a) + + if a.startswith('-'): + key = a.lstrip('-').split('=')[0] + if key in qt_flags: + self.kernel_argv.remove(a) def init_kernel_manager(self): # Don't let Qt or ZMQ swallow KeyboardInterupts. diff --git a/IPython/parallel/apps/ipclusterapp.py b/IPython/parallel/apps/ipclusterapp.py index 28b9b44..7b556fe 100755 --- a/IPython/parallel/apps/ipclusterapp.py +++ b/IPython/parallel/apps/ipclusterapp.py @@ -37,6 +37,7 @@ from IPython.core.application import BaseIPythonApplication from IPython.core.profiledir import ProfileDir from IPython.utils.daemonize import daemonize from IPython.utils.importstring import import_item +from IPython.utils.sysinfo import num_cpus from IPython.utils.traitlets import (Int, Unicode, Bool, CFloat, Dict, List, DottedObjectName) @@ -228,12 +229,32 @@ class IPClusterEngines(BaseParallelApplication): eslaunchers = [ l for l in launchers if 'EngineSet' in l.__name__] return [ProfileDir]+eslaunchers - n = Int(2, config=True, - help="The number of engines to start.") + n = Int(num_cpus(), config=True, + help="""The number of engines to start. The default is to use one for each + CPU on your machine""") engine_launcher_class = DottedObjectName('LocalEngineSetLauncher', config=True, - help="The class for launching a set of Engines." + help="""The class for launching a set of Engines. Change this value + to use various batch systems to launch your engines, such as PBS,SGE,MPIExec,etc. + Each launcher class has its own set of configuration options, for making sure + it will work in your environment. + + You can also write your own launcher, and specify it's absolute import path, + as in 'mymodule.launcher.FTLEnginesLauncher`. + + Examples include: + + LocalEngineSetLauncher : start engines locally as subprocesses [default] + MPIExecEngineSetLauncher : use mpiexec to launch in an MPI environment + PBSEngineSetLauncher : use PBS (qsub) to submit engines to a batch queue + SGEEngineSetLauncher : use SGE (qsub) to submit engines to a batch queue + SSHEngineSetLauncher : use SSH to start the controller + Note that SSH does *not* move the connection files + around, so you will likely have to do this manually + unless the machines are on a shared file system. + WindowsHPCEngineSetLauncher : use Windows HPC + """ ) daemonize = Bool(False, config=True, help="""Daemonize the ipcluster program. This implies --log-to-file. @@ -267,10 +288,14 @@ class IPClusterEngines(BaseParallelApplication): # not a module, presume it's the raw name in apps.launcher clsname = 'IPython.parallel.apps.launcher.'+clsname # print repr(clsname) - klass = import_item(clsname) + try: + klass = import_item(clsname) + except (ImportError, KeyError): + self.log.fatal("Could not import launcher class: %r"%clsname) + self.exit(1) launcher = klass( - work_dir=self.profile_dir.location, config=self.config, log=self.log + work_dir=u'.', config=self.config, log=self.log ) return launcher @@ -348,6 +373,12 @@ start_aliases.update(dict( )) start_aliases['clean-logs'] = 'IPClusterStart.clean_logs' +# set inherited Start keys directly, to ensure command-line args get higher priority +# than config file options. +for key,value in start_aliases.items(): + if value.startswith('IPClusterEngines'): + start_aliases[key] = value.replace('IPClusterEngines', 'IPClusterStart') + class IPClusterStart(IPClusterEngines): name = u'ipcluster' @@ -369,7 +400,21 @@ class IPClusterStart(IPClusterEngines): controller_launcher_class = DottedObjectName('LocalControllerLauncher', config=True, - help="The class for launching a Controller." + helep="""The class for launching a Controller. Change this value if you want + your controller to also be launched by a batch system, such as PBS,SGE,MPIExec,etc. + + Each launcher class has its own set of configuration options, for making sure + it will work in your environment. + + Examples include: + + LocalControllerLauncher : start engines locally as subprocesses + MPIExecControllerLauncher : use mpiexec to launch engines in an MPI universe + PBSControllerLauncher : use PBS (qsub) to submit engines to a batch queue + SGEControllerLauncher : use SGE (qsub) to submit engines to a batch queue + SSHControllerLauncher : use SSH to start the controller + WindowsHPCControllerLauncher : use Windows HPC + """ ) reset = Bool(False, config=True, help="Whether to reset config files as part of '--create'."