##// END OF EJS Templates
allow for List traitlets to come from command line
allow for List traitlets to come from command line

File last commit:

r11364:3882aa24
r11831:7ceeafd4
Show More
application.py
358 lines | 13.8 KiB | text/x-python | PythonLexer
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185 # encoding: utf-8
"""
Brian Granger
ipcontroller/ipengine use the new clusterdir.py module.
r2301 An application for IPython.
All top-level applications should use the classes in this module for
handling configuration and creating componenets.
Bernardo B. Marques
remove all trailling spaces
r4872 The job of an :class:`Application` is to create the master configuration
Brian Granger
First draft of refactored Component->Configurable.
r2731 object and then create the configurable objects, passing the config to them.
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185
Authors:
* Brian Granger
* Fernando Perez
MinRK
rename core.newapplication -> core.application
r4023 * Min RK
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185
"""
#-----------------------------------------------------------------------------
MinRK
move ipcluster create|list to `ipython profile create|list`...
r4024 # Copyright (C) 2008-2011 The IPython Development Team
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185 #
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
MinRK
prevent atexit handlers from generating crash report...
r4994 import atexit
MinRK
load bundled profiles without having to use 'profile create' or '--init'...
r4122 import glob
Brian Granger
Work on startup related things....
r2252 import logging
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 import os
MinRK
rename core.newapplication -> core.application
r4023 import shutil
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185 import sys
Brian Granger
Massive refactoring of of the core....
r2245
MinRK
catch_config -> catch_config_error
r5214 from IPython.config.application import Application, catch_config_error
Matthias BUSSONNIER
fix error in doc (arg->kwarg) and pep-8
r8885 from IPython.config.loader import ConfigFileNotFound
Fernando Perez
Move crash handling to the application level and simplify class structure....
r2403 from IPython.core import release, crashhandler
MinRK
move ipcluster create|list to `ipython profile create|list`...
r4024 from IPython.core.profiledir import ProfileDir, ProfileDirError
from IPython.utils.path import get_ipython_dir, get_ipython_package_dir
MinRK
add extra_config_file...
r11277 from IPython.utils.traitlets import List, Unicode, Type, Bool, Dict, Set
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185
#-----------------------------------------------------------------------------
# Classes and functions
#-----------------------------------------------------------------------------
MinRK
rename core.newapplication -> core.application
r4023
#-----------------------------------------------------------------------------
# Base Application Class
#-----------------------------------------------------------------------------
# aliases and flags
MinRK
aliases match flag pattern ('-' as wordsep, not '_')...
r4214 base_aliases = {
'profile' : 'BaseIPythonApplication.profile',
'ipython-dir' : 'BaseIPythonApplication.ipython_dir',
'log-level' : 'Application.log_level',
MinRK
add extra_config_file...
r11277 'config' : 'BaseIPythonApplication.extra_config_file',
MinRK
aliases match flag pattern ('-' as wordsep, not '_')...
r4214 }
Brian Granger
General work on the kernel config.
r2294
MinRK
rename core.newapplication -> core.application
r4023 base_flags = dict(
debug = ({'Application' : {'log_level' : logging.DEBUG}},
"set log level to logging.DEBUG (maximize logging output)"),
quiet = ({'Application' : {'log_level' : logging.CRITICAL}},
"set log level to logging.CRITICAL (minimize logging output)"),
init = ({'BaseIPythonApplication' : {
'copy_config_files' : True,
'auto_create' : True}
MinRK
command-line pass...
r4247 }, """Initialize profile with default config files. This is equivalent
to running `ipython profile create <profile>` prior to startup.
""")
MinRK
rename core.newapplication -> core.application
r4023 )
class BaseIPythonApplication(Application):
name = Unicode(u'ipython')
description = Unicode(u'IPython: an enhanced interactive Python shell.')
version = Unicode(release.version)
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
rename core.newapplication -> core.application
r4023 aliases = Dict(base_aliases)
flags = Dict(base_flags)
MinRK
expose IPClusterEngines.daemonize as `--daemonize` flag....
r4114 classes = List([ProfileDir])
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
rename core.newapplication -> core.application
r4023 # Track whether the config_file has changed,
# because some logic happens only if we aren't using the default.
MinRK
add extra_config_file...
r11277 config_file_specified = Set()
Bernardo B. Marques
remove all trailling spaces
r4872
Jonathan Frederic
Fix, config_file_name was ignored
r11364 config_file_name = Unicode()
MinRK
default config files are automatically generated...
r4025 def _config_file_name_default(self):
return self.name.replace('-','_') + u'_config.py'
MinRK
rename core.newapplication -> core.application
r4023 def _config_file_name_changed(self, name, old, new):
if new != old:
MinRK
add extra_config_file...
r11277 self.config_file_specified.add(new)
MinRK
rename core.newapplication -> core.application
r4023
# The directory that contains IPython's builtin profiles.
builtin_profile_dir = Unicode(
os.path.join(get_ipython_package_dir(), u'config', u'profile', u'default')
)
config_file_paths = List(Unicode)
def _config_file_paths_default(self):
return [os.getcwdu()]
MinRK
add extra_config_file...
r11277 extra_config_file = Unicode(config=True,
help="""Path to an extra config file to load.
If specified, load this config file in addition to any other IPython config.
""")
def _extra_config_file_changed(self, name, old, new):
try:
self.config_files.remove(old)
except ValueError:
pass
self.config_file_specified.add(new)
self.config_files.append(new)
Thomas Kluyver
Revert to using single default profile for Python 2 and 3.
r5259 profile = Unicode(u'default', config=True,
MinRK
rename core.newapplication -> core.application
r4023 help="""The IPython profile to use."""
)
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
rename core.newapplication -> core.application
r4023 def _profile_changed(self, name, old, new):
self.builtin_profile_dir = os.path.join(
get_ipython_package_dir(), u'config', u'profile', new
)
Bernardo B. Marques
remove all trailling spaces
r4872
ipython_dir = Unicode(get_ipython_dir(), config=True,
MinRK
rename core.newapplication -> core.application
r4023 help="""
The name of the IPython directory. This directory is used for logging
configuration (through profiles), history storage, etc. The default
is usually $HOME/.ipython. This options can also be specified through
Bradley M. Froehle
IPYTHON_DIR -> IPYTHONDIR in comments and documentation
r6696 the environment variable IPYTHONDIR.
Brian Granger
General work on the kernel config.
r2294 """
MinRK
rename core.newapplication -> core.application
r4023 )
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
rename core.newapplication -> core.application
r4023 overwrite = Bool(False, config=True,
help="""Whether to overwrite existing config files when copying""")
auto_create = Bool(False, config=True,
help="""Whether to create profile dir if it doesn't exist""")
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
rename core.newapplication -> core.application
r4023 config_files = List(Unicode)
def _config_files_default(self):
Jonathan Frederic
Fix, config_file_name was ignored
r11364 return [self.config_file_name]
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
rename core.newapplication -> core.application
r4023 copy_config_files = Bool(False, config=True,
MinRK
default config files are automatically generated...
r4025 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.
""")
MinRK
Don't use crash_handler by default...
r5317
verbose_crash = Bool(False, config=True,
Jason Grout
Fix typo enconters->encounters
r6872 help="""Create a massive crash report when IPython encounters what may be an
MinRK
Don't use crash_handler by default...
r5317 internal error. The default is to append a short message to the
usual traceback""")
MinRK
rename core.newapplication -> core.application
r4023
# The class to use as the crash handler.
crash_handler_class = Type(crashhandler.CrashHandler)
Thomas Spura
Use @catch_config_error to catch exception from getcwdu in nonexisting directory
r10381 @catch_config_error
MinRK
rename core.newapplication -> core.application
r4023 def __init__(self, **kwargs):
super(BaseIPythonApplication, self).__init__(**kwargs)
Thomas Spura
Search for first existing directory, if cwd doesn't exist....
r10154 # ensure current working directory exists
Thomas Spura
Report if cwd does not exist and raise exception in BaseIPythonApplication...
r10169 try:
directory = os.getcwdu()
except:
# raise exception
self.log.error("Current working directory doesn't exist.")
raise
Thomas Spura
Search for first existing directory, if cwd doesn't exist....
r10154
Bradley M. Froehle
IPYTHON_DIR -> IPYTHONDIR in comments and documentation
r6696 # ensure even default IPYTHONDIR exists
MinRK
rename core.newapplication -> core.application
r4023 if not os.path.exists(self.ipython_dir):
self._ipython_dir_changed('ipython_dir', self.ipython_dir, self.ipython_dir)
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
rename core.newapplication -> core.application
r4023 #-------------------------------------------------------------------------
# Various stages of Application creation
#-------------------------------------------------------------------------
Brian Granger
Semi-final Application and minor work on traitlets.
r2200
MinRK
rename core.newapplication -> core.application
r4023 def init_crash_handler(self):
"""Create a crash handler, typically setting sys.excepthook to it."""
self.crash_handler = self.crash_handler_class(self)
MinRK
Don't use crash_handler by default...
r5317 sys.excepthook = self.excepthook
MinRK
prevent atexit handlers from generating crash report...
r4994 def unset_crashhandler():
sys.excepthook = sys.__excepthook__
atexit.register(unset_crashhandler)
MinRK
Don't use crash_handler by default...
r5317
def excepthook(self, etype, evalue, tb):
"""this is sys.excepthook after init_crashhandler
set self.verbose_crash=True to use our full crashhandler, instead of
a regular traceback with a short message (crash_handler_lite)
"""
if self.verbose_crash:
return self.crash_handler(etype, evalue, tb)
else:
return crashhandler.crash_handler_lite(etype, evalue, tb)
MinRK
rename core.newapplication -> core.application
r4023 def _ipython_dir_changed(self, name, old, new):
if old in sys.path:
sys.path.remove(old)
sys.path.append(os.path.abspath(new))
if not os.path.isdir(new):
Bradley M. Froehle
Py3k: Octal (0777 -> 0o777)
r8490 os.makedirs(new, mode=0o777)
MinRK
rename core.newapplication -> core.application
r4023 readme = os.path.join(new, 'README')
if not os.path.exists(readme):
path = os.path.join(get_ipython_package_dir(), u'config', u'profile')
shutil.copy(os.path.join(path, 'README'), readme)
Bradley M. Froehle
Prefer IPYTHONDIR over IPYTHON_DIR.
r6697 self.log.debug("IPYTHONDIR set to: %s" % new)
MinRK
rename core.newapplication -> core.application
r4023
def load_config_file(self, suppress_errors=True):
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 """Load the config file.
MinRK
rename core.newapplication -> core.application
r4023
Thomas Kluyver
Tweak code with suggestions from yesterday.
r3458 By default, errors in loading config are handled, and a warning
printed on screen. For testing, the suppress_errors option is set
to False, so errors will make tests fail.
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 """
MinRK
make config-loading debug messages more explicit...
r4564 self.log.debug("Searching path %s for config files", self.config_file_paths)
MinRK
default config files are automatically generated...
r4025 base_config = 'ipython_config.py'
self.log.debug("Attempting to load config file: %s" %
base_config)
try:
Application.load_config_file(
self,
Bernardo B. Marques
remove all trailling spaces
r4872 base_config,
MinRK
default config files are automatically generated...
r4025 path=self.config_file_paths
)
MinRK
catch ConfigFileNotFound where appropriate...
r4909 except ConfigFileNotFound:
MinRK
default config files are automatically generated...
r4025 # ignore errors loading parent
MinRK
make config-loading debug messages more explicit...
r4564 self.log.debug("Config file %s not found", base_config)
MinRK
default config files are automatically generated...
r4025 pass
MinRK
add extra_config_file...
r11277
for config_file_name in self.config_files:
if not config_file_name or config_file_name == base_config:
continue
self.log.debug("Attempting to load config file: %s" %
self.config_file_name)
try:
Application.load_config_file(
self,
config_file_name,
path=self.config_file_paths
)
except ConfigFileNotFound:
# Only warn if the default config file was NOT being used.
if config_file_name in self.config_file_specified:
msg = self.log.warn
else:
msg = self.log.debug
msg("Config file not found, skipping: %s", config_file_name)
except:
# For testing purposes.
if not suppress_errors:
raise
self.log.warn("Error loading config file: %s" %
self.config_file_name, exc_info=True)
Brian Granger
General work on the kernel config.
r2294
MinRK
rename core.newapplication -> core.application
r4023 def init_profile_dir(self):
"""initialize the profile dir"""
try:
# location explicitly specified:
location = self.config.ProfileDir.location
except AttributeError:
# location not specified, find by profile name
Brian Granger
Fixing minor bug with the logging level in ipapp.py.
r2270 try:
MinRK
rename core.newapplication -> core.application
r4023 p = ProfileDir.find_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
except ProfileDirError:
# not found, maybe create it (always create default profile)
Matthias BUSSONNIER
fix error in doc (arg->kwarg) and pep-8
r8885 if self.auto_create or self.profile == 'default':
MinRK
rename core.newapplication -> core.application
r4023 try:
p = ProfileDir.create_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
except ProfileDirError:
self.log.fatal("Could not create profile: %r"%self.profile)
self.exit(1)
else:
self.log.info("Created profile dir: %r"%p.location)
else:
self.log.fatal("Profile %r not found."%self.profile)
self.exit(1)
else:
self.log.info("Using existing profile dir: %r"%p.location)
Brian Granger
Lots more work on the kernel scripts.
r2303 else:
MinRK
rename core.newapplication -> core.application
r4023 # location is fully specified
try:
p = ProfileDir.find_profile_dir(location, self.config)
except ProfileDirError:
# not found, maybe create it
if self.auto_create:
try:
p = ProfileDir.create_profile_dir(location, self.config)
except ProfileDirError:
self.log.fatal("Could not create profile directory: %r"%location)
self.exit(1)
else:
self.log.info("Creating new profile dir: %r"%location)
else:
self.log.fatal("Profile directory %r not found."%location)
self.exit(1)
else:
self.log.info("Using existing profile dir: %r"%location)
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
rename core.newapplication -> core.application
r4023 self.profile_dir = p
self.config_file_paths.append(p.location)
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
rename core.newapplication -> core.application
r4023 def init_config_files(self):
"""[optionally] copy default config files into profile dir."""
# copy config files
MinRK
load bundled profiles without having to use 'profile create' or '--init'...
r4122 path = self.builtin_profile_dir
MinRK
rename core.newapplication -> core.application
r4023 if self.copy_config_files:
src = self.profile
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
default config files are automatically generated...
r4025 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)
)
MinRK
rename core.newapplication -> core.application
r4023 self.profile_dir.copy_config_file(cfg, path=path, overwrite=self.overwrite)
MinRK
default config files are automatically generated...
r4025 else:
self.stage_default_config_file()
MinRK
load bundled profiles without having to use 'profile create' or '--init'...
r4122 else:
# Still stage *bundled* config files, but not generated ones
# This is necessary for `ipython profile=sympy` to load the profile
# on the first go
files = glob.glob(os.path.join(path, '*.py'))
for fullpath in files:
cfg = os.path.basename(fullpath)
if self.profile_dir.copy_config_file(cfg, path=path, overwrite=False):
# file was copied
self.log.warn("Staging bundled %s from %s into %r"%(
cfg, self.profile, self.profile_dir.location)
)
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
default config files are automatically generated...
r4025 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)
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
catch_config -> catch_config_error
r5214 @catch_config_error
MinRK
rename core.newapplication -> core.application
r4023 def initialize(self, argv=None):
MinRK
don't crash apps on TraitErrors when parsing command-line
r4106 # don't hook up crash handler before parsing command-line
MinRK
rename core.newapplication -> core.application
r4023 self.parse_command_line(argv)
MinRK
don't crash apps on TraitErrors when parsing command-line
r4106 self.init_crash_handler()
MinRK
default config files are automatically generated...
r4025 if self.subapp is not None:
# stop here if subapp is taking over
return
MinRK
rename core.newapplication -> core.application
r4023 cl_config = self.config
self.init_profile_dir()
self.init_config_files()
self.load_config_file()
# enforce cl-opts override configfile opts:
self.update_config(cl_config)
Brian Granger
Work on ipcontroller....
r2296