##// END OF EJS Templates
Merge pull request #7522 from minrk/store-scroll...
Merge pull request #7522 from minrk/store-scroll remember and persist manual scroll state.

File last commit:

r19468:ead6b15c
r20141:d0fbe137 merge
Show More
application.py
621 lines | 22.2 KiB | text/x-python | PythonLexer
Brian Granger
Created config.application and updated Configurable.
r3790 # encoding: utf-8
MinRK
allow custom log_formatter class on Applications
r16357 """A base class for a configurable application."""
Brian Granger
Created config.application and updated Configurable.
r3790
MinRK
allow custom log_formatter class on Applications
r16357 # Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License.
Brian Granger
Created config.application and updated Configurable.
r3790
Thomas Kluyver
Convert print statements to print function calls...
r13348 from __future__ import print_function
Brian Granger
Created config.application and updated Configurable.
r3790
Min RK
Warn about .py/.json collisions in config...
r19160 import json
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 (
Matthias BUSSONNIER
allow to load config from json file...
r13771 KVArgParseConfigLoader, PyFileConfigLoader, Config, ArgumentError, ConfigFileNotFound, JSONFileConfigLoader
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
MinRK
ensure Application.argv is unicode...
r13157 from IPython.utils import py3compat
Thomas Kluyver
Fix references to dict.iteritems and dict.itervalues
r13361 from IPython.utils.py3compat import string_types, iteritems
MinRK
wrap helpstring output to 80 cols
r4020
#-----------------------------------------------------------------------------
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`.
Thomas Kluyver
Format command name into subcommand_description at run time, not import...
r16494 """
MinRK
merge flags&aliases help output into just 'options'
r4195 # 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_help()
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 = ""
Thomas Kluyver
Remove Python 2.6 workaround
r12150 return super(LevelFormatter, self).format(record)
MinRK
add LevelFormatter for extra formatting on high level messages...
r10559
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.
MinRK
allow --help and config_file classes to differ...
r17959 classes = []
@property
def _help_classes(self):
"""Define `App.help_classes` if CLI classes should differ from config file classes"""
return getattr(self, 'help_classes', self.classes)
@property
def _config_classes(self):
"""Define `App.config_classes` if config file classes should differ from CLI classes."""
return getattr(self, 'config_classes', self.classes)
Brian Granger
Created config.application and updated Configurable.
r3790
# The version string of this application.
version = Unicode(u'0.0')
MinRK
remember argv used to initialize an Application...
r12283
# the argv used to initialize the application
MinRK
don't validate Application.argv type...
r12651 argv = List()
Brian Granger
Created config.application and updated Configurable.
r3790
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."""
Thomas Kluyver
Replace references to unicode and basestring
r13353 if isinstance(new, string_types):
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
allow custom log_formatter class on Applications
r16357 _log_formatter_cls = LevelFormatter
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]
MinRK
allow custom log_formatter class on Applications
r16357 _log_formatter = self._log_formatter_cls(fmt=new, datefmt=self.log_datefmt)
Boris de Laage
Make changes of Application.log_format effective (#3236) ...
r10475 _log_handler.setFormatter(_log_formatter)
MinRK
allow custom log_formatter class on Applications
r16357
Boris de Laage
Make changes of Application.log_format effective (#3236) ...
r10475
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
allow custom log_formatter class on Applications
r16357 _log_formatter = self._log_formatter_cls(fmt=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"""
Thomas Kluyver
Fix references to dict.iteritems and dict.itervalues
r13361 for key,value in iteritems(new):
MinRK
wrap helpstring output to 80 cols
r4020 assert len(value) == 2, "Bad flag: %r:%s"%(key,value)
assert isinstance(value[0], (dict, Config)), "Bad flag: %r:%s"%(key,value)
Thomas Kluyver
Replace references to unicode and basestring
r13353 assert isinstance(value[1], string_types), "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
allow --help and config_file classes to differ...
r17959 for cls in self._help_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
Thomas Kluyver
Fix references to dict.iteritems and dict.itervalues
r13361 for alias, longname in iteritems(self.aliases):
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('')
Thomas Kluyver
Convert print statements to print function calls...
r13348 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 = []
Thomas Kluyver
Fix references to dict.iteritems and dict.itervalues
r13361 for m, (cfg,help) in iteritems(self.flags):
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('')
Thomas Kluyver
Convert print statements to print function calls...
r13348 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('')
Thomas Kluyver
Convert print statements to print function calls...
r13348 print(os.linesep.join(lines))
MinRK
merge flags&aliases help output into just 'options'
r4195 self.print_flag_help()
self.print_alias_help()
Thomas Kluyver
Convert print statements to print function calls...
r13348 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('')
Thomas Kluyver
Format command name into subcommand_description at run time, not import...
r16494 for p in wrap_paragraphs(self.subcommand_description.format(
Thomas Kluyver
Fix applications displaying subcommands
r16561 app=self.name)):
MinRK
merge flags&aliases help output into just 'options'
r4195 lines.append(p)
lines.append('')
Thomas Kluyver
Fix references to dict.iteritems and dict.itervalues
r13361 for subc, (cls, help) in iteritems(self.subcommands):
Fernando Perez
Fix padding of matplotlib figures, after much whining from Stefan :)
r4254 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('')
Thomas Kluyver
Convert print statements to print function calls...
r13348 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 """
Jonathan Frederic
Moved print description and examples into default help output...
r11664 self.print_description()
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:
MinRK
allow --help and config_file classes to differ...
r17959 help_classes = self._help_classes
if help_classes:
Thomas Kluyver
Convert print statements to print function calls...
r13348 print("Class parameters")
print("----------------")
print()
MinRK
wrap helpstring output to 80 cols
r4020 for p in wrap_paragraphs(self.keyvalue_description):
Thomas Kluyver
Convert print statements to print function calls...
r13348 print(p)
print()
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
allow --help and config_file classes to differ...
r17959 for cls in help_classes:
MinRK
add `--help-all` flag, and don't print all configurables by default
r3946 cls.class_print_help()
Thomas Kluyver
Convert print statements to print function calls...
r13348 print()
MinRK
add `--help-all` flag, and don't print all configurables by default
r3946 else:
Thomas Kluyver
Convert print statements to print function calls...
r13348 print("To see all available configurables, use `--help-all`")
print()
Brian Granger
Created config.application and updated Configurable.
r3790
Jonathan Frederic
Moved print description and examples into default help output...
r11664 self.print_examples()
Brian Granger
Created config.application and updated Configurable.
r3790 def print_description(self):
"""Print the application description."""
MinRK
wrap helpstring output to 80 cols
r4020 for p in wrap_paragraphs(self.description):
Thomas Kluyver
Convert print statements to print function calls...
r13348 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:
Thomas Kluyver
Convert print statements to print function calls...
r13348 print("Examples")
print("--------")
print()
print(indent(dedent(self.examples.strip())))
print()
Brian Granger
Command line examples added for non-parallel apps.
r4215
Brian Granger
Created config.application and updated Configurable.
r3790 def print_version(self):
"""Print the version string."""
Thomas Kluyver
Convert print statements to print function calls...
r13348 print(self.version)
Brian Granger
Created config.application and updated Configurable.
r3790
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
Thomas Kluyver
Replace references to unicode and basestring
r13353 if isinstance(subapp, string_types):
MinRK
add subcommand support
r3949 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)
MinRK
allow --help and config_file classes to differ...
r17959 for cls in self._help_classes:
MinRK
promote aliases and flags, to ensure they have priority over config files...
r4977 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 = {}
Thomas Kluyver
Fix references to dict.iteritems and dict.itervalues
r13361 for alias, cls_trait in iteritems(self.aliases):
MinRK
promote aliases and flags, to ensure they have priority over config files...
r4977 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 = {}
Thomas Kluyver
Fix references to dict.iteritems and dict.itervalues
r13361 for key, (flagdict, help) in iteritems(self.flags):
MinRK
promote aliases and flags, to ensure they have priority over config files...
r4977 newflag = {}
Thomas Kluyver
Fix references to dict.iteritems and dict.itervalues
r13361 for cls, subdict in iteritems(flagdict):
MinRK
promote aliases and flags, to ensure they have priority over config files...
r4977 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
ensure Application.argv is unicode...
r13157 self.argv = [ py3compat.cast_unicode(arg) for arg in 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')):
self.print_help('--help-all' in interpreted_argv)
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()
loader = KVArgParseConfigLoader(argv=argv, aliases=aliases,
Matthias BUSSONNIER
allow to load config from json file...
r13771 flags=flags, log=self.log)
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
Matthias BUSSONNIER
allow to load config from json file...
r13771 @classmethod
Matthias BUSSONNIER
fix plural and embeded
r13787 def _load_config_files(cls, basefilename, path=None, log=None):
"""Load config files (py,json) by filename and path.
yield each config object in turn.
"""
Min RK
add system-wide IPython config...
r18527
if not isinstance(path, list):
path = [path]
for path in path[::-1]:
# path list is in descending priority order, so load files backwards:
pyloader = PyFileConfigLoader(basefilename+'.py', path=path, log=log)
jsonloader = JSONFileConfigLoader(basefilename+'.json', path=path, log=log)
config = None
for loader in [pyloader, jsonloader]:
try:
config = loader.load_config()
except ConfigFileNotFound:
pass
except Exception:
# 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 basefilename
# problem while running the file
if log:
log.error("Exception while loading config file %s",
filename, exc_info=True)
else:
if log:
log.debug("Loaded config file: %s", loader.full_filename)
if config:
yield config
Matthias BUSSONNIER
allow to load config from json file...
r13771
raise StopIteration
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):
MinRK
polish pass
r13870 """Load config files by filename and path."""
Matthias BUSSONNIER
allow to load config from json file...
r13771 filename, ext = os.path.splitext(filename)
Min RK
Warn about .py/.json collisions in config...
r19160 loaded = []
MinRK
polish pass
r13870 for config in self._load_config_files(filename, path=path, log=self.log):
Min RK
Warn about .py/.json collisions in config...
r19160 loaded.append(config)
MinRK
don't crash on bad config files
r4461 self.update_config(config)
Min RK
Warn about .py/.json collisions in config...
r19160 if len(loaded) > 1:
collisions = loaded[0].collisions(loaded[1])
if collisions:
self.log.warn("Collisions detected in {0}.py and {0}.json config files."
" {0}.json has higher priority: {1}".format(
filename, json.dumps(collisions, indent=2),
))
Bernardo B. Marques
remove all trailling spaces
r4872
Matthias BUSSONNIER
allow to load config from json file...
r13771
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('')
MinRK
allow --help and config_file classes to differ...
r17959 for cls in self._config_classes:
MinRK
default config files are automatically generated...
r4025 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
Min RK
add IPython.config.get_config...
r19468
def get_config():
"""Get the config object for the global Application instance, if there is one
otherwise return an empty config object
"""
if Application.initialized():
return Application.instance().config
else:
return Config()