1
# -*- coding: utf-8 -*-
3
IPython -- An enhanced Interactive Python
5
Requires Python 2.1 or better.
7
This file contains the main make_IPython() starter function.
9
$Id: ipmaker.py 2930 2008-01-11 07:03:11Z vivainio $"""
11
#*****************************************************************************
12
# Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
14
# Distributed under the terms of the BSD License. The full license is in
15
# the file COPYING, distributed as part of this software.
16
#*****************************************************************************
18
from IPython import Release
19
__author__ = '%s <%s>' % Release.authors['Fernando']
20
__license__ = Release.license
21
__version__ = Release.version
24
credits._Printer__data = """
27
IPython: Fernando Perez, Janko Hauser, Nathan Gray, and many users.
28
See http://ipython.scipy.org for more information.""" \
29
% credits._Printer__data
31
copyright._Printer__data += """
33
Copyright (c) 2001-2004 Fernando Perez, Janko Hauser, Nathan Gray.
34
All Rights Reserved."""
36
# Can happen if ipython was started with 'python -S', so that site.py is
40
#****************************************************************************
43
# From the standard library
50
from pprint import pprint,pformat
53
from IPython import DPyGetOpt
54
from IPython.ipstruct import Struct
55
from IPython.OutputTrap import OutputTrap
56
from IPython.ConfigLoader import ConfigLoader
57
from IPython.iplib import InteractiveShell
58
from IPython.usage import cmd_line_usage,interactive_usage
59
from IPython.genutils import *
61
#-----------------------------------------------------------------------------
62
def make_IPython(argv=None,user_ns=None,user_global_ns=None,debug=1,
63
rc_override=None,shell_class=InteractiveShell,
65
"""This is a dump of IPython into a single function.
67
Later it will have to be broken up in a sensible manner.
71
- argv: a list similar to sys.argv[1:]. It should NOT contain the desired
72
script name, b/c DPyGetOpt strips the first argument only for the real
75
- user_ns: a dict to be used as the user's namespace."""
77
#----------------------------------------------------------------------
78
# Defaults and initialization
80
# For developer debugging, deactivates crash handler and uses pdb.
86
# __IP is the main global that lives throughout and represents the whole
87
# application. If the user redefines it, all bets are off as to what
90
# __IP is the name of he global which the caller will have accessible as
91
# __IP.name. We set its name via the first parameter passed to
94
IP = shell_class('__IP',user_ns=user_ns,user_global_ns=user_global_ns,
95
embedded=embedded,**kw)
97
# Put 'help' in the user namespace
98
from site import _Helper
99
IP.user_config_ns = {}
100
IP.user_ns['help'] = _Helper()
104
# For developer debugging only (global flag)
105
from IPython import ultraTB
106
sys.excepthook = ultraTB.VerboseTB(call_pdb=1)
108
IP.BANNER_PARTS = ['Python %s\n'
109
'Type "copyright", "credits" or "license" '
110
'for more information.\n'
111
% (sys.version.split('\n')[0],),
112
"IPython %s -- An enhanced Interactive Python."
115
? -> Introduction and overview of IPython's features.
116
%quickref -> Quick reference.
117
help -> Python's own help system.
118
object? -> Details about 'object'. ?object also works, ?? prints more.
121
IP.usage = interactive_usage
123
# Platform-dependent suffix and directory names. We use _ipython instead
124
# of .ipython under win32 b/c there's software that breaks with .named
125
# directories on that platform.
126
if os.name == 'posix':
128
ipdir_def = '.ipython'
131
ipdir_def = '_ipython'
133
# default directory for configuration
134
ipythondir_def = os.path.abspath(os.environ.get('IPYTHONDIR',
135
os.path.join(IP.home_dir,ipdir_def)))
137
sys.path.insert(0, '') # add . to sys.path. Fix from Prabhu Ramachandran
139
# we need the directory where IPython itself is installed
141
IPython_dir = os.path.dirname(IPython.__file__)
144
#-------------------------------------------------------------------------
145
# Command line handling
147
# Valid command line options (uses DPyGetOpt syntax, like Perl's
150
# Any key not listed here gets deleted even if in the file (like session
151
# or profile). That's deliberate, to maintain the rc namespace clean.
153
# Each set of options appears twice: under _conv only the names are
154
# listed, indicating which type they must be converted to when reading the
155
# ipythonrc file. And under DPyGetOpt they are listed with the regular
156
# DPyGetOpt syntax (=s,=i,:f,etc).
158
# Make sure there's a space before each end of line (they get auto-joined!)
159
cmdline_opts = ('autocall=i autoindent! automagic! banner! cache_size|cs=i '
160
'c=s classic|cl color_info! colors=s confirm_exit! '
161
'debug! deep_reload! editor=s log|l messages! nosep '
162
'object_info_string_level=i pdb! '
163
'pprint! prompt_in1|pi1=s prompt_in2|pi2=s prompt_out|po=s '
166
'quick screen_length|sl=i prompts_pad_left=i '
167
'logfile|lf=s logplay|lp=s profile|p=s '
168
'readline! readline_merge_completions! '
169
'readline_omit__names! '
170
'rcfile=s separate_in|si=s separate_out|so=s '
171
'separate_out2|so2=s xmode=s wildcards_case_sensitive! '
172
'magic_docstrings system_verbose! '
173
'multi_line_specials! '
174
'term_title! wxversion=s '
177
# Options that can *only* appear at the cmd line (not in rcfiles).
179
# The "ignore" option is a kludge so that Emacs buffers don't crash, since
180
# the 'C-c !' command in emacs automatically appends a -i option at the end.
181
cmdline_only = ('help interact|i ipythondir=s Version upgrade '
182
'gthread! qthread! q4thread! wthread! tkthread! pylab! tk!')
184
# Build the actual name list to be used by DPyGetOpt
185
opts_names = qw(cmdline_opts) + qw(cmdline_only)
187
# Set sensible command line defaults.
188
# This should have everything from cmdline_opts and cmdline_only
189
opts_def = Struct(autocall = 1,
207
ipythondir = ipythondir_def,
212
multi_line_specials = 1,
214
object_info_string_level = 0,
218
prompt_in1 = 'In [\\#]: ',
219
prompt_in2 = ' .\\D.: ',
220
prompt_out = 'Out[\\#]: ',
221
prompts_pad_left = 1,
223
pylab_import_all = 1,
228
rcfile = 'ipythonrc' + rc_suffix,
230
readline_merge_completions = 1,
231
readline_omit__names = 0,
236
system_header = 'IPython system call: ',
242
wildcards_case_sensitive = 1,
246
magic_docstrings = 0, # undocumented, for doc generation
249
# Things that will *only* appear in rcfiles (not at the command line).
250
# Make sure there's a space before each end of line (they get auto-joined!)
251
rcfile_opts = { qwflat: 'include import_mod import_all execfile ',
252
qw_lol: 'import_some ',
253
# for things with embedded whitespace:
254
list_strings:'execute alias readline_parse_and_bind ',
255
# Regular strings need no conversion:
256
None:'readline_remove_delims ',
258
# Default values for these
259
rc_def = Struct(include = [],
266
readline_parse_and_bind = [],
267
readline_remove_delims = '',
270
# Build the type conversion dictionary from the above tables:
271
typeconv = rcfile_opts.copy()
272
typeconv.update(optstr2types(cmdline_opts))
274
# FIXME: the None key appears in both, put that back together by hand. Ugly!
275
typeconv[None] += ' ' + rcfile_opts[None]
277
# Remove quotes at ends of all strings (used to protect spaces)
278
typeconv[unquote_ends] = typeconv[None]
281
# Build the list we'll use to make all config decisions with defaults:
282
opts_all = opts_def.copy()
283
opts_all.update(rc_def)
285
# Build conflict resolver for recursive loading of config files:
286
# - preserve means the outermost file maintains the value, it is not
287
# overwritten if an included file has the same key.
288
# - add_flip applies + to the two values, so it better make sense to add
289
# those types of keys. But it flips them first so that things loaded
290
# deeper in the inclusion chain have lower precedence.
291
conflict = {'preserve': ' '.join([ typeconv[int],
292
typeconv[unquote_ends] ]),
293
'add_flip': ' '.join([ typeconv[qwflat],
295
typeconv[list_strings] ])
298
# Now actually process the command line
299
getopt = DPyGetOpt.DPyGetOpt()
300
getopt.setIgnoreCase(0)
302
getopt.parseConfiguration(opts_names)
305
getopt.processArguments(argv)
306
except DPyGetOpt.ArgumentError, exc:
308
warn('\nError in Arguments: "%s"' % exc)
311
# convert the options dict to a struct for much lighter syntax later
312
opts = Struct(getopt.optionValues)
313
args = getopt.freeValues
315
# this is the struct (which has default values at this point) with which
316
# we make all decisions:
317
opts_all.update(opts)
319
# Options that force an immediate exit
328
if opts_all.magic_docstrings:
329
IP.magic_magic('-latex')
332
# add personal ipythondir to sys.path so that users can put things in
333
# there for customization
334
sys.path.append(os.path.abspath(opts_all.ipythondir))
336
# Create user config directory if it doesn't exist. This must be done
337
# *after* getting the cmd line options.
338
if not os.path.isdir(opts_all.ipythondir):
339
IP.user_setup(opts_all.ipythondir,rc_suffix,'install')
341
# upgrade user config files while preserving a copy of the originals
343
IP.user_setup(opts_all.ipythondir,rc_suffix,'upgrade')
345
# check mutually exclusive options in the *original* command line
346
mutex_opts(opts,[qw('log logfile'),qw('rcfile profile'),
347
qw('classic profile'),qw('classic rcfile')])
349
#---------------------------------------------------------------------------
352
# if -logplay, we need to 'become' the other session. That basically means
353
# replacing the current command line environment with that of the old
354
# session and moving on.
356
# this is needed so that later we know we're in session reload mode, as
357
# opts_all will get overwritten:
361
load_logplay = opts_all.logplay
362
opts_debug_save = opts_all.debug
364
logplay = open(opts_all.logplay)
366
if opts_all.debug: IP.InteractiveTB()
367
warn('Could not open logplay file '+`opts_all.logplay`)
368
# restore state as if nothing had happened and move on, but make
369
# sure that later we don't try to actually load the session file
377
# this reloads that session's command line
378
cmd = logplay.readline()[6:]
380
# restore the true debug flag given so that the process of
381
# session loading itself can be monitored.
382
opts.debug = opts_debug_save
383
# save the logplay flag so later we don't overwrite the log
384
opts.logplay = load_logplay
385
# now we must update our own structure with defaults
386
opts_all.update(opts)
388
cmd = logplay.readline()[6:]
393
if opts_all.debug: IP.InteractiveTB()
394
warn("Logplay file lacking full configuration information.\n"
395
"I'll try to read it, but some things may not work.")
397
#-------------------------------------------------------------------------
398
# set up output traps: catch all output from files, being run, modules
399
# loaded, etc. Then give it to the user in a clean form at the end.
401
msg_out = 'Output messages. '
402
msg_err = 'Error messages. '
404
msg = Struct(config = OutputTrap('Configuration Loader',msg_out,
405
msg_err,msg_sep,debug,
407
user_exec = OutputTrap('User File Execution',msg_out,
408
msg_err,msg_sep,debug),
409
logplay = OutputTrap('Log Loader',msg_out,
410
msg_err,msg_sep,debug),
414
#-------------------------------------------------------------------------
415
# Process user ipythonrc-type configuration files
417
# turn on output trapping and log to msg.config
418
# remember that with debug on, trapping is actually disabled
419
msg.config.trap_all()
421
# look for rcfile in current or default directory
423
opts_all.rcfile = filefind(opts_all.rcfile,opts_all.ipythondir)
425
if opts_all.debug: IP.InteractiveTB()
426
warn('Configuration file %s not found. Ignoring request.'
427
% (opts_all.rcfile) )
429
# 'profiles' are a shorthand notation for config filenames
430
profile_handled_by_legacy = False
434
opts_all.rcfile = filefind('ipythonrc-' + opts_all.profile
437
profile_handled_by_legacy = True
439
if opts_all.debug: IP.InteractiveTB()
440
opts.profile = '' # remove profile from options if invalid
441
# We won't warn anymore, primary method is ipy_profile_PROFNAME
442
# which does trigger a warning.
444
# load the config file
447
print 'Launching IPython in quick mode. No config file read.'
448
elif opts_all.rcfile:
450
cfg_loader = ConfigLoader(conflict)
451
rcfiledata = cfg_loader.load(opts_all.rcfile,typeconv,
452
'include',opts_all.ipythondir,
454
unique = conflict['preserve'])
457
warn('Problems loading configuration file '+
459
'\nStarting with default -bare bones- configuration.')
461
warn('No valid configuration file found in either currrent directory\n'+
462
'or in the IPython config. directory: '+`opts_all.ipythondir`+
463
'\nProceeding with internal defaults.')
465
#------------------------------------------------------------------------
466
# Set exception handlers in mode requested by user.
467
otrap = OutputTrap(trap_out=1) # trap messages from magic_xmode
468
IP.magic_xmode(opts_all.xmode)
471
#------------------------------------------------------------------------
472
# Execute user config
474
# Create a valid config structure with the right precedence order:
475
# defaults < rcfile < command line. This needs to be in the instance, so
476
# that method calls below that rely on it find it.
477
IP.rc = rc_def.copy()
479
# Work with a local alias inside this routine to avoid unnecessary
483
IP_rc.update(opts_def)
486
IP_rc.update(rcfiledata)
488
IP_rc.update(rc_override)
490
# Store the original cmd line for reference:
494
# create a *runtime* Struct like rc for holding parameters which may be
495
# created and/or modified by runtime user extensions.
496
IP.runtime_rc = Struct()
498
# from this point on, all config should be handled through IP_rc,
499
# opts* shouldn't be used anymore.
502
# update IP_rc with some special things that need manual
503
# tweaks. Basically options which affect other options. I guess this
504
# should just be written so that options are fully orthogonal and we
505
# wouldn't worry about this stuff!
511
IP_rc.prompt_in1 = '>>> '
512
IP_rc.prompt_in2 = '... '
513
IP_rc.prompt_out = ''
514
IP_rc.separate_in = IP_rc.separate_out = IP_rc.separate_out2 = '0'
515
IP_rc.colors = 'NoColor'
516
IP_rc.xmode = 'Plain'
518
IP.pre_config_initialization()
520
# Define the history file for saving commands in between sessions
522
histfname = 'history-%s' % IP_rc.profile
524
histfname = 'history'
525
IP.histfile = os.path.join(opts_all.ipythondir,histfname)
527
# update exception handlers with rc file status
528
otrap.trap_out() # I don't want these messages ever.
529
IP.magic_xmode(IP_rc.xmode)
532
# activate logging if requested and not reloading a log
534
IP.magic_logstart(IP_rc.logplay + ' append')
536
IP.magic_logstart(IP_rc.logfile)
540
# find user editor so that it we don't have to look it up constantly
541
if IP_rc.editor.strip()=='0':
543
ed = os.environ['EDITOR']
545
if os.name == 'posix':
546
ed = 'vi' # the only one guaranteed to be there!
548
ed = 'notepad' # same in Windows!
551
# Keep track of whether this is an embedded instance or not (useful for
553
IP_rc.embedded = IP.embedded
557
from IPython import deep_reload
558
if IP_rc.deep_reload:
559
__builtin__.reload = deep_reload.reload
561
__builtin__.dreload = deep_reload.reload
566
# Save the current state of our namespace so that the interactive shell
567
# can later know which variables have been created by us from config files
568
# and loading. This way, loading a file (in any way) is treated just like
569
# defining things on the command line, and %who works as expected.
571
# DON'T do anything that affects the namespace beyond this point!
572
IP.internal_ns.update(__main__.__dict__)
574
#IP.internal_ns.update(locals()) # so our stuff doesn't show up in %who
576
# Now run through the different sections of the users's config
578
print 'Trying to execute the following configuration structure:'
579
print '(Things listed first are deeper in the inclusion tree and get'
580
print 'loaded first).\n'
581
pprint(IP_rc.__dict__)
583
for mod in IP_rc.import_mod:
585
exec 'import '+mod in IP.user_ns
588
import_fail_info(mod)
590
for mod_fn in IP_rc.import_some:
592
mod,fn = mod_fn[0],','.join(mod_fn[1:])
594
exec 'from '+mod+' import '+fn in IP.user_ns
597
import_fail_info(mod,fn)
599
for mod in IP_rc.import_all:
601
exec 'from '+mod+' import *' in IP.user_ns
604
import_fail_info(mod)
606
for code in IP_rc.execute:
608
exec code in IP.user_ns
611
warn('Failure executing code: ' + `code`)
613
# Execute the files the user wants in ipythonrc
614
for file in IP_rc.execfile:
616
file = filefind(file,sys.path+[IPython_dir])
618
warn(itpl('File $file not found. Skipping it.'))
620
IP.safe_execfile(os.path.expanduser(file),IP.user_ns)
622
# finally, try importing ipy_*_conf for final configuration
624
import ipy_system_conf
626
if opts_all.debug: IP.InteractiveTB()
627
warn("Could not import 'ipy_system_conf'")
630
import_fail_info('ipy_system_conf')
632
# only import prof module if ipythonrc-PROF was not found
633
if opts_all.profile and not profile_handled_by_legacy:
634
profmodname = 'ipy_profile_' + opts_all.profile
636
__import__(profmodname)
639
print "Error importing",profmodname,"- perhaps you should run %upgrade?"
640
import_fail_info(profmodname)
642
import ipy_profile_none
647
conf = opts_all.ipythondir + "/ipy_user_conf.py"
649
if not os.path.isfile(conf):
650
warn(conf + ' does not exist, please run %upgrade!')
652
import_fail_info("ipy_user_conf")
654
# finally, push the argv to options again to ensure highest priority
657
# release stdout and stderr and save config log into a global summary
658
msg.config.release_all()
660
msg.summary += msg.config.summary_all()
662
#------------------------------------------------------------------------
663
# Setup interactive session
665
# Now we should be fully configured. We can then execute files or load
666
# things only needed for interactive use. Then we'll open the shell.
668
# Take a snapshot of the user namespace before opening the shell. That way
669
# we'll be able to identify which things were interactively defined and
670
# which were defined through config files.
671
IP.user_config_ns.update(IP.user_ns)
673
# Force reading a file as if it were a session log. Slower but safer.
675
print 'Replaying log...'
682
msg.logplay.trap_all()
683
IP.safe_execfile(load_logplay,IP.user_ns,
684
islog = 1, quiet = logplay_quiet)
685
msg.logplay.release_all()
687
msg.summary += msg.logplay.summary_all()
689
warn('Problems replaying logfile %s.' % load_logplay)
692
# Load remaining files in command line
693
msg.user_exec.trap_all()
695
# Do NOT execute files named in the command line as scripts to be loaded
696
# by embedded instances. Doing so has the potential for an infinite
697
# recursion if there are exceptions thrown in the process.
699
# XXX FIXME: the execution of user files should be moved out to after
700
# ipython is fully initialized, just as if they were run via %run at the
701
# ipython prompt. This would also give them the benefit of ipython's
704
if (not embedded and IP_rc.args and
705
not IP_rc.args[0].lower().endswith('.ipy')):
706
name_save = IP.user_ns['__name__']
707
IP.user_ns['__name__'] = '__main__'
708
# Set our own excepthook in case the user code tries to call it
709
# directly. This prevents triggering the IPython crash handler.
710
old_excepthook,sys.excepthook = sys.excepthook, IP.excepthook
712
save_argv = sys.argv[1:] # save it for later restoring
717
IP.safe_execfile(args[0], IP.user_ns)
719
# Reset our crash handler in place
720
sys.excepthook = old_excepthook
721
sys.argv[:] = save_argv
722
IP.user_ns['__name__'] = name_save
724
msg.user_exec.release_all()
727
msg.summary += msg.user_exec.summary_all()
729
# since we can't specify a null string on the cmd line, 0 is the equivalent:
731
IP_rc.separate_in = IP_rc.separate_out = IP_rc.separate_out2 = '0'
732
if IP_rc.separate_in == '0': IP_rc.separate_in = ''
733
if IP_rc.separate_out == '0': IP_rc.separate_out = ''
734
if IP_rc.separate_out2 == '0': IP_rc.separate_out2 = ''
735
IP_rc.separate_in = IP_rc.separate_in.replace('\\n','\n')
736
IP_rc.separate_out = IP_rc.separate_out.replace('\\n','\n')
737
IP_rc.separate_out2 = IP_rc.separate_out2.replace('\\n','\n')
739
# Determine how many lines at the bottom of the screen are needed for
740
# showing prompts, so we can know wheter long strings are to be printed or
742
num_lines_bot = IP_rc.separate_in.count('\n')+1
743
IP_rc.screen_length = IP_rc.screen_length - num_lines_bot
745
# configure startup banner
746
if IP_rc.c: # regular python doesn't print the banner with -c
749
BANN_P = IP.BANNER_PARTS
753
if IP_rc.profile: BANN_P.append('IPython profile: %s\n' % IP_rc.profile)
755
# add message log (possibly empty)
756
if msg.summary: BANN_P.append(msg.summary)
757
# Final banner is a string
758
IP.BANNER = '\n'.join(BANN_P)
760
# Finalize the IPython instance. This assumes the rc structure is fully
762
IP.post_config_initialization()
765
#************************ end of file <ipmaker.py> **************************