##// END OF EJS Templates
Removed extra blank lines
Removed extra blank lines

File last commit:

r11341:d1828aa7 merge
r11396:9c85fe9c
Show More
application.py
576 lines | 20.5 KiB | text/x-python | PythonLexer
Brian Granger
Created config.application and updated Configurable.
r3790 # encoding: utf-8
"""
A base class for a configurable application.
Authors:
* Brian Granger
MinRK
update recently changed modules with Authors in docstring
r4018 * Min RK
Brian Granger
Created config.application and updated Configurable.
r3790 """
#-----------------------------------------------------------------------------
# Copyright (C) 2008-2011 The IPython Development Team
#
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
Brian Granger
IPython.config.application.Application updates....
r3794 import logging
MinRK
default config files are automatically generated...
r4025 import os
MinRK
make subcommands optional
r3952 import re
Brian Granger
Created config.application and updated Configurable.
r3790 import sys
MinRK
default config files are automatically generated...
r4025 from copy import deepcopy
MinRK
promote aliases and flags, to ensure they have priority over config files...
r4977 from collections import defaultdict
Brian Granger
Created config.application and updated Configurable.
r3790
MinRK
Show invalid config message on TraitErrors during initialization...
r5172 from IPython.external.decorator import decorator
Brian Granger
IPython.config.application.Application updates....
r3794 from IPython.config.configurable import SingletonConfigurable
Brian Granger
Created config.application and updated Configurable.
r3790 from IPython.config.loader import (
MinRK
avoid interpreting IOError in config file as file-not-found...
r4905 KVArgParseConfigLoader, PyFileConfigLoader, Config, ArgumentError, ConfigFileNotFound,
Brian Granger
Created config.application and updated Configurable.
r3790 )
MinRK
move shortname to Application...
r3852 from IPython.utils.traitlets import (
MinRK
add Integer traitlet...
r5344 Unicode, List, Enum, Dict, Instance, TraitError
MinRK
move shortname to Application...
r3852 )
MinRK
add subcommand support
r3949 from IPython.utils.importstring import import_item
MinRK
wrap helpstring output to 80 cols
r4020 from IPython.utils.text import indent, wrap_paragraphs, dedent
#-----------------------------------------------------------------------------
# function for re-wrapping a helpstring
#-----------------------------------------------------------------------------
MinRK
move shortname to Application...
r3852
Brian Granger
Created config.application and updated Configurable.
r3790 #-----------------------------------------------------------------------------
MinRK
include default value in help output...
r3944 # Descriptions for the various sections
MinRK
add descriptions for the various help sections
r3855 #-----------------------------------------------------------------------------
MinRK
merge flags&aliases help output into just 'options'
r4195 # merge flags&aliases into options
option_description = """
Fernando Perez
Fix padding of matplotlib figures, after much whining from Stefan :)
r4254 Arguments that take values are actually convenience aliases to full
Configurables, whose aliases are listed on the help line. For more information
on full configurables, see '--help-all'.
MinRK
add descriptions for the various help sections
r3855 """.strip() # trim newlines of front and back
keyvalue_description = """
Parameters are set from command-line arguments of the form:
MinRK
parse cl_args agnostic of leading '-'...
r4189 `--Class.trait=value`.
MinRK
merge flags&aliases help output into just 'options'
r4195 This line is evaluated in Python, so simple expressions are allowed, e.g.::
`--C.a='range(3)'` For setting C.a=[0,1,2].
MinRK
add descriptions for the various help sections
r3855 """.strip() # trim newlines of front and back
Paul Ivanov
comment reflects when the case below it can occur
r11340 # sys.argv can be missing, for example when python is embedded. See the docs
# for details: http://docs.python.org/2/c-api/intro.html#embedding-python
Thomas Spura
Set calling program to the empty string, when argv not in sys...
r11103 if not hasattr(sys, "argv"):
sys.argv = [""]
MinRK
merge flags&aliases help output into just 'options'
r4195 subcommand_description = """
Subcommands are launched as `{app} cmd [args]`. For information on using
subcommand 'cmd', do: `{app} cmd -h`.
""".strip().format(app=os.path.basename(sys.argv[0]))
# get running program name
MinRK
add descriptions for the various help sections
r3855 #-----------------------------------------------------------------------------
Brian Granger
Created config.application and updated Configurable.
r3790 # Application class
#-----------------------------------------------------------------------------
MinRK
Show invalid config message on TraitErrors during initialization...
r5172 @decorator
MinRK
catch_config -> catch_config_error
r5214 def catch_config_error(method, app, *args, **kwargs):
MinRK
Show invalid config message on TraitErrors during initialization...
r5172 """Method decorator for catching invalid config (Trait/ArgumentErrors) during init.
On a TraitError (generally caused by bad config), this will print the trait's
message, and exit the app.
For use on init methods, to prevent invoking excepthook on invalid input.
"""
try:
return method(app, *args, **kwargs)
except (TraitError, ArgumentError) as e:
app.print_description()
app.print_help()
app.print_examples()
app.log.fatal("Bad config encountered during initialization:")
app.log.fatal(str(e))
app.log.debug("Config at the time: %s", app.config)
app.exit(1)
Brian Granger
Created config.application and updated Configurable.
r3790
Brian Granger
Updates to config/application.
r3940 class ApplicationError(Exception):
pass
MinRK
add LevelFormatter for extra formatting on high level messages...
r10559 class LevelFormatter(logging.Formatter):
"""Formatter with additional `highlevel` record
This field is empty if log level is less than highlevel_limit,
otherwise it is formatted with self.highlevel_format.
Useful for adding 'WARNING' to warning messages,
without adding 'INFO' to info, etc.
"""
highlevel_limit = logging.WARN
MinRK
tweak default highlevel_format
r10562 highlevel_format = " %(levelname)s |"
MinRK
add LevelFormatter for extra formatting on high level messages...
r10559
def format(self, record):
if record.levelno >= self.highlevel_limit:
record.highlevel = self.highlevel_format % record.__dict__
else:
record.highlevel = ""
return super(LevelFormatter, self).format(record)
Brian Granger
Updates to config/application.
r3940
Brian Granger
IPython.config.application.Application updates....
r3794 class Application(SingletonConfigurable):
Brian Granger
Adding more documentation to config.application related files.
r3796 """A singleton application with full configuration support."""
Brian Granger
Created config.application and updated Configurable.
r3790
# The name of the application, will usually match the name of the command
# line application
Brian Granger
Fixing bugs in BaseIPythonApplication....
r3942 name = Unicode(u'application')
Brian Granger
Created config.application and updated Configurable.
r3790
# The description of the application that is printed at the beginning
# of the help.
description = Unicode(u'This is an application.')
MinRK
add descriptions for the various help sections
r3855 # default section descriptions
MinRK
merge flags&aliases help output into just 'options'
r4195 option_description = Unicode(option_description)
MinRK
add descriptions for the various help sections
r3855 keyvalue_description = Unicode(keyvalue_description)
MinRK
merge flags&aliases help output into just 'options'
r4195 subcommand_description = Unicode(subcommand_description)
Brian Granger
Command line examples added for non-parallel apps.
r4215
# The usage and example string that goes at the end of the help string.
examples = Unicode()
Brian Granger
Created config.application and updated Configurable.
r3790
# A sequence of Configurable subclasses whose config=True attributes will
MinRK
rename macros/shortnames to flags/aliases...
r3861 # be exposed at the command line.
Brian Granger
Created config.application and updated Configurable.
r3790 classes = List([])
# The version string of this application.
version = Unicode(u'0.0')
Brian Granger
Added tests for IPython.config.application.Application
r3795 # The log level for the application
MinRK
default config files are automatically generated...
r4025 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):
MinRK
fix setting log_level by name in Application...
r4039 """Adjust the log level when log_level is set."""
MinRK
default config files are automatically generated...
r4025 if isinstance(new, basestring):
MinRK
fix setting log_level by name in Application...
r4039 new = getattr(logging, new)
self.log_level = new
self.log.setLevel(new)
MinRK
move default log setup to _log_default from init_logging...
r6883
MinRK
add LevelFormatter for extra formatting on high level messages...
r10559 log_datefmt = Unicode("%Y-%m-%d %H:%M:%S", config=True,
help="The date format used by logging formatters for %(asctime)s"
)
def _log_datefmt_changed(self, name, old, new):
self._log_format_changed()
log_format = Unicode("[%(name)s]%(highlevel)s %(message)s", config=True,
MinRK
Application.log_format is a configurable
r6884 help="The Logging format template",
)
Boris de Laage
Make changes of Application.log_format effective (#3236) ...
r10475 def _log_format_changed(self, name, old, new):
"""Change the log formatter when log_format is set."""
_log_handler = self.log.handlers[0]
Paul Ivanov
fix typo, closes #3462...
r10989 _log_formatter = LevelFormatter(new, datefmt=self.log_datefmt)
Boris de Laage
Make changes of Application.log_format effective (#3236) ...
r10475 _log_handler.setFormatter(_log_formatter)
MinRK
move default log setup to _log_default from init_logging...
r6883 log = Instance(logging.Logger)
def _log_default(self):
"""Start logging for this application.
Antony Lee
Fix docstring of _log_default.
r9547 The default is to log to stderr using a StreamHandler, if no default
Antony Lee
Don't add logging handler if one already exists....
r9546 handler already exists. The log level starts at logging.WARN, but this
can be adjusted by setting the ``log_level`` attribute.
MinRK
move default log setup to _log_default from init_logging...
r6883 """
log = logging.getLogger(self.__class__.__name__)
log.setLevel(self.log_level)
MinRK
default application logger shouldn't propagate...
r10203 log.propagate = False
Antony Lee
Don't add logging handler if one already exists....
r9546 _log = log # copied from Logger.hasHandlers() (new in Python 3.2)
while _log:
if _log.handlers:
return log
if not _log.propagate:
break
else:
_log = _log.parent
MinRK
move default log setup to _log_default from init_logging...
r6883 if sys.executable.endswith('pythonw.exe'):
# this should really go to a file, but file-logging is only
# hooked up in parallel applications
_log_handler = logging.StreamHandler(open(os.devnull, 'w'))
else:
_log_handler = logging.StreamHandler()
MinRK
add LevelFormatter for extra formatting on high level messages...
r10559 _log_formatter = LevelFormatter(self.log_format, datefmt=self.log_datefmt)
MinRK
move default log setup to _log_default from init_logging...
r6883 _log_handler.setFormatter(_log_formatter)
log.addHandler(_log_handler)
return log
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
rename macros/shortnames to flags/aliases...
r3861 # the alias map for configurables
MinRK
aliases match flag pattern ('-' as wordsep, not '_')...
r4214 aliases = Dict({'log-level' : 'Application.log_level'})
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
rename macros/shortnames to flags/aliases...
r3861 # flags for loading Configurables or store_const style flags
# flags are loaded from this dict by '--key' flags
# this must be a dict of two-tuples, the first element being the Config/dict
# and the second being the help string for the flag
flags = Dict()
MinRK
wrap helpstring output to 80 cols
r4020 def _flags_changed(self, name, old, new):
"""ensure flags dict is valid"""
for key,value in new.iteritems():
assert len(value) == 2, "Bad flag: %r:%s"%(key,value)
assert isinstance(value[0], (dict, Config)), "Bad flag: %r:%s"%(key,value)
assert isinstance(value[1], basestring), "Bad flag: %r:%s"%(key,value)
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
add subcommand support
r3949 # subcommands for launching other applications
# if this is not empty, this will be a parent Application
Bernardo B. Marques
remove all trailling spaces
r4872 # this must be a dict of two-tuples,
MinRK
wrap helpstring output to 80 cols
r4020 # the first element being the application class/import string
MinRK
add subcommand support
r3949 # and the second being the help string for the subcommand
subcommands = Dict()
# parse_command_line will initialize a subapp, if requested
subapp = Instance('IPython.config.application.Application', allow_none=True)
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
allow extra_args in applications
r3958 # extra command-line arguments that don't set config values
extra_args = List(Unicode)
Bernardo B. Marques
remove all trailling spaces
r4872
Brian Granger
IPython.config.application.Application updates....
r3794
Brian Granger
Created config.application and updated Configurable.
r3790 def __init__(self, **kwargs):
Brian Granger
IPython.config.application.Application updates....
r3794 SingletonConfigurable.__init__(self, **kwargs)
MinRK
move InteractiveShellApp before TerminalIPythonApp in TerminalApp class list...
r4462 # Ensure my class is in self.classes, so my attributes appear in command line
# options and config files.
if self.__class__ not in self.classes:
self.classes.insert(0, self.__class__)
Bernardo B. Marques
remove all trailling spaces
r4872
Brian Granger
Updates to config/application.
r3940 def _config_changed(self, name, old, new):
SingletonConfigurable._config_changed(self, name, old, new)
self.log.debug('Config changed:')
self.log.debug(repr(new))
MinRK
catch_config -> catch_config_error
r5214 @catch_config_error
MinRK
add subcommand support
r3949 def initialize(self, argv=None):
"""Do the basic steps to configure me.
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
add subcommand support
r3949 Override in subclasses.
"""
self.parse_command_line(argv)
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
add subcommand support
r3949 def start(self):
"""Start the app mainloop.
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
add subcommand support
r3949 Override in subclasses.
"""
if self.subapp is not None:
return self.subapp.start()
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
rename macros/shortnames to flags/aliases...
r3861 def print_alias_help(self):
MinRK
wrap helpstring output to 80 cols
r4020 """Print the alias part of the help."""
MinRK
rename macros/shortnames to flags/aliases...
r3861 if not self.aliases:
MinRK
move shortname to Application...
r3852 return
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
merge flags&aliases help output into just 'options'
r4195 lines = []
MinRK
move shortname to Application...
r3852 classdict = {}
MinRK
print usage on invalid command-line arguments
r3951 for cls in self.classes:
MinRK
make subcommands optional
r3952 # include all parents (up to, but excluding Configurable) in available names
for c in cls.mro()[:-3]:
MinRK
print usage on invalid command-line arguments
r3951 classdict[c.__name__] = c
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
rename macros/shortnames to flags/aliases...
r3861 for alias, longname in self.aliases.iteritems():
MinRK
move shortname to Application...
r3852 classname, traitname = longname.split('.',1)
cls = classdict[classname]
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
move shortname to Application...
r3852 trait = cls.class_traits(config=True)[traitname]
MinRK
parse cl_args agnostic of leading '-'...
r4189 help = cls.class_get_trait_help(trait).splitlines()
# reformat first line
help[0] = help[0].replace(longname, alias) + ' (%s)'%longname
MinRK
add single '-' prefix for length 1 aliases and flags to help output
r4605 if len(alias) == 1:
help[0] = help[0].replace('--%s='%alias, '-%s '%alias)
MinRK
parse cl_args agnostic of leading '-'...
r4189 lines.extend(help)
MinRK
merge flags&aliases help output into just 'options'
r4195 # lines.append('')
MinRK
parse cl_args agnostic of leading '-'...
r4189 print os.linesep.join(lines)
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
rename macros/shortnames to flags/aliases...
r3861 def print_flag_help(self):
MinRK
wrap helpstring output to 80 cols
r4020 """Print the flag part of the help."""
MinRK
rename macros/shortnames to flags/aliases...
r3861 if not self.flags:
MinRK
move shortname to Application...
r3852 return
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
merge flags&aliases help output into just 'options'
r4195 lines = []
MinRK
rename macros/shortnames to flags/aliases...
r3861 for m, (cfg,help) in self.flags.iteritems():
MinRK
add single '-' prefix for length 1 aliases and flags to help output
r4605 prefix = '--' if len(m) > 1 else '-'
lines.append(prefix+m)
MinRK
wrap helpstring output to 80 cols
r4020 lines.append(indent(dedent(help.strip())))
MinRK
merge flags&aliases help output into just 'options'
r4195 # lines.append('')
print os.linesep.join(lines)
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
merge flags&aliases help output into just 'options'
r4195 def print_options(self):
if not self.flags and not self.aliases:
return
lines = ['Options']
lines.append('-'*len(lines[0]))
MinRK
include default value in help output...
r3944 lines.append('')
MinRK
merge flags&aliases help output into just 'options'
r4195 for p in wrap_paragraphs(self.option_description):
lines.append(p)
lines.append('')
print os.linesep.join(lines)
self.print_flag_help()
self.print_alias_help()
print
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
add subcommand support
r3949 def print_subcommands(self):
MinRK
wrap helpstring output to 80 cols
r4020 """Print the subcommand part of the help."""
MinRK
add subcommand support
r3949 if not self.subcommands:
return
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
add subcommand support
r3949 lines = ["Subcommands"]
lines.append('-'*len(lines[0]))
MinRK
merge flags&aliases help output into just 'options'
r4195 lines.append('')
for p in wrap_paragraphs(self.subcommand_description):
lines.append(p)
lines.append('')
Fernando Perez
Fix padding of matplotlib figures, after much whining from Stefan :)
r4254 for subc, (cls, help) in self.subcommands.iteritems():
lines.append(subc)
MinRK
add subcommand support
r3949 if help:
MinRK
wrap helpstring output to 80 cols
r4020 lines.append(indent(dedent(help.strip())))
MinRK
add subcommand support
r3949 lines.append('')
MinRK
merge flags&aliases help output into just 'options'
r4195 print os.linesep.join(lines)
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
add `--help-all` flag, and don't print all configurables by default
r3946 def print_help(self, classes=False):
"""Print the help for each Configurable class in self.classes.
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
wrap helpstring output to 80 cols
r4020 If classes=False (the default), only flags and aliases are printed.
MinRK
add `--help-all` flag, and don't print all configurables by default
r3946 """
MinRK
make subcommands optional
r3952 self.print_subcommands()
MinRK
merge flags&aliases help output into just 'options'
r4195 self.print_options()
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
add `--help-all` flag, and don't print all configurables by default
r3946 if classes:
if self.classes:
print "Class parameters"
print "----------------"
print
MinRK
wrap helpstring output to 80 cols
r4020 for p in wrap_paragraphs(self.keyvalue_description):
print p
print
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
add `--help-all` flag, and don't print all configurables by default
r3946 for cls in self.classes:
cls.class_print_help()
print
else:
print "To see all available configurables, use `--help-all`"
Brian Granger
Created config.application and updated Configurable.
r3790 print
def print_description(self):
"""Print the application description."""
MinRK
wrap helpstring output to 80 cols
r4020 for p in wrap_paragraphs(self.description):
print p
print
Brian Granger
Created config.application and updated Configurable.
r3790
Brian Granger
Command line examples added for non-parallel apps.
r4215 def print_examples(self):
"""Print usage and examples.
This usage string goes at the end of the command line help string
and should contain examples of the application's usage.
"""
if self.examples:
print "Examples"
print "--------"
print
print indent(dedent(self.examples.strip()))
print
Brian Granger
Created config.application and updated Configurable.
r3790 def print_version(self):
"""Print the version string."""
print self.version
def update_config(self, config):
Brian Granger
Adding more documentation to config.application related files.
r3796 """Fire the traits events when the config is updated."""
Brian Granger
Created config.application and updated Configurable.
r3790 # Save a copy of the current config.
newconfig = deepcopy(self.config)
# Merge the new config into the current one.
MinRK
make Config.merge a public method...
r10873 newconfig.merge(config)
Brian Granger
Created config.application and updated Configurable.
r3790 # Save the combined config as self.config, which triggers the traits
# events.
Brian Granger
Fixing minor bug in config.application.
r3941 self.config = newconfig
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
catch_config -> catch_config_error
r5214 @catch_config_error
MinRK
add subcommand support
r3949 def initialize_subcommand(self, subc, argv=None):
MinRK
wrap helpstring output to 80 cols
r4020 """Initialize a subcommand with argv."""
MinRK
allow extra_args in applications
r3958 subapp,help = self.subcommands.get(subc)
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
add subcommand support
r3949 if isinstance(subapp, basestring):
subapp = import_item(subapp)
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
use App.instance() in Application.initialize_subapp...
r3962 # clear existing instances
self.__class__.clear_instance()
MinRK
add subcommand support
r3949 # instantiate
MinRK
pass config to subapps...
r11006 self.subapp = subapp.instance(config=self.config)
MinRK
add subcommand support
r3949 # and initialize subapp
self.subapp.initialize(argv)
MinRK
promote aliases and flags, to ensure they have priority over config files...
r4977
def flatten_flags(self):
"""flatten flags and aliases, so cl-args override as expected.
This prevents issues such as an alias pointing to InteractiveShell,
but a config file setting the same trait in TerminalInteraciveShell
getting inappropriate priority over the command-line arg.
Only aliases with exactly one descendent in the class list
will be promoted.
"""
# build a tree of classes in our list that inherit from a particular
# it will be a dict by parent classname of classes in our list
# that are descendents
mro_tree = defaultdict(list)
for cls in self.classes:
clsname = cls.__name__
for parent in cls.mro()[1:-3]:
# exclude cls itself and Configurable,HasTraits,object
mro_tree[parent.__name__].append(clsname)
# flatten aliases, which have the form:
# { 'alias' : 'Class.trait' }
aliases = {}
for alias, cls_trait in self.aliases.iteritems():
cls,trait = cls_trait.split('.',1)
children = mro_tree[cls]
if len(children) == 1:
# exactly one descendent, promote alias
cls = children[0]
aliases[alias] = '.'.join([cls,trait])
# flatten flags, which are of the form:
# { 'key' : ({'Cls' : {'trait' : value}}, 'help')}
flags = {}
for key, (flagdict, help) in self.flags.iteritems():
newflag = {}
for cls, subdict in flagdict.iteritems():
children = mro_tree[cls]
# exactly one descendent, promote flag section
if len(children) == 1:
cls = children[0]
newflag[cls] = subdict
flags[key] = (newflag, help)
return flags, aliases
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
catch_config -> catch_config_error
r5214 @catch_config_error
Brian Granger
Created config.application and updated Configurable.
r3790 def parse_command_line(self, argv=None):
"""Parse the command line arguments."""
Brian Granger
Added tests for IPython.config.application.Application
r3795 argv = sys.argv[1:] if argv is None else argv
MinRK
allow `ipython help subcommand` syntax...
r6166
if argv and argv[0] == 'help':
# turn `ipython help notebook` into `ipython notebook -h`
argv = argv[1:] + ['-h']
Brian Granger
Created config.application and updated Configurable.
r3790
MinRK
make subcommands optional
r3952 if self.subcommands and len(argv) > 0:
# we have subcommands, and one may have been specified
subc, subargv = argv[0], argv[1:]
MinRK
allow extra_args in applications
r3958 if re.match(r'^\w(\-?\w)*$', subc) and subc in self.subcommands:
MinRK
make subcommands optional
r3952 # it's a subcommand, and *not* a flag or class parameter
return self.initialize_subcommand(subc, subargv)
Bernardo B. Marques
remove all trailling spaces
r4872
Timothy O'Donnell
Fix issue #2660. Help (-h --help --help-all) and version (--version -V)...
r8842 # Arguments after a '--' argument are for the script IPython may be
# about to run, not IPython iteslf. For arguments parsed here (help and
# version), we want to only search the arguments up to the first
# occurrence of '--', which we're calling interpreted_argv.
try:
interpreted_argv = argv[:argv.index('--')]
except ValueError:
interpreted_argv = argv
if any(x in interpreted_argv for x in ('-h', '--help-all', '--help')):
Brian Granger
Created config.application and updated Configurable.
r3790 self.print_description()
Timothy O'Donnell
Fix issue #2660. Help (-h --help --help-all) and version (--version -V)...
r8842 self.print_help('--help-all' in interpreted_argv)
Brian Granger
Command line examples added for non-parallel apps.
r4215 self.print_examples()
MinRK
exit cleanly on help/version
r3945 self.exit(0)
Brian Granger
Created config.application and updated Configurable.
r3790
Timothy O'Donnell
Fix issue #2660. Help (-h --help --help-all) and version (--version -V)...
r8842 if '--version' in interpreted_argv or '-V' in interpreted_argv:
Brian Granger
Created config.application and updated Configurable.
r3790 self.print_version()
MinRK
exit cleanly on help/version
r3945 self.exit(0)
MinRK
promote aliases and flags, to ensure they have priority over config files...
r4977
# flatten flags&aliases, so cl-args get appropriate priority:
flags,aliases = self.flatten_flags()
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
promote aliases and flags, to ensure they have priority over config files...
r4977 loader = KVArgParseConfigLoader(argv=argv, aliases=aliases,
flags=flags)
MinRK
Show invalid config message on TraitErrors during initialization...
r5172 config = loader.load_config()
self.update_config(config)
MinRK
allow extra_args in applications
r3958 # store unparsed args in extra_args
self.extra_args = loader.extra_args
Brian Granger
Created config.application and updated Configurable.
r3790
MinRK
catch_config -> catch_config_error
r5214 @catch_config_error
Brian Granger
Created config.application and updated Configurable.
r3790 def load_config_file(self, filename, path=None):
"""Load a .py based config file by filename and path."""
loader = PyFileConfigLoader(filename, path=path)
MinRK
don't crash on bad config files
r4461 try:
config = loader.load_config()
MinRK
avoid interpreting IOError in config file as file-not-found...
r4905 except ConfigFileNotFound:
# problem finding the file, raise
MinRK
still raise IOError on missing config file...
r4465 raise
MinRK
don't crash on bad config files
r4461 except Exception:
MinRK
make config-loading debug messages more explicit...
r4564 # try to get the full filename, but it will be empty in the
# unlikely event that the error raised before filefind finished
filename = loader.full_filename or filename
MinRK
still raise IOError on missing config file...
r4465 # problem while running the file
MinRK
make config-loading debug messages more explicit...
r4564 self.log.error("Exception while loading config file %s",
filename, exc_info=True)
MinRK
don't crash on bad config files
r4461 else:
MinRK
make config-loading debug messages more explicit...
r4564 self.log.debug("Loaded config file: %s", loader.full_filename)
MinRK
don't crash on bad config files
r4461 self.update_config(config)
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
default config files are automatically generated...
r4025 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)
Brian Granger
Created config.application and updated Configurable.
r3790
Brian Granger
Updates to config/application.
r3940 def exit(self, exit_status=0):
self.log.debug("Exiting application: %s" % self.name)
sys.exit(exit_status)
MinRK
include default value in help output...
r3944
MinRK
add Application.launch_new_instance classmethod...
r11171 @classmethod
MinRK
Application.launch_instance...
r11176 def launch_instance(cls, argv=None, **kwargs):
"""Launch a global instance of this Application
If a global instance already exists, this reinitializes and starts it
"""
MinRK
add Application.launch_new_instance classmethod...
r11171 app = cls.instance(**kwargs)
app.initialize(argv)
app.start()
MinRK
include default value in help output...
r3944 #-----------------------------------------------------------------------------
# utility functions, for convenience
#-----------------------------------------------------------------------------
def boolean_flag(name, configurable, set_help='', unset_help=''):
MinRK
wrap helpstring output to 80 cols
r4020 """Helper for building basic --trait, --no-trait flags.
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
include default value in help output...
r3944 Parameters
----------
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
include default value in help output...
r3944 name : str
The name of the flag.
configurable : str
The 'Class.trait' string of the trait to be set/unset with the flag
set_help : unicode
help string for --name flag
unset_help : unicode
help string for --no-name flag
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
include default value in help output...
r3944 Returns
-------
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
include default value in help output...
r3944 cfg : dict
A dict with two keys: 'name', and 'no-name', for setting and unsetting
the trait, respectively.
"""
# default helpstrings
set_help = set_help or "set %s=True"%configurable
unset_help = unset_help or "set %s=False"%configurable
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
include default value in help output...
r3944 cls,trait = configurable.split('.')
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
prevent flags from clobbering entire config sections...
r3957 setter = {cls : {trait : True}}
unsetter = {cls : {trait : False}}
MinRK
include default value in help output...
r3944 return {name : (setter, set_help), 'no-'+name : (unsetter, unset_help)}
MinRK
wrap helpstring output to 80 cols
r4020