ipapp.py
441 lines
| 17.8 KiB
| text/x-python
|
PythonLexer
Brian Granger
|
r2202 | #!/usr/bin/env python | |
# encoding: utf-8 | |||
""" | |||
The main IPython application object | |||
Authors: | |||
* Brian Granger | |||
* Fernando Perez | |||
Notes | |||
----- | |||
""" | |||
#----------------------------------------------------------------------------- | |||
# Copyright (C) 2008-2009 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
|
r2252 | import logging | |
Brian Granger
|
r2203 | import os | |
import sys | |||
import warnings | |||
Brian Granger
|
r2245 | from IPython.core.application import Application, IPythonArgParseConfigLoader | |
Brian Granger
|
r2202 | from IPython.core import release | |
from IPython.core.iplib import InteractiveShell | |||
Brian Granger
|
r2245 | from IPython.config.loader import ( | |
NoConfigDefault, | |||
Config, | |||
Brian Granger
|
r2252 | ConfigError, | |
Brian Granger
|
r2245 | PyFileConfigLoader | |
) | |||
Brian Granger
|
r2203 | ||
from IPython.utils.ipstruct import Struct | |||
Brian Granger
|
r2252 | from IPython.utils.genutils import filefind, get_ipython_dir | |
Brian Granger
|
r2203 | ||
#----------------------------------------------------------------------------- | |||
# Utilities and helpers | |||
#----------------------------------------------------------------------------- | |||
Brian Granger
|
r2202 | ||
ipython_desc = """ | |||
A Python shell with automatic history (input and output), dynamic object | |||
introspection, easier configuration, command completion, access to the system | |||
shell and more. | |||
""" | |||
Brian Granger
|
r2203 | def threaded_shell_warning(): | |
msg = """ | |||
The IPython threaded shells and their associated command line | |||
arguments (pylab/wthread/gthread/qthread/q4thread) have been | |||
deprecated. See the %gui magic for information on the new interface. | |||
""" | |||
warnings.warn(msg, category=DeprecationWarning, stacklevel=1) | |||
#----------------------------------------------------------------------------- | |||
# Main classes and functions | |||
#----------------------------------------------------------------------------- | |||
cl_args = ( | |||
(('-autocall',), dict( | |||
Brian Granger
|
r2245 | type=int, dest='InteractiveShell.autocall', default=NoConfigDefault, | |
help='Set the autocall value (0,1,2).', | |||
metavar='InteractiveShell.autocall') | |||
Brian Granger
|
r2203 | ), | |
(('-autoindent',), dict( | |||
Brian Granger
|
r2245 | action='store_true', dest='InteractiveShell.autoindent', default=NoConfigDefault, | |
Brian Granger
|
r2203 | help='Turn on autoindenting.') | |
), | |||
(('-noautoindent',), dict( | |||
Brian Granger
|
r2245 | action='store_false', dest='InteractiveShell.autoindent', default=NoConfigDefault, | |
Brian Granger
|
r2203 | help='Turn off autoindenting.') | |
), | |||
(('-automagic',), dict( | |||
Brian Granger
|
r2245 | action='store_true', dest='InteractiveShell.automagic', default=NoConfigDefault, | |
Brian Granger
|
r2203 | help='Turn on the auto calling of magic commands.') | |
), | |||
(('-noautomagic',), dict( | |||
Brian Granger
|
r2245 | action='store_false', dest='InteractiveShell.automagic', default=NoConfigDefault, | |
Brian Granger
|
r2203 | help='Turn off the auto calling of magic commands.') | |
), | |||
(('-autoedit_syntax',), dict( | |||
Brian Granger
|
r2245 | action='store_true', dest='InteractiveShell.autoedit_syntax', default=NoConfigDefault, | |
Brian Granger
|
r2203 | help='Turn on auto editing of files with syntax errors.') | |
), | |||
(('-noautoedit_syntax',), dict( | |||
Brian Granger
|
r2245 | action='store_false', dest='InteractiveShell.autoedit_syntax', default=NoConfigDefault, | |
Brian Granger
|
r2203 | help='Turn off auto editing of files with syntax errors.') | |
), | |||
(('-banner',), dict( | |||
Brian Granger
|
r2252 | action='store_true', dest='Global.display_banner', default=NoConfigDefault, | |
Brian Granger
|
r2203 | help='Display a banner upon starting IPython.') | |
), | |||
(('-nobanner',), dict( | |||
Brian Granger
|
r2252 | action='store_false', dest='Global.display_banner', default=NoConfigDefault, | |
Brian Granger
|
r2203 | help="Don't display a banner upon starting IPython.") | |
), | |||
(('-c',), dict( | |||
Brian Granger
|
r2245 | type=str, dest='InteractiveShell.c', default=NoConfigDefault, | |
help="Execute the given command string.", | |||
metavar='InteractiveShell.c') | |||
Brian Granger
|
r2203 | ), | |
(('-cache_size',), dict( | |||
Brian Granger
|
r2245 | type=int, dest='InteractiveShell.cache_size', default=NoConfigDefault, | |
help="Set the size of the output cache.", | |||
metavar='InteractiveShell.cache_size') | |||
Brian Granger
|
r2203 | ), | |
(('-classic',), dict( | |||
Brian Granger
|
r2245 | action='store_true', dest='Global.classic', default=NoConfigDefault, | |
Brian Granger
|
r2203 | help="Gives IPython a similar feel to the classic Python prompt.") | |
), | |||
(('-colors',), dict( | |||
Brian Granger
|
r2245 | type=str, dest='InteractiveShell.colors', default=NoConfigDefault, | |
help="Set the color scheme (NoColor, Linux, and LightBG).", | |||
metavar='InteractiveShell.colors') | |||
Brian Granger
|
r2203 | ), | |
(('-color_info',), dict( | |||
Brian Granger
|
r2245 | action='store_true', dest='InteractiveShell.color_info', default=NoConfigDefault, | |
Brian Granger
|
r2203 | help="Enable using colors for info related things.") | |
), | |||
(('-nocolor_info',), dict( | |||
Brian Granger
|
r2245 | action='store_false', dest='InteractiveShell.color_info', default=NoConfigDefault, | |
Brian Granger
|
r2203 | help="Disable using colors for info related things.") | |
), | |||
(('-confirm_exit',), dict( | |||
Brian Granger
|
r2245 | action='store_true', dest='InteractiveShell.confirm_exit', default=NoConfigDefault, | |
Brian Granger
|
r2203 | help="Prompt the user when existing.") | |
), | |||
(('-noconfirm_exit',), dict( | |||
Brian Granger
|
r2245 | action='store_false', dest='InteractiveShell.confirm_exit', default=NoConfigDefault, | |
Brian Granger
|
r2203 | help="Don't prompt the user when existing.") | |
), | |||
(('-deep_reload',), dict( | |||
Brian Granger
|
r2245 | action='store_true', dest='InteractiveShell.deep_reload', default=NoConfigDefault, | |
Brian Granger
|
r2203 | help="Enable deep (recursive) reloading by default.") | |
), | |||
(('-nodeep_reload',), dict( | |||
Brian Granger
|
r2245 | action='store_false', dest='InteractiveShell.deep_reload', default=NoConfigDefault, | |
Brian Granger
|
r2203 | help="Disable deep (recursive) reloading by default.") | |
), | |||
(('-editor',), dict( | |||
Brian Granger
|
r2245 | type=str, dest='InteractiveShell.editor', default=NoConfigDefault, | |
help="Set the editor used by IPython (default to $EDITOR/vi/notepad).", | |||
metavar='InteractiveShell.editor') | |||
Brian Granger
|
r2203 | ), | |
(('-log','-l'), dict( | |||
Brian Granger
|
r2245 | action='store_true', dest='InteractiveShell.logstart', default=NoConfigDefault, | |
Brian Granger
|
r2203 | help="Start logging to the default file (./ipython_log.py).") | |
), | |||
(('-logfile','-lf'), dict( | |||
Brian Granger
|
r2245 | type=str, dest='InteractiveShell.logfile', default=NoConfigDefault, | |
help="Specify the name of your logfile.", | |||
metavar='InteractiveShell.logfile') | |||
Brian Granger
|
r2203 | ), | |
(('-logplay','-lp'), dict( | |||
Brian Granger
|
r2245 | type=str, dest='InteractiveShell.logplay', default=NoConfigDefault, | |
help="Re-play a log file and then append to it.", | |||
metavar='InteractiveShell.logplay') | |||
Brian Granger
|
r2203 | ), | |
(('-pdb',), dict( | |||
Brian Granger
|
r2245 | action='store_true', dest='InteractiveShell.pdb', default=NoConfigDefault, | |
Brian Granger
|
r2203 | help="Enable auto calling the pdb debugger after every exception.") | |
), | |||
(('-nopdb',), dict( | |||
Brian Granger
|
r2245 | action='store_false', dest='InteractiveShell.pdb', default=NoConfigDefault, | |
Brian Granger
|
r2203 | help="Disable auto calling the pdb debugger after every exception.") | |
), | |||
(('-pprint',), dict( | |||
Brian Granger
|
r2245 | action='store_true', dest='InteractiveShell.pprint', default=NoConfigDefault, | |
Brian Granger
|
r2203 | help="Enable auto pretty printing of results.") | |
), | |||
(('-nopprint',), dict( | |||
Brian Granger
|
r2245 | action='store_false', dest='InteractiveShell.pprint', default=NoConfigDefault, | |
Brian Granger
|
r2203 | help="Disable auto auto pretty printing of results.") | |
), | |||
(('-prompt_in1','-pi1'), dict( | |||
Brian Granger
|
r2245 | type=str, dest='InteractiveShell.prompt_in1', default=NoConfigDefault, | |
help="Set the main input prompt ('In [\#]: ')", | |||
metavar='InteractiveShell.prompt_in1') | |||
Brian Granger
|
r2203 | ), | |
(('-prompt_in2','-pi2'), dict( | |||
Brian Granger
|
r2245 | type=str, dest='InteractiveShell.prompt_in2', default=NoConfigDefault, | |
help="Set the secondary input prompt (' .\D.: ')", | |||
metavar='InteractiveShell.prompt_in2') | |||
Brian Granger
|
r2203 | ), | |
(('-prompt_out','-po'), dict( | |||
Brian Granger
|
r2245 | type=str, dest='InteractiveShell.prompt_out', default=NoConfigDefault, | |
help="Set the output prompt ('Out[\#]:')", | |||
metavar='InteractiveShell.prompt_out') | |||
Brian Granger
|
r2203 | ), | |
(('-quick',), dict( | |||
Brian Granger
|
r2245 | action='store_true', dest='Global.quick', default=NoConfigDefault, | |
Brian Granger
|
r2203 | help="Enable quick startup with no config files.") | |
), | |||
(('-readline',), dict( | |||
Brian Granger
|
r2245 | action='store_true', dest='InteractiveShell.readline_use', default=NoConfigDefault, | |
Brian Granger
|
r2203 | help="Enable readline for command line usage.") | |
), | |||
(('-noreadline',), dict( | |||
Brian Granger
|
r2245 | action='store_false', dest='InteractiveShell.readline_use', default=NoConfigDefault, | |
Brian Granger
|
r2203 | help="Disable readline for command line usage.") | |
), | |||
(('-screen_length','-sl'), dict( | |||
Brian Granger
|
r2245 | type=int, dest='InteractiveShell.screen_length', default=NoConfigDefault, | |
help='Number of lines on screen, used to control printing of long strings.', | |||
metavar='InteractiveShell.screen_length') | |||
Brian Granger
|
r2203 | ), | |
(('-separate_in','-si'), dict( | |||
Brian Granger
|
r2245 | type=str, dest='InteractiveShell.separate_in', default=NoConfigDefault, | |
help="Separator before input prompts. Default '\n'.", | |||
metavar='InteractiveShell.separate_in') | |||
Brian Granger
|
r2203 | ), | |
(('-separate_out','-so'), dict( | |||
Brian Granger
|
r2245 | type=str, dest='InteractiveShell.separate_out', default=NoConfigDefault, | |
help="Separator before output prompts. Default 0 (nothing).", | |||
metavar='InteractiveShell.separate_out') | |||
Brian Granger
|
r2203 | ), | |
(('-separate_out2','-so2'), dict( | |||
Brian Granger
|
r2245 | type=str, dest='InteractiveShell.separate_out2', default=NoConfigDefault, | |
help="Separator after output prompts. Default 0 (nonight).", | |||
metavar='InteractiveShell.separate_out2') | |||
Brian Granger
|
r2203 | ), | |
(('-nosep',), dict( | |||
Brian Granger
|
r2245 | action='store_true', dest='Global.nosep', default=NoConfigDefault, | |
Brian Granger
|
r2203 | help="Eliminate all spacing between prompts.") | |
), | |||
Brian Granger
|
r2204 | (('-term_title',), dict( | |
Brian Granger
|
r2245 | action='store_true', dest='InteractiveShell.term_title', default=NoConfigDefault, | |
Brian Granger
|
r2204 | help="Enable auto setting the terminal title.") | |
), | |||
(('-noterm_title',), dict( | |||
Brian Granger
|
r2245 | action='store_false', dest='InteractiveShell.term_title', default=NoConfigDefault, | |
Brian Granger
|
r2204 | help="Disable auto setting the terminal title.") | |
), | |||
Brian Granger
|
r2203 | (('-xmode',), dict( | |
Brian Granger
|
r2245 | type=str, dest='InteractiveShell.xmode', default=NoConfigDefault, | |
help="Exception mode ('Plain','Context','Verbose')", | |||
metavar='InteractiveShell.xmode') | |||
Brian Granger
|
r2203 | ), | |
Brian Granger
|
r2252 | (('-ext',), dict( | |
type=str, dest='Global.extra_extension', default=NoConfigDefault, | |||
help="The dotted module name of an IPython extension to load.", | |||
metavar='Global.extra_extension') | |||
), | |||
Brian Granger
|
r2204 | # These are only here to get the proper deprecation warnings | |
(('-pylab','-wthread','-qthread','-q4thread','-gthread'), dict( | |||
Brian Granger
|
r2245 | action='store_true', dest='Global.threaded_shell', default=NoConfigDefault, | |
Brian Granger
|
r2204 | help="These command line flags are deprecated, see the 'gui' magic.") | |
), | |||
Brian Granger
|
r2203 | ) | |
Brian Granger
|
r2202 | class IPythonAppCLConfigLoader(IPythonArgParseConfigLoader): | |
Brian Granger
|
r2203 | ||
arguments = cl_args | |||
Brian Granger
|
r2202 | ||
Brian Granger
|
r2245 | _default_config_file_name = 'ipython_config.py' | |
Brian Granger
|
r2202 | class IPythonApp(Application): | |
name = 'ipython' | |||
Brian Granger
|
r2245 | config_file_name = _default_config_file_name | |
Brian Granger
|
r2202 | ||
Brian Granger
|
r2252 | def create_default_config(self): | |
super(IPythonApp, self).create_default_config() | |||
self.default_config.Global.display_banner=True | |||
# Let the parent class set the default, but each time log_level | |||
# changes from config, we need to update self.log_level as that is | |||
# what updates the actual log level in self.log. | |||
self.default_config.Global.log_level = self.log_level | |||
Brian Granger
|
r2202 | def create_command_line_config(self): | |
"""Create and return a command line config loader.""" | |||
return IPythonAppCLConfigLoader( | |||
description=ipython_desc, | |||
version=release.version) | |||
Brian Granger
|
r2203 | def post_load_command_line_config(self): | |
"""Do actions after loading cl config.""" | |||
clc = self.command_line_config | |||
# Display the deprecation warnings about threaded shells | |||
Brian Granger
|
r2245 | if hasattr(clc.Global, 'threaded_shell'): | |
Brian Granger
|
r2204 | threaded_shell_warning() | |
Brian Granger
|
r2245 | del clc.Global['threaded_shell'] | |
Brian Granger
|
r2203 | ||
def load_file_config(self): | |||
Brian Granger
|
r2245 | if hasattr(self.command_line_config.Global, 'quick'): | |
if self.command_line_config.Global.quick: | |||
self.file_config = Config() | |||
Brian Granger
|
r2203 | return | |
super(IPythonApp, self).load_file_config() | |||
def post_load_file_config(self): | |||
Brian Granger
|
r2252 | if hasattr(self.command_line_config.Global, 'extra_extension'): | |
if not hasattr(self.file_config.Global, 'extensions'): | |||
self.file_config.Global.extensions = [] | |||
self.file_config.Global.extensions.append( | |||
self.command_line_config.Global.extra_extension) | |||
del self.command_line_config.Global.extra_extension | |||
Brian Granger
|
r2203 | ||
def pre_construct(self): | |||
config = self.master_config | |||
Brian Granger
|
r2245 | if hasattr(config.Global, 'classic'): | |
if config.Global.classic: | |||
config.InteractiveShell.cache_size = 0 | |||
config.InteractiveShell.pprint = 0 | |||
config.InteractiveShell.prompt_in1 = '>>> ' | |||
config.InteractiveShell.prompt_in2 = '... ' | |||
config.InteractiveShell.prompt_out = '' | |||
config.InteractiveShell.separate_in = \ | |||
config.InteractiveShell.separate_out = \ | |||
config.InteractiveShell.separate_out2 = '' | |||
config.InteractiveShell.colors = 'NoColor' | |||
config.InteractiveShell.xmode = 'Plain' | |||
Brian Granger
|
r2203 | ||
# All this should be moved to traitlet handlers in InteractiveShell | |||
Brian Granger
|
r2204 | # But, currently InteractiveShell doesn't have support for changing | |
# these values at runtime. Once we support that, this should | |||
# be moved there!!! | |||
Brian Granger
|
r2245 | if hasattr(config.Global, 'nosep'): | |
if config.Global.nosep: | |||
config.InteractiveShell.separate_in = \ | |||
config.InteractiveShell.separate_out = \ | |||
config.InteractiveShell.separate_out2 = '0' | |||
Brian Granger
|
r2203 | ||
Brian Granger
|
r2202 | def construct(self): | |
Brian Granger
|
r2203 | # I am a little hesitant to put these into InteractiveShell itself. | |
# But that might be the place for them | |||
sys.path.insert(0, '') | |||
Brian Granger
|
r2252 | ||
Brian Granger
|
r2203 | # Create an InteractiveShell instance | |
Brian Granger
|
r2202 | self.shell = InteractiveShell( | |
parent=None, | |||
config=self.master_config | |||
) | |||
Brian Granger
|
r2252 | ||
def post_construct(self): | |||
"""Do actions after construct, but before starting the app.""" | |||
# shell.display_banner should always be False for the terminal | |||
# based app, because we call shell.show_banner() by hand below | |||
# so the banner shows *before* all extension loading stuff. | |||
self.shell.display_banner = False | |||
if self.master_config.Global.display_banner: | |||
self.shell.show_banner() | |||
# Make sure there is a space below the banner. | |||
if self.log_level <= logging.INFO: print | |||
self._load_extensions() | |||
self._run_exec_lines() | |||
self._run_exec_files() | |||
def _load_extensions(self): | |||
"""Load all IPython extensions in Global.extensions. | |||
This uses the :meth:`InteractiveShell.load_extensions` to load all | |||
the extensions listed in ``self.master_config.Global.extensions``. | |||
""" | |||
try: | |||
if hasattr(self.master_config.Global, 'extensions'): | |||
self.log.debug("Loading IPython extensions...") | |||
extensions = self.master_config.Global.extensions | |||
for ext in extensions: | |||
try: | |||
self.log.info("Loading IPython extension: %s" % ext) | |||
self.shell.load_extension(ext) | |||
except: | |||
self.log.warn("Error in loading extension: %s" % ext) | |||
self.shell.showtraceback() | |||
except: | |||
self.log.warn("Unknown error in loading extensions:") | |||
self.shell.showtraceback() | |||
def _run_exec_lines(self): | |||
"""Run lines of code in Global.exec_lines in the user's namespace.""" | |||
try: | |||
if hasattr(self.master_config.Global, 'exec_lines'): | |||
self.log.debug("Running code from Global.exec_lines...") | |||
exec_lines = self.master_config.Global.exec_lines | |||
for line in exec_lines: | |||
try: | |||
self.log.info("Running code in user namespace: %s" % line) | |||
self.shell.runlines(line) | |||
except: | |||
self.log.warn("Error in executing line in user namespace: %s" % line) | |||
self.shell.showtraceback() | |||
except: | |||
self.log.warn("Unknown error in handling Global.exec_lines:") | |||
self.shell.showtraceback() | |||
def _run_exec_files(self): | |||
try: | |||
if hasattr(self.master_config.Global, 'exec_files'): | |||
self.log.debug("Running files in Global.exec_files...") | |||
exec_files = self.master_config.Global.exec_files | |||
for fname in exec_files: | |||
full_filename = filefind(fname, ['.', self.ipythondir]) | |||
if os.path.isfile(full_filename): | |||
if full_filename.endswith('.py'): | |||
self.log.info("Running file in user namespace: %s" % full_filename) | |||
self.shell.safe_execfile(full_filename, self.shell.user_ns) | |||
elif full_filename.endswith('.ipy'): | |||
self.log.info("Running file in user namespace: %s" % full_filename) | |||
self.shell.safe_execfile_ipy(full_filename) | |||
else: | |||
self.log.warn("File does not have a .py or .ipy extension: <%s>" % full_filename) | |||
except: | |||
self.log.warn("Unknown error in handling Global.exec_files:") | |||
self.shell.showtraceback() | |||
Brian Granger
|
r2202 | def start_app(self): | |
Brian Granger
|
r2252 | self.log.debug("Starting IPython's mainloop...") | |
Brian Granger
|
r2202 | self.shell.mainloop() | |
Brian Granger
|
r2245 | def load_default_config(ipythondir=None): | |
"""Load the default config file from the default ipythondir. | |||
This is useful for embedded shells. | |||
""" | |||
if ipythondir is None: | |||
ipythondir = get_ipython_dir() | |||
cl = PyFileConfigLoader(_default_config_file_name, ipythondir) | |||
config = cl.load_config() | |||
return config | |||
Brian Granger
|
r2202 | if __name__ == '__main__': | |
app = IPythonApp() | |||
app.start() |