diff --git a/IPython/config/application.py b/IPython/config/application.py index 05022e0..5679b7d 100644 --- a/IPython/config/application.py +++ b/IPython/config/application.py @@ -19,10 +19,11 @@ Authors: # Imports #----------------------------------------------------------------------------- -from copy import deepcopy import logging +import os import re import sys +from copy import deepcopy from IPython.config.configurable import SingletonConfigurable from IPython.config.loader import ( @@ -98,9 +99,13 @@ class Application(SingletonConfigurable): version = Unicode(u'0.0') # The log level for the application - log_level = Enum((0,10,20,30,40,50), default_value=logging.WARN, - config=True, - help="Set the log level.") + log_level = Enum((0,10,20,30,40,50,'DEBUG','INFO','WARN','ERROR','CRITICAL'), + default_value=logging.WARN, + config=True, + help="Set the log level by value or name.") + def _log_level_changed(self, name, old, new): + if isinstance(new, basestring): + self.log_level = getattr(logging, new) # the alias map for configurables aliases = Dict(dict(log_level='Application.log_level')) @@ -336,6 +341,16 @@ class Application(SingletonConfigurable): loader = PyFileConfigLoader(filename, path=path) config = loader.load_config() self.update_config(config) + + def generate_config_file(self): + """generate default config file from Configurables""" + lines = ["# Configuration file for %s."%self.name] + lines.append('') + lines.append('c = get_config()') + lines.append('') + for cls in self.classes: + lines.append(cls.class_config_section()) + return '\n'.join(lines) def exit(self, exit_status=0): self.log.debug("Exiting application: %s" % self.name) diff --git a/IPython/config/configurable.py b/IPython/config/configurable.py index 94a7595..61a3ee2 100755 --- a/IPython/config/configurable.py +++ b/IPython/config/configurable.py @@ -180,6 +180,38 @@ class Configurable(HasTraits): """Get the help string for a single trait and print it.""" print cls.class_get_help() + @classmethod + def class_config_section(cls): + """Get the config class config section""" + def c(s): + """return a commented, wrapped block.""" + s = '\n\n'.join(wrap_paragraphs(s, 78)) + + return '# ' + s.replace('\n', '\n# ') + + # section header + breaker = '#' + '-'*78 + s = "# %s configuration"%cls.__name__ + lines = [breaker, s, breaker, ''] + # get the description trait + desc = cls.class_traits().get('description') + if desc: + desc = desc.default_value + else: + # no description trait, use __doc__ + desc = getattr(cls, '__doc__', '') + if desc: + lines.append(c(desc)) + lines.append('') + + for name,trait in cls.class_traits(config=True).iteritems(): + help = trait.get_metadata('help') or '' + lines.append(c(help)) + lines.append('# c.%s.%s = %r'%(cls.__name__, name, trait.get_default_value())) + lines.append('') + return '\n'.join(lines) + + class SingletonConfigurable(Configurable): """A configurable that only allows one instance. @@ -280,4 +312,4 @@ class LoggingConfigurable(Configurable): from IPython.config.application import Application return Application.instance().log - \ No newline at end of file + diff --git a/IPython/config/profile/default/__init__.py b/IPython/config/profile/default/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/IPython/config/profile/default/__init__.py +++ /dev/null diff --git a/IPython/config/profile/default/ipcluster_config.py b/IPython/config/profile/default/ipcluster_config.py deleted file mode 100644 index d345fd0..0000000 --- a/IPython/config/profile/default/ipcluster_config.py +++ /dev/null @@ -1,242 +0,0 @@ -import os - -c = get_config() - -#----------------------------------------------------------------------------- -# Select which launchers to use -#----------------------------------------------------------------------------- - -# This allows you to control what method is used to start the controller -# and engines. The following methods are currently supported: -# - Start as a regular process on localhost. -# - Start using mpiexec. -# - Start using the Windows HPC Server 2008 scheduler -# - Start using PBS/SGE -# - Start using SSH - - -# The selected launchers can be configured below. - -# Options are: -# - LocalControllerLauncher -# - MPIExecControllerLauncher -# - PBSControllerLauncher -# - SGEControllerLauncher -# - WindowsHPCControllerLauncher -# c.IPClusterStartApp.controller_launcher = 'IPython.parallel.apps.launcher.LocalControllerLauncher' -# c.IPClusterStartApp.controller_launcher = 'IPython.parallel.apps.launcher.PBSControllerLauncher' - -# Options are: -# - LocalEngineSetLauncher -# - MPIExecEngineSetLauncher -# - PBSEngineSetLauncher -# - SGEEngineSetLauncher -# - WindowsHPCEngineSetLauncher -# c.IPClusterEnginesApp.engine_launcher = 'IPython.parallel.apps.launcher.LocalEngineSetLauncher' - -#----------------------------------------------------------------------------- -# Application configuration -#----------------------------------------------------------------------------- - -# The default number of engines that will be started. This is overridden by -# the -n command line option: "ipcluster start -n 4" -# c.IPClusterEnginesApp.n = 2 - -# Log to a file in cluster_dir/log, otherwise just log to sys.stdout. -# c.BaseParallelApp.log_to_file = False - -# Remove old logs from cluster_dir/log before starting. -# c.BaseParallelApp.clean_logs = True - -# The working directory for the process. The application will use os.chdir -# to change to this directory before starting. -# c.BaseParallelApp.work_dir = os.getcwd() - - -#----------------------------------------------------------------------------- -# Local process launchers -#----------------------------------------------------------------------------- - -# The command line arguments to call the controller with. -# c.LocalControllerLauncher.controller_args = \ -# ['--log-to-file','--log-level', '40'] - -# The working directory for the controller -# c.LocalEngineSetLauncher.work_dir = u'' - -# Command line argument passed to the engines. -# c.LocalEngineSetLauncher.engine_args = ['--log-to-file','--log-level', '40'] - -#----------------------------------------------------------------------------- -# MPIExec launchers -#----------------------------------------------------------------------------- - -# The mpiexec/mpirun command to use in both the controller and engines. -# c.MPIExecLauncher.mpi_cmd = ['mpiexec'] - -# Additional arguments to pass to the actual mpiexec command. -# c.MPIExecLauncher.mpi_args = [] - -# The mpiexec/mpirun command and args can be overridden if they should be different -# for controller and engines. -# c.MPIExecControllerLauncher.mpi_cmd = ['mpiexec'] -# c.MPIExecControllerLauncher.mpi_args = [] -# c.MPIExecEngineSetLauncher.mpi_cmd = ['mpiexec'] -# c.MPIExecEngineSetLauncher.mpi_args = [] - -# The command line argument to call the controller with. -# c.MPIExecControllerLauncher.controller_args = \ -# ['--log-to-file','--log-level', '40'] - -# Command line argument passed to the engines. -# c.MPIExecEngineSetLauncher.engine_args = ['--log-to-file','--log-level', '40'] - -# The default number of engines to start if not given elsewhere. -# c.MPIExecEngineSetLauncher.n = 1 - -#----------------------------------------------------------------------------- -# SSH launchers -#----------------------------------------------------------------------------- - -# ipclusterz can be used to launch controller and engines remotely via ssh. -# Note that currently ipclusterz does not do any file distribution, so if -# machines are not on a shared filesystem, config and json files must be -# distributed. For this reason, the reuse_files defaults to True on an -# ssh-launched Controller. This flag can be overridded by the program_args -# attribute of c.SSHControllerLauncher. - -# set the ssh cmd for launching remote commands. The default is ['ssh'] -# c.SSHLauncher.ssh_cmd = ['ssh'] - -# set the ssh cmd for launching remote commands. The default is ['ssh'] -# c.SSHLauncher.ssh_args = ['tt'] - -# Set the user and hostname for the controller -# c.SSHControllerLauncher.hostname = 'controller.example.com' -# c.SSHControllerLauncher.user = os.environ.get('USER','username') - -# Set the arguments to be passed to ipcontrollerz -# note that remotely launched ipcontrollerz will not get the contents of -# the local ipcontrollerz_config.py unless it resides on the *remote host* -# in the location specified by the --cluster_dir argument. -# c.SSHControllerLauncher.program_args = ['-r', '-ip', '0.0.0.0', '--cluster_dir', '/path/to/cd'] - -# Set the default args passed to ipengine for SSH launched engines -# c.SSHEngineSetLauncher.engine_args = ['--mpi', 'mpi4py'] - -# SSH engines are launched as a dict of locations/n-engines. -# if a value is a tuple instead of an int, it is assumed to be of the form -# (n, [args]), setting the arguments to passed to ipengine on `host`. -# otherwise, c.SSHEngineSetLauncher.engine_args will be used as the default. - -# In this case, there will be 3 engines at my.example.com, and -# 2 at you@ipython.scipy.org with a special json connector location. -# c.SSHEngineSetLauncher.engines = {'my.example.com' : 3, -# 'you@ipython.scipy.org' : (2, ['-f', '/path/to/ipcontroller-engine.json']} -# } - -#----------------------------------------------------------------------------- -# Unix batch (PBS) schedulers launchers -#----------------------------------------------------------------------------- - -# SGE and PBS are very similar. All configurables in this section called 'PBS*' -# also exist as 'SGE*'. - -# The command line program to use to submit a PBS job. -# c.PBSLauncher.submit_command = ['qsub'] - -# The command line program to use to delete a PBS job. -# c.PBSLauncher.delete_command = ['qdel'] - -# The PBS queue in which the job should run -# c.PBSLauncher.queue = 'myqueue' - -# A regular expression that takes the output of qsub and find the job id. -# c.PBSLauncher.job_id_regexp = r'\d+' - -# If for some reason the Controller and Engines have different options above, they -# can be set as c.PBSControllerLauncher.<option> etc. - -# PBS and SGE have default templates, but you can specify your own, either as strings -# or from files, as described here: - -# The batch submission script used to start the controller. This is where -# environment variables would be setup, etc. This string is interpreted using -# Python's string formatting. Basically, you can use {queue} for the name -# of the PBS queue, and {profile_dir} for the profile_dir. -# c.PBSControllerLauncher.batch_template = """ -# #PBS -N ipcontroller -# #PBS -q {queue} -# -# ipcontroller profile_dir={profile_dir} -# """ - -# You can also load this template from a file -# c.PBSControllerLauncher.batch_template_file = u"/path/to/my/template.sh" - -# The name of the instantiated batch script that will actually be used to -# submit the job. This will be written to the cluster directory. -# c.PBSControllerLauncher.batch_file_name = u'pbs_controller' - -# The batch submission script used to start the engines. This is where -# environment variables would be setup, etc. This string is interpreted using -# Python's string formatting. Basically, you can use {queue} for the name -# of the PBS queue, and {profile_dir} for the profile_dir, and {n} -# for the number of engines. -# c.PBSEngineSetLauncher.batch_template = """ -# #PBS -N ipengine -# #PBS -l nprocs={n} -# -# ipengine profile_dir={profile_dir} -# """ - -# You can also load this template from a file -# c.PBSControllerLauncher.batch_template_file = u"/path/to/my/template.sh" - -# The name of the instantiated batch script that will actually be used to -# submit the job. This will be written to the cluster directory. -# c.PBSEngineSetLauncher.batch_file_name = u'pbs_engines' - - - -#----------------------------------------------------------------------------- -# Windows HPC Server 2008 launcher configuration -#----------------------------------------------------------------------------- - -# c.IPControllerJob.job_name = 'IPController' -# c.IPControllerJob.is_exclusive = False -# c.IPControllerJob.username = r'USERDOMAIN\USERNAME' -# c.IPControllerJob.priority = 'Highest' -# c.IPControllerJob.requested_nodes = '' -# c.IPControllerJob.project = 'MyProject' - -# c.IPControllerTask.task_name = 'IPController' -# c.IPControllerTask.controller_cmd = [u'ipcontroller.exe'] -# c.IPControllerTask.controller_args = ['--log-to-file', 'log_level=40'] -# c.IPControllerTask.environment_variables = {} - -# c.WindowsHPCControllerLauncher.scheduler = 'HEADNODE' -# c.WindowsHPCControllerLauncher.job_file_name = u'ipcontroller_job.xml' - - -# c.IPEngineSetJob.job_name = 'IPEngineSet' -# c.IPEngineSetJob.is_exclusive = False -# c.IPEngineSetJob.username = r'USERDOMAIN\USERNAME' -# c.IPEngineSetJob.priority = 'Highest' -# c.IPEngineSetJob.requested_nodes = '' -# c.IPEngineSetJob.project = 'MyProject' - -# c.IPEngineTask.task_name = 'IPEngine' -# c.IPEngineTask.engine_cmd = [u'ipengine.exe'] -# c.IPEngineTask.engine_args = ['--log-to-file', 'log_level=40'] -# c.IPEngineTask.environment_variables = {} - -# c.WindowsHPCEngineSetLauncher.scheduler = 'HEADNODE' -# c.WindowsHPCEngineSetLauncher.job_file_name = u'ipengineset_job.xml' - - - - - - - diff --git a/IPython/config/profile/default/ipcontroller_config.py b/IPython/config/profile/default/ipcontroller_config.py deleted file mode 100644 index e40a90c..0000000 --- a/IPython/config/profile/default/ipcontroller_config.py +++ /dev/null @@ -1,181 +0,0 @@ -from IPython.config.loader import Config - -c = get_config() - -#----------------------------------------------------------------------------- -# Application configuration -#----------------------------------------------------------------------------- -app = c.IPControllerApp - -# Basic Application config attributes - -# Start up messages are logged to stdout using the logging module. -# These all happen before the twisted reactor is started and are -# useful for debugging purposes. Can be (10=DEBUG,20=INFO,30=WARN,40=CRITICAL) -# and smaller is more verbose. -# app.log_level = 20 - -# Log to a file in cluster_dir/log, otherwise just log to sys.stdout. -# app.log_to_file = False - -# Remove old logs from cluster_dir/log before starting. -# app.clean_logs = True - -# A list of Python statements that will be run before starting the -# controller. This is provided because occasionally certain things need to -# be imported in the controller for pickling to work. -# app.import_statements = ['import math'] - -# Reuse the controller's JSON files. If False, JSON files are regenerated -# each time the controller is run. If True, they will be reused, *but*, you -# also must set the network ports by hand. If set, this will override the -# values set for the client and engine connections below. -# app.reuse_files = True - -# Enable exec_key authentication on all messages. Default is True -# app.secure = True - -# The working directory for the process. The application will use os.chdir -# to change to this directory before starting. -# app.work_dir = os.getcwd() - -# The log url for logging to an `iploggerz` application. This will override -# log-to-file. -# app.log_url = 'tcp://127.0.0.1:20202' - -# The specific external IP that is used to disambiguate multi-interface URLs. -# The default behavior is to guess from external IPs gleaned from `socket`. -# app.location = '192.168.1.123' - -# The ssh server remote clients should use to connect to this controller. -# It must be a machine that can see the interface specified in client_ip. -# The default for client_ip is localhost, in which case the sshserver must -# be an external IP of the controller machine. -# app.sshserver = 'controller.example.com' - -# the url to use for registration. If set, this overrides engine-ip, -# engine-transport client-ip,client-transport, and regport. -# c.RegistrationFactory.url = 'tcp://*:12345' - -# the port to use for registration. Clients and Engines both use this -# port for registration. -# c.RegistrationFactory.regport = 10101 - -#----------------------------------------------------------------------------- -# Configure the Task Scheduler -#----------------------------------------------------------------------------- - -# The routing scheme. 'pure' will use the pure-ZMQ scheduler. Any other -# value will use a Python scheduler with various routing schemes. -# python schemes are: lru, weighted, random, twobin. Default is 'weighted'. -# Note that the pure ZMQ scheduler does not support many features, such as -# dying engines, dependencies, or engine-subset load-balancing. -# c.ControllerFactory.scheme = 'pure' - -# The Python scheduler can limit the number of outstanding tasks per engine -# by using an HWM option. This allows engines with long-running tasks -# to not steal too many tasks from other engines. The default is 0, which -# means agressively distribute messages, never waiting for them to finish. -# c.TaskScheduler.hwm = 0 - -# Whether to use Threads or Processes to start the Schedulers. Threads will -# use less resources, but potentially reduce throughput. Default is to -# use processes. Note that the a Python scheduler will always be in a Process. -# c.ControllerFactory.usethreads - -#----------------------------------------------------------------------------- -# Configure the Hub -#----------------------------------------------------------------------------- - -# Which class to use for the db backend. Currently supported are DictDB (the -# default), and MongoDB. Uncomment this line to enable MongoDB, which will -# slow-down the Hub's responsiveness, but also reduce its memory footprint. -# c.HubFactory.db_class = 'IPython.parallel.controller.mongodb.MongoDB' - -# The heartbeat ping frequency. This is the frequency (in ms) at which the -# Hub pings engines for heartbeats. This determines how quickly the Hub -# will react to engines coming and going. A lower number means faster response -# time, but more network activity. The default is 100ms -# c.HubFactory.ping = 100 - -# HubFactory queue port pairs, to set by name: mux, iopub, control, task. Set -# each as a tuple of length 2 of ints. The default is to find random -# available ports -# c.HubFactory.mux = (10102,10112) - -#----------------------------------------------------------------------------- -# Configure the client connections -#----------------------------------------------------------------------------- - -# Basic client connection config attributes - -# The network interface the controller will listen on for client connections. -# This should be an IP address or interface on the controller. An asterisk -# means listen on all interfaces. The transport can be any transport -# supported by zeromq (tcp,epgm,pgm,ib,ipc): -# c.HubFactory.client_ip = '*' -# c.HubFactory.client_transport = 'tcp' - -# individual client ports to configure by name: query_port, notifier_port -# c.HubFactory.query_port = 12345 - -#----------------------------------------------------------------------------- -# Configure the engine connections -#----------------------------------------------------------------------------- - -# Basic config attributes for the engine connections. - -# The network interface the controller will listen on for engine connections. -# This should be an IP address or interface on the controller. An asterisk -# means listen on all interfaces. The transport can be any transport -# supported by zeromq (tcp,epgm,pgm,ib,ipc): -# c.HubFactory.engine_ip = '*' -# c.HubFactory.engine_transport = 'tcp' - -# set the engine heartbeat ports to use: -# c.HubFactory.hb = (10303,10313) - -#----------------------------------------------------------------------------- -# Configure the TaskRecord database backend -#----------------------------------------------------------------------------- - -# For memory/persistance reasons, tasks can be stored out-of-memory in a database. -# Currently, only sqlite and mongodb are supported as backends, but the interface -# is fairly simple, so advanced developers could write their own backend. - -# ----- in-memory configuration -------- -# this line restores the default behavior: in-memory storage of all results. -# c.HubFactory.db_class = 'IPython.parallel.controller.dictdb.DictDB' - -# ----- sqlite configuration -------- -# use this line to activate sqlite: -# c.HubFactory.db_class = 'IPython.parallel.controller.sqlitedb.SQLiteDB' - -# You can specify the name of the db-file. By default, this will be located -# in the active cluster_dir, e.g. ~/.ipython/clusterz_default/tasks.db -# c.SQLiteDB.filename = 'tasks.db' - -# You can also specify the location of the db-file, if you want it to be somewhere -# other than the cluster_dir. -# c.SQLiteDB.location = '/scratch/' - -# This will specify the name of the table for the controller to use. The default -# behavior is to use the session ID of the SessionFactory object (a uuid). Overriding -# this will result in results persisting for multiple sessions. -# c.SQLiteDB.table = 'results' - -# ----- mongodb configuration -------- -# use this line to activate mongodb: -# c.HubFactory.db_class = 'IPython.parallel.controller.mongodb.MongoDB' - -# You can specify the args and kwargs pymongo will use when creating the Connection. -# For more information on what these options might be, see pymongo documentation. -# c.MongoDB.connection_kwargs = {} -# c.MongoDB.connection_args = [] - -# This will specify the name of the mongo database for the controller to use. The default -# behavior is to use the session ID of the SessionFactory object (a uuid). Overriding -# this will result in task results persisting through multiple sessions. -# c.MongoDB.database = 'ipythondb' - - diff --git a/IPython/config/profile/default/ipengine_config.py b/IPython/config/profile/default/ipengine_config.py deleted file mode 100644 index 59c9ec7..0000000 --- a/IPython/config/profile/default/ipengine_config.py +++ /dev/null @@ -1,86 +0,0 @@ -c = get_config() - -#----------------------------------------------------------------------------- -# Application configuration -#----------------------------------------------------------------------------- -app = c.IPEngineApp - -# Start up messages are logged to stdout using the logging module. -# These all happen before the twisted reactor is started and are -# useful for debugging purposes. Can be (10=DEBUG,20=INFO,30=WARN,40=CRITICAL) -# and smaller is more verbose. -# app.log_level = 20 - -# Log to a file in cluster_dir/log, otherwise just log to sys.stdout. -# app.log_to_file = False - -# Remove old logs from cluster_dir/log before starting. -# app.clean_logs = True - -# A list of strings that will be executed in the users namespace on the engine -# before it connects to the controller. -# app.exec_lines = ['import numpy'] - -# The engine will try to connect to the controller multiple times, to allow -# the controller time to startup and write its FURL file. These parameters -# control the number of retries (connect_max_tries) and the initial delay -# (connect_delay) between attemps. The actual delay between attempts gets -# longer each time by a factor of 1.5 (delay[i] = 1.5*delay[i-1]) -# those attemps. -# app.connect_delay = 0.1 -# app.connect_max_tries = 15 - -# By default, the engine will look for the controller's JSON file in its own -# cluster directory. Sometimes, the JSON file will be elsewhere and this -# attribute can be set to the full path of the JSON file. -# app.url_file = u'/path/to/my/ipcontroller-engine.json' - -# The working directory for the process. The application will use os.chdir -# to change to this directory before starting. -# app.work_dir = os.getcwd() - -#----------------------------------------------------------------------------- -# MPI configuration -#----------------------------------------------------------------------------- - -# Upon starting the engine can be configured to call MPI_Init. This section -# configures that. - -# Select which MPI section to execute to setup MPI. The value of this -# attribute must match the name of another attribute in the MPI config -# section (mpi4py, pytrilinos, etc.). This can also be set by the --mpi -# command line option. -# c.MPI.use = '' - -# Initialize MPI using mpi4py. To use this, set c.MPI.use = 'mpi4py' to use -# --mpi=mpi4py at the command line. -# c.MPI.mpi4py = """from mpi4py import MPI as mpi -# mpi.size = mpi.COMM_WORLD.Get_size() -# mpi.rank = mpi.COMM_WORLD.Get_rank() -# """ - -# Initialize MPI using pytrilinos. To use this, set c.MPI.use = 'pytrilinos' -# to use --mpi=pytrilinos at the command line. -# c.MPI.pytrilinos = """from PyTrilinos import Epetra -# class SimpleStruct: -# pass -# mpi = SimpleStruct() -# mpi.rank = 0 -# mpi.size = 0 -# """ - -#----------------------------------------------------------------------------- -# Developer level configuration attributes -#----------------------------------------------------------------------------- - -# You shouldn't have to modify anything in this section. These attributes -# are more for developers who want to change the behavior of the controller -# at a fundamental level. - -# You should not have to change these attributes. - -# app.url_file_name = u'ipcontroller-engine.furl' - - - - diff --git a/IPython/config/profile/default/ipython_config.py b/IPython/config/profile/default/ipython_config.py deleted file mode 100644 index 9626c19..0000000 --- a/IPython/config/profile/default/ipython_config.py +++ /dev/null @@ -1,190 +0,0 @@ -# Get the config being loaded so we can set attributes on it -c = get_config() - -#----------------------------------------------------------------------------- -# Application-level options -#----------------------------------------------------------------------------- - -# c.TerminalIPythonApp.display_banner = True - -# c.TerminalIPythonApp.classic = False - -# c.TerminalIPythonApp.nosep = True - -# If you still use multiple versions of IPytho on the same machine, -# set this to True to suppress warnings about old configuration files -# c.TerminalIPythonApp.ignore_old_config = False - -# Set this to determine the detail of what is logged at startup. -# The default is 30 and possible values are 0,10,20,30,40,50. -# c.Application.log_level = 20 - -# This should be a list of importable Python modules that have an -# load_ipython_extension(ip) method. This method gets called when the extension -# is loaded. You can put your extensions anywhere they can be imported -# but we add the extensions subdir of the ipython directory to sys.path -# during extension loading, so you can put them there as well. -# c.InteractiveShellApp.extensions = [ -# 'myextension' -# ] - -# These lines are run in IPython in the user's namespace after extensions -# are loaded. They can contain full IPython syntax with magics etc. -# c.InteractiveShellApp.exec_lines = [ -# 'import numpy', -# 'a = 10; b = 20', -# '1/0' -# ] - -# These files are run in IPython in the user's namespace. Files with a .py -# extension need to be pure Python. Files with a .ipy extension can have -# custom IPython syntax (like magics, etc.). -# These files need to be in the cwd, the ipython_dir or be absolute paths. -# c.InteractiveShellApp.exec_files = [ -# 'mycode.py', -# 'fancy.ipy' -# ] - -#----------------------------------------------------------------------------- -# InteractiveShell options -#----------------------------------------------------------------------------- - -# c.InteractiveShell.autocall = 1 - -# c.TerminalInteractiveShell.autoedit_syntax = False - -# c.InteractiveShell.autoindent = True - -# c.InteractiveShell.automagic = False - -# c.TerminalInteractiveShell.banner1 = 'This if for overriding the default IPython banner' - -# c.TerminalInteractiveShell.banner2 = "This is for extra banner text" - -# c.InteractiveShell.cache_size = 1000 - -# c.InteractiveShell.colors = 'LightBG' - -# c.InteractiveShell.color_info = True - -# c.TerminalInteractiveShell.confirm_exit = True - -# c.InteractiveShell.deep_reload = False - -# c.TerminalInteractiveShell.editor = 'nano' - -# c.InteractiveShell.logstart = True - -# c.InteractiveShell.logfile = u'ipython_log.py' - -# c.InteractiveShell.logappend = u'mylog.py' - -# c.InteractiveShell.object_info_string_level = 0 - -# c.TerminalInteractiveShell.pager = 'less' - -# c.InteractiveShell.pdb = False - -# c.InteractiveShell.prompt_in1 = 'In [\#]: ' -# c.InteractiveShell.prompt_in2 = ' .\D.: ' -# c.InteractiveShell.prompt_out = 'Out[\#]: ' -# c.InteractiveShell.prompts_pad_left = True - -# c.InteractiveShell.quiet = False - -# c.InteractiveShell.history_length = 10000 - -# Readline -# c.InteractiveShell.readline_use = True - -# be careful with meta-key ('\M-<x>') bindings, because -# they conflict with 8-bit encodings (e.g. UTF8) - -# c.InteractiveShell.readline_parse_and_bind = [ -# 'tab: complete', -# '"\C-l": possible-completions', -# 'set show-all-if-ambiguous on', -# '"\C-o": tab-insert', -# '"\C-r": reverse-search-history', -# '"\C-s": forward-search-history', -# '"\C-p": history-search-backward', -# '"\C-n": history-search-forward', -# '"\e[A": history-search-backward', -# '"\e[B": history-search-forward', -# '"\C-k": kill-line', -# '"\C-u": unix-line-discard', -# ] -# c.InteractiveShell.readline_remove_delims = '-/~' -# c.InteractiveShell.readline_merge_completions = True -# c.InteractiveShell.readline_omit__names = 0 - -# c.TerminalInteractiveShell.screen_length = 0 - -# c.InteractiveShell.separate_in = '\n' -# c.InteractiveShell.separate_out = '' -# c.InteractiveShell.separate_out2 = '' - -# c.TerminalInteractiveShell.term_title = False - -# c.InteractiveShell.wildcards_case_sensitive = True - -# c.InteractiveShell.xmode = 'Context' - -#----------------------------------------------------------------------------- -# Formatter and display options -#----------------------------------------------------------------------------- - -# c.PlainTextFormatter.pprint = True - -#----------------------------------------------------------------------------- -# PrefilterManager options -#----------------------------------------------------------------------------- - -# c.PrefilterManager.multi_line_specials = True - -#----------------------------------------------------------------------------- -# AliasManager options -#----------------------------------------------------------------------------- - -# Do this to disable all defaults -# c.AliasManager.default_aliases = [] - -# c.AliasManager.user_aliases = [ -# ('foo', 'echo Hi') -# ] - -#----------------------------------------------------------------------------- -# HistoryManager options -#----------------------------------------------------------------------------- - -# Enable logging output as well as input to the database. -# c.HistoryManager.db_log_output = False - -# Only write to the database every n commands - this can save disk -# access (and hence power) over the default of writing on every command. -# c.HistoryManager.db_cache_size = 0 - -#----------------------------------------------------------------------------- -# QtConsole configuration -#----------------------------------------------------------------------------- - -# set the preferred typeface and font size. The default typeface is: -# 'Consolas' on Windows (fallback to 'Courier') -# 'Monaco' on OSX -# 'Monospace' elsewhere -# c.ConsoleWidget.font_family = "Consolas" - -# The point fontsize. Leave as zero to let Qt decide on the starting font size. -# While running, you can change the font size with ctrl- +/- -# c.ConsoleWidget.font_size = 0 - -# set the pygments syntax-highlighting style: -# c.IPythonWidget.syntax_style = 'default' - -# Configure the prompts: -# c.IPythonWidget.in_prompt = 'In [<span class="in-prompt-number">%i</span>]: ' -# c.IPythonWidget.out_prompt = 'Out[<span class="out-prompt-number">%i</span>]: ' - -# set the editor - this must be a *GUI* editor, like notepad/gedit/TextMate -# There is no default on systems other than Windows. -# c.IPythonWidget.editor = 'notepad' diff --git a/IPython/core/application.py b/IPython/core/application.py index 21f9aba..a5f633e 100644 --- a/IPython/core/application.py +++ b/IPython/core/application.py @@ -82,6 +82,8 @@ class BaseIPythonApplication(Application): config_file_specified = Bool(False) config_file_name = Unicode(u'ipython_config.py') + def _config_file_name_default(self): + return self.name.replace('-','_') + u'_config.py' def _config_file_name_changed(self, name, old, new): if new != old: self.config_file_specified = True @@ -102,8 +104,7 @@ class BaseIPythonApplication(Application): self.builtin_profile_dir = os.path.join( get_ipython_package_dir(), u'config', u'profile', new ) - - + ipython_dir = Unicode(get_ipython_dir(), config=True, help=""" The name of the IPython directory. This directory is used for logging @@ -123,7 +124,11 @@ class BaseIPythonApplication(Application): return [u'ipython_config.py'] copy_config_files = Bool(False, config=True, - help="""Whether to copy the default config files into the profile dir.""") + help="""Whether to install the default config files into the profile dir. + If a new profile is being created, and IPython contains config files for that + profile, then they will be staged into the new directory. Otherwise, + default config files will be automatically generated. + """) # The class to use as the crash handler. crash_handler_class = Type(crashhandler.CrashHandler) @@ -162,6 +167,21 @@ class BaseIPythonApplication(Application): printed on screen. For testing, the suppress_errors option is set to False, so errors will make tests fail. """ + base_config = 'ipython_config.py' + self.log.debug("Attempting to load config file: %s" % + base_config) + try: + Application.load_config_file( + self, + base_config, + path=self.config_file_paths + ) + except IOError: + # ignore errors loading parent + pass + if self.config_file_name == base_config: + # don't load secondary config + return self.log.debug("Attempting to load config file: %s" % self.config_file_name) try: @@ -235,21 +255,32 @@ class BaseIPythonApplication(Application): if self.copy_config_files: path = self.builtin_profile_dir src = self.profile - if not os.path.exists(path): - # use default if new profile doesn't have a preset - path = None - src = 'default' - - self.log.debug("Staging %s config files into %r [overwrite=%s]"%( - src, self.profile_dir.location, self.overwrite) - ) - for cfg in self.config_files: + cfg = self.config_file_name + if path and os.path.exists(os.path.join(path, cfg)): + self.log.warn("Staging %r from %s into %r [overwrite=%s]"%( + cfg, src, self.profile_dir.location, self.overwrite) + ) self.profile_dir.copy_config_file(cfg, path=path, overwrite=self.overwrite) + else: + self.stage_default_config_file() + + def stage_default_config_file(self): + """auto generate default config file, and stage it into the profile.""" + s = self.generate_config_file() + fname = os.path.join(self.profile_dir.location, self.config_file_name) + if self.overwrite or not os.path.exists(fname): + self.log.warn("Generating default config file: %r"%(fname)) + with open(fname, 'w') as f: + f.write(s) + def initialize(self, argv=None): self.init_crash_handler() self.parse_command_line(argv) + if self.subapp is not None: + # stop here if subapp is taking over + return cl_config = self.config self.init_profile_dir() self.init_config_files() diff --git a/IPython/core/profileapp.py b/IPython/core/profileapp.py index 9155025..069b314 100644 --- a/IPython/core/profileapp.py +++ b/IPython/core/profileapp.py @@ -162,6 +162,42 @@ class ProfileCreate(BaseIPythonApplication): aliases = Dict(dict(profile='BaseIPythonApplication.profile')) classes = [ProfileDir] + + def init_config_files(self): + super(ProfileCreate, self).init_config_files() + # use local imports, since these classes may import from here + from IPython.frontend.terminal.ipapp import TerminalIPythonApp + apps = [TerminalIPythonApp] + try: + from IPython.frontend.qt.console.qtconsoleapp import IPythonQtConsoleApp + except ImportError: + pass + else: + apps.append(IPythonQtConsoleApp) + if self.cluster: + from IPython.parallel.apps.ipcontrollerapp import IPControllerApp + from IPython.parallel.apps.ipengineapp import IPEngineApp + from IPython.parallel.apps.ipclusterapp import IPClusterStart + from IPython.parallel.apps.iploggerapp import IPLoggerApp + apps.extend([ + IPControllerApp, + IPEngineApp, + IPClusterStart, + IPLoggerApp, + ]) + for App in apps: + app = App() + app.config.update(self.config) + app.log = self.log + app.overwrite = self.overwrite + app.copy_config_files=True + app.profile = self.profile + app.init_profile_dir() + app.init_config_files() + print 'tic' + + def stage_default_config_file(self): + pass class ProfileApp(Application): name = u'ipython-profile' diff --git a/IPython/frontend/terminal/ipapp.py b/IPython/frontend/terminal/ipapp.py index 8d68708..24db945 100755 --- a/IPython/frontend/terminal/ipapp.py +++ b/IPython/frontend/terminal/ipapp.py @@ -208,9 +208,8 @@ class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp): "Create and manage IPython profiles.") )) - # *do* autocreate requested profile + # *do* autocreate requested profile, but don't create the config file. auto_create=Bool(True) - copy_config_files=Bool(True) # configurables ignore_old_config=Bool(False, config=True, help="Suppress warning messages about legacy config files" diff --git a/IPython/parallel/apps/ipclusterapp.py b/IPython/parallel/apps/ipclusterapp.py index 93c081c..cd944bf 100755 --- a/IPython/parallel/apps/ipclusterapp.py +++ b/IPython/parallel/apps/ipclusterapp.py @@ -322,7 +322,7 @@ class IPClusterStart(IPClusterEngines): classes = List() def _classes_default(self,): from IPython.parallel.apps import launcher - return [ProfileDir]+launcher.all_launchers + return [ProfileDir] + [IPClusterEngines] + launcher.all_launchers clean_logs = Bool(True, config=True, help="whether to cleanup old logs before starting") @@ -410,12 +410,11 @@ class IPClusterStart(IPClusterEngines): base='IPython.parallel.apps.ipclusterapp.IPCluster' -class IPBaseParallelApplication(Application): +class IPClusterApp(Application): name = u'ipcluster' description = _description - subcommands = {'create' : (base+'Create', create_help), - 'list' : (base+'List', list_help), + subcommands = { 'start' : (base+'Start', start_help), 'stop' : (base+'Stop', stop_help), 'engines' : (base+'Engines', engines_help), diff --git a/IPython/parallel/apps/ipengineapp.py b/IPython/parallel/apps/ipengineapp.py index baf4507..12eab5b 100755 --- a/IPython/parallel/apps/ipengineapp.py +++ b/IPython/parallel/apps/ipengineapp.py @@ -103,7 +103,7 @@ class MPI(Configurable): class IPEngineApp(BaseParallelApplication): - app_name = Unicode(u'ipengine') + name = Unicode(u'ipengine') description = Unicode(_description) config_file_name = Unicode(default_config_file_name) classes = List([ProfileDir, Session, EngineFactory, Kernel, MPI]) diff --git a/IPython/parallel/apps/iploggerapp.py b/IPython/parallel/apps/iploggerapp.py index 8fbb8f5..8c98f2d 100755 --- a/IPython/parallel/apps/iploggerapp.py +++ b/IPython/parallel/apps/iploggerapp.py @@ -61,7 +61,7 @@ aliases.update(dict(url='LogWatcher.url', topics='LogWatcher.topics')) class IPLoggerApp(BaseParallelApplication): - name = u'iploggerz' + name = u'iplogger' description = _description config_file_name = Unicode(default_config_file_name)