##// END OF EJS Templates
Testing '#:' attribute docstrings for sphinx....
Testing '#:' attribute docstrings for sphinx. This is supposed to work and give us class/instance docstrings, but it's not yet. I have a question on the sphinx list about it, let's leave it in the code until we figure out what we need to do to sphinx for it to work (it doesn't hurt otherwise).

File last commit:

r2363:f4d0cb7d
r2387:284a8dec
Show More
ipapp.py
555 lines | 21.9 KiB | text/x-python | PythonLexer
#!/usr/bin/env python
# encoding: utf-8
"""
The :class:`~IPython.core.application.Application` object for the command
line :command:`ipython` program.
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
#-----------------------------------------------------------------------------
import logging
import os
import sys
from IPython.core import release
from IPython.core.application import Application, BaseAppArgParseConfigLoader
from IPython.core.error import UsageError
from IPython.core.iplib import InteractiveShell
from IPython.core.pylabtools import pylab_activate
from IPython.config.loader import (
NoConfigDefault,
Config,
PyFileConfigLoader
)
from IPython.lib import inputhook
from IPython.utils.genutils import filefind, get_ipython_dir
#-----------------------------------------------------------------------------
# Utilities and helpers
#-----------------------------------------------------------------------------
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.
"""
#-----------------------------------------------------------------------------
# Main classes and functions
#-----------------------------------------------------------------------------
cl_args = (
(('--autocall',), dict(
type=int, dest='InteractiveShell.autocall', default=NoConfigDefault,
help='Set the autocall value (0,1,2).',
metavar='InteractiveShell.autocall')
),
(('--autoindent',), dict(
action='store_true', dest='InteractiveShell.autoindent', default=NoConfigDefault,
help='Turn on autoindenting.')
),
(('--no-autoindent',), dict(
action='store_false', dest='InteractiveShell.autoindent', default=NoConfigDefault,
help='Turn off autoindenting.')
),
(('--automagic',), dict(
action='store_true', dest='InteractiveShell.automagic', default=NoConfigDefault,
help='Turn on the auto calling of magic commands.')
),
(('--no-automagic',), dict(
action='store_false', dest='InteractiveShell.automagic', default=NoConfigDefault,
help='Turn off the auto calling of magic commands.')
),
(('--autoedit-syntax',), dict(
action='store_true', dest='InteractiveShell.autoedit_syntax', default=NoConfigDefault,
help='Turn on auto editing of files with syntax errors.')
),
(('--no-autoedit-syntax',), dict(
action='store_false', dest='InteractiveShell.autoedit_syntax', default=NoConfigDefault,
help='Turn off auto editing of files with syntax errors.')
),
(('--banner',), dict(
action='store_true', dest='Global.display_banner', default=NoConfigDefault,
help='Display a banner upon starting IPython.')
),
(('--no-banner',), dict(
action='store_false', dest='Global.display_banner', default=NoConfigDefault,
help="Don't display a banner upon starting IPython.")
),
(('--cache-size',), dict(
type=int, dest='InteractiveShell.cache_size', default=NoConfigDefault,
help="Set the size of the output cache.",
metavar='InteractiveShell.cache_size')
),
(('--classic',), dict(
action='store_true', dest='Global.classic', default=NoConfigDefault,
help="Gives IPython a similar feel to the classic Python prompt.")
),
(('--colors',), dict(
type=str, dest='InteractiveShell.colors', default=NoConfigDefault,
help="Set the color scheme (NoColor, Linux, and LightBG).",
metavar='InteractiveShell.colors')
),
(('--color-info',), dict(
action='store_true', dest='InteractiveShell.color_info', default=NoConfigDefault,
help="Enable using colors for info related things.")
),
(('--no-color-info',), dict(
action='store_false', dest='InteractiveShell.color_info', default=NoConfigDefault,
help="Disable using colors for info related things.")
),
(('--confirm-exit',), dict(
action='store_true', dest='InteractiveShell.confirm_exit', default=NoConfigDefault,
help="Prompt the user when existing.")
),
(('--no-confirm-exit',), dict(
action='store_false', dest='InteractiveShell.confirm_exit', default=NoConfigDefault,
help="Don't prompt the user when existing.")
),
(('--deep-reload',), dict(
action='store_true', dest='InteractiveShell.deep_reload', default=NoConfigDefault,
help="Enable deep (recursive) reloading by default.")
),
(('--no-deep-reload',), dict(
action='store_false', dest='InteractiveShell.deep_reload', default=NoConfigDefault,
help="Disable deep (recursive) reloading by default.")
),
(('--editor',), dict(
type=str, dest='InteractiveShell.editor', default=NoConfigDefault,
help="Set the editor used by IPython (default to $EDITOR/vi/notepad).",
metavar='InteractiveShell.editor')
),
(('--log','-l'), dict(
action='store_true', dest='InteractiveShell.logstart', default=NoConfigDefault,
help="Start logging to the default file (./ipython_log.py).")
),
(('--logfile','-lf'), dict(
type=unicode, dest='InteractiveShell.logfile', default=NoConfigDefault,
help="Start logging to logfile.",
metavar='InteractiveShell.logfile')
),
(('--log-append','-la'), dict(
type=unicode, dest='InteractiveShell.logappend', default=NoConfigDefault,
help="Start logging to the give file in append mode.",
metavar='InteractiveShell.logfile')
),
(('--pdb',), dict(
action='store_true', dest='InteractiveShell.pdb', default=NoConfigDefault,
help="Enable auto calling the pdb debugger after every exception.")
),
(('--no-pdb',), dict(
action='store_false', dest='InteractiveShell.pdb', default=NoConfigDefault,
help="Disable auto calling the pdb debugger after every exception.")
),
(('--pprint',), dict(
action='store_true', dest='InteractiveShell.pprint', default=NoConfigDefault,
help="Enable auto pretty printing of results.")
),
(('--no-pprint',), dict(
action='store_false', dest='InteractiveShell.pprint', default=NoConfigDefault,
help="Disable auto auto pretty printing of results.")
),
(('--prompt-in1','-pi1'), dict(
type=str, dest='InteractiveShell.prompt_in1', default=NoConfigDefault,
help="Set the main input prompt ('In [\#]: ')",
metavar='InteractiveShell.prompt_in1')
),
(('--prompt-in2','-pi2'), dict(
type=str, dest='InteractiveShell.prompt_in2', default=NoConfigDefault,
help="Set the secondary input prompt (' .\D.: ')",
metavar='InteractiveShell.prompt_in2')
),
(('--prompt-out','-po'), dict(
type=str, dest='InteractiveShell.prompt_out', default=NoConfigDefault,
help="Set the output prompt ('Out[\#]:')",
metavar='InteractiveShell.prompt_out')
),
(('--quick',), dict(
action='store_true', dest='Global.quick', default=NoConfigDefault,
help="Enable quick startup with no config files.")
),
(('--readline',), dict(
action='store_true', dest='InteractiveShell.readline_use', default=NoConfigDefault,
help="Enable readline for command line usage.")
),
(('--no-readline',), dict(
action='store_false', dest='InteractiveShell.readline_use', default=NoConfigDefault,
help="Disable readline for command line usage.")
),
(('--screen-length','-sl'), dict(
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')
),
(('--separate-in','-si'), dict(
type=str, dest='InteractiveShell.separate_in', default=NoConfigDefault,
help="Separator before input prompts. Default '\n'.",
metavar='InteractiveShell.separate_in')
),
(('--separate-out','-so'), dict(
type=str, dest='InteractiveShell.separate_out', default=NoConfigDefault,
help="Separator before output prompts. Default 0 (nothing).",
metavar='InteractiveShell.separate_out')
),
(('--separate-out2','-so2'), dict(
type=str, dest='InteractiveShell.separate_out2', default=NoConfigDefault,
help="Separator after output prompts. Default 0 (nonight).",
metavar='InteractiveShell.separate_out2')
),
(('-no-sep',), dict(
action='store_true', dest='Global.nosep', default=NoConfigDefault,
help="Eliminate all spacing between prompts.")
),
(('--term-title',), dict(
action='store_true', dest='InteractiveShell.term_title', default=NoConfigDefault,
help="Enable auto setting the terminal title.")
),
(('--no-term-title',), dict(
action='store_false', dest='InteractiveShell.term_title', default=NoConfigDefault,
help="Disable auto setting the terminal title.")
),
(('--xmode',), dict(
type=str, dest='InteractiveShell.xmode', default=NoConfigDefault,
help="Exception mode ('Plain','Context','Verbose')",
metavar='InteractiveShell.xmode')
),
(('--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')
),
(('-c',), dict(
type=str, dest='Global.code_to_run', default=NoConfigDefault,
help="Execute the given command string.",
metavar='Global.code_to_run')
),
(('-i',), dict(
action='store_true', dest='Global.force_interact', default=NoConfigDefault,
help="If running code from the command line, become interactive afterwards.")
),
(('--wthread','-wthread'), dict(
action='store_true', dest='Global.wthread', default=NoConfigDefault,
help="Enable wxPython event loop integration.")
),
(('--q4thread','--qthread','-q4thread','-qthread'), dict(
action='store_true', dest='Global.q4thread', default=NoConfigDefault,
help="Enable Qt4 event loop integration. Qt3 is no longer supported.")
),
(('--gthread','-gthread'), dict(
action='store_true', dest='Global.gthread', default=NoConfigDefault,
help="Enable GTK event loop integration.")
),
(('--pylab',), dict(
action='store_true', dest='Global.pylab', default=NoConfigDefault,
help="Pre-load matplotlib and numpy for interactive use.")
)
)
class IPythonAppCLConfigLoader(BaseAppArgParseConfigLoader):
arguments = cl_args
def load_config(self):
"""Do actions just before loading the command line config."""
# Special hack: there are countless uses of 'ipython -pylab' (with one
# dash) in the wild, including in printed books. Since argparse does
# will interpret -pylab as '-p ylab', sending us in a search for a
# profile named 'ylab', instead we special-case here -pylab as the
# first or second option only (this is how old ipython used to work)
# and convert this use to --pylab. Ugly, but needed for this one
# very widely used case.
firstargs = sys.argv[:3]
try:
idx = firstargs.index('-pylab')
except ValueError:
pass
else:
sys.argv[idx] = '--pylab'
return super(IPythonAppCLConfigLoader, self).load_config()
default_config_file_name = u'ipython_config.py'
class IPythonApp(Application):
name = u'ipython'
description = 'IPython: an enhanced interactive Python shell.'
config_file_name = default_config_file_name
def create_default_config(self):
super(IPythonApp, self).create_default_config()
# Eliminate multiple lookups
Global = self.default_config.Global
# Set all default values
Global.display_banner = True
# If the -c flag is given or a file is given to run at the cmd line
# like "ipython foo.py", normally we exit without starting the main
# loop. The force_interact config variable allows a user to override
# this and interact. It is also set by the -i cmd line flag, just
# like Python.
Global.force_interact = False
# By default always interact by starting the IPython mainloop.
Global.interact = True
# No GUI integration by default
Global.wthread = False
Global.q4thread = False
Global.gthread = False
# Pylab off by default
Global.pylab = False
def create_command_line_config(self):
"""Create and return a command line config loader."""
return IPythonAppCLConfigLoader(
description=self.description,
version=release.version
)
def load_file_config(self):
if hasattr(self.command_line_config.Global, 'quick'):
if self.command_line_config.Global.quick:
self.file_config = Config()
return
super(IPythonApp, self).load_file_config()
def post_load_file_config(self):
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
def pre_construct(self):
config = self.master_config
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'
if hasattr(config.Global, 'nosep'):
if config.Global.nosep:
config.InteractiveShell.separate_in = \
config.InteractiveShell.separate_out = \
config.InteractiveShell.separate_out2 = ''
# if there is code of files to run from the cmd line, don't interact
# unless the -i flag (Global.force_interact) is true.
code_to_run = config.Global.get('code_to_run','')
file_to_run = False
if len(self.extra_args)>=1:
if self.extra_args[0]:
file_to_run = True
if file_to_run or code_to_run:
if not config.Global.force_interact:
config.Global.interact = False
def construct(self):
# I am a little hesitant to put these into InteractiveShell itself.
# But that might be the place for them
sys.path.insert(0, '')
# Create an InteractiveShell instance
self.shell = InteractiveShell(
parent=None,
config=self.master_config
)
def post_construct(self):
"""Do actions after construct, but before starting the app."""
config = self.master_config
# 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 config.Global.display_banner and \
config.Global.interact:
self.shell.show_banner()
# Make sure there is a space below the banner.
if self.log_level <= logging.INFO: print
# Now a variety of things that happen after the banner is printed.
self._enable_gui_pylab()
self._load_extensions()
self._run_exec_lines()
self._run_exec_files()
self._run_cmd_line_code()
self._configure_xmode()
def _enable_gui_pylab(self):
"""Enable GUI event loop integration, taking pylab into account."""
Global = self.master_config.Global
# Select which gui to use
if Global.wthread:
gui = inputhook.GUI_WX
elif Global.q4thread:
gui = inputhook.GUI_QT
elif Global.gthread:
gui = inputhook.GUI_GTK
else:
gui = None
if Global.pylab:
activate = self.shell.enable_pylab
else:
# Enable only GUI integration, no pylab
activate = inputhook.enable_gui
if gui or Global.pylab:
try:
m = "Enabling GUI event loop integration, toolkit=%s, pylab=%s"\
% (gui, Global.pylab)
self.log.info(m)
activate(gui)
except:
self.log.warn("Error in enabling GUI event loop integration:")
self.shell.showtraceback()
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 _exec_file(self, fname):
full_filename = filefind(fname, [u'.', self.ipython_dir])
if os.path.isfile(full_filename):
if full_filename.endswith(u'.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)
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:
self._exec_file(fname)
except:
self.log.warn("Unknown error in handling Global.exec_files:")
self.shell.showtraceback()
def _run_cmd_line_code(self):
if hasattr(self.master_config.Global, 'code_to_run'):
line = self.master_config.Global.code_to_run
try:
self.log.info("Running code given at command line (-c): %s" % line)
self.shell.runlines(line)
except:
self.log.warn("Error in executing line in user namespace: %s" % line)
self.shell.showtraceback()
return
# Like Python itself, ignore the second if the first of these is present
try:
fname = self.extra_args[0]
except:
pass
else:
try:
self._exec_file(fname)
except:
self.log.warn("Error in executing file in user namespace: %s" % fname)
self.shell.showtraceback()
def _configure_xmode(self):
# XXX - shouldn't this be read from the config? I'm still a little
# lost with all the details of handling the new config guys...
self.shell.InteractiveTB.set_mode(mode=self.shell.xmode)
def start_app(self):
if self.master_config.Global.interact:
self.log.debug("Starting IPython's mainloop...")
self.shell.mainloop()
def load_default_config(ipython_dir=None):
"""Load the default config file from the default ipython_dir.
This is useful for embedded shells.
"""
if ipython_dir is None:
ipython_dir = get_ipython_dir()
cl = PyFileConfigLoader(default_config_file_name, ipython_dir)
config = cl.load_config()
return config
def launch_new_instance():
"""Create and run a full blown IPython instance"""
app = IPythonApp()
app.start()