ipmaker.py
763 lines
| 28.2 KiB
| text/x-python
|
PythonLexer
/ IPython / ipmaker.py
fperez
|
r0 | # -*- coding: utf-8 -*- | ||
""" | ||||
IPython -- An enhanced Interactive Python | ||||
Requires Python 2.1 or better. | ||||
This file contains the main make_IPython() starter function. | ||||
fperez
|
r909 | $Id: ipmaker.py 2899 2007-12-28 08:32:59Z fperez $""" | ||
fperez
|
r0 | |||
#***************************************************************************** | ||||
fperez
|
r88 | # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu> | ||
fperez
|
r0 | # | ||
# Distributed under the terms of the BSD License. The full license is in | ||||
# the file COPYING, distributed as part of this software. | ||||
#***************************************************************************** | ||||
from IPython import Release | ||||
__author__ = '%s <%s>' % Release.authors['Fernando'] | ||||
__license__ = Release.license | ||||
__version__ = Release.version | ||||
fperez
|
r520 | try: | ||
credits._Printer__data = """ | ||||
Python: %s | ||||
fperez
|
r0 | |||
fperez
|
r520 | IPython: Fernando Perez, Janko Hauser, Nathan Gray, and many users. | ||
See http://ipython.scipy.org for more information.""" \ | ||||
% credits._Printer__data | ||||
fperez
|
r0 | |||
fperez
|
r520 | copyright._Printer__data += """ | ||
fperez
|
r0 | |||
fperez
|
r520 | Copyright (c) 2001-2004 Fernando Perez, Janko Hauser, Nathan Gray. | ||
All Rights Reserved.""" | ||||
except NameError: | ||||
# Can happen if ipython was started with 'python -S', so that site.py is | ||||
# not loaded | ||||
pass | ||||
fperez
|
r0 | |||
#**************************************************************************** | ||||
# Required modules | ||||
# From the standard library | ||||
fperez
|
r52 | import __main__ | ||
import __builtin__ | ||||
import os | ||||
import re | ||||
import sys | ||||
import types | ||||
fperez
|
r0 | from pprint import pprint,pformat | ||
# Our own | ||||
from IPython import DPyGetOpt | ||||
fperez
|
r98 | from IPython.ipstruct import Struct | ||
fperez
|
r0 | from IPython.OutputTrap import OutputTrap | ||
from IPython.ConfigLoader import ConfigLoader | ||||
fperez
|
r61 | from IPython.iplib import InteractiveShell | ||
fperez
|
r0 | from IPython.usage import cmd_line_usage,interactive_usage | ||
from IPython.genutils import * | ||||
#----------------------------------------------------------------------------- | ||||
fperez
|
r58 | def make_IPython(argv=None,user_ns=None,user_global_ns=None,debug=1, | ||
rc_override=None,shell_class=InteractiveShell, | ||||
embedded=False,**kw): | ||||
fperez
|
r0 | """This is a dump of IPython into a single function. | ||
Later it will have to be broken up in a sensible manner. | ||||
Arguments: | ||||
- argv: a list similar to sys.argv[1:]. It should NOT contain the desired | ||||
script name, b/c DPyGetOpt strips the first argument only for the real | ||||
sys.argv. | ||||
- user_ns: a dict to be used as the user's namespace.""" | ||||
#---------------------------------------------------------------------- | ||||
# Defaults and initialization | ||||
# For developer debugging, deactivates crash handler and uses pdb. | ||||
DEVDEBUG = False | ||||
if argv is None: | ||||
argv = sys.argv | ||||
# __IP is the main global that lives throughout and represents the whole | ||||
# application. If the user redefines it, all bets are off as to what | ||||
# happens. | ||||
# __IP is the name of he global which the caller will have accessible as | ||||
# __IP.name. We set its name via the first parameter passed to | ||||
# InteractiveShell: | ||||
fperez
|
r58 | IP = shell_class('__IP',user_ns=user_ns,user_global_ns=user_global_ns, | ||
embedded=embedded,**kw) | ||||
fperez
|
r0 | |||
# Put 'help' in the user namespace | ||||
fperez
|
r5 | from site import _Helper | ||
vivainio
|
r754 | IP.user_config_ns = {} | ||
fperez
|
r5 | IP.user_ns['help'] = _Helper() | ||
fperez
|
r0 | |||
fperez
|
r59 | |||
fperez
|
r0 | if DEVDEBUG: | ||
# For developer debugging only (global flag) | ||||
from IPython import ultraTB | ||||
sys.excepthook = ultraTB.VerboseTB(call_pdb=1) | ||||
IP.BANNER_PARTS = ['Python %s\n' | ||||
'Type "copyright", "credits" or "license" ' | ||||
'for more information.\n' | ||||
% (sys.version.split('\n')[0],), | ||||
"IPython %s -- An enhanced Interactive Python." | ||||
% (__version__,), | ||||
vivainio
|
r812 | """\ | ||
fperez
|
r834 | ? -> Introduction and overview of IPython's features. | ||
vivainio
|
r824 | %quickref -> Quick reference. | ||
help -> Python's own help system. | ||||
object? -> Details about 'object'. ?object also works, ?? prints more. | ||||
fperez
|
r0 | """ ] | ||
IP.usage = interactive_usage | ||||
fperez
|
r33 | # Platform-dependent suffix and directory names. We use _ipython instead | ||
# of .ipython under win32 b/c there's software that breaks with .named | ||||
# directories on that platform. | ||||
fperez
|
r0 | if os.name == 'posix': | ||
rc_suffix = '' | ||||
ipdir_def = '.ipython' | ||||
else: | ||||
rc_suffix = '.ini' | ||||
ipdir_def = '_ipython' | ||||
# default directory for configuration | ||||
fperez
|
r315 | ipythondir_def = os.path.abspath(os.environ.get('IPYTHONDIR', | ||
fperez
|
r0 | os.path.join(IP.home_dir,ipdir_def))) | ||
vivainio
|
r171 | sys.path.insert(0, '') # add . to sys.path. Fix from Prabhu Ramachandran | ||
fperez
|
r0 | # we need the directory where IPython itself is installed | ||
import IPython | ||||
IPython_dir = os.path.dirname(IPython.__file__) | ||||
del IPython | ||||
#------------------------------------------------------------------------- | ||||
# Command line handling | ||||
# Valid command line options (uses DPyGetOpt syntax, like Perl's | ||||
# GetOpt::Long) | ||||
# Any key not listed here gets deleted even if in the file (like session | ||||
# or profile). That's deliberate, to maintain the rc namespace clean. | ||||
# Each set of options appears twice: under _conv only the names are | ||||
# listed, indicating which type they must be converted to when reading the | ||||
# ipythonrc file. And under DPyGetOpt they are listed with the regular | ||||
# DPyGetOpt syntax (=s,=i,:f,etc). | ||||
# Make sure there's a space before each end of line (they get auto-joined!) | ||||
fperez
|
r84 | cmdline_opts = ('autocall=i autoindent! automagic! banner! cache_size|cs=i ' | ||
fperez
|
r0 | 'c=s classic|cl color_info! colors=s confirm_exit! ' | ||
fperez
|
r299 | 'debug! deep_reload! editor=s log|l messages! nosep ' | ||
'object_info_string_level=i pdb! ' | ||||
fperez
|
r0 | 'pprint! prompt_in1|pi1=s prompt_in2|pi2=s prompt_out|po=s ' | ||
fperez
|
r554 | 'pylab_import_all! ' | ||
fperez
|
r0 | 'quick screen_length|sl=i prompts_pad_left=i ' | ||
'logfile|lf=s logplay|lp=s profile|p=s ' | ||||
'readline! readline_merge_completions! ' | ||||
'readline_omit__names! ' | ||||
'rcfile=s separate_in|si=s separate_out|so=s ' | ||||
fperez
|
r41 | 'separate_out2|so2=s xmode=s wildcards_case_sensitive! ' | ||
fperez
|
r0 | 'magic_docstrings system_verbose! ' | ||
fperez
|
r54 | 'multi_line_specials! ' | ||
fperez
|
r515 | 'term_title! wxversion=s ' | ||
fperez
|
r54 | 'autoedit_syntax!') | ||
fperez
|
r0 | |||
# Options that can *only* appear at the cmd line (not in rcfiles). | ||||
# The "ignore" option is a kludge so that Emacs buffers don't crash, since | ||||
# the 'C-c !' command in emacs automatically appends a -i option at the end. | ||||
vivainio
|
r804 | cmdline_only = ('help interact|i ipythondir=s Version upgrade ' | ||
fperez
|
r903 | 'gthread! qthread! q4thread! wthread! tkthread! pylab! tk!') | ||
fperez
|
r0 | |||
# Build the actual name list to be used by DPyGetOpt | ||||
opts_names = qw(cmdline_opts) + qw(cmdline_only) | ||||
# Set sensible command line defaults. | ||||
# This should have everything from cmdline_opts and cmdline_only | ||||
opts_def = Struct(autocall = 1, | ||||
fperez
|
r294 | autoedit_syntax = 0, | ||
autoindent = 0, | ||||
fperez
|
r0 | automagic = 1, | ||
banner = 1, | ||||
c = '', | ||||
fperez
|
r909 | cache_size = 1000, | ||
fperez
|
r0 | classic = 0, | ||
color_info = 0, | ||||
fperez
|
r909 | colors = 'NoColor', | ||
fperez
|
r0 | confirm_exit = 1, | ||
debug = 0, | ||||
deep_reload = 0, | ||||
editor = '0', | ||||
fperez
|
r909 | gthread = 0, | ||
fperez
|
r0 | help = 0, | ||
fperez
|
r894 | interact = 1, | ||
fperez
|
r315 | ipythondir = ipythondir_def, | ||
fperez
|
r0 | log = 0, | ||
logfile = '', | ||||
logplay = '', | ||||
messages = 1, | ||||
fperez
|
r909 | multi_line_specials = 1, | ||
fperez
|
r0 | nosep = 0, | ||
fperez
|
r909 | object_info_string_level = 0, | ||
fperez
|
r0 | pdb = 0, | ||
pprint = 0, | ||||
profile = '', | ||||
fperez
|
r18 | prompt_in1 = 'In [\\#]: ', | ||
prompt_in2 = ' .\\D.: ', | ||||
prompt_out = 'Out[\\#]: ', | ||||
fperez
|
r0 | prompts_pad_left = 1, | ||
fperez
|
r909 | pylab = 0, | ||
fperez
|
r554 | pylab_import_all = 1, | ||
fperez
|
r909 | q4thread = 0, | ||
qthread = 0, | ||||
fperez
|
r0 | quick = 0, | ||
fperez
|
r909 | quiet = 0, | ||
rcfile = 'ipythonrc' + rc_suffix, | ||||
fperez
|
r0 | readline = 1, | ||
readline_merge_completions = 1, | ||||
readline_omit__names = 0, | ||||
screen_length = 0, | ||||
separate_in = '\n', | ||||
separate_out = '\n', | ||||
separate_out2 = '', | ||||
fptest
|
r418 | system_header = 'IPython system call: ', | ||
fperez
|
r0 | system_verbose = 0, | ||
fperez
|
r515 | term_title = 1, | ||
fperez
|
r0 | tk = 0, | ||
upgrade = 0, | ||||
Version = 0, | ||||
fperez
|
r41 | wildcards_case_sensitive = 1, | ||
fperez
|
r909 | wthread = 0, | ||
fperez
|
r91 | wxversion = '0', | ||
fperez
|
r909 | xmode = 'Context', | ||
fperez
|
r0 | magic_docstrings = 0, # undocumented, for doc generation | ||
) | ||||
# Things that will *only* appear in rcfiles (not at the command line). | ||||
# Make sure there's a space before each end of line (they get auto-joined!) | ||||
rcfile_opts = { qwflat: 'include import_mod import_all execfile ', | ||||
qw_lol: 'import_some ', | ||||
# for things with embedded whitespace: | ||||
list_strings:'execute alias readline_parse_and_bind ', | ||||
# Regular strings need no conversion: | ||||
None:'readline_remove_delims ', | ||||
} | ||||
# Default values for these | ||||
rc_def = Struct(include = [], | ||||
import_mod = [], | ||||
import_all = [], | ||||
import_some = [[]], | ||||
execute = [], | ||||
execfile = [], | ||||
alias = [], | ||||
readline_parse_and_bind = [], | ||||
readline_remove_delims = '', | ||||
) | ||||
# Build the type conversion dictionary from the above tables: | ||||
typeconv = rcfile_opts.copy() | ||||
typeconv.update(optstr2types(cmdline_opts)) | ||||
# FIXME: the None key appears in both, put that back together by hand. Ugly! | ||||
typeconv[None] += ' ' + rcfile_opts[None] | ||||
# Remove quotes at ends of all strings (used to protect spaces) | ||||
typeconv[unquote_ends] = typeconv[None] | ||||
del typeconv[None] | ||||
# Build the list we'll use to make all config decisions with defaults: | ||||
opts_all = opts_def.copy() | ||||
opts_all.update(rc_def) | ||||
# Build conflict resolver for recursive loading of config files: | ||||
# - preserve means the outermost file maintains the value, it is not | ||||
# overwritten if an included file has the same key. | ||||
# - add_flip applies + to the two values, so it better make sense to add | ||||
# those types of keys. But it flips them first so that things loaded | ||||
# deeper in the inclusion chain have lower precedence. | ||||
conflict = {'preserve': ' '.join([ typeconv[int], | ||||
typeconv[unquote_ends] ]), | ||||
'add_flip': ' '.join([ typeconv[qwflat], | ||||
typeconv[qw_lol], | ||||
typeconv[list_strings] ]) | ||||
} | ||||
# Now actually process the command line | ||||
getopt = DPyGetOpt.DPyGetOpt() | ||||
getopt.setIgnoreCase(0) | ||||
getopt.parseConfiguration(opts_names) | ||||
try: | ||||
getopt.processArguments(argv) | ||||
fperez
|
r893 | except DPyGetOpt.ArgumentError, exc: | ||
fperez
|
r0 | print cmd_line_usage | ||
fperez
|
r893 | warn('\nError in Arguments: "%s"' % exc) | ||
fperez
|
r41 | sys.exit(1) | ||
fperez
|
r0 | |||
# convert the options dict to a struct for much lighter syntax later | ||||
opts = Struct(getopt.optionValues) | ||||
args = getopt.freeValues | ||||
# this is the struct (which has default values at this point) with which | ||||
# we make all decisions: | ||||
opts_all.update(opts) | ||||
# Options that force an immediate exit | ||||
if opts_all.help: | ||||
page(cmd_line_usage) | ||||
sys.exit() | ||||
if opts_all.Version: | ||||
print __version__ | ||||
sys.exit() | ||||
if opts_all.magic_docstrings: | ||||
IP.magic_magic('-latex') | ||||
sys.exit() | ||||
fperez
|
r315 | # add personal ipythondir to sys.path so that users can put things in | ||
# there for customization | ||||
sys.path.append(os.path.abspath(opts_all.ipythondir)) | ||||
fperez
|
r0 | # Create user config directory if it doesn't exist. This must be done | ||
# *after* getting the cmd line options. | ||||
if not os.path.isdir(opts_all.ipythondir): | ||||
IP.user_setup(opts_all.ipythondir,rc_suffix,'install') | ||||
# upgrade user config files while preserving a copy of the originals | ||||
if opts_all.upgrade: | ||||
IP.user_setup(opts_all.ipythondir,rc_suffix,'upgrade') | ||||
# check mutually exclusive options in the *original* command line | ||||
mutex_opts(opts,[qw('log logfile'),qw('rcfile profile'), | ||||
qw('classic profile'),qw('classic rcfile')]) | ||||
#--------------------------------------------------------------------------- | ||||
# Log replay | ||||
# if -logplay, we need to 'become' the other session. That basically means | ||||
# replacing the current command line environment with that of the old | ||||
# session and moving on. | ||||
# this is needed so that later we know we're in session reload mode, as | ||||
# opts_all will get overwritten: | ||||
load_logplay = 0 | ||||
if opts_all.logplay: | ||||
load_logplay = opts_all.logplay | ||||
opts_debug_save = opts_all.debug | ||||
try: | ||||
logplay = open(opts_all.logplay) | ||||
except IOError: | ||||
if opts_all.debug: IP.InteractiveTB() | ||||
warn('Could not open logplay file '+`opts_all.logplay`) | ||||
# restore state as if nothing had happened and move on, but make | ||||
# sure that later we don't try to actually load the session file | ||||
logplay = None | ||||
load_logplay = 0 | ||||
del opts_all.logplay | ||||
else: | ||||
try: | ||||
logplay.readline() | ||||
logplay.readline(); | ||||
# this reloads that session's command line | ||||
cmd = logplay.readline()[6:] | ||||
exec cmd | ||||
# restore the true debug flag given so that the process of | ||||
# session loading itself can be monitored. | ||||
opts.debug = opts_debug_save | ||||
# save the logplay flag so later we don't overwrite the log | ||||
opts.logplay = load_logplay | ||||
# now we must update our own structure with defaults | ||||
opts_all.update(opts) | ||||
# now load args | ||||
cmd = logplay.readline()[6:] | ||||
exec cmd | ||||
logplay.close() | ||||
except: | ||||
logplay.close() | ||||
if opts_all.debug: IP.InteractiveTB() | ||||
warn("Logplay file lacking full configuration information.\n" | ||||
"I'll try to read it, but some things may not work.") | ||||
#------------------------------------------------------------------------- | ||||
# set up output traps: catch all output from files, being run, modules | ||||
# loaded, etc. Then give it to the user in a clean form at the end. | ||||
msg_out = 'Output messages. ' | ||||
msg_err = 'Error messages. ' | ||||
msg_sep = '\n' | ||||
msg = Struct(config = OutputTrap('Configuration Loader',msg_out, | ||||
msg_err,msg_sep,debug, | ||||
quiet_out=1), | ||||
user_exec = OutputTrap('User File Execution',msg_out, | ||||
msg_err,msg_sep,debug), | ||||
logplay = OutputTrap('Log Loader',msg_out, | ||||
msg_err,msg_sep,debug), | ||||
summary = '' | ||||
) | ||||
#------------------------------------------------------------------------- | ||||
# Process user ipythonrc-type configuration files | ||||
# turn on output trapping and log to msg.config | ||||
# remember that with debug on, trapping is actually disabled | ||||
msg.config.trap_all() | ||||
# look for rcfile in current or default directory | ||||
try: | ||||
opts_all.rcfile = filefind(opts_all.rcfile,opts_all.ipythondir) | ||||
except IOError: | ||||
if opts_all.debug: IP.InteractiveTB() | ||||
warn('Configuration file %s not found. Ignoring request.' | ||||
% (opts_all.rcfile) ) | ||||
# 'profiles' are a shorthand notation for config filenames | ||||
vivainio
|
r786 | profile_handled_by_legacy = False | ||
fperez
|
r0 | if opts_all.profile: | ||
vivainio
|
r154 | |||
fperez
|
r0 | try: | ||
opts_all.rcfile = filefind('ipythonrc-' + opts_all.profile | ||||
+ rc_suffix, | ||||
opts_all.ipythondir) | ||||
vivainio
|
r786 | profile_handled_by_legacy = True | ||
fperez
|
r0 | except IOError: | ||
if opts_all.debug: IP.InteractiveTB() | ||||
opts.profile = '' # remove profile from options if invalid | ||||
vivainio
|
r175 | # We won't warn anymore, primary method is ipy_profile_PROFNAME | ||
# which does trigger a warning. | ||||
vivainio
|
r110 | |||
fperez
|
r0 | # load the config file | ||
rcfiledata = None | ||||
if opts_all.quick: | ||||
print 'Launching IPython in quick mode. No config file read.' | ||||
elif opts_all.rcfile: | ||||
try: | ||||
cfg_loader = ConfigLoader(conflict) | ||||
rcfiledata = cfg_loader.load(opts_all.rcfile,typeconv, | ||||
'include',opts_all.ipythondir, | ||||
purge = 1, | ||||
unique = conflict['preserve']) | ||||
except: | ||||
IP.InteractiveTB() | ||||
warn('Problems loading configuration file '+ | ||||
`opts_all.rcfile`+ | ||||
'\nStarting with default -bare bones- configuration.') | ||||
else: | ||||
warn('No valid configuration file found in either currrent directory\n'+ | ||||
'or in the IPython config. directory: '+`opts_all.ipythondir`+ | ||||
'\nProceeding with internal defaults.') | ||||
#------------------------------------------------------------------------ | ||||
# Set exception handlers in mode requested by user. | ||||
otrap = OutputTrap(trap_out=1) # trap messages from magic_xmode | ||||
IP.magic_xmode(opts_all.xmode) | ||||
otrap.release_out() | ||||
#------------------------------------------------------------------------ | ||||
# Execute user config | ||||
fperez
|
r43 | # Create a valid config structure with the right precedence order: | ||
# defaults < rcfile < command line. This needs to be in the instance, so | ||||
# that method calls below that rely on it find it. | ||||
IP.rc = rc_def.copy() | ||||
# Work with a local alias inside this routine to avoid unnecessary | ||||
# attribute lookups. | ||||
IP_rc = IP.rc | ||||
fperez
|
r41 | IP_rc.update(opts_def) | ||
fperez
|
r0 | if rcfiledata: | ||
# now we can update | ||||
fperez
|
r41 | IP_rc.update(rcfiledata) | ||
IP_rc.update(opts) | ||||
IP_rc.update(rc_override) | ||||
fperez
|
r0 | |||
# Store the original cmd line for reference: | ||||
fperez
|
r41 | IP_rc.opts = opts | ||
IP_rc.args = args | ||||
fperez
|
r0 | |||
# create a *runtime* Struct like rc for holding parameters which may be | ||||
# created and/or modified by runtime user extensions. | ||||
IP.runtime_rc = Struct() | ||||
fperez
|
r41 | # from this point on, all config should be handled through IP_rc, | ||
fperez
|
r0 | # opts* shouldn't be used anymore. | ||
fperez
|
r41 | # update IP_rc with some special things that need manual | ||
fperez
|
r0 | # tweaks. Basically options which affect other options. I guess this | ||
# should just be written so that options are fully orthogonal and we | ||||
# wouldn't worry about this stuff! | ||||
fperez
|
r41 | if IP_rc.classic: | ||
IP_rc.quick = 1 | ||||
IP_rc.cache_size = 0 | ||||
IP_rc.pprint = 0 | ||||
IP_rc.prompt_in1 = '>>> ' | ||||
IP_rc.prompt_in2 = '... ' | ||||
IP_rc.prompt_out = '' | ||||
IP_rc.separate_in = IP_rc.separate_out = IP_rc.separate_out2 = '0' | ||||
IP_rc.colors = 'NoColor' | ||||
IP_rc.xmode = 'Plain' | ||||
fperez
|
r0 | |||
vivainio
|
r185 | IP.pre_config_initialization() | ||
fperez
|
r0 | # configure readline | ||
# Define the history file for saving commands in between sessions | ||||
fperez
|
r41 | if IP_rc.profile: | ||
histfname = 'history-%s' % IP_rc.profile | ||||
fperez
|
r0 | else: | ||
histfname = 'history' | ||||
IP.histfile = os.path.join(opts_all.ipythondir,histfname) | ||||
# update exception handlers with rc file status | ||||
otrap.trap_out() # I don't want these messages ever. | ||||
fperez
|
r41 | IP.magic_xmode(IP_rc.xmode) | ||
fperez
|
r0 | otrap.release_out() | ||
# activate logging if requested and not reloading a log | ||||
fperez
|
r41 | if IP_rc.logplay: | ||
IP.magic_logstart(IP_rc.logplay + ' append') | ||||
elif IP_rc.logfile: | ||||
IP.magic_logstart(IP_rc.logfile) | ||||
elif IP_rc.log: | ||||
fperez
|
r0 | IP.magic_logstart() | ||
# find user editor so that it we don't have to look it up constantly | ||||
fperez
|
r41 | if IP_rc.editor.strip()=='0': | ||
fperez
|
r0 | try: | ||
ed = os.environ['EDITOR'] | ||||
except KeyError: | ||||
if os.name == 'posix': | ||||
ed = 'vi' # the only one guaranteed to be there! | ||||
else: | ||||
ed = 'notepad' # same in Windows! | ||||
fperez
|
r41 | IP_rc.editor = ed | ||
# Keep track of whether this is an embedded instance or not (useful for | ||||
# post-mortems). | ||||
IP_rc.embedded = IP.embedded | ||||
fperez
|
r0 | |||
# Recursive reload | ||||
try: | ||||
from IPython import deep_reload | ||||
fperez
|
r41 | if IP_rc.deep_reload: | ||
fperez
|
r0 | __builtin__.reload = deep_reload.reload | ||
else: | ||||
__builtin__.dreload = deep_reload.reload | ||||
del deep_reload | ||||
except ImportError: | ||||
pass | ||||
# Save the current state of our namespace so that the interactive shell | ||||
# can later know which variables have been created by us from config files | ||||
# and loading. This way, loading a file (in any way) is treated just like | ||||
# defining things on the command line, and %who works as expected. | ||||
# DON'T do anything that affects the namespace beyond this point! | ||||
fperez
|
r41 | IP.internal_ns.update(__main__.__dict__) | ||
fperez
|
r0 | |||
#IP.internal_ns.update(locals()) # so our stuff doesn't show up in %who | ||||
# Now run through the different sections of the users's config | ||||
vivainio
|
r110 | if IP_rc.debug: | ||
fperez
|
r0 | print 'Trying to execute the following configuration structure:' | ||
print '(Things listed first are deeper in the inclusion tree and get' | ||||
print 'loaded first).\n' | ||||
fperez
|
r41 | pprint(IP_rc.__dict__) | ||
fperez
|
r0 | |||
fperez
|
r41 | for mod in IP_rc.import_mod: | ||
fperez
|
r0 | try: | ||
exec 'import '+mod in IP.user_ns | ||||
except : | ||||
IP.InteractiveTB() | ||||
import_fail_info(mod) | ||||
fperez
|
r41 | for mod_fn in IP_rc.import_some: | ||
vivainio
|
r492 | if not mod_fn == []: | ||
mod,fn = mod_fn[0],','.join(mod_fn[1:]) | ||||
try: | ||||
exec 'from '+mod+' import '+fn in IP.user_ns | ||||
except : | ||||
IP.InteractiveTB() | ||||
import_fail_info(mod,fn) | ||||
fperez
|
r0 | |||
fperez
|
r41 | for mod in IP_rc.import_all: | ||
fperez
|
r0 | try: | ||
exec 'from '+mod+' import *' in IP.user_ns | ||||
except : | ||||
IP.InteractiveTB() | ||||
import_fail_info(mod) | ||||
fperez
|
r41 | for code in IP_rc.execute: | ||
fperez
|
r0 | try: | ||
exec code in IP.user_ns | ||||
except: | ||||
IP.InteractiveTB() | ||||
warn('Failure executing code: ' + `code`) | ||||
# Execute the files the user wants in ipythonrc | ||||
fperez
|
r41 | for file in IP_rc.execfile: | ||
fperez
|
r0 | try: | ||
file = filefind(file,sys.path+[IPython_dir]) | ||||
except IOError: | ||||
warn(itpl('File $file not found. Skipping it.')) | ||||
else: | ||||
IP.safe_execfile(os.path.expanduser(file),IP.user_ns) | ||||
vivainio
|
r130 | # finally, try importing ipy_*_conf for final configuration | ||
try: | ||||
import ipy_system_conf | ||||
except ImportError: | ||||
vivainio
|
r175 | if opts_all.debug: IP.InteractiveTB() | ||
vivainio
|
r154 | warn("Could not import 'ipy_system_conf'") | ||
vivainio
|
r241 | except: | ||
IP.InteractiveTB() | ||||
import_fail_info('ipy_system_conf') | ||||
vivainio
|
r786 | # only import prof module if ipythonrc-PROF was not found | ||
if opts_all.profile and not profile_handled_by_legacy: | ||||
vivainio
|
r154 | profmodname = 'ipy_profile_' + opts_all.profile | ||
try: | ||||
__import__(profmodname) | ||||
vivainio
|
r820 | except: | ||
vivainio
|
r233 | IP.InteractiveTB() | ||
vivainio
|
r820 | print "Error importing",profmodname,"- perhaps you should run %upgrade?" | ||
vivainio
|
r241 | import_fail_info(profmodname) | ||
vivainio
|
r678 | else: | ||
import ipy_profile_none | ||||
vivainio
|
r154 | try: | ||
import ipy_user_conf | ||||
vivainio
|
r820 | |||
vivainio
|
r233 | except: | ||
vivainio
|
r820 | conf = opts_all.ipythondir + "/ipy_user_conf.py" | ||
vivainio
|
r233 | IP.InteractiveTB() | ||
vivainio
|
r820 | if not os.path.isfile(conf): | ||
warn(conf + ' does not exist, please run %upgrade!') | ||||
vivainio
|
r241 | import_fail_info("ipy_user_conf") | ||
vivainio
|
r802 | |||
# finally, push the argv to options again to ensure highest priority | ||||
IP_rc.update(opts) | ||||
fperez
|
r315 | |||
fperez
|
r0 | # release stdout and stderr and save config log into a global summary | ||
msg.config.release_all() | ||||
fperez
|
r41 | if IP_rc.messages: | ||
fperez
|
r0 | msg.summary += msg.config.summary_all() | ||
#------------------------------------------------------------------------ | ||||
# Setup interactive session | ||||
# Now we should be fully configured. We can then execute files or load | ||||
# things only needed for interactive use. Then we'll open the shell. | ||||
# Take a snapshot of the user namespace before opening the shell. That way | ||||
# we'll be able to identify which things were interactively defined and | ||||
# which were defined through config files. | ||||
vivainio
|
r754 | IP.user_config_ns.update(IP.user_ns) | ||
fperez
|
r0 | |||
# Force reading a file as if it were a session log. Slower but safer. | ||||
if load_logplay: | ||||
print 'Replaying log...' | ||||
try: | ||||
fperez
|
r41 | if IP_rc.debug: | ||
fperez
|
r0 | logplay_quiet = 0 | ||
else: | ||||
logplay_quiet = 1 | ||||
msg.logplay.trap_all() | ||||
IP.safe_execfile(load_logplay,IP.user_ns, | ||||
islog = 1, quiet = logplay_quiet) | ||||
msg.logplay.release_all() | ||||
fperez
|
r41 | if IP_rc.messages: | ||
fperez
|
r0 | msg.summary += msg.logplay.summary_all() | ||
except: | ||||
warn('Problems replaying logfile %s.' % load_logplay) | ||||
IP.InteractiveTB() | ||||
# Load remaining files in command line | ||||
msg.user_exec.trap_all() | ||||
# Do NOT execute files named in the command line as scripts to be loaded | ||||
# by embedded instances. Doing so has the potential for an infinite | ||||
# recursion if there are exceptions thrown in the process. | ||||
# XXX FIXME: the execution of user files should be moved out to after | ||||
# ipython is fully initialized, just as if they were run via %run at the | ||||
# ipython prompt. This would also give them the benefit of ipython's | ||||
# nice tracebacks. | ||||
vivainio
|
r148 | |||
vivainio
|
r241 | if (not embedded and IP_rc.args and | ||
not IP_rc.args[0].lower().endswith('.ipy')): | ||||
fperez
|
r0 | name_save = IP.user_ns['__name__'] | ||
IP.user_ns['__name__'] = '__main__' | ||||
vivainio
|
r148 | # Set our own excepthook in case the user code tries to call it | ||
# directly. This prevents triggering the IPython crash handler. | ||||
old_excepthook,sys.excepthook = sys.excepthook, IP.excepthook | ||||
fperez
|
r300 | save_argv = sys.argv[1:] # save it for later restoring | ||
vivainio
|
r150 | |||
sys.argv = args | ||||
fperez
|
r300 | |||
fperez
|
r0 | try: | ||
vivainio
|
r148 | IP.safe_execfile(args[0], IP.user_ns) | ||
fperez
|
r0 | finally: | ||
# Reset our crash handler in place | ||||
sys.excepthook = old_excepthook | ||||
fperez
|
r300 | sys.argv[:] = save_argv | ||
vivainio
|
r148 | IP.user_ns['__name__'] = name_save | ||
fperez
|
r0 | |||
msg.user_exec.release_all() | ||||
fperez
|
r300 | |||
fperez
|
r41 | if IP_rc.messages: | ||
fperez
|
r0 | msg.summary += msg.user_exec.summary_all() | ||
# since we can't specify a null string on the cmd line, 0 is the equivalent: | ||||
fperez
|
r41 | if IP_rc.nosep: | ||
IP_rc.separate_in = IP_rc.separate_out = IP_rc.separate_out2 = '0' | ||||
if IP_rc.separate_in == '0': IP_rc.separate_in = '' | ||||
if IP_rc.separate_out == '0': IP_rc.separate_out = '' | ||||
if IP_rc.separate_out2 == '0': IP_rc.separate_out2 = '' | ||||
IP_rc.separate_in = IP_rc.separate_in.replace('\\n','\n') | ||||
IP_rc.separate_out = IP_rc.separate_out.replace('\\n','\n') | ||||
IP_rc.separate_out2 = IP_rc.separate_out2.replace('\\n','\n') | ||||
fperez
|
r0 | |||
# Determine how many lines at the bottom of the screen are needed for | ||||
# showing prompts, so we can know wheter long strings are to be printed or | ||||
# paged: | ||||
fperez
|
r41 | num_lines_bot = IP_rc.separate_in.count('\n')+1 | ||
IP_rc.screen_length = IP_rc.screen_length - num_lines_bot | ||||
fperez
|
r0 | |||
# configure startup banner | ||||
fperez
|
r41 | if IP_rc.c: # regular python doesn't print the banner with -c | ||
IP_rc.banner = 0 | ||||
if IP_rc.banner: | ||||
BANN_P = IP.BANNER_PARTS | ||||
fperez
|
r0 | else: | ||
fperez
|
r41 | BANN_P = [] | ||
fperez
|
r0 | |||
fperez
|
r41 | if IP_rc.profile: BANN_P.append('IPython profile: %s\n' % IP_rc.profile) | ||
fperez
|
r0 | |||
# add message log (possibly empty) | ||||
fperez
|
r41 | if msg.summary: BANN_P.append(msg.summary) | ||
# Final banner is a string | ||||
IP.BANNER = '\n'.join(BANN_P) | ||||
# Finalize the IPython instance. This assumes the rc structure is fully | ||||
# in place. | ||||
fperez
|
r0 | IP.post_config_initialization() | ||
return IP | ||||
#************************ end of file <ipmaker.py> ************************** | ||||