diff --git a/IPython/ColorANSI.py b/IPython/ColorANSI.py
new file mode 100644
index 0000000..420f706
--- /dev/null
+++ b/IPython/ColorANSI.py
@@ -0,0 +1,155 @@
+# -*- coding: utf-8 -*-
+"""Tools for coloring text in ANSI terminals.
+
+$Id: ColorANSI.py 410 2004-11-04 07:58:17Z fperez $"""
+
+#*****************************************************************************
+#       Copyright (C) 2002-2004 Fernando Perez. <fperez@colorado.edu>
+#
+#  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
+
+__all__ = ['TermColors','InputTermColors','ColorScheme','ColorSchemeTable']
+
+import os
+from UserDict import UserDict
+
+from IPython.Struct import Struct
+
+def make_color_table(in_class):
+    """Build a set of color attributes in a class.
+
+    Helper function for building the *TermColors classes."""
+    
+    color_templates = (
+        ("Black"       , "0;30"),
+        ("Red"         , "0;31"),
+        ("Green"       , "0;32"),
+        ("Brown"       , "0;33"),
+        ("Blue"        , "0;34"),
+        ("Purple"      , "0;35"),
+        ("Cyan"        , "0;36"),
+        ("LightGray"   , "0;37"),
+        ("DarkGray"    , "1;30"),
+        ("LightRed"    , "1;31"),
+        ("LightGreen"  , "1;32"),
+        ("Yellow"      , "1;33"),
+        ("LightBlue"   , "1;34"),
+        ("LightPurple" , "1;35"),
+        ("LightCyan"   , "1;36"),
+        ("White"       , "1;37"),  )
+
+    for name,value in color_templates:
+        setattr(in_class,name,in_class._base % value)
+
+class TermColors:
+    """Color escape sequences.
+
+    This class defines the escape sequences for all the standard (ANSI?) 
+    colors in terminals. Also defines a NoColor escape which is just the null
+    string, suitable for defining 'dummy' color schemes in terminals which get
+    confused by color escapes.
+
+    This class should be used as a mixin for building color schemes."""
+    
+    NoColor = ''  # for color schemes in color-less terminals.
+    Normal = '\033[0m'   # Reset normal coloring
+    _base  = '\033[%sm'  # Template for all other colors
+
+# Build the actual color table as a set of class attributes:
+make_color_table(TermColors)
+
+class InputTermColors:
+    """Color escape sequences for input prompts.
+
+    This class is similar to TermColors, but the escapes are wrapped in \001
+    and \002 so that readline can properly know the length of each line and
+    can wrap lines accordingly.  Use this class for any colored text which
+    needs to be used in input prompts, such as in calls to raw_input().
+
+    This class defines the escape sequences for all the standard (ANSI?) 
+    colors in terminals. Also defines a NoColor escape which is just the null
+    string, suitable for defining 'dummy' color schemes in terminals which get
+    confused by color escapes.
+
+    This class should be used as a mixin for building color schemes."""
+    
+    NoColor = ''  # for color schemes in color-less terminals.
+    Normal = '\001\033[0m\002'   # Reset normal coloring
+    _base  = '\001\033[%sm\002'  # Template for all other colors
+
+# Build the actual color table as a set of class attributes:
+make_color_table(InputTermColors)
+
+class ColorScheme:
+    """Generic color scheme class. Just a name and a Struct."""
+    def __init__(self,__scheme_name_,colordict=None,**colormap):
+        self.name = __scheme_name_
+        if colordict is None:
+            self.colors = Struct(**colormap)
+        else:
+            self.colors = Struct(colordict)
+        
+class ColorSchemeTable(UserDict):
+    """General class to handle tables of color schemes.
+
+    It's basically a dict of color schemes with a couple of shorthand
+    attributes and some convenient methods.
+    
+    active_scheme_name -> obvious
+    active_colors -> actual color table of the active scheme"""
+
+    def __init__(self,scheme_list=None,default_scheme=''):
+        """Create a table of color schemes.
+
+        The table can be created empty and manually filled or it can be
+        created with a list of valid color schemes AND the specification for
+        the default active scheme.
+        """
+        
+        UserDict.__init__(self)
+        if scheme_list is None:
+            self.active_scheme_name = ''
+            self.active_colors = None
+        else:
+            if default_scheme == '':
+                raise ValueError,'you must specify the default color scheme'
+            for scheme in scheme_list:
+                self.add_scheme(scheme)
+            self.set_active_scheme(default_scheme)
+
+    def add_scheme(self,new_scheme):
+        """Add a new color scheme to the table."""
+        if not isinstance(new_scheme,ColorScheme):
+            raise ValueError,'ColorSchemeTable only accepts ColorScheme instances'
+        self[new_scheme.name] = new_scheme
+        
+    def set_active_scheme(self,scheme,case_sensitive=0):
+        """Set the currently active scheme.
+
+        Names are by default compared in a case-insensitive way, but this can
+        be changed by setting the parameter case_sensitive to true."""
+
+        scheme_list = self.keys()
+        if case_sensitive:
+            valid_schemes = scheme_list
+            scheme_test = scheme
+        else:
+            valid_schemes = [s.lower() for s in scheme_list]
+            scheme_test = scheme.lower()
+        try:
+            scheme_idx = valid_schemes.index(scheme_test)
+        except ValueError:
+            raise ValueError,'Unrecognized color scheme: ' + scheme + \
+                  '\nValid schemes: '+str(scheme_list).replace("'', ",'')
+        else:
+            active = scheme_list[scheme_idx]
+            self.active_scheme_name = active
+            self.active_colors = self[active].colors
+            # Now allow using '' as an index for the current active scheme
+            self[''] = self[active]
diff --git a/IPython/ConfigLoader.py b/IPython/ConfigLoader.py
new file mode 100644
index 0000000..192a92e
--- /dev/null
+++ b/IPython/ConfigLoader.py
@@ -0,0 +1,116 @@
+# -*- coding: utf-8 -*-
+"""Configuration loader
+
+$Id: ConfigLoader.py 525 2005-02-19 10:53:12Z fperez $"""
+
+#*****************************************************************************
+#       Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
+#
+#  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
+
+import os
+from pprint import pprint
+import exceptions
+
+from IPython import ultraTB
+from IPython.Struct import Struct
+from IPython.genutils import *
+
+class ConfigLoaderError(exceptions.Exception):
+    """Exception for ConfigLoader class."""
+
+    def __init__(self,args=None):
+        self.args = args
+
+class ConfigLoader:
+
+    """Configuration file loader capable of handling recursive inclusions and
+    with parametrized conflict resolution for multiply found keys."""
+
+    def __init__(self,conflict=None,field_sep=None,reclimit=15):
+
+        """The reclimit parameter controls the number of recursive
+        configuration file inclusions. This way we can stop early on (before
+        python's own recursion limit is hit) if there is a circular
+        inclusion.
+
+        - conflict: dictionary for conflict resolutions (see Struct.merge())
+
+        """
+        self.conflict = conflict
+        self.field_sep = field_sep
+        self.reset(reclimit)
+        
+    def reset(self,reclimit=15):
+        self.reclimit = reclimit
+        self.recdepth = 0
+        self.included = []
+        
+    def load(self,fname,convert=None,recurse_key='',incpath = '.',**kw):
+        """Load a configuration file, return the resulting Struct.
+
+        Call: load_config(fname,convert=None,conflict=None,recurse_key='')
+
+         - fname: file to load from.
+         - convert: dictionary of type conversions (see read_dict())
+         - recurse_key: keyword in dictionary to trigger recursive file
+         inclusions.
+         """
+
+        if self.recdepth > self.reclimit:
+            raise ConfigLoaderError, 'maximum recursive inclusion of rcfiles '+\
+                  'exceeded: ' + `self.recdepth` + \
+                  '.\nMaybe you have a circular chain of inclusions?'
+        self.recdepth += 1
+        fname = filefind(fname,incpath)
+        data = Struct()
+        # avoid including the same file more than once
+        if fname in self.included:
+            return data
+        Xinfo = ultraTB.AutoFormattedTB()
+        if convert==None and recurse_key : convert = {qwflat:recurse_key}
+        # for production, change warn to 0:
+        data.merge(read_dict(fname,convert,fs=self.field_sep,strip=1,
+                             warn=0,no_empty=0,**kw))
+        # keep track of successfully loaded files
+        self.included.append(fname)
+        if recurse_key in data.keys():
+            for incfilename in data[recurse_key]:
+                found=0
+                try:
+                    incfile = filefind(incfilename,incpath)
+                except IOError:
+                    if os.name in ['nt','dos']:
+                        try:
+                            # Try again with '.ini' extension
+                            incfilename += '.ini'
+                            incfile = filefind(incfilename,incpath)
+                        except IOError:
+                            found = 0
+                        else:
+                            found = 1
+                    else:
+                        found = 0
+                else:
+                    found = 1
+                if found:
+                    try:
+                        data.merge(self.load(incfile,convert,recurse_key,
+                                             incpath,**kw),
+                                   self.conflict)
+                    except:
+                        Xinfo()
+                        warn('Problem loading included file: '+
+                             `incfilename` + '. Ignoring it...')
+                else:
+                    warn('File `%s` not found. Included by %s' % (incfilename,fname))
+
+        return data
+
+# end ConfigLoader
diff --git a/IPython/CrashHandler.py b/IPython/CrashHandler.py
new file mode 100644
index 0000000..12acbd6
--- /dev/null
+++ b/IPython/CrashHandler.py
@@ -0,0 +1,109 @@
+# -*- coding: utf-8 -*-
+"""sys.excepthook for IPython itself, leaves a detailed report on disk.
+
+$Id: CrashHandler.py 410 2004-11-04 07:58:17Z fperez $"""
+
+#*****************************************************************************
+#       Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
+#
+#  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
+
+#****************************************************************************
+# Required modules
+
+# From the standard library
+import os,sys
+from pprint import pprint,pformat
+
+# Homebrewed
+from IPython.genutils import *
+from IPython.Itpl import Itpl,itpl,printpl
+from IPython import ultraTB
+from IPython.ultraTB import ColorScheme,ColorSchemeTable  # too long names
+
+#****************************************************************************
+class CrashHandler:
+    """sys.excepthook for IPython itself, leaves a detailed report on disk."""
+
+    def __init__(self,IP):
+        self.IP = IP  # IPython instance
+        self.bug_contact = Release.authors['Fernando'][0]
+        self.mailto = Release.authors['Fernando'][1]
+
+    def __call__(self,etype, evalue, etb):
+
+        # Report tracebacks shouldn't use color in general (safer for users)
+        color_scheme = 'NoColor'
+
+        # Use this ONLY for developer debugging (keep commented out for release)
+        #color_scheme = 'Linux'   # dbg
+        
+        try:
+            rptdir = self.IP.rc.ipythondir
+        except:
+            rptdir = os.getcwd()
+        if not os.path.isdir(rptdir):
+            rptdir = os.getcwd()
+        self.report_name = os.path.join(rptdir,'IPython_crash_report.txt')
+        self.TBhandler = ultraTB.VerboseTB(color_scheme=color_scheme,long_header=1)
+        traceback = self.TBhandler.text(etype,evalue,etb,context=31)
+
+        # print traceback to screen
+        print >> sys.stderr, traceback
+
+        # and generate a complete report on disk
+        try:
+            report = open(self.report_name,'w')
+        except:
+            print >> sys.stderr, 'Could not create crash report on disk.'
+            return
+
+        msg = itpl('\n'+'*'*70+'\n'
+"""
+Oops, IPython crashed. We do our best to make it stable, but...
+
+A crash report was automatically generated with the following information:
+  - A verbatim copy of the traceback above this text.
+  - A copy of your input history during this session.
+  - Data on your current IPython configuration.
+
+It was left in the file named:
+\t'$self.report_name'
+If you can email this file to the developers, the information in it will help
+them in understanding and correcting the problem.
+
+You can mail it to $self.bug_contact at $self.mailto
+with the subject 'IPython Crash Report'.
+
+If you want to do it now, the following command will work (under Unix):
+mail -s 'IPython Crash Report' $self.mailto < $self.report_name
+
+To ensure accurate tracking of this issue, please file a report about it at:
+http://www.scipy.net/roundup/ipython  (IPython's online bug tracker).
+""")
+        print >> sys.stderr, msg
+
+        sec_sep = '\n\n'+'*'*75+'\n\n'
+        report.write('*'*75+'\n\n'+'IPython post-mortem report\n\n')
+        report.write('IPython version: %s \n\n' % __version__)
+        report.write('Platform info  : os.name -> %s, sys.platform -> %s' %
+                     (os.name,sys.platform) )
+        report.write(sec_sep+'Current user configuration structure:\n\n')
+        report.write(pformat(self.IP.rc.dict()))
+        report.write(sec_sep+'Crash traceback:\n\n' + traceback)
+        try:
+            report.write(sec_sep+"History of session input:")
+            for line in self.IP.user_ns['_ih']:
+                report.write(line)
+            report.write('\n*** Last line of input (may not be in above history):\n')
+            report.write(self.IP._last_input_line+'\n')
+        except:
+            pass
+        report.close()
diff --git a/IPython/DPyGetOpt.py b/IPython/DPyGetOpt.py
new file mode 100644
index 0000000..75a7461
--- /dev/null
+++ b/IPython/DPyGetOpt.py
@@ -0,0 +1,671 @@
+# -*- coding: utf-8 -*-
+"""DPyGetOpt -- Demiurge Python GetOptions Module
+
+ $Id: DPyGetOpt.py 389 2004-10-09 07:59:30Z fperez $
+
+This module is modeled after perl's Getopt::Long module-- which
+is, in turn, modeled after GNU's extended getopt() function.
+
+Upon instantiation, the option specification should be a sequence
+(list) of option definitions.
+
+Options that take no arguments should simply contain the name of
+the option.  If a ! is post-pended, the option can be negated by
+prepending 'no';  ie 'debug!' specifies that -debug and -nodebug
+should be accepted.
+
+Mandatory arguments to options are specified using a postpended
+'=' + a type specifier.  '=s' specifies a mandatory string
+argument, '=i' specifies a mandatory integer argument, and '=f'
+specifies a mandatory real number.  In all cases, the '=' can be
+substituted with ':' to specify that the argument is optional.
+
+Dashes '-' in option names are allowed.
+
+If an option has the character '@' postpended (after the
+argumentation specification), it can appear multiple times within
+each argument list that is processed. The results will be stored
+in a list.
+
+The option name can actually be a list of names separated by '|'
+characters;  ie-- 'foo|bar|baz=f@' specifies that all -foo, -bar,
+and -baz options that appear on within the parsed argument list
+must have a real number argument and that the accumulated list
+of values will be available under the name 'foo'
+
+$Id: DPyGetOpt.py 389 2004-10-09 07:59:30Z fperez $"""
+
+#*****************************************************************************
+#
+# Copyright (c) 2001 Bill Bumgarner <bbum@friday.com>
+#
+#
+# Published under the terms of the MIT license, hereby reproduced:
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+#
+#*****************************************************************************
+
+__author__  = 'Bill Bumgarner <bbum@friday.com>'
+__license__ = 'MIT'
+__version__ = '1.2'
+
+# Modified to use re instead of regex and regsub modules.
+# 2001/5/7, Jonathan Hogg <jonathan@onegoodidea.com>
+
+import string
+import re
+import sys
+import types
+
+arg_error  = 'DPyGetOpt Argument Error'
+spec_error = 'DPyGetOpt Specification Error'
+term_error = 'DPyGetOpt Termination Error'
+
+specificationExpr = re.compile('(?P<required>.)(?P<type>.)(?P<multi>@?)')
+
+ArgRequired	= 'Requires an Argument'
+ArgOptional	= 'Argument Optional'
+
+# The types modules is not used for these identifiers because there
+# is no identifier for 'boolean' or 'generic'
+StringArgType	= 'String Argument Type'
+IntegerArgType	= 'Integer Argument Type'
+RealArgType		= 'Real Argument Type'
+BooleanArgType	= 'Boolean Argument Type'
+GenericArgType  = 'Generic Argument Type'
+
+# dictionary of conversion functions-- boolean and generic options
+# do not accept arguments and do not need conversion functions;
+# the identity function is used purely for convenience.
+ConversionFunctions = {
+	StringArgType : lambda x: x,
+	IntegerArgType : string.atoi,
+	RealArgType : string.atof,
+	BooleanArgType : lambda x: x,
+	GenericArgType : lambda x: x,
+	}
+
+class DPyGetOpt:
+
+	def __init__(self, spec = None, terminators = ['--']):
+		"""
+		Declare and intialize instance variables
+
+		Yes, declaration is not necessary... but one of the things
+		I sorely miss from C/Obj-C is the concept of having an
+		interface definition that clearly declares all instance
+		variables and methods without providing any implementation
+		 details.   it is a useful reference!
+
+		all instance variables are initialized to 0/Null/None of
+		the appropriate type-- not even the default value...
+		"""
+
+#		sys.stderr.write(string.join(spec) + "\n")
+
+		self.allowAbbreviations	= 1  # boolean, 1 if abbreviations will
+											  # be expanded
+		self.freeValues		= [] # list, contains free values
+		self.ignoreCase		= 0  # boolean, YES if ignoring case
+		self.needsParse		= 0  # boolean, YES if need to reparse parameter spec
+		self.optionNames	= {} # dict, all option names-- value is index of tuple
+		self.optionStartExpr	= None # regexp defining the start of an option (ie; '-', '--')
+		self.optionTuples	= [] # list o' tuples containing defn of options AND aliases
+		self.optionValues	= {} # dict, option names (after alias expansion) -> option value(s)
+		self.orderMixed		= 0  # boolean, YES if options can be mixed with args
+		self.posixCompliance	= 0  # boolean, YES indicates posix like behaviour
+		self.spec		= [] # list, raw specs (in case it must be reparsed)
+		self.terminators	= terminators # list, strings that terminate argument processing
+		self.termValues		= [] # list, values after terminator
+		self.terminator		= None # full name of terminator that ended
+						       # option processing
+
+		# set up defaults
+		self.setPosixCompliance()
+		self.setIgnoreCase()
+		self.setAllowAbbreviations()
+
+		# parse spec-- if present
+		if spec:
+			self.parseConfiguration(spec)
+
+	def setPosixCompliance(self, aFlag = 0):
+		"""
+		Enables and disables posix compliance.
+
+		When enabled, '+' can be used as an option prefix and free
+		values can be mixed with options.
+		"""
+		self.posixCompliance = aFlag
+		self.needsParse = 1
+
+		if self.posixCompliance:
+			self.optionStartExpr = re.compile('(--|-)(?P<option>[A-Za-z0-9_-]+)(?P<arg>=.*)?')
+			self.orderMixed = 0
+		else:
+			self.optionStartExpr = re.compile('(--|-|\+)(?P<option>[A-Za-z0-9_-]+)(?P<arg>=.*)?')
+			self.orderMixed = 1
+
+	def isPosixCompliant(self):
+		"""
+		Returns the value of the posix compliance flag.
+		"""
+		return self.posixCompliance
+
+	def setIgnoreCase(self, aFlag = 1):
+		"""
+		Enables and disables ignoring case during option processing.
+		"""
+		self.needsParse = 1
+		self.ignoreCase = aFlag
+
+	def ignoreCase(self):
+		"""
+		Returns 1 if the option processor will ignore case when
+		processing options.
+		"""
+		return self.ignoreCase
+
+	def setAllowAbbreviations(self, aFlag = 1):
+		"""
+		Enables and disables the expansion of abbreviations during
+		option processing.
+		"""
+		self.allowAbbreviations = aFlag
+
+	def willAllowAbbreviations(self):
+		"""
+		Returns 1 if abbreviated options will be automatically
+		expanded to the non-abbreviated form (instead of causing an
+		unrecognized option error).
+		"""
+		return self.allowAbbreviations
+
+	def addTerminator(self, newTerm):
+		"""
+		Adds newTerm as terminator of option processing.
+
+		Whenever the option processor encounters one of the terminators
+		during option processing, the processing of options terminates
+		immediately, all remaining options are stored in the termValues
+		instance variable and the full name of the terminator is stored
+		in the terminator instance variable.
+		"""
+		self.terminators = self.terminators + [newTerm]
+
+	def _addOption(self, oTuple):
+		"""
+		Adds the option described by oTuple (name, (type, mode,
+		default), alias) to optionTuples.  Adds index keyed under name
+		to optionNames.  Raises spec_error if name already in
+		optionNames
+		"""
+		(name, (type, mode, default, multi), realName) = oTuple
+
+		# verify name and add to option names dictionary
+		if self.optionNames.has_key(name):
+			if realName:
+				raise spec_error, 'Alias \'' + name + '\' for \'' + realName + \
+						'\' already used for another option or alias.'
+			else:
+				raise spec_error, 'Option named \'' + name + \
+						'\' specified more than once. Specification: ' + option
+
+		# validated. add to optionNames
+		self.optionNames[name] = self.tupleIndex
+		self.tupleIndex = self.tupleIndex + 1
+
+		# add to optionTuples
+		self.optionTuples = self.optionTuples + [oTuple]
+
+		# if type is boolean, add negation
+		if type == BooleanArgType:
+			alias		 = 'no' + name
+			specTuple = (type, mode, 0, multi)
+			oTuple = (alias, specTuple, name)
+
+			# verify name and add to option names dictionary
+			if self.optionNames.has_key(alias):
+				if realName:
+					raise spec_error, 'Negated alias \'' + name + '\' for \'' + realName + \
+							'\' already used for another option or alias.'
+				else:
+					raise spec_error, 'Negated option named \'' + name + \
+							'\' specified more than once. Specification: ' + option
+
+			# validated. add to optionNames
+			self.optionNames[alias] = self.tupleIndex
+			self.tupleIndex = self.tupleIndex + 1
+
+			# add to optionTuples
+			self.optionTuples = self.optionTuples + [oTuple]
+
+	def addOptionConfigurationTuple(self, oTuple):
+		(name, argSpec, realName) = oTuple
+		if self.ignoreCase:
+			name = string.lower(name)
+			if realName:
+				realName = string.lower(realName)
+			else:
+				realName = name
+
+			oTuple = (name, argSpec, realName)
+
+		# add option
+		self._addOption(oTuple)
+
+	def addOptionConfigurationTuples(self, oTuple):
+		if type(oTuple) is ListType:
+			for t in oTuple:
+				self.addOptionConfigurationTuple(t)
+		else:
+			self.addOptionConfigurationTuple(oTuple)
+
+	def parseConfiguration(self, spec):
+		# destroy previous stored information + store raw spec
+		self.spec			= spec
+		self.optionTuples	= []
+		self.optionNames  = {}
+		self.tupleIndex   = 0
+
+		tupleIndex = 0
+
+		# create some regex's for parsing each spec
+		splitExpr = \
+					 re.compile('(?P<names>\w+[-A-Za-z0-9|]*)?(?P<spec>!|[=:][infs]@?)?')
+		for option in spec:
+         # push to lower case (does not negatively affect
+         # specification)
+			if self.ignoreCase:
+				option = string.lower(option)
+
+			# break into names, specification
+			match = splitExpr.match(option)
+			if match is None:
+				raise spec_error, 'Invalid specification {' + option + '}'
+
+			names			  = match.group('names')
+			specification = match.group('spec')
+
+			# break name into name, aliases
+			nlist = string.split(names, '|')
+
+			# get name
+			name	  = nlist[0]
+			aliases = nlist[1:]
+
+			# specificationExpr = regex.symcomp('\(<required>.\)\(<type>.\)\(<multi>@?\)')
+			if not specification:
+				#spec tuple is ('type', 'arg mode', 'default value', 'multiple')
+				argType		= GenericArgType
+				argMode		= None
+				argDefault	= 1
+				argMultiple	= 0
+			elif specification == '!':
+				argType		= BooleanArgType
+				argMode		= None
+				argDefault	= 1
+				argMultiple	= 0
+			else:
+				# parse
+				match = specificationExpr.match(specification)
+				if match is None:
+					# failed to parse, die
+					raise spec_error, 'Invalid configuration for option \'' + option + '\''
+
+				# determine mode
+				required = match.group('required')
+				if required == '=':
+					argMode = ArgRequired
+				elif required == ':':
+					argMode = ArgOptional
+				else:
+					raise spec_error, 'Unknown requirement configuration \'' + required + '\''
+
+				# determine type
+				type = match.group('type')
+				if type == 's':
+					argType	  = StringArgType
+					argDefault = ''
+				elif type == 'i':
+					argType	  = IntegerArgType
+					argDefault = 1
+				elif type == 'f' or type == 'n':
+					argType	  = RealArgType
+					argDefault = 1
+				else:
+					raise spec_error, 'Unknown type specifier \'' + type + '\''
+
+				# determine quantity
+				if match.group('multi') == '@':
+					argMultiple = 1
+				else:
+					argMultiple = 0
+			## end else (of not specification)
+
+			# construct specification tuple
+			specTuple = (argType, argMode, argDefault, argMultiple)
+
+			# add the option-- option tuple is (name, specTuple, real name)
+			oTuple = (name, specTuple, name)
+			self._addOption(oTuple)
+
+			for alias in aliases:
+				# drop to all lower (if configured to do so)
+				if self.ignoreCase:
+					alias = string.lower(alias)
+				# create configuration tuple
+				oTuple = (alias, specTuple, name)
+				# add
+				self._addOption(oTuple)
+
+		# successfully parsed....
+		self.needsParse = 0
+
+	def _getArgTuple(self, argName):
+		"""
+		Returns a list containing all the specification tuples that
+		match argName.  If none match, None is returned.  If one
+		matches, a list with one tuple is returned.  If more than one
+		match, a list containing all the tuples that matched is
+		returned.
+
+		In other words, this function does not pass judgement upon the
+		validity of multiple matches.
+		"""
+		# is it in the optionNames dict?
+
+		try:
+#			sys.stderr.write(argName + string.join(self.optionNames.keys()) + "\n")
+
+			# yes, get index
+			tupleIndex = self.optionNames[argName]
+			# and return tuple as element of list
+			return [self.optionTuples[tupleIndex]]
+		except KeyError:
+			# are abbreviations allowed?
+			if not self.allowAbbreviations:
+				# No! terefore, this cannot be valid argument-- nothing found
+				return None
+
+		# argName might be an abbreviation (and, abbreviations must
+		# be allowed... or this would not have been reached!)
+
+		# create regex for argName
+		argExpr = re.compile('^' + argName)
+
+		tuples = filter(lambda x, argExpr=argExpr: argExpr.search(x[0]) is not None,
+							  self.optionTuples)
+
+		if not len(tuples):
+			return None
+		else:
+			return tuples
+
+	def _isTerminator(self, optionName):
+		"""
+		Returns the full name of the terminator if optionName is a valid
+		terminator.  If it is, sets self.terminator to the full name of
+		the terminator.
+
+		If more than one terminator matched, raises a term_error with a
+		string describing the ambiguity.
+		"""
+
+#		sys.stderr.write(optionName + "\n")
+#		sys.stderr.write(repr(self.terminators))
+
+		if optionName in self.terminators:
+			self.terminator = optionName
+		elif not self.allowAbbreviations:
+			return None
+
+# regex thing in bogus
+#		termExpr = regex.compile('^' + optionName)
+
+		terms = filter(lambda x, on=optionName: string.find(x,on) == 0, self.terminators)
+
+		if not len(terms):
+			return None
+		elif len(terms) > 1:
+			raise term_error, 'Ambiguous terminator \'' + optionName + \
+					'\' matches ' + repr(terms)
+
+		self.terminator = terms[0]
+		return self.terminator
+
+	def processArguments(self, args = None):
+		"""
+		Processes args, a list of arguments (including options).
+
+		If args is the same as sys.argv, automatically trims the first
+		argument (the executable name/path).
+
+		If an exception is not raised, the argument list was parsed
+		correctly.
+
+		Upon successful completion, the freeValues instance variable
+		will contain all the arguments that were not associated with an
+		option in the order they were encountered.  optionValues is a
+		dictionary containing the value of each option-- the method
+		valueForOption() can be used to query this dictionary.
+		terminator will contain the argument encountered that terminated
+		option processing (or None, if a terminator was never
+		encountered) and termValues will contain all of the options that
+		appeared after the Terminator (or an empty list).
+		"""
+
+		if hasattr(sys, "argv") and args == sys.argv:
+			args = sys.argv[1:]
+
+		max		= len(args) # maximum index + 1
+		self.freeValues	= []        # array to hold return values
+		self.optionValues= {}
+		index		= 0         # initial index
+		self.terminator = None
+		self.termValues  = []
+
+		while index < max:
+			# obtain argument
+			arg = args[index]
+			# increment index -- REMEMBER; it is NOW incremented
+			index = index + 1
+
+			# terminate immediately if option terminator encountered
+			if self._isTerminator(arg):
+				self.freeValues = self.freeValues + args[index:]
+				self.termValues = args[index:]
+				return
+
+			# is this possibly an option?
+			match = self.optionStartExpr.match(arg)
+			if match is None:
+				# not an option-- add to freeValues
+				self.freeValues = self.freeValues + [arg]
+				if not self.orderMixed:
+					# mixing not allowed;  add rest of args as freeValues
+					self.freeValues = self.freeValues + args[index:]
+					# return to caller
+					return
+				else:
+					continue
+
+			# grab name
+			optName = match.group('option')
+
+			# obtain next argument-- index has already been incremented
+			nextArg = match.group('arg')
+			if nextArg:
+				nextArg = nextArg[1:]
+				index = index - 1 # put it back
+			else:
+				try:
+					nextArg = args[index]
+				except:
+					nextArg = None
+
+			# transpose to lower case, if necessary
+			if self.ignoreCase:
+				optName = string.lower(optName)
+
+			# obtain defining tuple
+			tuples = self._getArgTuple(optName)
+
+			if tuples == None:
+				raise arg_error, 'Illegal option \'' + arg + '\''
+			elif len(tuples) > 1:
+				raise arg_error, 'Ambiguous option \'' + arg + '\';  matches ' + \
+						repr(map(lambda x: x[0], tuples))
+			else:
+				config = tuples[0]
+
+			# config is now set to the configuration tuple for the
+			# argument
+			(fullName, spec, realName) = config
+			(optType, optMode, optDefault, optMultiple) = spec
+
+			# if opt mode required, but nextArg is none, raise an error
+			if (optMode == ArgRequired):
+				if (not nextArg) or self._isTerminator(nextArg):
+#					print nextArg
+					raise arg_error, 'Option \'' + arg + \
+							'\' requires an argument of type ' + optType
+
+			if (not optMode == None) and nextArg and (not self._isTerminator(nextArg)):
+				# nextArg defined, option configured to possibly consume arg
+				try:
+					# grab conversion function-- the try is more for internal diagnostics
+					func = ConversionFunctions[optType]
+					try:
+						optionValue = func(nextArg)
+						index = index + 1
+					except:
+						# only raise conversion error if REQUIRED to consume argument
+						if optMode == ArgRequired:
+							raise arg_error, 'Invalid argument to option \'' + arg + \
+									'\';  should be \'' + optType + '\''
+						else:
+							optionValue = optDefault
+				except arg_error:
+					raise arg_error, sys.exc_value
+				except:
+					raise arg_error, '(' + arg + \
+							') Conversion function for \'' + optType + '\' not found.'
+			else:
+				optionValue = optDefault
+
+			# add value to options dictionary
+			if optMultiple:
+				# can be multiple values
+				try:
+					# try to append element
+					self.optionValues[realName] = self.optionValues[realName] + [optionValue]
+				except:
+					# failed-- must not exist;  add it
+					self.optionValues[realName] = [optionValue]
+			else:
+				# only one value per
+				if self.isPosixCompliant and self.optionValues.has_key(realName):
+					raise arg_error, 'Argument \'' + arg + '\' occurs multiple times.'
+
+				self.optionValues[realName] = optionValue
+
+	def valueForOption(self, optionName, defaultValue = None):
+		"""
+		Return the value associated with optionName.  If optionName was
+		not encountered during parsing of the arguments, returns the
+		defaultValue (which defaults to None).
+		"""
+		try:
+			optionValue = self.optionValues[optionName]
+		except:
+			optionValue = defaultValue
+
+		return optionValue
+
+##
+## test/example section
+##
+test_error = 'Test Run Amok!'
+def _test():
+	"""
+	A relatively complete test suite.
+	"""
+	try:
+		DPyGetOpt(['foo', 'bar=s', 'foo'])
+	except:
+		print 'EXCEPTION (should be \'foo\' already used..): ' + sys.exc_value
+
+	try:
+		DPyGetOpt(['foo|bar|apple=s@', 'baz|apple!'])
+	except:
+		print 'EXCEPTION (should be duplicate alias/name error): ' + sys.exc_value
+
+	x = DPyGetOpt(['apple|atlas=i@', 'application|executable=f@'])
+	try:
+		x.processArguments(['-app', '29.3'])
+	except:
+		print 'EXCEPTION (should be ambiguous argument): ' +	sys.exc_value
+
+	x = DPyGetOpt(['foo'], ['antigravity', 'antithesis'])
+	try:
+		x.processArguments(['-foo', 'anti'])
+	except:
+		print 'EXCEPTION (should be ambiguous terminator): ' + sys.exc_value
+
+	profile = ['plain-option',
+				  'boolean-option!',
+				  'list-of-integers=i@',
+				  'list-real-option|list-real-alias|list-real-pseudonym=f@',
+				  'optional-string-option:s',
+				  'abbreviated-string-list=s@']
+
+	terminators = ['terminator']
+
+	args = ['-plain-option',
+			  '+noboolean-option',
+			  '--list-of-integers', '1',
+			  '+list-of-integers', '2',
+			  '-list-of-integers', '3',
+			  'freeargone',
+			  '-list-real-option', '1.1',
+			  '+list-real-alias', '1.2',
+			  '--list-real-pseudonym', '1.3',
+			  'freeargtwo',
+			  '-abbreviated-string-list', 'String1',
+			  '--abbreviated-s', 'String2',
+			  '-abbrev', 'String3',
+			  '-a', 'String4',
+			  '-optional-string-option',
+			  'term',
+			  'next option should look like an invalid arg',
+			  '-a']
+
+
+	print 'Using profile: ' + repr(profile)
+	print 'With terminator: ' + repr(terminators)
+	print 'Processing arguments: ' + repr(args)
+
+	go = DPyGetOpt(profile, terminators)
+	go.processArguments(args)
+
+	print 'Options (and values): ' + repr(go.optionValues)
+	print 'free args: ' + repr(go.freeValues)
+	print 'term args: ' + repr(go.termValues)
diff --git a/IPython/Debugger.py b/IPython/Debugger.py
new file mode 100644
index 0000000..5a030bc
--- /dev/null
+++ b/IPython/Debugger.py
@@ -0,0 +1,53 @@
+# -*- coding: utf-8 -*-
+"""
+Pdb debugger class.
+
+Modified from the standard pdb.Pdb class to avoid including readline, so that
+the command line completion of other programs which include this isn't
+damaged.
+
+In the future, this class will be expanded with improvements over the standard
+pdb.
+
+The code in this file is mainly lifted out of cmd.py in Python 2.2, with minor
+changes. Licensing should therefore be under the standard Python terms.  For
+details on the PSF (Python Software Foundation) standard license, see:
+
+http://www.python.org/2.2.3/license.html
+
+$Id: Debugger.py 590 2005-05-30 06:26:51Z fperez $"""
+
+from IPython import Release
+__author__  = '%s <%s>' % Release.authors['Fernando']
+__license__ = 'Python'
+
+import pdb,bdb,cmd,os,sys
+
+class Pdb(pdb.Pdb):
+    """Modified Pdb class, does not load readline."""
+    def __init__(self):
+        bdb.Bdb.__init__(self)
+        cmd.Cmd.__init__(self,completekey=None) # don't load readline
+        self.prompt = '(Pdb) '
+        self.aliases = {}
+
+        # Read $HOME/.pdbrc and ./.pdbrc
+        self.rcLines = []
+        if os.environ.has_key('HOME'):
+            envHome = os.environ['HOME']
+            try:
+                rcFile = open(os.path.join(envHome, ".pdbrc"))
+            except IOError:
+                pass
+            else:
+                for line in rcFile.readlines():
+                    self.rcLines.append(line)
+                rcFile.close()
+        try:
+            rcFile = open(".pdbrc")
+        except IOError:
+            pass
+        else:
+            for line in rcFile.readlines():
+                self.rcLines.append(line)
+            rcFile.close()
diff --git a/IPython/Extensions/InterpreterExec.py b/IPython/Extensions/InterpreterExec.py
new file mode 100644
index 0000000..f4fb63a
--- /dev/null
+++ b/IPython/Extensions/InterpreterExec.py
@@ -0,0 +1,270 @@
+# -*- coding: utf-8 -*-
+"""Modified input prompt for executing files.
+
+We define a special input line filter to allow typing lines which begin with
+'~', '/' or '.'. If one of those strings is encountered, it is automatically
+executed.
+
+$Id: InterpreterExec.py 573 2005-04-08 08:38:09Z fperez $"""
+
+#*****************************************************************************
+#       Copyright (C) 2004 W.J. van der Laan <gnufnork@hetdigitalegat.nl>
+#       Copyright (C) 2004 Fernando Perez <fperez@colorado.edu>
+#
+#  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__ = 'W.J. van der Laan <gnufnork@hetdigitalegat.nl>, '\
+             '%s <%s>' %  Release.authors['Fernando']
+__license__ = Release.license
+
+def prefilter_shell(self,line,continuation):
+    """Alternate prefilter, modified for shell-like functionality.
+
+    - Execute all lines beginning with '~', '/' or '.'
+    - $var=cmd <=> %sc var=cmd
+    - $$var=cmd <=> %sc -l var=cmd
+    """
+
+    if line:
+        l0 = line[0]
+        if l0 in '~/.':
+            return self._prefilter("!%s"%line,continuation)
+        elif l0=='$':
+            lrest = line[1:]
+            if lrest.startswith('$'):
+                # $$var=cmd <=> %sc -l var=cmd
+                return self._prefilter("%ssc -l %s" % (self.ESC_MAGIC,lrest[1:]),
+                                       continuation)
+            else:
+                # $var=cmd <=> %sc var=cmd
+                return self._prefilter("%ssc %s" % (self.ESC_MAGIC,lrest),
+                                       continuation)
+        else:
+            return self._prefilter(line,continuation)
+    else:
+        return self._prefilter(line,continuation)
+
+# Rebind this to be the new IPython prefilter:
+from IPython.iplib import InteractiveShell
+InteractiveShell.prefilter = prefilter_shell
+# Clean up the namespace.
+del InteractiveShell,prefilter_shell
+
+# Provide pysh and further shell-oriented services
+import os,sys,shutil
+from IPython.genutils import system,shell,getoutput,getoutputerror
+
+# Short aliases for getting shell output as a string and a list
+sout = getoutput
+lout = lambda cmd: getoutput(cmd,split=1)
+
+# Empty function, meant as a docstring holder so help(pysh) works.
+def pysh():
+    """Pysh is a set of modules and extensions to IPython which make shell-like
+    usage with Python syntax more convenient.  Keep in mind that pysh is NOT a
+    full-blown shell, so don't try to make it your /etc/passwd entry!
+    
+    In particular, it has no job control, so if you type Ctrl-Z (under Unix),
+    you'll suspend pysh itself, not the process you just started.
+
+    Since pysh is really nothing but a customized IPython, you should
+    familiarize yourself with IPython's features.  This brief help mainly
+    documents areas in which pysh differs from the normal IPython.
+
+    ALIASES
+    -------
+    All of your $PATH has been loaded as IPython aliases, so you should be
+    able to type any normal system command and have it executed.  See %alias? 
+    and %unalias? for details on the alias facilities.
+
+    SPECIAL SYNTAX
+    --------------
+    Any lines which begin with '~', '/' and '.' will be executed as shell
+    commands instead of as Python code. The special escapes below are also
+    recognized.  !cmd is valid in single or multi-line input, all others are
+    only valid in single-line input:
+
+    !cmd      - pass 'cmd' directly to the shell
+    !!cmd     - execute 'cmd' and return output as a list (split on '\\n')
+    $var=cmd  - capture output of cmd into var, as a string
+    $$var=cmd - capture output of cmd into var, as a list (split on '\\n')
+
+    The $/$$ syntaxes make Python variables from system output, which you can
+    later use for further scripting.  The converse is also possible: when
+    executing an alias or calling to the system via !/!!, you can expand any
+    python variable or expression by prepending it with $.  Full details of
+    the allowed syntax can be found in Python's PEP 215.
+
+    A few brief examples will illustrate these:
+
+        fperez[~/test]|3> !ls *s.py
+        scopes.py  strings.py
+
+    ls is an internal alias, so there's no need to use !:
+        fperez[~/test]|4> ls *s.py
+        scopes.py*  strings.py
+
+    !!ls will return the output into a Python variable:
+        fperez[~/test]|5> !!ls *s.py
+                      <5> ['scopes.py', 'strings.py']
+        fperez[~/test]|6> print _5
+        ['scopes.py', 'strings.py']
+
+    $ and $$ allow direct capture to named variables:
+        fperez[~/test]|7> $astr = ls *s.py
+        fperez[~/test]|8> astr
+                      <8> 'scopes.py\\nstrings.py'
+
+        fperez[~/test]|9> $$alist = ls *s.py
+        fperez[~/test]|10> alist
+                      <10> ['scopes.py', 'strings.py']
+
+    alist is now a normal python list you can loop over.  Using $ will expand
+    back the python values when alias calls are made:
+        fperez[~/test]|11> for f in alist:
+                      |..>     print 'file',f,
+                      |..>     wc -l $f
+                      |..>
+        file scopes.py     13 scopes.py
+        file strings.py      4 strings.py
+
+    Note that you may need to protect your variables with braces if you want
+    to append strings to their names.  To copy all files in alist to .bak
+    extensions, you must use:
+        fperez[~/test]|12> for f in alist:
+                      |..>     cp $f ${f}.bak
+
+    If you try using $f.bak, you'll get an AttributeError exception saying
+    that your string object doesn't have a .bak attribute.  This is because
+    the $ expansion mechanism allows you to expand full Python expressions:
+        fperez[~/test]|13> echo "sys.platform is: $sys.platform"
+        sys.platform is: linux2
+
+    IPython's input history handling is still active, which allows you to
+    rerun a single block of multi-line input by simply using exec:    
+        fperez[~/test]|14> $$alist = ls *.eps
+        fperez[~/test]|15> exec _i11
+        file image2.eps    921 image2.eps
+        file image.eps    921 image.eps
+
+    While these are new special-case syntaxes, they are designed to allow very
+    efficient use of the shell with minimal typing.  At an interactive shell
+    prompt, conciseness of expression wins over readability.
+
+    USEFUL FUNCTIONS AND MODULES
+    ----------------------------
+    The os, sys and shutil modules from the Python standard library are
+    automatically loaded.  Some additional functions, useful for shell usage,
+    are listed below.  You can request more help about them with '?'.
+
+    shell   - execute a command in the underlying system shell    
+    system  - like shell(), but return the exit status of the command
+    sout    - capture the output of a command as a string
+    lout    - capture the output of a command as a list (split on '\\n')
+    getoutputerror - capture (output,error) of a shell command
+
+    sout/lout are the functional equivalents of $/$$.  They are provided to
+    allow you to capture system output in the middle of true python code,
+    function definitions, etc (where $ and $$ are invalid).
+
+    DIRECTORY MANAGEMENT
+    --------------------
+    Since each command passed by pysh to the underlying system is executed in
+    a subshell which exits immediately, you can NOT use !cd to navigate the
+    filesystem.
+
+    Pysh provides its own builtin '%cd' magic command to move in the
+    filesystem (the % is not required with automagic on).  It also maintains a
+    list of visited directories (use %dhist to see it) and allows direct
+    switching to any of them.  Type 'cd?' for more details.
+
+    %pushd, %popd and %dirs are provided for directory stack handling.
+
+    PROMPT CUSTOMIZATION
+    --------------------
+    
+    The supplied ipythonrc-pysh profile comes with an example of a very
+    colored and detailed prompt, mainly to serve as an illustration.  The
+    valid escape sequences, besides color names, are:
+
+        \\#  - Prompt number.
+        \\D  - Dots, as many as there are digits in \\# (so they align).
+        \\w  - Current working directory (cwd).
+        \\W  - Basename of current working directory.
+        \\XN - Where N=0..5. N terms of the cwd, with $HOME written as ~.
+        \\YN - Where N=0..5. Like XN, but if ~ is term N+1 it's also shown.
+        \\u  - Username.
+        \\H  - Full hostname.
+        \\h  - Hostname up to first '.'
+        \\$  - Root symbol ($ or #).
+        \\t  - Current time, in H:M:S format.
+        \\v  - IPython release version.
+        \\n  - Newline.
+        \\r  - Carriage return.
+        \\\\ - An explicitly escaped '\\'.
+
+    You can configure your prompt colors using any ANSI color escape.  Each
+    color escape sets the color for any subsequent text, until another escape
+    comes in and changes things.  The valid color escapes are:
+
+        \\C_Black
+        \\C_Blue
+        \\C_Brown
+        \\C_Cyan
+        \\C_DarkGray
+        \\C_Green
+        \\C_LightBlue
+        \\C_LightCyan
+        \\C_LightGray
+        \\C_LightGreen
+        \\C_LightPurple
+        \\C_LightRed
+        \\C_Purple
+        \\C_Red
+        \\C_White
+        \\C_Yellow
+        \\C_Normal - Stop coloring, defaults to your terminal settings.
+    """
+    pass
+
+# Configure a few things.  Much of this is fairly hackish, since IPython
+# doesn't really expose a clean API for it.  Be careful if you start making
+# many modifications here.
+
+print """\
+Welcome to pysh, a set of extensions to IPython for shell usage.
+help(pysh) -> help on the installed shell extensions and syntax.
+"""
+
+#  Set the 'cd' command to quiet mode, a more shell-like behavior
+__IPYTHON__.default_option('cd','-q')
+
+# Load all of $PATH as aliases
+if os.name == 'posix':
+    # %rehash is very fast, but it doesn't check for executability, it simply
+    # dumps everything in $PATH as an alias. Use rehashx if you want more
+    # checks.
+    __IPYTHON__.magic_rehash()
+else:
+    # Windows users: the list of extensions considered executable is read from
+    # the environment variable 'pathext'.  If this is undefined, IPython
+    # defaults to EXE, COM and BAT.
+    # %rehashx is the one which does extension analysis, at the cost of
+    # being much slower than %rehash.
+    __IPYTHON__.magic_rehashx()
+
+# Remove %sc,%sx if present as aliases
+__IPYTHON__.magic_unalias('sc')
+__IPYTHON__.magic_unalias('sx')
+
+# We need different criteria for line-splitting, so that aliases such as
+# 'gnome-terminal' are interpreted as a single alias instead of variable
+# 'gnome' minus variable 'terminal'.
+import re
+__IPYTHON__.line_split = re.compile(r'^(\s*)([\?\w\.\-\+]+\w*\s*)(\(?.*$)')
+
+# Namespace cleanup
+del re
diff --git a/IPython/Extensions/InterpreterPasteInput.py b/IPython/Extensions/InterpreterPasteInput.py
new file mode 100644
index 0000000..fb325fe
--- /dev/null
+++ b/IPython/Extensions/InterpreterPasteInput.py
@@ -0,0 +1,91 @@
+# -*- coding: utf-8 -*-
+"""Modified input prompt for entering text with >>> or ... at the start.
+
+We define a special input line filter to allow typing lines which begin with
+'>>> ' or '... '. These two strings, if present at the start of the input
+line, are stripped. This allows for direct pasting of code from examples such
+as those available in the standard Python tutorial.
+
+Normally pasting such code is one chunk is impossible because of the
+extraneous >>> and ..., requiring one to do a line by line paste with careful
+removal of those characters. This module allows pasting that kind of
+multi-line examples in one pass.
+
+Here is an 'screenshot' of a section of the tutorial pasted into IPython with
+this feature enabled:
+
+In [1]: >>> def fib2(n): # return Fibonacci series up to n
+   ...: ...     '''Return a list containing the Fibonacci series up to n.'''
+   ...: ...     result = []
+   ...: ...     a, b = 0, 1
+   ...: ...     while b < n:
+   ...: ...         result.append(b)    # see below
+   ...: ...         a, b = b, a+b
+   ...: ...     return result
+   ...:
+
+In [2]: fib2(10)
+Out[2]: [1, 1, 2, 3, 5, 8]
+
+The >>> and ... are stripped from the input so that the python interpreter
+only sees the real part of the code.
+
+All other input is processed normally.
+"""
+#*****************************************************************************
+#       Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
+#
+#  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
+
+# This file is an example of how to modify IPython's line-processing behavior
+# without touching the internal code. We'll define an alternate pre-processing
+# stage which allows a special form of input (which is invalid Python syntax)
+# for certain quantities, rewrites a line of proper Python in those cases, and
+# then passes it off to IPython's normal processor for further work.
+
+# With this kind of customization, IPython can be adapted for many
+# special-purpose scenarios providing alternate input syntaxes.
+
+# This file can be imported like a regular module.
+
+# IPython has a prefilter() function that analyzes each input line. We redefine
+# it here to first pre-process certain forms of input
+
+# The prototype of any alternate prefilter must be like this one (the name
+# doesn't matter):
+# - line is a string containing the user input line.
+# - continuation is a parameter which tells us if we are processing a first line of
+#   user input or the second or higher of a multi-line statement.
+
+def prefilter_paste(self,line,continuation):
+    """Alternate prefilter for input of pasted code from an interpreter.
+    """
+
+    from re import match
+
+    if match(r'^>>> |^\.\.\. ',line):
+        # In the end, always call the default IPython _prefilter() function.
+        # Note that self must be passed explicitly, b/c we're calling the
+        # unbound class method (since this method will overwrite the instance
+        # prefilter())
+        return self._prefilter(line[4:],continuation)
+    elif line.strip() == '...':
+        return self._prefilter('',continuation)
+    else:
+        return self._prefilter(line,continuation)
+            
+# Rebind this to be the new IPython prefilter:
+from IPython.iplib import InteractiveShell
+InteractiveShell.prefilter = prefilter_paste
+
+# Clean up the namespace.
+del InteractiveShell,prefilter_paste
+
+# Just a heads up at the console
+print '*** Pasting of code with ">>>" or "..." has been enabled.'
diff --git a/IPython/Extensions/PhysicalQInput.py b/IPython/Extensions/PhysicalQInput.py
new file mode 100644
index 0000000..c8d4929
--- /dev/null
+++ b/IPython/Extensions/PhysicalQInput.py
@@ -0,0 +1,83 @@
+# -*- coding: utf-8 -*-
+"""Modified input prompt for entering quantities with units.
+
+Modify the behavior of the interactive interpreter to allow direct input of
+quantities with units without having to make a function call.
+
+Now the following forms are accepted:
+
+x = 4 m
+y = -.45e3 m/s
+g = 9.8 m/s**2
+a = 2.3 m/s^2   # ^ -> ** automatically
+
+All other input is processed normally.
+"""
+#*****************************************************************************
+#       Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
+#
+#  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
+
+# This file is an example of how to modify IPython's line-processing behavior
+# without touching the internal code. We'll define an alternate pre-processing
+# stage which allows a special form of input (which is invalid Python syntax)
+# for certain quantities, rewrites a line of proper Python in those cases, and
+# then passes it off to IPython's normal processor for further work.
+
+# With this kind of customization, IPython can be adapted for many
+# special-purpose scenarios providing alternate input syntaxes.
+
+# This file can be imported like a regular module.
+
+# IPython has a prefilter() function that analyzes each input line. We redefine
+# it here to first pre-process certain forms of input
+
+# The prototype of any alternate prefilter must be like this one (the name
+# doesn't matter):
+# - line is a string containing the user input line.
+# - continuation is a parameter which tells us if we are processing a first line of
+#   user input or the second or higher of a multi-line statement.
+
+def prefilter_PQ(self,line,continuation):
+    """Alternate prefilter for input of PhysicalQuantityInteractive objects.
+
+    This assumes that the function PhysicalQuantityInteractive() has been
+    imported."""
+
+    from re import match
+    from IPython.iplib import InteractiveShell
+
+    # This regexp is what does the real work
+    unit_split = match(r'\s*(\w+)\s*=\s*(-?\d*\.?\d*[eE]?-?\d*)\s+([a-zA-Z].*)',
+                       line)
+
+    # If special input was ecnountered, process it:
+    if unit_split:
+        var,val,units = unit_split.groups()
+        if var and val and units:
+            units = units.replace('^','**')
+            # Now a valid line needs to be constructed for IPython to process:
+            line = var +" = PhysicalQuantityInteractive(" + val + ", '" + \
+                   units + "')"
+            #print 'New line:',line   # dbg
+            
+    # In the end, always call the default IPython _prefilter() function.  Note
+    # that self must be passed explicitly, b/c we're calling the unbound class
+    # method (since this method will overwrite the instance prefilter())
+    return InteractiveShell._prefilter(self,line,continuation)
+
+# Rebind this to be the new IPython prefilter:
+from IPython.iplib import InteractiveShell
+InteractiveShell.prefilter = prefilter_PQ
+
+# Clean up the namespace.
+del InteractiveShell,prefilter_PQ
+
+# Just a heads up at the console
+print '*** Simplified input for physical quantities enabled.'
diff --git a/IPython/Extensions/PhysicalQInteractive.py b/IPython/Extensions/PhysicalQInteractive.py
new file mode 100644
index 0000000..8d26117
--- /dev/null
+++ b/IPython/Extensions/PhysicalQInteractive.py
@@ -0,0 +1,88 @@
+# -*- coding: utf-8 -*-
+"""Modify the PhysicalQuantities class for more convenient interactive use.
+
+Also redefine some math functions to operate on PhysQties with no need for
+special method syntax. This just means moving them out to the global
+namespace.
+
+This module should always be loaded *after* math or Numeric, so it can
+overwrite math functions with the versions that handle units."""
+
+#*****************************************************************************
+#       Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
+#
+#  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
+
+from Scientific.Physics.PhysicalQuantities import PhysicalQuantity
+
+# This code can be set up to work with Numeric or with math for providing the
+# mathematical functions. Uncomment the one you prefer to use below.
+
+# If you use math, sin(x) won't work for x an array, only float or PhysQty
+import math
+
+# If you use Numeric, sin(x) works for x a float, PhysQty an array.
+#import Numeric as math
+
+class PhysicalQuantityFunction:
+    """Generic function wrapper for PhysicalQuantity instances.
+
+    Calls functions from either the math library or the instance's methods as
+    required.  Allows using sin(theta) or sqrt(v**2) syntax irrespective of
+    whether theta is a pure number or a PhysicalQuantity.
+
+    This is *slow*. It's meant for convenient interactive use, not for
+    speed."""
+
+    def __init__(self,name):
+        self.name = name
+        
+    def __call__(self,x):
+        if isinstance(x,PhysicalQuantity):
+            return PhysicalQuantity.__dict__[self.name](x)
+        else:
+            return math.__dict__[self.name](x)
+
+class PhysicalQuantityInteractive(PhysicalQuantity):
+    """Physical quantity with units - modified for Interactive use.
+
+    Basically, the __str__ and __repr__ methods have been swapped for more
+    convenient interactive use. Powers are shown as ^ instead of ** and only 4
+    significant figures are shown.
+
+    Also adds the following aliases for commonly used methods:
+      b = PhysicalQuantity.inBaseUnits
+      u = PhysicalQuantity.inUnitsOf
+      
+    These are useful when doing a lot of interactive calculations.
+    """
+    
+    # shorthands for the most useful unit conversions
+    b = PhysicalQuantity.inBaseUnits  # so you can just type x.b to get base units
+    u = PhysicalQuantity.inUnitsOf
+
+    # This can be done, but it can get dangerous when coupled with IPython's
+    # auto-calling. Everything ends up shown in baseunits and things like x*2
+    # get automatically converted to k(*2), which doesn't work.
+    # Probably not a good idea in general...
+    #__call__ = b
+    
+    def __str__(self):
+        return PhysicalQuantity.__repr__(self)
+ 
+    def __repr__(self):
+        value = '%.4G' % self.value
+        units = self.unit.name().replace('**','^')
+        return value + ' ' + units
+
+# implement the methods defined in PhysicalQuantity as PhysicalQuantityFunctions
+sin = PhysicalQuantityFunction('sin')
+cos = PhysicalQuantityFunction('cos')
+tan = PhysicalQuantityFunction('tan')
+sqrt = PhysicalQuantityFunction('sqrt')
diff --git a/IPython/Extensions/__init__.py b/IPython/Extensions/__init__.py
new file mode 100644
index 0000000..abc363b
--- /dev/null
+++ b/IPython/Extensions/__init__.py
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+"""This directory is meant for special-purpose extensions to IPython.
+
+This can include things which alter the syntax processing stage (see
+PhysicalQ_Input for an example of how to do this).
+
+Any file located here can be called with an 'execfile =' option as
+
+  execfile = Extensions/filename.py
+
+since the IPython directory itself is already part of the search path for
+files listed as 'execfile ='.
+"""
diff --git a/IPython/Extensions/numeric_formats.py b/IPython/Extensions/numeric_formats.py
new file mode 100644
index 0000000..05905a0
--- /dev/null
+++ b/IPython/Extensions/numeric_formats.py
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+"""
+Extension for printing Numeric Arrays in flexible ways.
+"""
+
+def num_display(self,arg):
+    """Display method for printing which treats Numeric arrays specially.
+    """
+
+    # Non-numpy variables are printed using the system default
+    if type(arg) != ArrayType:
+        self._display(arg)
+        return
+    # Otherwise, we do work.
+    format = __IPYTHON__.runtime_rc.numarray_print_format
+    print 'NumPy array, format:',format
+    # Here is where all the printing logic needs to be implemented
+    print arg # nothing yet :)
+
+
+def magic_format(self,parameter_s=''):
+    """Specifies format of numerical output.
+
+    This command is similar to Ocave's format command.
+    """
+
+    valid_formats = ['long','short']
+    
+    if parameter_s in valid_formats:
+        self.runtime_rc.numarray_print_format = parameter_s
+        print 'Numeric output format is now:',parameter_s
+    else:
+        print 'Invalid format:',parameter_s
+        print 'Valid formats:',valid_formats
+
+# setup default format
+__IPYTHON__.runtime_rc.numarray_print_format = 'long'
+
+# Bind our new functions to the interpreter
+__IPYTHON__.__class__.magic_format = magic_format
+__IPYTHON__.hooks.display = num_display
diff --git a/IPython/FakeModule.py b/IPython/FakeModule.py
new file mode 100644
index 0000000..c3cac63
--- /dev/null
+++ b/IPython/FakeModule.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+"""
+Class which mimics a module.
+
+Needed to allow pickle to correctly resolve namespaces during IPython
+sessions.
+
+$Id: FakeModule.py 410 2004-11-04 07:58:17Z fperez $"""
+
+#*****************************************************************************
+#       Copyright (C) 2002-2004 Fernando Perez. <fperez@colorado.edu>
+#
+#  Distributed under the terms of the BSD License.  The full license is in
+#  the file COPYING, distributed as part of this software.
+#*****************************************************************************
+
+class FakeModule:
+    """Simple class with attribute access to fake a module.
+
+    This is not meant to replace a module, but to allow inserting a fake
+    module in sys.modules so that systems which rely on run-time module
+    importing (like shelve and pickle) work correctly in interactive IPython
+    sessions.
+
+    Do NOT use this code for anything other than this IPython private hack."""
+
+    def __init__(self,adict):
+
+        # It seems pydoc (and perhaps others) needs any module instance to
+        # implement a __nonzero__ method, so we add it if missing:
+        if '__nonzero__' not in adict:
+            def __nonzero__():
+                return 1
+            adict['__nonzero__'] = __nonzero__
+
+            self.__dict__ = adict
+
+    def __getattr__(self,key):
+        try:
+            return self.__dict__[key]
+        except KeyError, e:
+            raise AttributeError("FakeModule object has no attribute %s" % e)
+
+    def __str__(self):
+        return "<IPython.FakeModule instance>"
+
+    def __repr__(self):
+        return str(self)
diff --git a/IPython/FlexCompleter.py b/IPython/FlexCompleter.py
new file mode 100644
index 0000000..5fe88f8
--- /dev/null
+++ b/IPython/FlexCompleter.py
@@ -0,0 +1,198 @@
+# -*- coding: utf-8 -*-
+"""Word completion for GNU readline 2.0.
+
+---------------------------------------------------------------------------
+NOTE: This version is a re-implementation of rlcompleter with selectable
+namespace.
+
+The problem with rlcompleter is that it's hardwired to work with
+__main__.__dict__, and in some cases one may have 'sandboxed' namespaces. So
+this class is a ripoff of rlcompleter, with the namespace to work in as an
+optional parameter.
+
+This class can be used just like rlcompleter, but the Completer class now has
+a constructor with the optional 'namespace' parameter.
+
+A patch has been submitted to Python@sourceforge for these changes to go in
+the standard Python distribution.
+
+The patch went in for Python 2.3.  Once IPython drops support for Python 2.2,
+this file can be significantly reduced.
+---------------------------------------------------------------------------
+
+Original rlcompleter documentation:
+
+This requires the latest extension to the readline module (the
+completes keywords, built-ins and globals in __main__; when completing
+NAME.NAME..., it evaluates (!) the expression up to the last dot and
+completes its attributes.
+
+It's very cool to do "import string" type "string.", hit the
+completion key (twice), and see the list of names defined by the
+string module!
+
+Tip: to use the tab key as the completion key, call
+
+    readline.parse_and_bind("tab: complete")
+
+Notes:
+
+- Exceptions raised by the completer function are *ignored* (and
+generally cause the completion to fail).  This is a feature -- since
+readline sets the tty device in raw (or cbreak) mode, printing a
+traceback wouldn't work well without some complicated hoopla to save,
+reset and restore the tty state.
+
+- The evaluation of the NAME.NAME... form may cause arbitrary
+application defined code to be executed if an object with a
+__getattr__ hook is found.  Since it is the responsibility of the
+application (or the user) to enable this feature, I consider this an
+acceptable risk.  More complicated expressions (e.g. function calls or
+indexing operations) are *not* evaluated.
+
+- GNU readline is also used by the built-in functions input() and
+raw_input(), and thus these also benefit/suffer from the completer
+features.  Clearly an interactive application can benefit by
+specifying its own completer function and using raw_input() for all
+its input.
+
+- When the original stdin is not a tty device, GNU readline is never
+used, and this module (and the readline module) are silently inactive.
+
+"""
+
+#*****************************************************************************
+#
+# Since this file is essentially a minimally modified copy of the rlcompleter
+# module which is part of the standard Python distribution, I assume that the
+# proper procedure is to maintain its copyright as belonging to the Python
+# Software Foundation:
+#
+#       Copyright (C) 2001 Python Software Foundation, www.python.org
+#
+#  Distributed under the terms of the Python Software Foundation license.
+#
+#  Full text available at:
+#
+#                  http://www.python.org/2.1/license.html
+#
+#*****************************************************************************
+
+import readline
+import __builtin__
+import __main__
+
+__all__ = ["Completer"]
+
+class Completer:
+    def __init__(self, namespace = None):
+        """Create a new completer for the command line.
+
+        Completer([namespace]) -> completer instance.
+
+        If unspecified, the default namespace where completions are performed
+        is __main__ (technically, __main__.__dict__). Namespaces should be
+        given as dictionaries.
+
+        Completer instances should be used as the completion mechanism of
+        readline via the set_completer() call:
+
+        readline.set_completer(Completer(my_namespace).complete)
+        """
+        
+        if namespace and type(namespace) != type({}):
+            raise TypeError,'namespace must be a dictionary'
+
+        # Don't bind to namespace quite yet, but flag whether the user wants a
+        # specific namespace or to use __main__.__dict__. This will allow us
+        # to bind to __main__.__dict__ at completion time, not now.
+        if namespace is None:
+            self.use_main_ns = 1
+        else:
+            self.use_main_ns = 0
+            self.namespace = namespace
+
+    def complete(self, text, state):
+        """Return the next possible completion for 'text'.
+
+        This is called successively with state == 0, 1, 2, ... until it
+        returns None.  The completion should begin with 'text'.
+
+        """
+        if self.use_main_ns:
+            self.namespace = __main__.__dict__
+            
+        if state == 0:
+            if "." in text:
+                self.matches = self.attr_matches(text)
+            else:
+                self.matches = self.global_matches(text)
+        try:
+            return self.matches[state]
+        except IndexError:
+            return None
+
+    def global_matches(self, text):
+        """Compute matches when text is a simple name.
+
+        Return a list of all keywords, built-in functions and names currently
+        defined in self.namespace that match.
+
+        """
+        import keyword
+        matches = []
+        n = len(text)
+        for list in [keyword.kwlist,
+                     __builtin__.__dict__.keys(),
+                     self.namespace.keys()]:
+            for word in list:
+                if word[:n] == text and word != "__builtins__":
+                    matches.append(word)
+        return matches
+
+    def attr_matches(self, text):
+        """Compute matches when text contains a dot.
+
+        Assuming the text is of the form NAME.NAME....[NAME], and is
+        evaluatable in self.namespace, it will be evaluated and its attributes
+        (as revealed by dir()) are used as possible completions.  (For class
+        instances, class members are are also considered.)
+
+        WARNING: this can still invoke arbitrary C code, if an object
+        with a __getattr__ hook is evaluated.
+
+        """
+        import re
+
+        # Another option, seems to work great. Catches things like ''.<tab>
+        m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
+
+        if not m:
+            return []
+        expr, attr = m.group(1, 3)
+        object = eval(expr, self.namespace)
+        words = dir(object)
+        if hasattr(object,'__class__'):
+            words.append('__class__')
+            words.extend(get_class_members(object.__class__))
+        n = len(attr)
+        matches = []
+        for word in words:
+            try:
+                if word[:n] == attr and word != "__builtins__":
+                    matches.append("%s.%s" % (expr, word))
+            except:
+                # some badly behaved objects pollute dir() with non-strings,
+                # which cause the completion to fail.  This way we skip the
+                # bad entries and can still continue processing the others.
+                pass
+        return matches
+
+def get_class_members(klass):
+    ret = dir(klass)
+    if hasattr(klass,'__bases__'):
+        for base in klass.__bases__:
+            ret.extend(get_class_members(base))
+    return ret
+
+readline.set_completer(Completer().complete)
diff --git a/IPython/Gnuplot2.py b/IPython/Gnuplot2.py
new file mode 100644
index 0000000..4fe431f
--- /dev/null
+++ b/IPython/Gnuplot2.py
@@ -0,0 +1,655 @@
+# -*- coding: utf-8 -*-
+"""Improved replacement for the Gnuplot.Gnuplot class.
+
+This module imports Gnuplot and replaces some of its functionality with
+improved versions. They add better handling of arrays for plotting and more
+convenient PostScript generation, plus some fixes for hardcopy().
+
+It also adds a convenient plot2 method for plotting dictionaries and
+lists/tuples of arrays.
+
+This module is meant to be used as a drop-in replacement to the original
+Gnuplot, so it should be safe to do:
+
+import IPython.Gnuplot2 as Gnuplot
+
+$Id: Gnuplot2.py 392 2004-10-09 22:01:51Z fperez $"""
+
+import string,os,time,types
+import cStringIO
+import sys
+import tempfile
+import Numeric
+import Gnuplot as Gnuplot_ori
+from IPython.genutils import popkey,xsys
+
+# needed by hardcopy():
+gp = Gnuplot_ori.gp
+
+# Patch for Gnuplot.py 1.6 compatibility.
+# Thanks to Hayden Callow <h.callow@elec.canterbury.ac.nz>
+try:
+    OptionException = Gnuplot_ori.PlotItems.OptionException
+except AttributeError:
+    OptionException = Gnuplot_ori.Errors.OptionError
+
+# exhibit a similar interface to Gnuplot so it can be somewhat drop-in
+Data      = Gnuplot_ori.Data
+Func      = Gnuplot_ori.Func
+GridData  = Gnuplot_ori.GridData
+PlotItem  = Gnuplot_ori.PlotItem
+PlotItems = Gnuplot_ori.PlotItems
+
+# Modify some of Gnuplot's functions with improved versions (or bugfixed, in
+# hardcopy's case). In order to preserve the docstrings at runtime, I've
+# copied them from the original code.
+
+# After some significant changes in v 1.7 of Gnuplot.py, we need to do a bit
+# of version checking.
+
+if Gnuplot_ori.__version__ <= '1.6':
+    _BaseFileItem = PlotItems.File
+    _BaseTempFileItem = PlotItems.TempFile
+
+    # Fix the File class to add the 'index' option for Gnuplot versions < 1.7
+    class File(_BaseFileItem):
+
+        _option_list = _BaseFileItem._option_list.copy()
+        _option_list.update({
+            'index' : lambda self, index: self.set_option_index(index),
+            })
+
+        # A new initializer is needed b/c we want to add a modified
+        # _option_sequence list which includes 'index' in the right place.
+        def __init__(self,*args,**kw):
+            self._option_sequence = ['binary', 'index', 'using', 'smooth', 'axes',
+                         'title', 'with']
+
+            _BaseFileItem.__init__(self,*args,**kw)
+
+        # Let's fix the constructor docstring
+        __newdoc = \
+            """Additional Keyword arguments added by IPython:
+
+             'index=<int>' -- similar to the `index` keyword in Gnuplot.
+                 This allows only some of the datasets in a file to be
+                 plotted. Datasets within a file are assumed to be separated
+                 by _pairs_ of blank lines, and the first one is numbered as
+                 0 (similar to C/Python usage)."""
+        __init__.__doc__ = PlotItems.File.__init__.__doc__ + __newdoc
+
+        def set_option_index(self, index):
+            if index is None:
+                self.clear_option('index')
+            elif type(index) in [type(''), type(1)]:
+                self._options['index'] = (index, 'index %s' % index)
+            elif type(index) is type(()):
+                self._options['index'] = (index,'index %s' %
+                                          string.join(map(repr, index), ':'))
+            else:
+                raise OptionException('index=%s' % (index,))
+
+    # We need a FileClass with a different name from 'File', which is a
+    # factory function in 1.7, so that our String class can subclass FileClass
+    # in any version.
+    _FileClass = File
+
+else:  # Gnuplot.py version 1.7 and greater
+    _FileClass = _BaseFileItem = PlotItems._FileItem
+    _BaseTempFileItem = PlotItems._TempFileItem
+    File = PlotItems.File
+
+# Now, we can add our generic code which is version independent
+
+# First some useful utilities
+def eps_fix_bbox(fname):
+    """Fix the bounding box of an eps file by running ps2eps on it.
+
+    If its name ends in .eps, the original file is removed.
+
+    This is particularly useful for plots made by Gnuplot with square aspect
+    ratio: there is a bug in Gnuplot which makes it generate a bounding box
+    which is far wider than the actual plot.
+
+    This function assumes that ps2eps is installed in your system."""
+
+    # note: ps2ps and eps2eps do NOT work, ONLY ps2eps works correctly. The
+    # others make output with bitmapped fonts, which looks horrible.
+    print 'Fixing eps file: <%s>' % fname
+    xsys('ps2eps -f -q -l %s' % fname)
+    if fname.endswith('.eps'):
+        os.rename(fname+'.eps',fname)
+
+def is_list1d(x,containers = [types.ListType,types.TupleType]):
+    """Returns true if x appears to be a 1d list/tuple/array.
+
+    The heuristics are: identify Numeric arrays, or lists/tuples whose first
+    element is not itself a list/tuple. This way zipped lists should work like
+    the original Gnuplot. There's no inexpensive way to know if a list doesn't
+    have a composite object after its first element, so that kind of input
+    will produce an error. But it should work well in most cases.
+    """
+    x_type = type(x)
+
+    return x_type == Numeric.ArrayType and len(x.shape)==1 or \
+           (x_type in containers and
+            type(x[0]) not in containers + [Numeric.ArrayType])
+
+def zip_items(items,titles=None):
+    """zip together neighboring 1-d arrays, and zip standalone ones
+    with their index. Leave other plot items alone."""
+
+    class StandaloneItem(Exception): pass
+    
+    def get_titles(titles):
+        """Return the next title and the input titles array.
+
+        The input array may be changed to None when no titles are left to
+        prevent extra unnecessary calls to this function."""
+        
+        try:
+            title = titles[tit_ct[0]]  # tit_ct[0] is in zip_items'scope
+        except IndexError:
+            titles = None # so we don't enter again
+            title = None
+        else:
+            tit_ct[0] += 1
+        return title,titles
+
+    new_items = []
+
+    if titles:
+        # Initialize counter. It was put in a list as a hack to allow the
+        # nested get_titles to modify it without raising a NameError.
+        tit_ct = [0]
+
+    n = 0  # this loop needs to be done by hand
+    while n < len(items):
+        item = items[n]
+        try:
+            if is_list1d(item):
+                if n==len(items)-1: # last in list
+                    raise StandaloneItem
+                else: # check the next item and zip together if needed
+                    next_item = items[n+1]
+                    if next_item is None:
+                        n += 1
+                        raise StandaloneItem
+                    elif is_list1d(next_item):
+                        # this would be best done with an iterator
+                        if titles:
+                            title,titles = get_titles(titles)
+                        else:
+                            title = None
+                        new_items.append(Data(zip(item,next_item),
+                                              title=title))
+                        n += 1  # avoid double-inclusion of next item
+                    else: # can't zip with next, zip with own index list
+                        raise StandaloneItem
+            else:  # not 1-d array
+                new_items.append(item)
+        except StandaloneItem:
+            if titles:
+                title,titles = get_titles(titles)
+            else:
+                title = None
+            new_items.append(Data(zip(range(len(item)),item),title=title))
+        except AttributeError:
+            new_items.append(item)
+        n+=1
+
+    return new_items
+
+# And some classes with enhanced functionality.
+class String(_FileClass):
+    """Make a PlotItem from data in a string with the same format as a File.
+
+    This allows writing data directly inside python scripts using the exact
+    same format and manipulation options which would be used for external
+    files."""
+
+    def __init__(self, data_str, **keyw):
+        """Construct a String object.
+
+        <data_str> is a string formatted exactly like a valid Gnuplot data
+        file would be. All options from the File constructor are valid here.
+
+        Warning: when used for interactive plotting in scripts which exit
+        immediately, you may get an error because the temporary file used to
+        hold the string data was deleted before Gnuplot had a chance to see
+        it. You can work around this problem by putting a raw_input() call at
+        the end of the script.
+
+        This problem does not appear when generating PostScript output, only
+        with Gnuplot windows."""
+
+        self.tmpfile = _BaseTempFileItem()
+        tmpfile = file(self.tmpfile.filename,'w')
+        tmpfile.write(data_str)
+        _BaseFileItem.__init__(self,self.tmpfile,**keyw)
+
+
+class Gnuplot(Gnuplot_ori.Gnuplot):
+    """Improved Gnuplot class.
+
+    Enhancements: better plot,replot and hardcopy methods. New methods for
+    quick range setting.
+    """
+
+    def xrange(self,min='*',max='*'):
+        """Set xrange. If min/max is omitted, it is set to '*' (auto).
+
+        Note that this is different from the regular Gnuplot behavior, where
+        an unspecified limit means no change. Here any unspecified limit is
+        set to autoscaling, allowing these functions to be used for full
+        autoscaling when called with no arguments.
+
+        To preserve one limit's current value while changing the other, an
+        explicit '' argument must be given as the limit to be kept.
+
+        Similar functions exist for [y{2}z{2}rtuv]range."""
+        
+        self('set xrange [%s:%s]' % (min,max))
+             
+    def yrange(self,min='*',max='*'):
+        self('set yrange [%s:%s]' % (min,max))
+             
+    def zrange(self,min='*',max='*'):
+        self('set zrange [%s:%s]' % (min,max))
+             
+    def x2range(self,min='*',max='*'):
+        self('set xrange [%s:%s]' % (min,max))
+             
+    def y2range(self,min='*',max='*'):
+        self('set yrange [%s:%s]' % (min,max))
+             
+    def z2range(self,min='*',max='*'):
+        self('set zrange [%s:%s]' % (min,max))
+             
+    def rrange(self,min='*',max='*'):
+        self('set rrange [%s:%s]' % (min,max))
+             
+    def trange(self,min='*',max='*'):
+        self('set trange [%s:%s]' % (min,max))
+             
+    def urange(self,min='*',max='*'):
+        self('set urange [%s:%s]' % (min,max))
+             
+    def vrange(self,min='*',max='*'):
+        self('set vrange [%s:%s]' % (min,max))
+
+    def set_ps(self,option):
+        """Set an option for the PostScript terminal and reset default term."""
+
+        self('set terminal postscript %s ' % option)
+        self('set terminal %s' % gp.GnuplotOpts.default_term)
+
+    def __plot_ps(self, plot_method,*items, **keyw):
+        """Wrapper for plot/splot/replot, with processing of hardcopy options.
+
+        For internal use only."""
+
+        # Filter out PostScript options which will crash the normal plot/replot
+        psargs = {'filename':None,
+                  'mode':None,
+                  'eps':None,
+                  'enhanced':None,
+                  'color':None,
+                  'solid':None,
+                  'duplexing':None,
+                  'fontname':None,
+                  'fontsize':None,
+                  'debug':0 }
+
+        for k in psargs.keys():
+            if keyw.has_key(k):
+                psargs[k] = keyw[k]
+                del keyw[k]
+
+        # Filter out other options the original plot doesn't know
+        hardcopy = popkey(keyw,'hardcopy',psargs['filename'] is not None)
+        titles = popkey(keyw,'titles',0)
+        
+        # the filename keyword should control hardcopy generation, this is an
+        # override switch only which needs to be explicitly set to zero
+        if hardcopy:
+            if psargs['filename'] is None:
+                raise ValueError, \
+                      'If you request hardcopy, you must give a filename.'
+
+            # set null output so nothing goes to screen. hardcopy() restores output
+            self('set term dumb')
+            # I don't know how to prevent screen output in Windows
+            if os.name == 'posix':
+                self('set output "/dev/null"')
+
+        new_items = zip_items(items,titles)
+        # plot_method is either plot or replot from the original Gnuplot class:
+        plot_method(self,*new_items,**keyw)
+
+        # Do hardcopy if requested
+        if hardcopy:
+            if psargs['filename'].endswith('.eps'):
+                psargs['eps'] = 1
+            self.hardcopy(**psargs)
+
+    def plot(self, *items, **keyw):
+        """Draw a new plot.
+
+        Clear the current plot and create a new 2-d plot containing
+        the specified items.  Each arguments should be of the
+        following types:
+
+        'PlotItem' (e.g., 'Data', 'File', 'Func') -- This is the most
+            flexible way to call plot because the PlotItems can
+            contain suboptions.  Moreover, PlotItems can be saved to
+            variables so that their lifetime is longer than one plot
+            command; thus they can be replotted with minimal overhead.
+
+        'string' (e.g., 'sin(x)') -- The string is interpreted as
+            'Func(string)' (a function that is computed by gnuplot).
+
+        Anything else -- The object, which should be convertible to an
+            array, is passed to the 'Data' constructor, and thus
+            plotted as data.  If the conversion fails, an exception is
+            raised.
+
+
+        This is a modified version of plot(). Compared to the original in
+        Gnuplot.py, this version has several enhancements, listed below.
+
+
+        Modifications to the input arguments
+        ------------------------------------
+
+        (1-d array means Numeric array, list or tuple):
+
+        (i) Any 1-d array which is NOT followed by another 1-d array, is
+        automatically zipped with range(len(array_1d)). Typing g.plot(y) will
+        plot y against its indices.
+
+        (ii) If two 1-d arrays are contiguous in the argument list, they are
+        automatically zipped together. So g.plot(x,y) plots y vs. x, and
+        g.plot(x1,y1,x2,y2) plots y1 vs. x1 and y2 vs. x2.
+
+        (iii) Any 1-d array which is followed by None is automatically zipped
+        with range(len(array_1d)). In this form, typing g.plot(y1,None,y2)
+        will plot both y1 and y2 against their respective indices (and NOT
+        versus one another). The None prevents zipping y1 and y2 together, and
+        since y2 is unpaired it is automatically zipped to its indices by (i)
+
+        (iv) Any other arguments which don't match these cases are left alone and
+        passed to the code below.
+
+        For lists or tuples, the heuristics used to determine whether they are
+        in fact 1-d is fairly simplistic: their first element is checked, and
+        if it is not a list or tuple itself, it is assumed that the whole
+        object is one-dimensional.
+
+        An additional optional keyword 'titles' has been added: it must be a
+        list of strings to be used as labels for the individual plots which
+        are NOT PlotItem objects (since those objects carry their own labels
+        within).
+
+
+        PostScript generation
+        ---------------------
+
+        This version of plot() also handles automatically the production of
+        PostScript output. The main options are (given as keyword arguments):
+
+        - filename: a string, typically ending in .eps. If given, the plot is
+        sent to this file in PostScript format.
+        
+        - hardcopy: this can be set to 0 to override 'filename'. It does not
+        need to be given to produce PostScript, its purpose is to allow
+        switching PostScript output off globally in scripts without having to
+        manually change 'filename' values in multiple calls.
+
+        All other keywords accepted by Gnuplot.hardcopy() are transparently
+        passed, and safely ignored if output is sent to the screen instead of
+        PostScript.
+
+        For example:
+        
+        In [1]: x=frange(0,2*pi,npts=100)
+
+        Generate a plot in file 'sin.eps':
+
+        In [2]: plot(x,sin(x),filename = 'sin.eps')
+
+        Plot to screen instead, without having to change the filename:
+
+        In [3]: plot(x,sin(x),filename = 'sin.eps',hardcopy=0)
+
+        Pass the 'color=0' option to hardcopy for monochrome output:
+
+        In [4]: plot(x,sin(x),filename = 'sin.eps',color=0)
+
+        PostScript generation through plot() is useful mainly for scripting
+        uses where you are not interested in interactive plotting. For
+        interactive use, the hardcopy() function is typically more convenient:
+        
+        In [5]: plot(x,sin(x))
+
+        In [6]: hardcopy('sin.eps')  """
+        
+        self.__plot_ps(Gnuplot_ori.Gnuplot.plot,*items,**keyw)
+        
+    def plot2(self,arg,**kw):
+        """Plot the entries of a dictionary or a list/tuple of arrays.        
+        
+        This simple utility calls plot() with a list of Gnuplot.Data objects
+        constructed either from the values of the input dictionary, or the entries
+        in it if it is a tuple or list.  Each item gets labeled with the key/index
+        in the Gnuplot legend.
+
+        Each item is plotted by zipping it with a list of its indices.
+
+        Any keywords are passed directly to plot()."""
+
+        if hasattr(arg,'keys'):
+            keys = arg.keys()
+            keys.sort()
+        else:
+            keys = range(len(arg))
+
+        pitems = [Data(zip(range(len(arg[k])),arg[k]),title=`k`) for k in keys]
+        self.plot(*pitems,**kw)
+
+    def splot(self, *items, **keyw):
+        """Draw a new three-dimensional plot.
+
+        Clear the current plot and create a new 3-d plot containing
+        the specified items.  Arguments can be of the following types:
+
+        'PlotItem' (e.g., 'Data', 'File', 'Func', 'GridData' ) -- This
+            is the most flexible way to call plot because the
+            PlotItems can contain suboptions.  Moreover, PlotItems can
+            be saved to variables so that their lifetime is longer
+            than one plot command--thus they can be replotted with
+            minimal overhead.
+
+        'string' (e.g., 'sin(x*y)') -- The string is interpreted as a
+            'Func()' (a function that is computed by gnuplot).
+
+        Anything else -- The object is converted to a Data() item, and
+            thus plotted as data.  Note that each data point should
+            normally have at least three values associated with it
+            (i.e., x, y, and z).  If the conversion fails, an
+            exception is raised.
+
+        This is a modified version of splot(). Compared to the original in
+        Gnuplot.py, this version has several enhancements, listed in the
+        plot() documentation.
+        """
+        
+        self.__plot_ps(Gnuplot_ori.Gnuplot.splot,*items,**keyw)
+
+    def replot(self, *items, **keyw):
+        """Replot the data, possibly adding new 'PlotItem's.
+
+        Replot the existing graph, using the items in the current
+        itemlist.  If arguments are specified, they are interpreted as
+        additional items to be plotted alongside the existing items on
+        the same graph.  See 'plot' for details.
+
+        If you want to replot to a postscript file, you MUST give the
+        'filename' keyword argument in each call to replot. The Gnuplot python
+        interface has no way of knowing that your previous call to
+        Gnuplot.plot() was meant for PostScript output."""
+        
+        self.__plot_ps(Gnuplot_ori.Gnuplot.replot,*items,**keyw)
+
+    # The original hardcopy has a bug. See fix at the end. The rest of the code
+    # was lifted verbatim from the original, so that people using IPython get the
+    # benefits without having to manually patch Gnuplot.py
+    def hardcopy(self, filename=None,
+                 mode=None,
+                 eps=None,
+                 enhanced=None,
+                 color=None,
+                 solid=None,
+                 duplexing=None,
+                 fontname=None,
+                 fontsize=None,
+                 debug = 0,
+                 ):
+        """Create a hardcopy of the current plot.
+
+        Create a postscript hardcopy of the current plot to the
+        default printer (if configured) or to the specified filename.
+
+        Note that gnuplot remembers the postscript suboptions across
+        terminal changes.  Therefore if you set, for example, color=1
+        for one hardcopy then the next hardcopy will also be color
+        unless you explicitly choose color=0.  Alternately you can
+        force all of the options to their defaults by setting
+        mode='default'.  I consider this to be a bug in gnuplot.
+
+        Keyword arguments:
+
+          'filename=<string>' -- if a filename is specified, save the
+              output in that file; otherwise print it immediately
+              using the 'default_lpr' configuration option.  If the
+              filename ends in '.eps', EPS mode is automatically
+              selected (like manually specifying eps=1 or mode='eps').
+
+          'mode=<string>' -- set the postscript submode ('landscape',
+              'portrait', 'eps', or 'default').  The default is
+              to leave this option unspecified.
+
+          'eps=<bool>' -- shorthand for 'mode="eps"'; asks gnuplot to
+              generate encapsulated postscript.
+
+          'enhanced=<bool>' -- if set (the default), then generate
+              enhanced postscript, which allows extra features like
+              font-switching, superscripts, and subscripts in axis
+              labels.  (Some old gnuplot versions do not support
+              enhanced postscript; if this is the case set
+              gp.GnuplotOpts.prefer_enhanced_postscript=None.)
+
+          'color=<bool>' -- if set, create a plot with color.  Default
+              is to leave this option unchanged.
+
+          'solid=<bool>' -- if set, force lines to be solid (i.e., not
+              dashed).
+
+          'duplexing=<string>' -- set duplexing option ('defaultplex',
+              'simplex', or 'duplex').  Only request double-sided
+              printing if your printer can handle it.  Actually this
+              option is probably meaningless since hardcopy() can only
+              print a single plot at a time.
+
+          'fontname=<string>' -- set the default font to <string>,
+              which must be a valid postscript font.  The default is
+              to leave this option unspecified.
+
+          'fontsize=<double>' -- set the default font size, in
+              postscript points.
+
+          'debug=<bool>' -- print extra debugging information (useful if
+              your PostScript files are misteriously not being created).
+        """
+
+        if filename is None:
+            assert gp.GnuplotOpts.default_lpr is not None, \
+                   OptionException('default_lpr is not set, so you can only '
+                                   'print to a file.')
+            filename = gp.GnuplotOpts.default_lpr
+            lpr_output = 1
+        else:
+            if filename.endswith('.eps'):
+                eps = 1
+            lpr_output = 0
+
+        # Be careful processing the options.  If the user didn't
+        # request an option explicitly, do not specify it on the 'set
+        # terminal' line (don't even specify the default value for the
+        # option).  This is to avoid confusing older versions of
+        # gnuplot that do not support all of these options.  The
+        # exception is 'enhanced', which is just too useful to have to
+        # specify each time!
+
+        setterm = ['set', 'terminal', 'postscript']
+        if eps:
+            assert mode is None or mode=='eps', \
+                   OptionException('eps option and mode are incompatible')
+            setterm.append('eps')
+        else:
+            if mode is not None:
+                assert mode in ['landscape', 'portrait', 'eps', 'default'], \
+                       OptionException('illegal mode "%s"' % mode)
+                setterm.append(mode)
+        if enhanced is None:
+            enhanced = gp.GnuplotOpts.prefer_enhanced_postscript
+        if enhanced is not None:
+            if enhanced: setterm.append('enhanced')
+            else: setterm.append('noenhanced')
+        if color is not None:
+            if color: setterm.append('color')
+            else: setterm.append('monochrome')
+        if solid is not None:
+            if solid: setterm.append('solid')
+            else: setterm.append('dashed')
+        if duplexing is not None:
+            assert duplexing in ['defaultplex', 'simplex', 'duplex'], \
+                   OptionException('illegal duplexing mode "%s"' % duplexing)
+            setterm.append(duplexing)
+        if fontname is not None:
+            setterm.append('"%s"' % fontname)
+        if fontsize is not None:
+            setterm.append('%s' % fontsize)
+
+        self(string.join(setterm))
+        self.set_string('output', filename)
+        # replot the current figure (to the printer):
+        self.refresh()
+
+        # fperez. Ugly kludge: often for some reason the file is NOT created
+        # and we must reissue the creation commands. I have no idea why!
+        if not lpr_output:
+            #print 'Hardcopy <%s>' % filename  # dbg
+            maxtries = 20
+            delay = 0.1  # delay (in seconds) between print attempts
+            for i in range(maxtries):
+                time.sleep(0.05)  # safety, very small delay
+                if os.path.isfile(filename):
+                    if debug:
+                        print 'Hardcopy to file <%s> success at attempt #%s.' \
+                        % (filename,i+1)
+                    break
+                time.sleep(delay)
+                # try again, issue all commands just in case
+                self(string.join(setterm))
+                self.set_string('output', filename)
+                self.refresh()
+            if not os.path.isfile(filename):
+                print >> sys.stderr,'ERROR: Tried %s times and failed to '\
+                'create hardcopy file `%s`' % (maxtries,filename)
+
+        # reset the terminal to its `default' setting:
+        self('set terminal %s' % gp.GnuplotOpts.default_term)
+        self.set_string('output')
+
+#********************** End of file <Gnuplot2.py> ************************
diff --git a/IPython/GnuplotInteractive.py b/IPython/GnuplotInteractive.py
new file mode 100644
index 0000000..0e99ba6
--- /dev/null
+++ b/IPython/GnuplotInteractive.py
@@ -0,0 +1,148 @@
+# -*- coding: utf-8 -*-
+"""Interactive functions and magic functions for Gnuplot usage.
+
+This requires the Gnuplot.py module for interfacing python with Gnuplot, which
+can be downloaded from:
+
+http://gnuplot-py.sourceforge.net/
+
+See gphelp() below for details on the services offered by this module.
+
+Inspired by a suggestion/request from Arnd Baecker.
+
+$Id: GnuplotInteractive.py 389 2004-10-09 07:59:30Z fperez $"""
+
+__all__ = ['Gnuplot','gp','gp_new','plot','plot2','splot','replot',
+           'hardcopy','gpdata','gpfile','gpstring','gpfunc','gpgrid',
+           'gphelp']
+
+import IPython.GnuplotRuntime as GRun
+from IPython.genutils import page,warn
+
+# Set global names for interactive use
+Gnuplot  = GRun.Gnuplot
+gp_new   = GRun.gp_new
+gp       = GRun.gp
+plot     = gp.plot
+plot2    = gp.plot2
+splot    = gp.splot
+replot   = gp.replot
+hardcopy = gp.hardcopy
+
+# Accessors for the main plot object constructors:
+gpdata   = Gnuplot.Data
+gpfile   = Gnuplot.File
+gpstring = Gnuplot.String
+gpfunc   = Gnuplot.Func
+gpgrid   = Gnuplot.GridData
+
+def gphelp():
+    """Print information about the Gnuplot facilities in IPython."""
+
+    page("""
+IPython provides an interface to access the Gnuplot scientific plotting
+system, in an environment similar to that of Mathematica or Matlab.
+
+New top-level global objects
+----------------------------
+
+Please see their respective docstrings for further details.
+
+- gp: a running Gnuplot instance. You can access its methods as
+gp.<method>. gp(`a string`) will execute the given string as if it had been
+typed in an interactive gnuplot window.
+
+- plot, splot, replot and hardcopy: aliases to the methods of the same name in
+the global running Gnuplot instance gp. These allow you to simply type:
+
+In [1]: plot(x,sin(x),title='Sin(x)')  # assuming x is a Numeric array
+
+and obtain a plot of sin(x) vs x with the title 'Sin(x)'.
+
+- gp_new: a function which returns a new Gnuplot instance. This can be used to
+have multiple Gnuplot instances running in your session to compare different
+plots, each in a separate window.
+
+- Gnuplot: alias to the Gnuplot2 module, an improved drop-in replacement for
+the original Gnuplot.py. Gnuplot2 needs Gnuplot but redefines several of its
+functions with improved versions (Gnuplot2 comes with IPython).
+
+- gpdata, gpfile, gpstring, gpfunc, gpgrid: aliases to Gnuplot.Data,
+Gnuplot.File, Gnuplot.String, Gnuplot.Func and Gnuplot.GridData
+respectively. These functions create objects which can then be passed to the
+plotting commands. See the Gnuplot.py documentation for details.
+
+Keep in mind that all commands passed to a Gnuplot instance are executed in
+the Gnuplot namespace, where no Python variables exist. For example, for
+plotting sin(x) vs x as above, typing
+
+In [2]: gp('plot x,sin(x)')
+
+would not work. Instead, you would get the plot of BOTH the functions 'x' and
+'sin(x)', since Gnuplot doesn't know about the 'x' Python array. The plot()
+method lives in python and does know about these variables.
+
+
+New magic functions
+-------------------
+
+%gpc: pass one command to Gnuplot and execute it or open a Gnuplot shell where
+each line of input is executed.
+
+%gp_set_default: reset the value of IPython's global Gnuplot instance.""")
+    
+# Code below is all for IPython use
+# Define the magic functions for communicating with the above gnuplot instance.
+def magic_gpc(self,parameter_s=''):
+    """Execute a gnuplot command or open a gnuplot shell.
+
+    Usage (omit the % if automagic is on). There are two ways to use it:
+
+      1) %gpc 'command' -> passes 'command' directly to the gnuplot instance.
+
+      2) %gpc -> will open up a prompt (gnuplot>>>) which takes input like the
+      standard gnuplot interactive prompt. If you need to type a multi-line
+      command, use \\ at the end of each intermediate line.
+
+      Upon exiting of the gnuplot sub-shell, you return to your IPython
+      session (the gnuplot sub-shell can be invoked as many times as needed).
+      """
+
+    if parameter_s.strip():
+        self.shell.gnuplot(parameter_s)
+    else:
+        self.shell.gnuplot.interact()
+
+def magic_gp_set_default(self,parameter_s=''):
+    """Set the default gnuplot instance accessed by the %gp magic function.
+
+    %gp_set_default name
+
+    Call with the name of the new instance at the command line. If you want to
+    set this instance in your own code (using an embedded IPython, for
+    example), simply set the variable __IPYTHON__.gnuplot to your own gnuplot
+    instance object."""
+
+    gname = parameter_s.strip()
+    G = eval(gname,self.shell.user_ns)
+    self.shell.gnuplot = G
+    self.shell.user_ns.update({'plot':G.plot,'splot':G.splot,'plot2':G.plot2,
+                               'replot':G.replot,'hardcopy':G.hardcopy})
+
+try:
+    __IPYTHON__
+except NameError:
+    pass
+else:
+    # make the global Gnuplot instance known to IPython
+    __IPYTHON__.gnuplot = GRun.gp
+    __IPYTHON__.gnuplot.shell_first_time = 1
+
+    print """*** Type `gphelp` for help on the Gnuplot integration features."""
+
+    # Add the new magic functions to the class dict
+    from IPython.iplib import InteractiveShell
+    InteractiveShell.magic_gpc = magic_gpc
+    InteractiveShell.magic_gp_set_default = magic_gp_set_default
+
+#********************** End of file <GnuplotInteractive.py> *******************
diff --git a/IPython/GnuplotRuntime.py b/IPython/GnuplotRuntime.py
new file mode 100644
index 0000000..1e99dba
--- /dev/null
+++ b/IPython/GnuplotRuntime.py
@@ -0,0 +1,147 @@
+# -*- coding: utf-8 -*-
+"""Basic Gnuplot functionality for inclusion in other code.
+
+This module creates a running Gnuplot instance called 'gp' and builds other
+convenient globals for quick use in running scripts. It is intended to allow
+you to script plotting tasks in Python with a minimum of effort. A typical
+usage would be:
+
+import IPython.GnuplotRuntime as GP  # or some other short name
+GP.gp.plot(GP.File('your_data.dat'))
+
+
+This module exposes the following objects:
+
+- gp: a running Gnuplot instance. You can access its methods as
+gp.<method>. gp(`a string`) will execute the given string as if it had been
+typed in an interactive gnuplot window.
+
+- gp_new: a function which returns a new Gnuplot instance. This can be used to
+have multiple Gnuplot instances running in your session to compare different
+plots.
+
+- Gnuplot: alias to the Gnuplot2 module, an improved drop-in replacement for
+the original Gnuplot.py. Gnuplot2 needs Gnuplot but redefines several of its
+functions with improved versions (Gnuplot2 comes with IPython).
+
+- Data: alias to Gnuplot.Data, makes a PlotItem from array data.
+
+- File: alias to Gnuplot.File, makes a PlotItem from a file.
+
+- String: alias to Gnuplot.String, makes a PlotItem from a string formatted
+exactly like a file for Gnuplot.File would be.
+
+- Func: alias to Gnuplot.Func, makes a PlotItem from a function string.
+
+- GridData: alias to Gnuplot.GridData, makes a PlotItem from grid data.
+
+- pm3d_config: a string with Gnuplot commands to set up the pm3d mode for
+surface plotting. You can activate it simply by calling gp(pm3d_config).
+
+- eps_fix_bbox: A Unix-only function to fix eps files with bad bounding boxes
+(which Gnuplot generates when the plot size is set to square).
+
+This requires the Gnuplot.py module for interfacing Python with Gnuplot, which
+can be downloaded from:
+
+http://gnuplot-py.sourceforge.net/
+
+Inspired by a suggestion/request from Arnd Baecker.
+
+$Id: GnuplotRuntime.py 389 2004-10-09 07:59:30Z fperez $"""
+
+__all__ = ['Gnuplot','gp','gp_new','Data','File','Func','GridData',
+           'pm3d_config','eps_fix_bbox']
+
+import os,tempfile,sys
+from IPython.genutils import getoutput
+
+#---------------------------------------------------------------------------
+# Notes on mouse support for Gnuplot.py
+
+# If you do not have a mouse-enabled gnuplot, set gnuplot_mouse to 0. If you
+# use gnuplot, you should really grab a recent, mouse enabled copy. It is an
+# extremely useful feature.  Mouse support is official as of gnuplot 4.0,
+# released in April 2004.
+
+# For the mouse features to work correctly, you MUST set your Gnuplot.py
+# module to use temporary files instead of 'inline data' for data
+# communication. Note that this is the default, so unless you've manually
+# fiddled with it you should be ok. If you need to make changes, in the
+# Gnuplot module directory, loook for the gp_unix.py file and make sure the
+# prefer_inline_data variable is set to 0. If you set it to 1 Gnuplot.py will
+# try to pass the data to gnuplot via standard input, which completely
+# confuses the mouse control system (even though it may be a bit faster than
+# using temp files).
+
+# As of Gnuplot.py v1.7, a new option was added to use FIFOs (pipes).  This
+# mechanism, while fast, also breaks the mouse system.  You must therefore set
+# the variable prefer_fifo_data to 0 in gp_unix.py.
+
+tmpname = tempfile.mktemp()
+open(tmpname,'w').write('set mouse')
+gnu_out = getoutput('gnuplot '+ tmpname)
+os.unlink(tmpname)
+if gnu_out:  # Gnuplot won't print anything if it has mouse support
+    print "*** Your version of Gnuplot appears not to have mouse support."
+    gnuplot_mouse = 0
+else:
+    gnuplot_mouse = 1
+del tmpname,gnu_out
+
+# Default state for persistence of new gnuplot instances
+if os.name in ['nt','dos'] or sys.platform == 'cygwin':
+    gnuplot_persist = 0
+else:
+    gnuplot_persist = 1
+
+import IPython.Gnuplot2 as Gnuplot
+
+class NotGiven: pass
+
+def gp_new(mouse=NotGiven,persist=NotGiven):
+    """Return a new Gnuplot instance.
+
+    The instance returned uses the improved methods defined in Gnuplot2.
+
+    Options (boolean):
+
+    - mouse: if unspecified, the module global gnuplot_mouse is used.
+
+    - persist: if unspecified, the module global gnuplot_persist is used."""
+    
+    if mouse is NotGiven:
+        mouse = gnuplot_mouse
+    if persist is NotGiven:
+        persist = gnuplot_persist
+    g = Gnuplot.Gnuplot(persist=persist)
+    if mouse:
+        g('set mouse')
+    return g
+
+# Global-level names.
+
+# A global Gnuplot instance for interactive use:
+gp = gp_new()
+
+# Accessors for the main plot object constructors:
+Data = Gnuplot.Data
+File = Gnuplot.File
+Func = Gnuplot.Func
+String = Gnuplot.String
+GridData = Gnuplot.GridData
+
+# A Unix-only function to fix eps files with bad bounding boxes (which Gnuplot
+# generates when the plot size is set to square):
+eps_fix_bbox = Gnuplot.eps_fix_bbox
+
+# String for configuring pm3d. Simply call g(pm3d_config) to execute it.  pm3d
+# is a very nice mode for plotting colormaps on surfaces. Modify the defaults
+# below to suit your taste.
+pm3d_config = """
+set pm3d solid
+set hidden3d
+unset surface
+set isosamples 50
+"""
+#******************** End of file <GnuplotRuntime.py> ******************
diff --git a/IPython/Itpl.py b/IPython/Itpl.py
new file mode 100644
index 0000000..c62ab4f
--- /dev/null
+++ b/IPython/Itpl.py
@@ -0,0 +1,253 @@
+# -*- coding: utf-8 -*-
+"""String interpolation for Python (by Ka-Ping Yee, 14 Feb 2000).
+
+This module lets you quickly and conveniently interpolate values into
+strings (in the flavour of Perl or Tcl, but with less extraneous
+punctuation).  You get a bit more power than in the other languages,
+because this module allows subscripting, slicing, function calls,
+attribute lookup, or arbitrary expressions.  Variables and expressions
+are evaluated in the namespace of the caller.
+
+The itpl() function returns the result of interpolating a string, and
+printpl() prints out an interpolated string.  Here are some examples:
+
+    from Itpl import printpl
+    printpl("Here is a $string.")
+    printpl("Here is a $module.member.")
+    printpl("Here is an $object.member.")
+    printpl("Here is a $functioncall(with, arguments).")
+    printpl("Here is an ${arbitrary + expression}.")
+    printpl("Here is an $array[3] member.")
+    printpl("Here is a $dictionary['member'].")
+
+The filter() function filters a file object so that output through it
+is interpolated.  This lets you produce the illusion that Python knows
+how to do interpolation:
+
+    import Itpl
+    sys.stdout = Itpl.filter()
+    f = "fancy"
+    print "Isn't this $f?"
+    print "Standard output has been replaced with a $sys.stdout object."
+    sys.stdout = Itpl.unfilter()
+    print "Okay, back $to $normal."
+
+Under the hood, the Itpl class represents a string that knows how to
+interpolate values.  An instance of the class parses the string once
+upon initialization; the evaluation and substitution can then be done
+each time the instance is evaluated with str(instance).  For example:
+
+    from Itpl import Itpl
+    s = Itpl("Here is $foo.")
+    foo = 5
+    print str(s)
+    foo = "bar"
+    print str(s)
+
+$Id: Itpl.py 542 2005-03-18 09:16:04Z fperez $
+"""                   # ' -> close an open quote for stupid emacs
+
+#*****************************************************************************
+#
+# Copyright (c) 2001 Ka-Ping Yee <ping@lfw.org>
+#
+#
+# Published under the terms of the MIT license, hereby reproduced:
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+#
+#*****************************************************************************
+
+__author__  = 'Ka-Ping Yee <ping@lfw.org>'
+__license__ = 'MIT'
+
+import sys, string
+from types import StringType
+from tokenize import tokenprog
+
+class ItplError(ValueError):
+    def __init__(self, text, pos):
+        self.text = text
+        self.pos = pos
+    def __str__(self):
+        return "unfinished expression in %s at char %d" % (
+            repr(self.text), self.pos)
+
+def matchorfail(text, pos):
+    match = tokenprog.match(text, pos)
+    if match is None:
+        raise ItplError(text, pos)
+    return match, match.end()
+
+class Itpl:
+    """Class representing a string with interpolation abilities.
+    
+    Upon creation, an instance works out what parts of the format
+    string are literal and what parts need to be evaluated.  The
+    evaluation and substitution happens in the namespace of the
+    caller when str(instance) is called."""
+
+    def __init__(self, format):
+        """The single argument to this constructor is a format string.
+
+        The format string is parsed according to the following rules:
+
+        1.  A dollar sign and a name, possibly followed by any of: 
+              - an open-paren, and anything up to the matching paren 
+              - an open-bracket, and anything up to the matching bracket 
+              - a period and a name 
+            any number of times, is evaluated as a Python expression.
+
+        2.  A dollar sign immediately followed by an open-brace, and
+            anything up to the matching close-brace, is evaluated as
+            a Python expression.
+
+        3.  Outside of the expressions described in the above two rules,
+            two dollar signs in a row give you one literal dollar sign."""
+
+        if type(format) != StringType:
+            raise TypeError, "needs string initializer"
+        self.format = format
+
+        namechars = "abcdefghijklmnopqrstuvwxyz" \
+            "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
+        chunks = []
+        pos = 0
+
+        while 1:
+            dollar = string.find(format, "$", pos)
+            if dollar < 0: break
+            nextchar = format[dollar+1]
+
+            if nextchar == "{":
+                chunks.append((0, format[pos:dollar]))
+                pos, level = dollar+2, 1
+                while level:
+                    match, pos = matchorfail(format, pos)
+                    tstart, tend = match.regs[3]
+                    token = format[tstart:tend]
+                    if token == "{": level = level+1
+                    elif token == "}": level = level-1
+                chunks.append((1, format[dollar+2:pos-1]))
+
+            elif nextchar in namechars:
+                chunks.append((0, format[pos:dollar]))
+                match, pos = matchorfail(format, dollar+1)
+                while pos < len(format):
+                    if format[pos] == "." and \
+                        pos+1 < len(format) and format[pos+1] in namechars:
+                        match, pos = matchorfail(format, pos+1)
+                    elif format[pos] in "([":
+                        pos, level = pos+1, 1
+                        while level:
+                            match, pos = matchorfail(format, pos)
+                            tstart, tend = match.regs[3]
+                            token = format[tstart:tend]
+                            if token[0] in "([": level = level+1
+                            elif token[0] in ")]": level = level-1
+                    else: break
+                chunks.append((1, format[dollar+1:pos]))
+
+            else:
+                chunks.append((0, format[pos:dollar+1]))
+                pos = dollar + 1 + (nextchar == "$")
+
+        if pos < len(format): chunks.append((0, format[pos:]))
+        self.chunks = chunks
+
+    def __repr__(self):
+        return "<Itpl %s >" % repr(self.format)
+
+    def __str__(self):
+        """Evaluate and substitute the appropriate parts of the string."""
+
+        # We need to skip enough frames to get to the actual caller outside of
+        # Itpl.
+        frame = sys._getframe(1)
+        while frame.f_globals["__name__"] == __name__: frame = frame.f_back
+        loc, glob = frame.f_locals, frame.f_globals
+
+        result = []
+        for live, chunk in self.chunks:
+            if live: result.append(str(eval(chunk,glob,loc)))
+            else: result.append(chunk)
+
+        return ''.join(result)
+
+class ItplNS(Itpl):
+    """Class representing a string with interpolation abilities.
+
+    This inherits from Itpl, but at creation time a namespace is provided
+    where the evaluation will occur.  The interpolation becomes a bit more
+    efficient, as no traceback needs to be extracte.  It also allows the
+    caller to supply a different namespace for the interpolation to occur than
+    its own."""
+    
+    def __init__(self, format,globals,locals=None):
+        """ItplNS(format,globals[,locals]) -> interpolating string instance.
+
+        This constructor, besides a format string, takes a globals dictionary
+        and optionally a locals (which defaults to globals if not provided).
+
+        For further details, see the Itpl constructor."""
+
+        if locals is None:
+            locals = globals
+        self.globals = globals
+        self.locals = locals
+        Itpl.__init__(self,format)
+        
+    def __str__(self):
+        """Evaluate and substitute the appropriate parts of the string."""
+        glob = self.globals
+        loc = self.locals
+        result = []
+        for live, chunk in self.chunks:
+            if live: result.append(str(eval(chunk,glob,loc)))
+            else: result.append(chunk)
+        return ''.join(result)
+
+# utilities for fast printing
+def itpl(text): return str(Itpl(text))
+def printpl(text): print itpl(text)
+# versions with namespace
+def itplns(text,globals,locals=None): return str(ItplNS(text,globals,locals))
+def printplns(text,globals,locals=None): print itplns(text,globals,locals)
+
+class ItplFile:
+    """A file object that filters each write() through an interpolator."""
+    def __init__(self, file): self.file = file
+    def __repr__(self): return "<interpolated " + repr(self.file) + ">"
+    def __getattr__(self, attr): return getattr(self.file, attr)
+    def write(self, text): self.file.write(str(Itpl(text)))
+
+def filter(file=sys.stdout):
+    """Return an ItplFile that filters writes to the given file object.
+    
+    'file = filter(file)' replaces 'file' with a filtered object that
+    has a write() method.  When called with no argument, this creates
+    a filter to sys.stdout."""
+    return ItplFile(file)
+
+def unfilter(ifile=None):
+    """Return the original file that corresponds to the given ItplFile.
+    
+    'file = unfilter(file)' undoes the effect of 'file = filter(file)'.
+    'sys.stdout = unfilter()' undoes the effect of 'sys.stdout = filter()'."""
+    return ifile and ifile.file or sys.stdout.file
diff --git a/IPython/Logger.py b/IPython/Logger.py
new file mode 100644
index 0000000..ae721aa
--- /dev/null
+++ b/IPython/Logger.py
@@ -0,0 +1,185 @@
+# -*- coding: utf-8 -*-
+"""
+Logger class for IPython's logging facilities.
+
+$Id: Logger.py 430 2004-11-30 08:52:05Z fperez $
+"""
+
+#*****************************************************************************
+#       Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
+#       Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
+#
+#  Distributed under the terms of the BSD License.  The full license is in
+#  the file COPYING, distributed as part of this software.
+#*****************************************************************************
+
+#****************************************************************************
+# Modules and globals
+
+from IPython import Release
+__author__  = '%s <%s>\n%s <%s>' % \
+              ( Release.authors['Janko'] + Release.authors['Fernando'] )
+__license__ = Release.license
+
+# Python standard modules
+import os,sys,glob
+
+# Homebrewed
+from IPython.genutils import *
+
+#****************************************************************************
+# FIXME: The logger class shouldn't be a mixin, it throws too many things into
+# the InteractiveShell namespace. Rather make it a standalone tool, and create
+# a Logger instance in InteractiveShell that uses it. Doing this will require
+# tracking down a *lot* of nasty uses of the Logger attributes in
+# InteractiveShell, but will clean up things quite a bit.
+
+class Logger:
+    """A Logfile Mixin class with different policies for file creation"""
+
+    # FIXME: once this isn't a mixin, log_ns should just be 'namespace', since the
+    # names won't collide anymore.
+    def __init__(self,log_ns):
+        self._i00,self._i,self._ii,self._iii = '','','',''
+        self.do_full_cache = 0 # FIXME. There's also a do_full.. in OutputCache
+        self.log_ns = log_ns
+        # defaults
+        self.LOGMODE = 'backup'
+        self.defname = 'logfile'
+        
+    def create_log(self,header='',fname='',defname='.Logger.log'):
+        """Generate a new log-file with a default header"""
+        if fname:
+            self.LOG = fname
+
+        if self.LOG:
+            self.logfname = self.LOG
+        else:
+            self.logfname = defname
+        
+        if self.LOGMODE == 'over':
+            if os.path.isfile(self.logfname):
+                os.remove(self.logfname) 
+            self.logfile = open(self.logfname,'w')
+        if self.LOGMODE == 'backup':
+            if os.path.isfile(self.logfname):
+                backup_logname = self.logfname+'~'
+                # Manually remove any old backup, since os.rename may fail
+                # under Windows.
+                if os.path.isfile(backup_logname):
+                    os.remove(backup_logname)
+                os.rename(self.logfname,backup_logname)
+            self.logfile = open(self.logfname,'w')
+        elif self.LOGMODE == 'global':
+            self.logfname = os.path.join(self.home_dir, self.defname)
+            self.logfile = open(self.logfname, 'a')
+            self.LOG = self.logfname
+        elif self.LOGMODE == 'rotate':
+            if os.path.isfile(self.logfname):
+                if os.path.isfile(self.logfname+'.001~'): 
+                    old = glob.glob(self.logfname+'.*~')
+                    old.sort()
+                    old.reverse()
+                    for f in old:
+                        root, ext = os.path.splitext(f)
+                        num = int(ext[1:-1])+1
+                        os.rename(f, root+'.'+`num`.zfill(3)+'~')
+                os.rename(self.logfname, self.logfname+'.001~')
+            self.logfile = open(self.logfname,'w')
+        elif self.LOGMODE == 'append':
+            self.logfile = open(self.logfname,'a')
+            
+        if self.LOGMODE != 'append':
+            self.logfile.write(header)
+        self.logfile.flush()
+
+    def logstart(self, header='',parameter_s = ''):
+        if not hasattr(self, 'LOG'):
+            logfname = self.LOG or parameter_s or './'+self.defname
+            self.create_log(header,logfname)
+        elif parameter_s and hasattr(self,'logfname') and \
+             parameter_s != self.logfname:
+            self.close_log()
+            self.create_log(header,parameter_s)
+            
+        self._dolog = 1
+
+    def switch_log(self,val):
+        """Switch logging on/off. val should be ONLY 0 or 1."""
+
+        if not val in [0,1]:
+            raise ValueError, \
+                  'Call switch_log ONLY with 0 or 1 as argument, not with:',val
+        
+        label = {0:'OFF',1:'ON'}
+
+        try:
+            _ = self.logfile
+        except AttributeError:
+            print """
+Logging hasn't been started yet (use %logstart for that).
+
+%logon/%logoff are for temporarily starting and stopping logging for a logfile
+which already exists. But you must first start the logging process with
+%logstart (optionally giving a logfile name)."""
+            
+        else:
+            if self._dolog == val:
+                print 'Logging is already',label[val]
+            else:
+                print 'Switching logging',label[val]
+                self._dolog = 1 - self._dolog
+
+    def logstate(self):
+        """Print a status message about the logger."""
+        try:
+            logfile = self.logfname
+        except:
+            print 'Logging has not been activated.'
+        else:
+            state = self._dolog and 'active' or 'temporarily suspended'
+            print """
+File:\t%s
+Mode:\t%s
+State:\t%s """ % (logfile,self.LOGMODE,state)
+
+        
+    def log(self, line,continuation=None):
+        """Write the line to a log and create input cache variables _i*."""
+
+        # update the auto _i tables
+        #print '***logging line',line # dbg
+        #print '***cache_count', self.outputcache.prompt_count # dbg
+        input_hist = self.log_ns['_ih']
+        if not continuation and line:
+            self._iii = self._ii
+            self._ii = self._i
+            self._i = self._i00
+            # put back the final \n of every input line
+            self._i00 = line+'\n'
+            #print 'Logging input:<%s>' % line  # dbg
+            input_hist.append(self._i00)
+
+        # hackish access to top-level namespace to create _i1,_i2... dynamically
+        to_main = {'_i':self._i,'_ii':self._ii,'_iii':self._iii}
+        if self.do_full_cache:
+            in_num = self.outputcache.prompt_count
+            # add blank lines if the input cache fell out of sync. This can happen
+            # for embedded instances which get killed via C-D and then get resumed.
+            while in_num >= len(input_hist):
+                input_hist.append('\n')
+            new_i = '_i%s' % in_num
+            if continuation:
+                self._i00 = '%s%s\n' % (self.log_ns[new_i],line)
+                input_hist[in_num] = self._i00
+            to_main[new_i] = self._i00
+        self.log_ns.update(to_main)
+        
+        if self._dolog and line:
+            self.logfile.write(line+'\n')
+            self.logfile.flush()
+
+    def close_log(self):
+        if hasattr(self, 'logfile'):
+            self.logfile.close()
+            self.logfname = ''
diff --git a/IPython/Magic.py b/IPython/Magic.py
new file mode 100644
index 0000000..2096c73
--- /dev/null
+++ b/IPython/Magic.py
@@ -0,0 +1,2490 @@
+# -*- coding: utf-8 -*-
+"""Magic functions for InteractiveShell.
+
+$Id: Magic.py 583 2005-05-13 21:20:33Z fperez $"""
+
+#*****************************************************************************
+#       Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
+#       Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
+#
+#  Distributed under the terms of the BSD License.  The full license is in
+#  the file COPYING, distributed as part of this software.
+#*****************************************************************************
+
+#****************************************************************************
+# Modules and globals
+
+from IPython import Release
+__author__  = '%s <%s>\n%s <%s>' % \
+              ( Release.authors['Janko'] + Release.authors['Fernando'] )
+__license__ = Release.license
+
+# Python standard modules
+import __builtin__
+import os,sys,inspect,pydoc,re,tempfile,shlex,pdb,bdb,time
+try:
+    import profile,pstats
+except ImportError:
+    profile = pstats = None
+from getopt import getopt
+from pprint import pprint, pformat
+from cStringIO import StringIO
+
+# Homebrewed
+from IPython.Struct import Struct
+from IPython.Itpl import Itpl, itpl, printpl,itplns
+from IPython.FakeModule import FakeModule
+from IPython import OInspect
+from IPython.genutils import *
+
+# Globals to be set later by Magic constructor
+MAGIC_PREFIX = ''
+MAGIC_ESCAPE = ''
+
+#***************************************************************************
+# Utility functions
+def magic2python(cmd):
+    """Convert a command string of magic syntax to valid Python code."""
+
+    if cmd.startswith('#'+MAGIC_ESCAPE) or \
+           cmd.startswith(MAGIC_ESCAPE):
+        if cmd[0]=='#':
+            cmd = cmd[1:]
+        # we need to return the proper line end later
+        if cmd[-1] == '\n':
+            endl = '\n'
+        else:
+            endl = ''
+        try:
+            func,args = cmd[1:].split(' ',1)
+        except:
+            func,args = cmd[1:].rstrip(),''
+        args = args.replace('"','\\"').replace("'","\\'").rstrip()
+        return '%s%s ("%s")%s' % (MAGIC_PREFIX,func,args,endl)
+    else:
+        return cmd
+
+def on_off(tag):
+    """Return an ON/OFF string for a 1/0 input. Simple utility function."""
+    return ['OFF','ON'][tag]
+
+def get_py_filename(name):
+    """Return a valid python filename in the current directory.
+
+    If the given name is not a file, it adds '.py' and searches again.
+    Raises IOError with an informative message if the file isn't found."""
+
+    name = os.path.expanduser(name)
+    if not os.path.isfile(name) and not name.endswith('.py'):
+        name += '.py'
+    if os.path.isfile(name):
+        return name
+    else:
+        raise IOError,'File `%s` not found.' % name
+
+# Try to use shlex.split for converting an input string into a sys.argv-type
+# list.  This appeared in Python 2.3, so here's a quick backport for 2.2.
+try:
+    shlex_split = shlex.split
+except AttributeError:
+    _quotesre = re.compile(r'[\'"](.*)[\'"]')
+    _wordchars = ('abcdfeghijklmnopqrstuvwxyz'
+                  'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-.~*?'
+                  'ßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ'
+                  'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ%s'
+                  % os.sep)
+    
+    def shlex_split(s):
+        """Simplified backport to Python 2.2 of shlex.split().
+
+        This is a quick and dirty hack, since the shlex module under 2.2 lacks
+        several of the features needed to really match the functionality of
+        shlex.split() in 2.3."""
+
+        lex = shlex.shlex(StringIO(s))
+        # Try to get options, extensions and path separators as characters
+        lex.wordchars = _wordchars
+        lex.commenters = ''
+        # Make a list out of the lexer by hand, since in 2.2 it's not an
+        # iterator.
+        lout = []
+        while 1:
+            token = lex.get_token()
+            if token == '':
+                break
+            # Try to handle quoted tokens correctly
+            quotes = _quotesre.match(token)
+            if quotes:
+                token = quotes.group(1)
+            lout.append(token)
+        return lout
+
+#****************************************************************************
+# Utility classes
+class Macro:
+    """Simple class to store the value of macros as strings.
+
+    This allows us to later exec them by checking when something is an
+    instance of this class."""
+    
+    def __init__(self,cmds):
+        """Build a macro from a list of commands."""
+
+        # Since the list may include multi-line entries, first make sure that
+        # they've been all broken up before passing it to magic2python
+        cmdlist = map(magic2python,''.join(cmds).split('\n'))
+        self.value = '\n'.join(cmdlist)
+
+    def __str__(self):
+        return self.value
+
+#***************************************************************************
+# Main class implementing Magic functionality
+class Magic:
+    """Magic functions for InteractiveShell.
+
+    Shell functions which can be reached as %function_name. All magic
+    functions should accept a string, which they can parse for their own
+    needs. This can make some functions easier to type, eg `%cd ../`
+    vs. `%cd("../")`
+
+    ALL definitions MUST begin with the prefix magic_. The user won't need it
+    at the command line, but it is is needed in the definition. """
+
+    # class globals
+    auto_status = ['Automagic is OFF, % prefix IS needed for magic functions.',
+                   'Automagic is ON, % prefix NOT needed for magic functions.']
+
+    #......................................................................
+    # some utility functions
+
+    def __init__(self,shell):
+        # XXX This is hackish, clean up later to avoid these messy globals
+        global MAGIC_PREFIX, MAGIC_ESCAPE
+        
+        self.options_table = {}
+        MAGIC_PREFIX = shell.name+'.magic_'
+        MAGIC_ESCAPE = shell.ESC_MAGIC
+        if profile is None:
+            self.magic_prun = self.profile_missing_notice
+
+    def profile_missing_notice(self, *args, **kwargs):
+        error("""\
+The profile module could not be found.  If you are a Debian user,
+it has been removed from the standard Debian package because of its non-free
+license. To use profiling, please install"python2.3-profiler" from non-free.""")
+    
+    def default_option(self,fn,optstr):
+        """Make an entry in the options_table for fn, with value optstr"""
+        
+        if fn not in self.lsmagic():
+            error("%s is not a magic function" % fn)
+        self.options_table[fn] = optstr
+
+    def lsmagic(self):
+        """Return a list of currently available magic functions.
+
+        Gives a list of the bare names after mangling (['ls','cd', ...], not
+        ['magic_ls','magic_cd',...]"""
+
+        # FIXME. This needs a cleanup, in the way the magics list is built.
+        
+        # magics in class definition
+        class_magic = lambda fn: fn.startswith('magic_') and \
+                      callable(Magic.__dict__[fn])
+        # in instance namespace (run-time user additions)
+        inst_magic =  lambda fn: fn.startswith('magic_') and \
+                     callable(self.__dict__[fn])
+        # and bound magics by user (so they can access self):
+        inst_bound_magic =  lambda fn: fn.startswith('magic_') and \
+                           callable(self.__class__.__dict__[fn])
+        magics = filter(class_magic,Magic.__dict__.keys()) + \
+                 filter(inst_magic,self.__dict__.keys()) + \
+                 filter(inst_bound_magic,self.__class__.__dict__.keys())
+        out = []
+        for fn in magics:
+            out.append(fn.replace('magic_','',1))
+        out.sort()
+        return out
+    
+    def set_shell(self,shell):
+        self.shell = shell
+        self.alias_table = shell.alias_table
+
+    def extract_input_slices(self,slices):
+        """Return as a string a set of input history slices.
+
+        The set of slices is given as a list of strings (like ['1','4:8','9'],
+        since this function is for use by magic functions which get their
+        arguments as strings."""
+
+        cmds = []
+        for chunk in slices:
+            if ':' in chunk:
+                ini,fin = map(int,chunk.split(':'))
+            else:
+                ini = int(chunk)
+                fin = ini+1
+            cmds.append(self.shell.input_hist[ini:fin])
+        return cmds
+        
+    def _ofind(self,oname):
+        """Find an object in the available namespaces.
+
+        self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
+
+        Has special code to detect magic functions.
+        """
+        
+        oname = oname.strip()
+
+        # Namespaces to search in:
+        user_ns        = self.shell.user_ns
+        internal_ns    = self.shell.internal_ns
+        builtin_ns     = __builtin__.__dict__
+        alias_ns       = self.shell.alias_table
+
+        # Put them in a list. The order is important so that we find things in
+        # the same order that Python finds them.
+        namespaces = [ ('Interactive',user_ns),
+                       ('IPython internal',internal_ns),
+                       ('Python builtin',builtin_ns),
+                       ('Alias',alias_ns),
+                       ]
+
+        # initialize results to 'null'
+        found = 0; obj = None;  ospace = None;  ds = None;
+        ismagic = 0; isalias = 0
+
+        # Look for the given name by splitting it in parts.  If the head is
+        # found, then we look for all the remaining parts as members, and only
+        # declare success if we can find them all.
+        oname_parts = oname.split('.')
+        oname_head, oname_rest = oname_parts[0],oname_parts[1:]
+        for nsname,ns in namespaces:
+            try:
+                obj = ns[oname_head]
+            except KeyError:
+                continue
+            else:
+                for part in oname_rest:
+                    try:
+                        obj = getattr(obj,part)
+                    except:
+                        # Blanket except b/c some badly implemented objects
+                        # allow __getattr__ to raise exceptions other than
+                        # AttributeError, which then crashes IPython.
+                        break
+                else:
+                    # If we finish the for loop (no break), we got all members
+                    found = 1
+                    ospace = nsname
+                    if ns == alias_ns:
+                        isalias = 1
+                    break  # namespace loop
+
+        # Try to see if it's magic
+        if not found:
+            if oname.startswith(self.shell.ESC_MAGIC):
+                oname = oname[1:]
+            obj = getattr(self,'magic_'+oname,None)
+            if obj is not None:
+                found = 1
+                ospace = 'IPython internal'
+                ismagic = 1
+
+        # Last try: special-case some literals like '', [], {}, etc:
+        if not found and oname_head in ["''",'""','[]','{}','()']:
+            obj = eval(oname_head)
+            found = 1
+            ospace = 'Interactive'
+            
+        return {'found':found, 'obj':obj, 'namespace':ospace,
+                'ismagic':ismagic, 'isalias':isalias}
+        
+    def arg_err(self,func):
+        """Print docstring if incorrect arguments were passed"""
+        print 'Error in arguments:'
+        print OInspect.getdoc(func)
+
+
+    def format_latex(self,str):
+        """Format a string for latex inclusion."""
+
+        # Characters that need to be escaped for latex:
+        escape_re = re.compile(r'(%|_|\$)',re.MULTILINE)
+        # Magic command names as headers:
+        cmd_name_re = re.compile(r'^(%s.*?):' % self.shell.ESC_MAGIC,
+                                 re.MULTILINE)
+        # Magic commands 
+        cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % self.shell.ESC_MAGIC,
+                            re.MULTILINE)
+        # Paragraph continue
+        par_re = re.compile(r'\\$',re.MULTILINE)
+
+        str = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',str)
+        str = cmd_re.sub(r'\\texttt{\g<cmd>}',str)
+        str = par_re.sub(r'\\\\',str)
+        str = escape_re.sub(r'\\\1',str)
+        return str
+
+    def format_screen(self,str):
+        """Format a string for screen printing.
+
+        This removes some latex-type format codes."""
+        # Paragraph continue
+        par_re = re.compile(r'\\$',re.MULTILINE)
+        str = par_re.sub('',str)
+        return str
+
+    def parse_options(self,arg_str,opt_str,*long_opts,**kw):
+        """Parse options passed to an argument string.
+
+        The interface is similar to that of getopt(), but it returns back a
+        Struct with the options as keys and the stripped argument string still
+        as a string.
+
+        arg_str is quoted as a true sys.argv vector by calling on the fly a
+        python process in a subshell.  This allows us to easily expand
+        variables, glob files, quote arguments, etc, with all the power and
+        correctness of the underlying system shell.
+
+        Options:
+          -mode: default 'string'. If given as 'list', the argument string is
+          returned as a list (split on whitespace) instead of a string.
+
+          -list_all: put all option values in lists. Normally only options
+          appearing more than once are put in a list."""
+
+        # inject default options at the beginning of the input line
+        caller = sys._getframe(1).f_code.co_name.replace('magic_','')
+        arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
+        
+        mode = kw.get('mode','string')
+        if mode not in ['string','list']:
+            raise ValueError,'incorrect mode given: %s' % mode
+        # Get options
+        list_all = kw.get('list_all',0)
+
+        # Check if we have more than one argument to warrant extra processing:
+        odict = {}  # Dictionary with options
+        args = arg_str.split()
+        if len(args) >= 1:
+            # If the list of inputs only has 0 or 1 thing in it, there's no
+            # need to look for options
+            argv = shlex_split(arg_str)
+            # Do regular option processing
+            opts,args = getopt(argv,opt_str,*long_opts)
+            for o,a in opts:
+                if o.startswith('--'):
+                    o = o[2:]
+                else:
+                    o = o[1:]
+                try:
+                    odict[o].append(a)
+                except AttributeError:
+                    odict[o] = [odict[o],a]
+                except KeyError:
+                    if list_all:
+                        odict[o] = [a]
+                    else:
+                        odict[o] = a
+
+        # Prepare opts,args for return
+        opts = Struct(odict)
+        if mode == 'string':
+            args = ' '.join(args)
+
+        return opts,args
+    
+    #......................................................................
+    # And now the actual magic functions
+
+    # Functions for IPython shell work (vars,funcs, config, etc)
+    def magic_lsmagic(self, parameter_s = ''):
+        """List currently available magic functions."""
+        mesc = self.shell.ESC_MAGIC
+        print 'Available magic functions:\n'+mesc+\
+              ('  '+mesc).join(self.lsmagic())
+        print '\n' + Magic.auto_status[self.shell.rc.automagic]
+        return None
+        
+    def magic_magic(self, parameter_s = ''):
+        """Print information about the magic function system."""
+
+        mode = ''
+        try:
+            if parameter_s.split()[0] == '-latex':
+                mode = 'latex'
+        except:
+            pass
+
+        magic_docs = []
+        for fname in self.lsmagic():
+            mname = 'magic_' + fname
+            for space in (Magic,self,self.__class__):
+                try:
+                    fn = space.__dict__[mname]
+                except KeyError:
+                    pass
+                else:
+                    break
+            magic_docs.append('%s%s:\n\t%s\n' %(self.shell.ESC_MAGIC,
+                                                fname,fn.__doc__))
+        magic_docs = ''.join(magic_docs)
+
+        if mode == 'latex':
+            print self.format_latex(magic_docs)
+            return
+        else:
+            magic_docs = self.format_screen(magic_docs)
+        
+        outmsg = """
+IPython's 'magic' functions
+===========================
+
+The magic function system provides a series of functions which allow you to
+control the behavior of IPython itself, plus a lot of system-type
+features. All these functions are prefixed with a % character, but parameters
+are given without parentheses or quotes.
+
+NOTE: If you have 'automagic' enabled (via the command line option or with the
+%automagic function), you don't need to type in the % explicitly.  By default,
+IPython ships with automagic on, so you should only rarely need the % escape.
+
+Example: typing '%cd mydir' (without the quotes) changes you working directory
+to 'mydir', if it exists.
+
+You can define your own magic functions to extend the system. See the supplied
+ipythonrc and example-magic.py files for details (in your ipython
+configuration directory, typically $HOME/.ipython/).
+
+You can also define your own aliased names for magic functions. In your
+ipythonrc file, placing a line like:
+
+  execute __IPYTHON__.magic_pf = __IPYTHON__.magic_profile
+
+will define %pf as a new name for %profile.
+
+You can also call magics in code using the ipmagic() function, which IPython
+automatically adds to the builtin namespace.  Type 'ipmagic?' for details.
+
+For a list of the available magic functions, use %lsmagic. For a description
+of any of them, type %magic_name?, e.g. '%cd?'.
+
+Currently the magic system has the following functions:\n"""
+
+        mesc = self.shell.ESC_MAGIC
+        outmsg = ("%s\n%s\n\nSummary of magic functions (from %slsmagic):"
+                  "\n\n%s%s\n\n%s" % (outmsg,
+                                     magic_docs,mesc,mesc,
+                                     ('  '+mesc).join(self.lsmagic()),
+                                     Magic.auto_status[self.shell.rc.automagic] ) )
+
+        page(outmsg,screen_lines=self.shell.rc.screen_length)
+  
+    def magic_automagic(self, parameter_s = ''):
+        """Make magic functions callable without having to type the initial %.
+        
+        Toggles on/off (when off, you must call it as %automagic, of
+        course). Note that magic functions have lowest priority, so if there's
+        a variable whose name collides with that of a magic fn, automagic
+        won't work for that function (you get the variable instead). However,
+        if you delete the variable (del var), the previously shadowed magic
+        function becomes visible to automagic again."""
+
+        rc = self.shell.rc
+        rc.automagic = not rc.automagic
+        print '\n' + Magic.auto_status[rc.automagic]
+
+    def magic_autocall(self, parameter_s = ''):
+        """Make functions callable without having to type parentheses.
+
+        This toggles the autocall command line option on and off."""
+        
+        rc = self.shell.rc
+        rc.autocall = not rc.autocall
+        print "Automatic calling is:",['OFF','ON'][rc.autocall]
+
+    def magic_autoindent(self, parameter_s = ''):
+        """Toggle autoindent on/off (if available)."""
+
+        self.shell.set_autoindent()
+        print "Automatic indentation is:",['OFF','ON'][self.shell.autoindent]
+
+    def magic_system_verbose(self, parameter_s = ''):
+        """Toggle verbose printing of system calls on/off."""
+
+        self.shell.rc_set_toggle('system_verbose')
+        print "System verbose printing is:",\
+              ['OFF','ON'][self.shell.rc.system_verbose]
+
+    def magic_history(self, parameter_s = ''):
+        """Print input history (_i<n> variables), with most recent last.
+        
+        %history [-n]       -> print at most 40 inputs (some may be multi-line)\\
+        %history [-n] n     -> print at most n inputs\\
+        %history [-n] n1 n2 -> print inputs between n1 and n2 (n2 not included)\\
+
+        Each input's number <n> is shown, and is accessible as the
+        automatically generated variable _i<n>.  Multi-line statements are
+        printed starting at a new line for easy copy/paste.
+
+        If option -n is used, input numbers are not printed. This is useful if
+        you want to get a printout of many lines which can be directly pasted
+        into a text editor.
+
+        This feature is only available if numbered prompts are in use."""
+
+        if not self.do_full_cache:
+            print 'This feature is only available if numbered prompts are in use.'
+            return
+        opts,args = self.parse_options(parameter_s,'n',mode='list')
+        
+        default_length = 40
+        if len(args) == 0:
+            final = self.outputcache.prompt_count
+            init = max(1,final-default_length)
+        elif len(args) == 1:
+            final = self.outputcache.prompt_count
+            init = max(1,final-int(args[0]))
+        elif len(args) == 2:
+            init,final = map(int,args)
+        else:
+            warn('%hist takes 0, 1 or 2 arguments separated by spaces.')
+            print self.magic_hist.__doc__
+            return
+        width = len(str(final))
+        line_sep = ['','\n']
+        input_hist = self.shell.input_hist
+        print_nums = not opts.has_key('n')
+        for in_num in range(init,final):
+            inline = input_hist[in_num]
+            multiline = inline.count('\n') > 1
+            if print_nums:
+                print str(in_num).ljust(width)+':'+ line_sep[multiline],
+            if inline.startswith('#'+self.shell.ESC_MAGIC) or \
+                   inline.startswith('#!'):
+                print inline[1:],
+            else:
+                print inline,
+
+    def magic_hist(self, parameter_s=''):
+        """Alternate name for %history."""
+        return self.magic_history(parameter_s)
+
+    def magic_p(self, parameter_s=''):
+        """Just a short alias for Python's 'print'."""
+        exec 'print ' + parameter_s in self.shell.user_ns
+
+    def magic_r(self, parameter_s=''):
+        """Repeat previous input.
+
+        If given an argument, repeats the previous command which starts with
+        the same string, otherwise it just repeats the previous input.
+
+        Shell escaped commands (with ! as first character) are not recognized
+        by this system, only pure python code and magic commands.
+        """
+
+        start = parameter_s.strip()
+        esc_magic = self.shell.ESC_MAGIC
+        # Identify magic commands even if automagic is on (which means
+        # the in-memory version is different from that typed by the user).
+        if self.shell.rc.automagic:
+            start_magic = esc_magic+start
+        else:
+            start_magic = start
+        # Look through the input history in reverse
+        for n in range(len(self.shell.input_hist)-2,0,-1):
+            input = self.shell.input_hist[n]
+            # skip plain 'r' lines so we don't recurse to infinity
+            if input != 'ipmagic("r")\n' and \
+                   (input.startswith(start) or input.startswith(start_magic)):
+                #print 'match',`input`  # dbg
+                if input.startswith(esc_magic):
+                    input = magic2python(input)
+                    #print 'modified',`input`  # dbg
+                print 'Executing:',input,
+                exec input in self.shell.user_ns
+                return
+        print 'No previous input matching `%s` found.' % start
+
+    def magic_page(self, parameter_s=''):
+        """Pretty print the object and display it through a pager.
+        
+        If no parameter is given, use _ (last output)."""
+        # After a function contributed by Olivier Aubert, slightly modified.
+
+        oname = parameter_s and parameter_s or '_' 
+        info = self._ofind(oname)
+        if info['found']:
+            page(pformat(info['obj']))
+        else:
+            print 'Object `%s` not found' % oname
+
+    def magic_profile(self, parameter_s=''):
+        """Print your currently active IPyhton profile."""
+        if self.shell.rc.profile:
+            printpl('Current IPython profile: $self.shell.rc.profile.')
+        else:
+            print 'No profile active.'
+        
+    def _inspect(self,meth,oname,**kw):
+        """Generic interface to the inspector system.
+
+        This function is meant to be called by pdef, pdoc & friends."""
+        
+        oname = oname.strip()
+        info = Struct(self._ofind(oname))
+        if info.found:
+            pmethod = getattr(self.shell.inspector,meth)
+            formatter = info.ismagic and self.format_screen or None
+            if meth == 'pdoc':
+                pmethod(info.obj,oname,formatter)
+            elif meth == 'pinfo':
+                pmethod(info.obj,oname,formatter,info,**kw)
+            else:
+                pmethod(info.obj,oname)
+        else:
+            print 'Object `%s` not found.' % oname
+            return 'not found'  # so callers can take other action
+        
+    def magic_pdef(self, parameter_s=''):
+        """Print the definition header for any callable object.
+
+        If the object is a class, print the constructor information."""
+        self._inspect('pdef',parameter_s)
+        
+    def magic_pdoc(self, parameter_s=''):
+        """Print the docstring for an object.
+
+        If the given object is a class, it will print both the class and the
+        constructor docstrings."""
+        self._inspect('pdoc',parameter_s)
+
+    def magic_psource(self, parameter_s=''):
+        """Print (or run through pager) the source code for an object."""
+        self._inspect('psource',parameter_s)
+
+    def magic_pfile(self, parameter_s=''):
+        """Print (or run through pager) the file where an object is defined.
+
+        The file opens at the line where the object definition begins. IPython
+        will honor the environment variable PAGER if set, and otherwise will
+        do its best to print the file in a convenient form.
+
+        If the given argument is not an object currently defined, IPython will
+        try to interpret it as a filename (automatically adding a .py extension
+        if needed). You can thus use %pfile as a syntax highlighting code
+        viewer."""
+
+        # first interpret argument as an object name
+        out = self._inspect('pfile',parameter_s)
+        # if not, try the input as a filename
+        if out == 'not found':
+            try:
+                filename = get_py_filename(parameter_s)
+            except IOError,msg:
+                print msg
+                return
+            page(self.shell.inspector.format(file(filename).read()))
+            
+    def magic_pinfo(self, parameter_s=''):
+        """Provide detailed information about an object.
+
+        '%pinfo object' is just a synonym for object? or ?object."""
+
+        #print 'pinfo par: <%s>' % parameter_s  # dbg
+
+        # detail_level: 0 -> obj? , 1 -> obj??
+        detail_level = 0
+        # We need to detect if we got called as 'pinfo pinfo foo', which can
+        # happen if the user types 'pinfo foo?' at the cmd line.
+        pinfo,qmark1,oname,qmark2 = \
+               re.match('(pinfo )?(\?*)(.*?)(\??$)',parameter_s).groups()
+        if pinfo or qmark1 or qmark2:
+            detail_level = 1
+        self._inspect('pinfo',oname,detail_level=detail_level)
+
+    def magic_who_ls(self, parameter_s=''):
+        """Return a sorted list of all interactive variables.
+
+        If arguments are given, only variables of types matching these
+        arguments are returned."""
+
+        user_ns = self.shell.user_ns
+        out = []
+        typelist = parameter_s.split()
+        for i in self.shell.user_ns.keys():
+            if not (i.startswith('_') or i.startswith('_i')) \
+                   and not (self.internal_ns.has_key(i) or
+                            self.user_config_ns.has_key(i)):
+                if typelist:
+                    if type(user_ns[i]).__name__ in typelist:
+                        out.append(i)
+                else:
+                    out.append(i)
+        out.sort()
+        return out
+        
+    def magic_who(self, parameter_s=''):
+        """Print all interactive variables, with some minimal formatting.
+
+        If any arguments are given, only variables whose type matches one of
+        these are printed.  For example:
+
+          %who function str
+
+        will only list functions and strings, excluding all other types of
+        variables.  To find the proper type names, simply use type(var) at a
+        command line to see how python prints type names.  For example:
+
+          In [1]: type('hello')\\
+          Out[1]: <type 'str'>
+
+        indicates that the type name for strings is 'str'.
+
+        %who always excludes executed names loaded through your configuration
+        file and things which are internal to IPython.
+
+        This is deliberate, as typically you may load many modules and the
+        purpose of %who is to show you only what you've manually defined."""
+
+        varlist = self.magic_who_ls(parameter_s)
+        if not varlist:
+            print 'Interactive namespace is empty.'
+            return
+
+        # if we have variables, move on...
+
+        # stupid flushing problem: when prompts have no separators, stdout is
+        # getting lost. I'm starting to think this is a python bug. I'm having
+        # to force a flush with a print because even a sys.stdout.flush
+        # doesn't seem to do anything!
+
+        count = 0
+        for i in varlist:
+            print i+'\t',
+            count += 1
+            if count > 8:
+                count = 0
+                print
+            sys.stdout.flush()  # FIXME. Why the hell isn't this flushing???
+            
+        print # well, this does force a flush at the expense of an extra \n
+
+    def magic_whos(self, parameter_s=''):
+        """Like %who, but gives some extra information about each variable.
+
+        The same type filtering of %who can be applied here.
+
+        For all variables, the type is printed. Additionally it prints:
+        
+          - For {},[],(): their length.
+
+          - For Numeric arrays, a summary with shape, number of elements,
+          typecode and size in memory.
+
+          - Everything else: a string representation, snipping their middle if
+          too long."""
+        
+        varnames = self.magic_who_ls(parameter_s)
+        if not varnames:
+            print 'Interactive namespace is empty.'
+            return
+
+        # if we have variables, move on...
+
+        # for these types, show len() instead of data:
+        seq_types = [types.DictType,types.ListType,types.TupleType]
+
+        # for Numeric arrays, display summary info
+        try:
+            import Numeric
+        except ImportError:
+            array_type = None
+        else:
+            array_type = Numeric.ArrayType.__name__
+        
+        # Find all variable names and types so we can figure out column sizes
+        get_vars = lambda i: self.locals[i]
+        type_name = lambda v: type(v).__name__
+        varlist = map(get_vars,varnames)
+        typelist = map(type_name,varlist)
+        # column labels and # of spaces as separator
+        varlabel = 'Variable'
+        typelabel = 'Type'
+        datalabel = 'Data/Info'
+        colsep = 3
+        # variable format strings
+        vformat    = "$vname.ljust(varwidth)$vtype.ljust(typewidth)"
+        vfmt_short = '$vstr[:25]<...>$vstr[-25:]'
+        aformat    = "%s: %s elems, type `%s`, %s bytes"
+        # find the size of the columns to format the output nicely
+        varwidth = max(max(map(len,varnames)), len(varlabel)) + colsep
+        typewidth = max(max(map(len,typelist)), len(typelabel)) + colsep
+        # table header
+        print varlabel.ljust(varwidth) + typelabel.ljust(typewidth) + \
+              ' '+datalabel+'\n' + '-'*(varwidth+typewidth+len(datalabel)+1)
+        # and the table itself
+        kb = 1024
+        Mb = 1048576  # kb**2
+        for vname,var,vtype in zip(varnames,varlist,typelist):
+            print itpl(vformat),
+            if vtype in seq_types:
+                print len(var)
+            elif vtype==array_type:
+                vshape = str(var.shape).replace(',','').replace(' ','x')[1:-1]
+                vsize  = Numeric.size(var)
+                vbytes = vsize*var.itemsize()
+                if vbytes < 100000:
+                    print aformat % (vshape,vsize,var.typecode(),vbytes)
+                else:
+                    print aformat % (vshape,vsize,var.typecode(),vbytes),
+                    if vbytes < Mb:
+                        print '(%s kb)' % (vbytes/kb,)
+                    else:
+                        print '(%s Mb)' % (vbytes/Mb,)
+            else:
+                vstr = str(var)
+                if len(vstr) < 50:
+                    print vstr
+                else:
+                    printpl(vfmt_short)
+                
+    def magic_reset(self, parameter_s=''):
+        """Resets the namespace by removing all names defined by the user.
+
+        Input/Output history are left around in case you need them."""
+
+        ans = raw_input(
+          "Once deleted, variables cannot be recovered. Proceed (y/n)? ")
+        if not ans.lower() == 'y':
+            print 'Nothing done.'
+            return
+        for i in self.magic_who_ls():
+            del(self.locals[i])
+
+    def magic_config(self,parameter_s=''):
+        """Show IPython's internal configuration."""
+        
+        page('Current configuration structure:\n'+
+             pformat(self.shell.rc.dict()))
+
+    def magic_logstart(self,parameter_s=''):
+        """Start logging anywhere in a session.
+
+        %logstart [log_name [log_mode]]
+
+        If no name is given, it defaults to a file named 'ipython.log' in your
+        current directory, in 'rotate' mode (see below).
+
+        '%logstart name' saves to file 'name' in 'backup' mode.  It saves your
+        history up to that point and then continues logging.
+
+        %logstart takes a second optional parameter: logging mode. This can be one
+        of (note that the modes are given unquoted):\\
+          over: overwrite existing log.\\
+          backup: rename (if exists) to name~ and start name.\\
+          append: well, that says it.\\
+          rotate: create rotating logs name.1~, name.2~, etc.
+        """
+
+        #FIXME. This function should all be moved to the Logger class.
+        
+        valid_modes = qw('over backup append rotate')
+        if self.LOG:
+            print 'Logging is already in place. Logfile:',self.LOG
+            return
+
+        par = parameter_s.strip()
+        if not par:
+            logname = self.LOGDEF
+            logmode = 'rotate'  # use rotate for the auto-generated logs
+        else:
+            try:
+                logname,logmode = par.split()
+            except:
+                try:
+                    logname = par
+                    logmode = 'backup'
+                except:
+                    warn('Usage: %log [log_name [log_mode]]')
+                    return
+        if not logmode in valid_modes:
+            warn('Logging NOT activated.\n'
+                 'Usage: %log [log_name [log_mode]]\n'
+                 'Valid modes: '+str(valid_modes))
+            return
+
+        # If we made it this far, I think we're ok:
+        print 'Activating auto-logging.'
+        print 'Current session state plus future input saved to:',logname
+        print 'Logging mode: ',logmode
+        # put logname into rc struct as if it had been called on the command line,
+        # so it ends up saved in the log header
+        # Save it in case we need to restore it...
+        old_logfile = self.shell.rc.opts.get('logfile','')  
+        logname = os.path.expanduser(logname)
+        self.shell.rc.opts.logfile = logname
+        self.LOGMODE = logmode  # FIXME: this should be set through a function.
+        try:
+            header = str(self.LOGHEAD)
+            self.create_log(header,logname)
+            self.logstart(header,logname)
+        except:
+            self.LOG = ''  # we are NOT logging, something went wrong
+            self.shell.rc.opts.logfile = old_logfile
+            warn("Couldn't start log: "+str(sys.exc_info()[1]))
+        else:  # log input history up to this point
+            self.logfile.write(self.shell.user_ns['_ih'][1:])
+            self.logfile.flush()
+        
+    def magic_logoff(self,parameter_s=''):
+        """Temporarily stop logging.
+
+        You must have previously started logging."""
+        self.switch_log(0)
+        
+    def magic_logon(self,parameter_s=''):
+        """Restart logging.
+
+        This function is for restarting logging which you've temporarily
+        stopped with %logoff. For starting logging for the first time, you
+        must use the %logstart function, which allows you to specify an
+        optional log filename."""
+        
+        self.switch_log(1)
+    
+    def magic_logstate(self,parameter_s=''):
+        """Print the status of the logging system."""
+
+        self.logstate()
+        
+    def magic_pdb(self, parameter_s=''):
+        """Control the calling of the pdb interactive debugger.
+
+        Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
+        argument it works as a toggle.
+
+        When an exception is triggered, IPython can optionally call the
+        interactive pdb debugger after the traceback printout. %pdb toggles
+        this feature on and off."""
+
+        par = parameter_s.strip().lower()
+
+        if par:
+            try:
+                pdb = {'off':0,'0':0,'on':1,'1':1}[par]
+            except KeyError:
+                print 'Incorrect argument. Use on/1, off/0 or nothing for a toggle.'
+                return
+            else:
+               self.shell.InteractiveTB.call_pdb = pdb 
+        else:
+            self.shell.InteractiveTB.call_pdb = 1 - self.shell.InteractiveTB.call_pdb
+        print 'Automatic pdb calling has been turned',\
+              on_off(self.shell.InteractiveTB.call_pdb)
+
+
+    def magic_prun(self, parameter_s ='',user_mode=1,
+                   opts=None,arg_lst=None,prog_ns=None):
+
+        """Run a statement through the python code profiler.
+
+        Usage:\\
+          %prun [options] statement
+
+        The given statement (which doesn't require quote marks) is run via the
+        python profiler in a manner similar to the profile.run() function.
+        Namespaces are internally managed to work correctly; profile.run
+        cannot be used in IPython because it makes certain assumptions about
+        namespaces which do not hold under IPython.
+
+        Options:
+
+        -l <limit>: you can place restrictions on what or how much of the
+        profile gets printed. The limit value can be:
+
+          * A string: only information for function names containing this string
+          is printed.
+
+          * An integer: only these many lines are printed.
+
+          * A float (between 0 and 1): this fraction of the report is printed
+          (for example, use a limit of 0.4 to see the topmost 40% only).
+
+        You can combine several limits with repeated use of the option. For
+        example, '-l __init__ -l 5' will print only the topmost 5 lines of
+        information about class constructors.
+
+        -r: return the pstats.Stats object generated by the profiling. This
+        object has all the information about the profile in it, and you can
+        later use it for further analysis or in other functions.
+
+        Since magic functions have a particular form of calling which prevents
+        you from writing something like:\\
+          In [1]: p = %prun -r print 4  # invalid!\\
+        you must instead use IPython's automatic variables to assign this:\\
+          In [1]: %prun -r print 4  \\
+          Out[1]: <pstats.Stats instance at 0x8222cec>\\
+          In [2]: stats = _
+
+        If you really need to assign this value via an explicit function call,
+        you can always tap directly into the true name of the magic function
+        by using the ipmagic function (which IPython automatically adds to the
+        builtins):\\
+          In [3]: stats = ipmagic('prun','-r print 4')
+
+        You can type ipmagic? for more details on ipmagic.
+
+       -s <key>: sort profile by given key. You can provide more than one key
+        by using the option several times: '-s key1 -s key2 -s key3...'. The
+        default sorting key is 'time'.
+
+        The following is copied verbatim from the profile documentation
+        referenced below:
+
+        When more than one key is provided, additional keys are used as
+        secondary criteria when the there is equality in all keys selected
+        before them.
+        
+        Abbreviations can be used for any key names, as long as the
+        abbreviation is unambiguous.  The following are the keys currently
+        defined:
+
+                Valid Arg       Meaning\\
+                  "calls"      call count\\
+                  "cumulative" cumulative time\\
+                  "file"       file name\\
+                  "module"     file name\\
+                  "pcalls"     primitive call count\\
+                  "line"       line number\\
+                  "name"       function name\\
+                  "nfl"        name/file/line\\
+                  "stdname"    standard name\\
+                  "time"       internal time
+
+        Note that all sorts on statistics are in descending order (placing
+        most time consuming items first), where as name, file, and line number
+        searches are in ascending order (i.e., alphabetical). The subtle
+        distinction between "nfl" and "stdname" is that the standard name is a
+        sort of the name as printed, which means that the embedded line
+        numbers get compared in an odd way.  For example, lines 3, 20, and 40
+        would (if the file names were the same) appear in the string order
+        "20" "3" and "40".  In contrast, "nfl" does a numeric compare of the
+        line numbers.  In fact, sort_stats("nfl") is the same as
+        sort_stats("name", "file", "line").
+
+        -T <filename>: save profile results as shown on screen to a text
+        file. The profile is still shown on screen.
+
+        -D <filename>: save (via dump_stats) profile statistics to given
+        filename. This data is in a format understod by the pstats module, and
+        is generated by a call to the dump_stats() method of profile
+        objects. The profile is still shown on screen.
+
+        If you want to run complete programs under the profiler's control, use
+        '%run -p [prof_opts] filename.py [args to program]' where prof_opts
+        contains profiler specific options as described here.
+        
+        You can read the complete documentation for the profile module with:\\
+          In [1]: import profile; profile.help() """
+
+        opts_def = Struct(D=[''],l=[],s=['time'],T=[''])
+        # protect user quote marks
+        parameter_s = parameter_s.replace('"',r'\"').replace("'",r"\'")
+        
+        if user_mode:  # regular user call
+            opts,arg_str = self.parse_options(parameter_s,'D:l:rs:T:',
+                                              list_all=1)
+            namespace = self.shell.user_ns
+        else:  # called to run a program by %run -p
+            try:
+                filename = get_py_filename(arg_lst[0])
+            except IOError,msg:
+                error(msg)
+                return
+
+            arg_str = 'execfile(filename,prog_ns)'
+            namespace = locals()
+
+        opts.merge(opts_def)
+        
+        prof = profile.Profile()
+        try:
+            prof = prof.runctx(arg_str,namespace,namespace)
+            sys_exit = ''
+        except SystemExit:
+            sys_exit = """*** SystemExit exception caught in code being profiled."""
+
+        stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
+
+        lims = opts.l
+        if lims:
+            lims = []  # rebuild lims with ints/floats/strings
+            for lim in opts.l:
+                try:
+                    lims.append(int(lim))
+                except ValueError:
+                    try:
+                        lims.append(float(lim))
+                    except ValueError:
+                        lims.append(lim)
+                    
+        # trap output
+        sys_stdout = sys.stdout
+        stdout_trap = StringIO()
+        try:
+            sys.stdout = stdout_trap
+            stats.print_stats(*lims)
+        finally:
+            sys.stdout = sys_stdout
+        output = stdout_trap.getvalue()
+        output = output.rstrip()
+
+        page(output,screen_lines=self.shell.rc.screen_length)
+        print sys_exit,
+
+        dump_file = opts.D[0]
+        text_file = opts.T[0]
+        if dump_file:
+            prof.dump_stats(dump_file)
+            print '\n*** Profile stats marshalled to file',\
+                  `dump_file`+'.',sys_exit
+        if text_file:
+            file(text_file,'w').write(output)
+            print '\n*** Profile printout saved to text file',\
+                  `text_file`+'.',sys_exit
+
+        if opts.has_key('r'):
+            return stats
+        else:
+            return None
+
+    def magic_run(self, parameter_s ='',runner=None):
+        """Run the named file inside IPython as a program.
+
+        Usage:\\
+          %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options]] file [args]
+
+        Parameters after the filename are passed as command-line arguments to
+        the program (put in sys.argv). Then, control returns to IPython's
+        prompt.
+
+        This is similar to running at a system prompt:\\
+          $ python file args\\
+        but with the advantage of giving you IPython's tracebacks, and of
+        loading all variables into your interactive namespace for further use
+        (unless -p is used, see below).
+
+        The file is executed in a namespace initially consisting only of
+        __name__=='__main__' and sys.argv constructed as indicated. It thus
+        sees its environment as if it were being run as a stand-alone
+        program. But after execution, the IPython interactive namespace gets
+        updated with all variables defined in the program (except for __name__
+        and sys.argv). This allows for very convenient loading of code for
+        interactive work, while giving each program a 'clean sheet' to run in.
+
+        Options:
+        
+        -n: __name__ is NOT set to '__main__', but to the running file's name
+        without extension (as python does under import).  This allows running
+        scripts and reloading the definitions in them without calling code
+        protected by an ' if __name__ == "__main__" ' clause.
+
+        -i: run the file in IPython's namespace instead of an empty one. This
+        is useful if you are experimenting with code written in a text editor
+        which depends on variables defined interactively.
+
+        -e: ignore sys.exit() calls or SystemExit exceptions in the script
+        being run.  This is particularly useful if IPython is being used to
+        run unittests, which always exit with a sys.exit() call.  In such
+        cases you are interested in the output of the test results, not in
+        seeing a traceback of the unittest module.
+
+        -t: print timing information at the end of the run.  IPython will give
+        you an estimated CPU time consumption for your script, which under
+        Unix uses the resource module to avoid the wraparound problems of
+        time.clock().  Under Unix, an estimate of time spent on system tasks
+        is also given (for Windows platforms this is reported as 0.0).
+
+        If -t is given, an additional -N<N> option can be given, where <N>
+        must be an integer indicating how many times you want the script to
+        run.  The final timing report will include total and per run results.
+
+        For example (testing the script uniq_stable.py):
+
+            In [1]: run -t uniq_stable
+
+            IPython CPU timings (estimated):\\
+              User  :    0.19597 s.\\
+              System:        0.0 s.\\
+
+            In [2]: run -t -N5 uniq_stable
+
+            IPython CPU timings (estimated):\\
+            Total runs performed: 5\\
+              Times :      Total       Per run\\
+              User  :   0.910862 s,  0.1821724 s.\\
+              System:        0.0 s,        0.0 s.
+
+        -d: run your program under the control of pdb, the Python debugger.
+        This allows you to execute your program step by step, watch variables,
+        etc.  Internally, what IPython does is similar to calling:
+        
+          pdb.run('execfile("YOURFILENAME")')
+
+        with a breakpoint set on line 1 of your file.  You can change the line
+        number for this automatic breakpoint to be <N> by using the -bN option
+        (where N must be an integer).  For example:
+
+          %run -d -b40 myscript
+
+        will set the first breakpoint at line 40 in myscript.py.  Note that
+        the first breakpoint must be set on a line which actually does
+        something (not a comment or docstring) for it to stop execution.
+
+        When the pdb debugger starts, you will see a (Pdb) prompt.  You must
+        first enter 'c' (without qoutes) to start execution up to the first
+        breakpoint.
+
+        Entering 'help' gives information about the use of the debugger.  You
+        can easily see pdb's full documentation with "import pdb;pdb.help()"
+        at a prompt.
+
+        -p: run program under the control of the Python profiler module (which
+        prints a detailed report of execution times, function calls, etc).
+
+        You can pass other options after -p which affect the behavior of the
+        profiler itself. See the docs for %prun for details.
+
+        In this mode, the program's variables do NOT propagate back to the
+        IPython interactive namespace (because they remain in the namespace
+        where the profiler executes them).
+
+        Internally this triggers a call to %prun, see its documentation for
+        details on the options available specifically for profiling."""
+
+        # get arguments and set sys.argv for program to be run.
+        opts,arg_lst = self.parse_options(parameter_s,'nidtN:b:pD:l:rs:T:e',
+                                          mode='list',list_all=1)
+
+        try:
+            filename = get_py_filename(arg_lst[0])
+        except IndexError:
+            warn('you must provide at least a filename.')
+            print '\n%run:\n',OInspect.getdoc(self.magic_run)
+            return
+        except IOError,msg:
+            error(msg)
+            return
+
+        # Control the response to exit() calls made by the script being run
+        exit_ignore = opts.has_key('e')
+        
+        # Make sure that the running script gets a proper sys.argv as if it
+        # were run from a system shell.
+        save_argv = sys.argv # save it for later restoring
+        sys.argv = [filename]+ arg_lst[1:]  # put in the proper filename
+
+        if opts.has_key('i'):
+            prog_ns = self.shell.user_ns
+            __name__save = self.shell.user_ns['__name__']
+            prog_ns['__name__'] = '__main__'
+        else:
+            if opts.has_key('n'):
+                name = os.path.splitext(os.path.basename(filename))[0]
+            else:
+                name = '__main__'
+            prog_ns = {'__name__':name}
+
+        # pickle fix.  See iplib for an explanation
+        sys.modules[prog_ns['__name__']] = FakeModule(prog_ns)
+        
+        stats = None
+        try:
+            if opts.has_key('p'):
+                stats = self.magic_prun('',0,opts,arg_lst,prog_ns)
+            else:
+                if opts.has_key('d'):
+                    deb = pdb.Pdb()
+                    # reset Breakpoint state, which is moronically kept
+                    # in a class
+                    bdb.Breakpoint.next = 1
+                    bdb.Breakpoint.bplist = {}
+                    bdb.Breakpoint.bpbynumber = [None]
+                    # Set an initial breakpoint to stop execution
+                    maxtries = 10
+                    bp = int(opts.get('b',[1])[0])
+                    checkline = deb.checkline(filename,bp)
+                    if not checkline:
+                        for bp in range(bp+1,bp+maxtries+1):
+                            if deb.checkline(filename,bp):
+                                break
+                        else:
+                            msg = ("\nI failed to find a valid line to set "
+                                   "a breakpoint\n"
+                                   "after trying up to line: %s.\n"
+                                   "Please set a valid breakpoint manually "
+                                   "with the -b option." % bp)
+                            error(msg)
+                            return
+                    # if we find a good linenumber, set the breakpoint
+                    deb.do_break('%s:%s' % (filename,bp))
+                    # Start file run
+                    print "NOTE: Enter 'c' at the",
+                    print "(Pdb) prompt to start your script."
+                    deb.run('execfile("%s")' % filename,prog_ns)
+                else:
+                    if runner is None:
+                        runner = self.shell.safe_execfile
+                    if opts.has_key('t'):
+                        try:
+                            nruns = int(opts['N'][0])
+                            if nruns < 1:
+                                error('Number of runs must be >=1')
+                                return
+                        except (KeyError):
+                            nruns = 1
+                        if nruns == 1:
+                            t0 = clock2()
+                            runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore)
+                            t1 = clock2()
+                            t_usr = t1[0]-t0[0]
+                            t_sys = t1[1]-t1[1]
+                            print "\nIPython CPU timings (estimated):"
+                            print "  User  : %10s s." % t_usr
+                            print "  System: %10s s." % t_sys
+                        else:
+                            runs = range(nruns)
+                            t0 = clock2()
+                            for nr in runs:
+                                runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore)
+                            t1 = clock2()
+                            t_usr = t1[0]-t0[0]
+                            t_sys = t1[1]-t1[1]
+                            print "\nIPython CPU timings (estimated):"
+                            print "Total runs performed:",nruns
+                            print "  Times : %10s    %10s" % ('Total','Per run')
+                            print "  User  : %10s s, %10s s." % (t_usr,t_usr/nruns)
+                            print "  System: %10s s, %10s s." % (t_sys,t_sys/nruns)
+                            
+                    else:
+                        runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore)
+                if opts.has_key('i'):
+                    self.shell.user_ns['__name__'] = __name__save
+                else:
+                    # update IPython interactive namespace
+                    del prog_ns['__name__']
+                    self.shell.user_ns.update(prog_ns)
+        finally:
+            sys.argv = save_argv
+        return stats
+
+    def magic_runlog(self, parameter_s =''):
+        """Run files as logs.
+
+        Usage:\\
+          %runlog file1 file2 ...
+
+        Run the named files (treating them as log files) in sequence inside
+        the interpreter, and return to the prompt.  This is much slower than
+        %run because each line is executed in a try/except block, but it
+        allows running files with syntax errors in them.
+
+        Normally IPython will guess when a file is one of its own logfiles, so
+        you can typically use %run even for logs. This shorthand allows you to
+        force any file to be treated as a log file."""
+
+        for f in parameter_s.split():
+            self.shell.safe_execfile(f,self.shell.user_ns,
+                                     self.shell.user_ns,islog=1)
+
+    def magic_time(self,parameter_s = ''):
+        """Time execution of a Python statement or expression.
+
+        The CPU and wall clock times are printed, and the value of the
+        expression (if any) is returned.  Note that under Win32, system time
+        is always reported as 0, since it can not be measured.
+
+        This function provides very basic timing functionality.  In Python
+        2.3, the timeit module offers more control and sophistication, but for
+        now IPython supports Python 2.2, so we can not rely on timeit being
+        present.
+        
+        Some examples:
+
+          In [1]: time 2**128
+          CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
+          Wall time: 0.00
+          Out[1]: 340282366920938463463374607431768211456L
+
+          In [2]: n = 1000000
+
+          In [3]: time sum(range(n))
+          CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
+          Wall time: 1.37
+          Out[3]: 499999500000L
+
+          In [4]: time print 'hello world'
+          hello world
+          CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
+          Wall time: 0.00
+          """
+        
+        # fail immediately if the given expression can't be compiled
+        try:
+            mode = 'eval'
+            code = compile(parameter_s,'<timed eval>',mode)
+        except SyntaxError:
+            mode = 'exec'
+            code = compile(parameter_s,'<timed exec>',mode)
+        # skew measurement as little as possible
+        glob = self.shell.user_ns
+        clk = clock2
+        wtime = time.time
+        # time execution
+        wall_st = wtime()
+        if mode=='eval':
+            st = clk()
+            out = eval(code,glob)
+            end = clk()
+        else:
+            st = clk()
+            exec code in glob
+            end = clk()
+            out = None
+        wall_end = wtime()
+        # Compute actual times and report
+        wall_time = wall_end-wall_st
+        cpu_user = end[0]-st[0]
+        cpu_sys = end[1]-st[1]
+        cpu_tot = cpu_user+cpu_sys
+        print "CPU times: user %.2f s, sys: %.2f s, total: %.2f s" % \
+              (cpu_user,cpu_sys,cpu_tot)
+        print "Wall time: %.2f" % wall_time
+        return out
+
+    def magic_macro(self,parameter_s = ''):
+        """Define a set of input lines as a macro for future re-execution.
+
+        Usage:\\
+          %macro name n1:n2 n3:n4 ... n5 .. n6 ...
+
+        This will define a global variable called `name` which is a string
+        made of joining the slices and lines you specify (n1,n2,... numbers
+        above) from your input history into a single string. This variable
+        acts like an automatic function which re-executes those lines as if
+        you had typed them. You just type 'name' at the prompt and the code
+        executes.
+
+        Note that the slices use the standard Python slicing notation (5:8
+        means include lines numbered 5,6,7).
+
+        For example, if your history contains (%hist prints it):
+        
+          44: x=1\\
+          45: y=3\\
+          46: z=x+y\\
+          47: print x\\
+          48: a=5\\
+          49: print 'x',x,'y',y\\
+
+        you can create a macro with lines 44 through 47 (included) and line 49
+        called my_macro with:
+
+          In [51]: %macro my_macro 44:48 49
+
+        Now, typing `my_macro` (without quotes) will re-execute all this code
+        in one pass.
+
+        You don't need to give the line-numbers in order, and any given line
+        number can appear multiple times. You can assemble macros with any
+        lines from your input history in any order.
+
+        The macro is a simple object which holds its value in an attribute,
+        but IPython's display system checks for macros and executes them as
+        code instead of printing them when you type their name.
+
+        You can view a macro's contents by explicitly printing it with:
+        
+          'print macro_name'.
+
+        For one-off cases which DON'T contain magic function calls in them you
+        can obtain similar results by explicitly executing slices from your
+        input history with:
+
+          In [60]: exec In[44:48]+In[49]"""
+
+        args = parameter_s.split()
+        name,ranges = args[0], args[1:]
+        #print 'rng',ranges  # dbg
+        cmds = self.extract_input_slices(ranges)
+        macro = Macro(cmds)
+        self.shell.user_ns.update({name:macro})
+        print 'Macro `%s` created. To execute, type its name (without quotes).' % name
+        print 'Macro contents:'
+        print str(macro).rstrip(),
+
+    def magic_save(self,parameter_s = ''):
+        """Save a set of lines to a given filename.
+
+        Usage:\\
+          %save filename n1:n2 n3:n4 ... n5 .. n6 ...
+
+        This function uses the same syntax as %macro for line extraction, but
+        instead of creating a macro it saves the resulting string to the
+        filename you specify.
+
+        It adds a '.py' extension to the file if you don't do so yourself, and
+        it asks for confirmation before overwriting existing files."""
+
+        args = parameter_s.split()
+        fname,ranges = args[0], args[1:]
+        if not fname.endswith('.py'):
+            fname += '.py'
+        if os.path.isfile(fname):
+            ans = raw_input('File `%s` exists. Overwrite (y/[N])? ' % fname)
+            if ans.lower() not in ['y','yes']:
+                print 'Operation cancelled.'
+                return
+        cmds = ''.join(self.extract_input_slices(ranges))
+        f = file(fname,'w')
+        f.write(cmds)
+        f.close()
+        print 'The following commands were written to file `%s`:' % fname
+        print cmds
+
+    def magic_ed(self,parameter_s = ''):
+        """Alias to %edit."""
+        return self.magic_edit(parameter_s)
+
+    def magic_edit(self,parameter_s = '',last_call=['','']):
+        """Bring up an editor and execute the resulting code.
+
+        Usage:
+          %edit [options] [args]
+
+        %edit runs IPython's editor hook.  The default version of this hook is
+        set to call the __IPYTHON__.rc.editor command.  This is read from your
+        environment variable $EDITOR.  If this isn't found, it will default to
+        vi under Linux/Unix and to notepad under Windows.  See the end of this
+        docstring for how to change the editor hook.
+
+        You can also set the value of this editor via the command line option
+        '-editor' or in your ipythonrc file. This is useful if you wish to use
+        specifically for IPython an editor different from your typical default
+        (and for Windows users who typically don't set environment variables).
+
+        This command allows you to conveniently edit multi-line code right in
+        your IPython session.
+        
+        If called without arguments, %edit opens up an empty editor with a
+        temporary file and will execute the contents of this file when you
+        close it (don't forget to save it!).
+
+        Options:
+
+        -p: this will call the editor with the same data as the previous time
+        it was used, regardless of how long ago (in your current session) it
+        was.
+
+        -x: do not execute the edited code immediately upon exit. This is
+        mainly useful if you are editing programs which need to be called with
+        command line arguments, which you can then do using %run.
+
+        Arguments:
+
+        If arguments are given, the following possibilites exist:
+
+        - The arguments are numbers or pairs of colon-separated numbers (like
+        1 4:8 9). These are interpreted as lines of previous input to be
+        loaded into the editor. The syntax is the same of the %macro command.
+
+        - If the argument doesn't start with a number, it is evaluated as a
+        variable and its contents loaded into the editor. You can thus edit
+        any string which contains python code (including the result of
+        previous edits).
+
+        - If the argument is the name of an object (other than a string),
+        IPython will try to locate the file where it was defined and open the
+        editor at the point where it is defined. You can use `%edit function`
+        to load an editor exactly at the point where 'function' is defined,
+        edit it and have the file be executed automatically.
+
+        Note: opening at an exact line is only supported under Unix, and some
+        editors (like kedit and gedit up to Gnome 2.8) do not understand the
+        '+NUMBER' parameter necessary for this feature. Good editors like
+        (X)Emacs, vi, jed, pico and joe all do.
+
+        - If the argument is not found as a variable, IPython will look for a
+        file with that name (adding .py if necessary) and load it into the
+        editor. It will execute its contents with execfile() when you exit,
+        loading any code in the file into your interactive namespace.
+
+        After executing your code, %edit will return as output the code you
+        typed in the editor (except when it was an existing file). This way
+        you can reload the code in further invocations of %edit as a variable,
+        via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
+        the output.
+
+        Note that %edit is also available through the alias %ed.
+
+        This is an example of creating a simple function inside the editor and
+        then modifying it. First, start up the editor:
+
+        In [1]: ed\\
+        Editing... done. Executing edited code...\\
+        Out[1]: 'def foo():\\n    print "foo() was defined in an editing session"\\n'
+
+        We can then call the function foo():
+        
+        In [2]: foo()\\
+        foo() was defined in an editing session
+
+        Now we edit foo.  IPython automatically loads the editor with the
+        (temporary) file where foo() was previously defined:
+        
+        In [3]: ed foo\\
+        Editing... done. Executing edited code...
+
+        And if we call foo() again we get the modified version:
+        
+        In [4]: foo()\\
+        foo() has now been changed!
+
+        Here is an example of how to edit a code snippet successive
+        times. First we call the editor:
+
+        In [8]: ed\\
+        Editing... done. Executing edited code...\\
+        hello\\
+        Out[8]: "print 'hello'\\n"
+
+        Now we call it again with the previous output (stored in _):
+
+        In [9]: ed _\\
+        Editing... done. Executing edited code...\\
+        hello world\\
+        Out[9]: "print 'hello world'\\n"
+
+        Now we call it with the output #8 (stored in _8, also as Out[8]):
+
+        In [10]: ed _8\\
+        Editing... done. Executing edited code...\\
+        hello again\\
+        Out[10]: "print 'hello again'\\n"
+
+
+        Changing the default editor hook:
+
+        If you wish to write your own editor hook, you can put it in a
+        configuration file which you load at startup time.  The default hook
+        is defined in the IPython.hooks module, and you can use that as a
+        starting example for further modifications.  That file also has
+        general instructions on how to set a new hook for use once you've
+        defined it."""
+        
+        # FIXME: This function has become a convoluted mess.  It needs a
+        # ground-up rewrite with clean, simple logic.
+
+        def make_filename(arg):
+            "Make a filename from the given args"
+            try:
+                filename = get_py_filename(arg)
+            except IOError:
+                if args.endswith('.py'):
+                    filename = arg
+                else:
+                    filename = None
+            return filename
+
+        # custom exceptions
+        class DataIsObject(Exception): pass
+
+        opts,args = self.parse_options(parameter_s,'px')
+
+        # Default line number value
+        lineno = None
+        if opts.has_key('p'):
+            args = '_%s' % last_call[0]
+            if not self.shell.user_ns.has_key(args):
+                args = last_call[1]
+            
+        # use last_call to remember the state of the previous call, but don't
+        # let it be clobbered by successive '-p' calls.
+        try:
+            last_call[0] = self.shell.outputcache.prompt_count
+            if not opts.has_key('p'):
+                last_call[1] = parameter_s
+        except:
+            pass
+
+        # by default this is done with temp files, except when the given
+        # arg is a filename
+        use_temp = 1
+
+        if re.match(r'\d',args):
+            # Mode where user specifies ranges of lines, like in %macro.
+            # This means that you can't edit files whose names begin with
+            # numbers this way. Tough.
+            ranges = args.split()
+            data = ''.join(self.extract_input_slices(ranges))
+        elif args.endswith('.py'):
+            filename = make_filename(args)
+            data = ''
+            use_temp = 0
+        elif args:
+            try:
+                # Load the parameter given as a variable. If not a string,
+                # process it as an object instead (below)
+
+                #print '*** args',args,'type',type(args)  # dbg
+                data = eval(args,self.shell.user_ns)
+                if not type(data) in StringTypes:
+                    raise DataIsObject
+            except (NameError,SyntaxError):
+                # given argument is not a variable, try as a filename
+                filename = make_filename(args)
+                if filename is None:
+                    warn("Argument given (%s) can't be found as a variable "
+                         "or as a filename." % args)
+                    return
+                data = ''
+                use_temp = 0
+            except DataIsObject:
+                # For objects, try to edit the file where they are defined
+                try:
+                    filename = inspect.getabsfile(data)
+                    datafile = 1
+                except TypeError:
+                    filename = make_filename(args)
+                    datafile = 1
+                    warn('Could not find file where `%s` is defined.\n'
+                         'Opening a file named `%s`' % (args,filename))
+                # Now, make sure we can actually read the source (if it was in
+                # a temp file it's gone by now).
+                if datafile:
+                    try:
+                        lineno = inspect.getsourcelines(data)[1]
+                    except IOError:
+                        filename = make_filename(args)
+                        if filename is None:
+                            warn('The file `%s` where `%s` was defined cannot '
+                                 'be read.' % (filename,data))
+                            return
+                use_temp = 0
+        else:
+            data = ''
+
+        if use_temp:
+            filename = tempfile.mktemp('.py')
+            self.shell.tempfiles.append(filename)
+        
+        if data and use_temp:
+            tmp_file = open(filename,'w')
+            tmp_file.write(data)
+            tmp_file.close()
+
+        # do actual editing here
+        print 'Editing...',
+        sys.stdout.flush()
+        self.shell.hooks.editor(filename,lineno)
+        if opts.has_key('x'):  # -x prevents actual execution
+            print
+        else:
+            print 'done. Executing edited code...'
+            try:
+                execfile(filename,self.shell.user_ns)
+            except IOError,msg:
+                if msg.filename == filename:
+                    warn('File not found. Did you forget to save?')
+                    return
+                else:
+                    self.shell.showtraceback()
+            except:
+                self.shell.showtraceback()
+        if use_temp:
+            contents = open(filename).read()
+            return contents
+
+    def magic_xmode(self,parameter_s = ''):
+        """Switch modes for the exception handlers.
+
+        Valid modes: Plain, Context and Verbose.
+
+        If called without arguments, acts as a toggle."""
+
+        new_mode = parameter_s.strip().capitalize()
+        try:
+            self.InteractiveTB.set_mode(mode = new_mode)
+            print 'Exception reporting mode:',self.InteractiveTB.mode
+        except:
+            warn('Error changing exception modes.\n' + str(sys.exc_info()[1]))
+            
+    def magic_colors(self,parameter_s = ''):
+        """Switch color scheme for prompts, info system and exception handlers.
+
+        Currently implemented schemes: NoColor, Linux, LightBG.
+
+        Color scheme names are not case-sensitive."""
+        
+        new_scheme = parameter_s.strip()
+        if not new_scheme:
+            print 'You must specify a color scheme.'
+            return
+        # Under Windows, check for Gary Bishop's readline, which is necessary
+        # for ANSI coloring
+        if os.name in ['nt','dos']:
+            try:
+                import readline
+            except ImportError:
+                has_readline = 0
+            else:
+                try:
+                    readline.GetOutputFile()
+                except AttributeError:
+                    has_readline = 0
+                else:
+                    has_readline = 1
+            if not has_readline:
+                msg = """\
+Proper color support under MS Windows requires Gary Bishop's readline library.
+You can find it at:
+http://sourceforge.net/projects/uncpythontools
+Gary's readline needs the ctypes module, from:
+http://starship.python.net/crew/theller/ctypes
+
+Defaulting color scheme to 'NoColor'"""
+                new_scheme = 'NoColor'
+                warn(msg)
+        
+        # Set prompt colors
+        try:
+            self.shell.outputcache.set_colors(new_scheme)
+        except:
+            warn('Error changing prompt color schemes.\n'
+                 + str(sys.exc_info()[1]))
+        else:
+            self.shell.rc.colors = \
+                       self.shell.outputcache.color_table.active_scheme_name
+        # Set exception colors
+        try:
+            self.shell.InteractiveTB.set_colors(scheme = new_scheme)
+            self.shell.SyntaxTB.set_colors(scheme = new_scheme)
+        except:
+            warn('Error changing exception color schemes.\n'
+                 + str(sys.exc_info()[1]))
+        # Set info (for 'object?') colors
+        if self.shell.rc.color_info:
+            try:
+                self.shell.inspector.set_active_scheme(new_scheme)
+            except:
+                warn('Error changing object inspector color schemes.\n'
+                     + str(sys.exc_info()[1]))
+        else:
+            self.shell.inspector.set_active_scheme('NoColor')
+                
+    def magic_color_info(self,parameter_s = ''):
+        """Toggle color_info.
+
+        The color_info configuration parameter controls whether colors are
+        used for displaying object details (by things like %psource, %pfile or
+        the '?' system). This function toggles this value with each call.
+
+        Note that unless you have a fairly recent pager (less works better
+        than more) in your system, using colored object information displays
+        will not work properly. Test it and see."""
+        
+        self.shell.rc.color_info = 1 - self.shell.rc.color_info
+        self.magic_colors(self.shell.rc.colors)
+        print 'Object introspection functions have now coloring:',
+        print ['OFF','ON'][self.shell.rc.color_info]
+
+    def magic_Pprint(self, parameter_s=''):
+        """Toggle pretty printing on/off."""
+        
+        self.shell.outputcache.Pprint = 1 - self.shell.outputcache.Pprint
+        print 'Pretty printing has been turned', \
+              ['OFF','ON'][self.shell.outputcache.Pprint]
+        
+    def magic_Exit(self, parameter_s=''):
+        """Exit IPython without confirmation."""
+
+        self.shell.exit_now = True
+
+    def magic_Quit(self, parameter_s=''):
+        """Exit IPython without confirmation (like %Exit)."""
+
+        self.shell.exit_now = True
+        
+    #......................................................................
+    # Functions to implement unix shell-type things
+    
+    def magic_alias(self, parameter_s = ''):
+        """Define an alias for a system command.
+
+        '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
+
+        Then, typing 'alias_name params' will execute the system command 'cmd
+        params' (from your underlying operating system).
+
+        Aliases have lower precedence than magic functions and Python normal
+        variables, so if 'foo' is both a Python variable and an alias, the
+        alias can not be executed until 'del foo' removes the Python variable.
+
+        You can use the %l specifier in an alias definition to represent the
+        whole line when the alias is called.  For example:
+
+          In [2]: alias all echo "Input in brackets: <%l>"\\
+          In [3]: all hello world\\
+          Input in brackets: <hello world>
+
+        You can also define aliases with parameters using %s specifiers (one
+        per parameter):
+        
+          In [1]: alias parts echo first %s second %s\\
+          In [2]: %parts A B\\
+          first A second B\\
+          In [3]: %parts A\\
+          Incorrect number of arguments: 2 expected.\\
+          parts is an alias to: 'echo first %s second %s'
+
+        Note that %l and %s are mutually exclusive.  You can only use one or
+        the other in your aliases.
+
+        Aliases expand Python variables just like system calls using ! or !! 
+        do: all expressions prefixed with '$' get expanded.  For details of
+        the semantic rules, see PEP-215:
+        http://www.python.org/peps/pep-0215.html.  This is the library used by
+        IPython for variable expansion.  If you want to access a true shell
+        variable, an extra $ is necessary to prevent its expansion by IPython:
+
+        In [6]: alias show echo\\
+        In [7]: PATH='A Python string'\\
+        In [8]: show $PATH\\
+        A Python string\\
+        In [9]: show $$PATH\\
+        /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
+
+        You can use the alias facility to acess all of $PATH.  See the %rehash
+        and %rehashx functions, which automatically create aliases for the
+        contents of your $PATH.
+
+        If called with no parameters, %alias prints the current alias table."""
+
+        par = parameter_s.strip()
+        if not par:
+            if self.shell.rc.automagic:
+                prechar = ''
+            else:
+                prechar = self.shell.ESC_MAGIC
+            print 'Alias\t\tSystem Command\n'+'-'*30
+            atab = self.shell.alias_table
+            aliases = atab.keys()
+            aliases.sort()
+            for alias in aliases:
+                print prechar+alias+'\t\t'+atab[alias][1]
+            print '-'*30+'\nTotal number of aliases:',len(aliases)
+            return
+        try:
+            alias,cmd = par.split(None,1)
+        except:
+            print OInspect.getdoc(self.magic_alias)
+        else:
+            nargs = cmd.count('%s')
+            if nargs>0 and cmd.find('%l')>=0:
+                error('The %s and %l specifiers are mutually exclusive '
+                      'in alias definitions.')
+            else:  # all looks OK
+                self.shell.alias_table[alias] = (nargs,cmd)
+                self.shell.alias_table_validate(verbose=1)
+    # end magic_alias
+
+    def magic_unalias(self, parameter_s = ''):
+        """Remove an alias"""
+
+        aname = parameter_s.strip()
+        if aname in self.shell.alias_table:
+            del self.shell.alias_table[aname]
+            
+    def magic_rehash(self, parameter_s = ''):
+        """Update the alias table with all entries in $PATH.
+
+        This version does no checks on execute permissions or whether the
+        contents of $PATH are truly files (instead of directories or something
+        else).  For such a safer (but slower) version, use %rehashx."""
+
+        # This function (and rehashx) manipulate the alias_table directly
+        # rather than calling magic_alias, for speed reasons.  A rehash on a
+        # typical Linux box involves several thousand entries, so efficiency
+        # here is a top concern.
+        
+        path = filter(os.path.isdir,os.environ['PATH'].split(os.pathsep))
+        alias_table = self.shell.alias_table
+        for pdir in path:
+            for ff in os.listdir(pdir):
+                # each entry in the alias table must be (N,name), where
+                # N is the number of positional arguments of the alias.
+                alias_table[ff] = (0,ff)
+        # Make sure the alias table doesn't contain keywords or builtins
+        self.shell.alias_table_validate()
+        # Call again init_auto_alias() so we get 'rm -i' and other modified
+        # aliases since %rehash will probably clobber them
+        self.shell.init_auto_alias()
+
+    def magic_rehashx(self, parameter_s = ''):
+        """Update the alias table with all executable files in $PATH.
+
+        This version explicitly checks that every entry in $PATH is a file
+        with execute access (os.X_OK), so it is much slower than %rehash.
+
+        Under Windows, it checks executability as a match agains a
+        '|'-separated string of extensions, stored in the IPython config
+        variable win_exec_ext.  This defaults to 'exe|com|bat'. """
+        
+        path = filter(os.path.isdir,os.environ['PATH'].split(os.pathsep))
+        alias_table = self.shell.alias_table
+
+        if os.name == 'posix':
+            isexec = lambda fname:os.path.isfile(fname) and \
+                     os.access(fname,os.X_OK)
+        else:
+
+            try:
+                winext = os.environ['pathext'].replace(';','|').replace('.','')
+            except KeyError:
+                winext = 'exe|com|bat'
+    
+            execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
+            isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
+        savedir = os.getcwd()
+        try:
+            # write the whole loop for posix/Windows so we don't have an if in
+            # the innermost part
+            if os.name == 'posix':
+                for pdir in path:
+                    os.chdir(pdir)
+                    for ff in os.listdir(pdir):
+                        if isexec(ff):
+                            # each entry in the alias table must be (N,name),
+                            # where N is the number of positional arguments of the
+                            # alias.
+                            alias_table[ff] = (0,ff)
+            else:
+                for pdir in path:
+                    os.chdir(pdir)
+                    for ff in os.listdir(pdir):
+                        if isexec(ff):
+                            alias_table[execre.sub(r'\1',ff)] = (0,ff)
+            # Make sure the alias table doesn't contain keywords or builtins
+            self.shell.alias_table_validate()
+            # Call again init_auto_alias() so we get 'rm -i' and other
+            # modified aliases since %rehashx will probably clobber them
+            self.shell.init_auto_alias()
+        finally:
+            os.chdir(savedir)
+        
+    def magic_pwd(self, parameter_s = ''):
+        """Return the current working directory path."""
+        return os.getcwd()
+
+    def magic_cd(self, parameter_s=''):
+        """Change the current working directory.
+
+        This command automatically maintains an internal list of directories
+        you visit during your IPython session, in the variable _dh. The
+        command %dhist shows this history nicely formatted.
+
+        Usage:
+
+          cd 'dir': changes to directory 'dir'.
+
+          cd -: changes to the last visited directory.
+
+          cd -<n>: changes to the n-th directory in the directory history.
+
+          cd -b <bookmark_name>: jump to a bookmark set by %bookmark
+             (note: cd <bookmark_name> is enough if there is no
+              directory <bookmark_name>, but a bookmark with the name exists.)
+
+        Options:
+
+        -q: quiet.  Do not print the working directory after the cd command is
+        executed.  By default IPython's cd command does print this directory,
+        since the default prompts do not display path information.
+        
+        Note that !cd doesn't work for this purpose because the shell where
+        !command runs is immediately discarded after executing 'command'."""
+
+        parameter_s = parameter_s.strip()
+        bkms = self.shell.persist.get("bookmarks",{})
+
+        numcd = re.match(r'(-)(\d+)$',parameter_s)
+        # jump in directory history by number
+        if numcd:
+            nn = int(numcd.group(2))
+            try:
+                ps = self.shell.user_ns['_dh'][nn]
+            except IndexError:
+                print 'The requested directory does not exist in history.'
+                return
+            else:
+                opts = {}
+        else:
+            opts,ps = self.parse_options(parameter_s,'qb',mode='string')
+        # jump to previous
+        if ps == '-':
+            try:
+                ps = self.shell.user_ns['_dh'][-2]
+            except IndexError:
+                print 'No previous directory to change to.'
+                return
+        # jump to bookmark
+        elif opts.has_key('b') or (bkms.has_key(ps) and not os.path.isdir(ps)):
+            if bkms.has_key(ps):
+                target = bkms[ps]
+                print '(bookmark:%s) -> %s' % (ps,target)
+                ps = target
+            else:
+                if bkms:
+                    error("Bookmark '%s' not found.  "
+                          "Use '%bookmark -l' to see your bookmarks." % ps)
+                else:
+                    print "Bookmarks not set - use %bookmark <bookmarkname>"
+                return
+            
+        # at this point ps should point to the target dir
+        if ps:
+            try:
+                os.chdir(os.path.expanduser(ps))
+            except OSError:
+                print sys.exc_info()[1]
+            else:
+                self.shell.user_ns['_dh'].append(os.getcwd())
+        else:
+            os.chdir(self.home_dir)
+            self.shell.user_ns['_dh'].append(os.getcwd())
+        if not 'q' in opts:
+            print self.shell.user_ns['_dh'][-1]
+
+    def magic_dhist(self, parameter_s=''):
+        """Print your history of visited directories.
+
+        %dhist       -> print full history\\
+        %dhist n     -> print last n entries only\\
+        %dhist n1 n2 -> print entries between n1 and n2 (n1 not included)\\
+
+        This history is automatically maintained by the %cd command, and
+        always available as the global list variable _dh. You can use %cd -<n>
+        to go to directory number <n>."""
+
+        dh = self.shell.user_ns['_dh']
+        if parameter_s:
+            try:
+                args = map(int,parameter_s.split())
+            except:
+                self.arg_err(Magic.magic_dhist)
+                return
+            if len(args) == 1:
+                ini,fin = max(len(dh)-(args[0]),0),len(dh)
+            elif len(args) == 2:
+                ini,fin = args
+            else:
+                self.arg_err(Magic.magic_dhist)
+                return
+        else:
+            ini,fin = 0,len(dh)
+        nlprint(dh,
+                header = 'Directory history (kept in _dh)',
+                start=ini,stop=fin)
+
+    def magic_env(self, parameter_s=''):
+        """List environment variables."""
+        
+        # environ is an instance of UserDict
+        return os.environ.data
+
+    def magic_pushd(self, parameter_s=''):
+        """Place the current dir on stack and change directory.
+        
+        Usage:\\
+          %pushd ['dirname']
+
+        %pushd with no arguments does a %pushd to your home directory.
+        """
+        if parameter_s == '': parameter_s = '~'
+        if len(self.dir_stack)>0 and os.path.expanduser(parameter_s) != \
+           os.path.expanduser(self.dir_stack[0]):
+            try:
+                self.magic_cd(parameter_s)
+                self.dir_stack.insert(0,os.getcwd().replace(self.home_dir,'~'))
+                self.magic_dirs()
+            except:
+                print 'Invalid directory'
+        else:
+            print 'You are already there!'
+
+    def magic_popd(self, parameter_s=''):
+        """Change to directory popped off the top of the stack.
+        """
+        if len (self.dir_stack) > 1:
+            self.dir_stack.pop(0)
+            self.magic_cd(self.dir_stack[0])
+            print self.dir_stack[0]
+        else:
+            print "You can't remove the starting directory from the stack:",\
+                  self.dir_stack
+
+    def magic_dirs(self, parameter_s=''):
+        """Return the current directory stack."""
+
+        return self.dir_stack[:]
+
+    def magic_sc(self, parameter_s=''):
+        """Shell capture - execute a shell command and capture its output.
+
+        %sc [options] varname=command
+
+        IPython will run the given command using commands.getoutput(), and
+        will then update the user's interactive namespace with a variable
+        called varname, containing the value of the call.  Your command can
+        contain shell wildcards, pipes, etc.
+
+        The '=' sign in the syntax is mandatory, and the variable name you
+        supply must follow Python's standard conventions for valid names.
+
+        Options:
+
+          -l: list output.  Split the output on newlines into a list before
+          assigning it to the given variable.  By default the output is stored
+          as a single string.
+
+          -v: verbose.  Print the contents of the variable.
+
+        In most cases you should not need to split as a list, because the
+        returned value is a special type of string which can automatically
+        provide its contents either as a list (split on newlines) or as a
+        space-separated string.  These are convenient, respectively, either
+        for sequential processing or to be passed to a shell command.
+
+        For example:
+
+            # Capture into variable a
+            In [9]: sc a=ls *py
+
+            # a is a string with embedded newlines
+            In [10]: a
+            Out[10]: 'setup.py\nwin32_manual_post_install.py'
+
+            # which can be seen as a list:
+            In [11]: a.l
+            Out[11]: ['setup.py', 'win32_manual_post_install.py']
+
+            # or as a whitespace-separated string:
+            In [12]: a.s
+            Out[12]: 'setup.py win32_manual_post_install.py'
+
+            # a.s is useful to pass as a single command line:
+            In [13]: !wc -l $a.s
+              146 setup.py
+              130 win32_manual_post_install.py
+              276 total
+
+            # while the list form is useful to loop over:
+            In [14]: for f in a.l:
+               ....:      !wc -l $f
+               ....:
+            146 setup.py
+            130 win32_manual_post_install.py
+
+        Similiarly, the lists returned by the -l option are also special, in
+        the sense that you can equally invoke the .s attribute on them to
+        automatically get a whitespace-separated string from their contents:
+
+            In [1]: sc -l b=ls *py
+
+            In [2]: b
+            Out[2]: ['setup.py', 'win32_manual_post_install.py']
+
+            In [3]: b.s
+            Out[3]: 'setup.py win32_manual_post_install.py'
+
+        In summary, both the lists and strings used for ouptut capture have
+        the following special attributes:
+
+            .l (or .list) : value as list.
+            .n (or .nlstr): value as newline-separated string.
+            .s (or .spstr): value as space-separated string.
+        """
+
+        opts,args = self.parse_options(parameter_s,'lv')
+        # Try to get a variable name and command to run
+        try:
+            # the variable name must be obtained from the parse_options
+            # output, which uses shlex.split to strip options out.
+            var,_ = args.split('=',1)
+            var = var.strip()
+            # But the the command has to be extracted from the original input
+            # parameter_s, not on what parse_options returns, to avoid the
+            # quote stripping which shlex.split performs on it.
+            _,cmd = parameter_s.split('=',1)
+        except ValueError:
+            var,cmd = '',''
+        if not var:
+            error('you must specify a variable to assign the command to.')
+            return
+        # If all looks ok, proceed
+        out,err = self.shell.getoutputerror(cmd)
+        if err:
+            print >> Term.cerr,err
+        if opts.has_key('l'):
+            out = SList(out.split('\n'))
+        else:
+            out = LSString(out)
+        if opts.has_key('v'):
+            print '%s ==\n%s' % (var,pformat(out))
+        self.shell.user_ns.update({var:out})
+
+    def magic_sx(self, parameter_s=''):
+        """Shell execute - run a shell command and capture its output.
+
+        %sx command
+
+        IPython will run the given command using commands.getoutput(), and
+        return the result formatted as a list (split on '\\n').  Since the
+        output is _returned_, it will be stored in ipython's regular output
+        cache Out[N] and in the '_N' automatic variables.
+
+        Notes:
+
+        1) If an input line begins with '!!', then %sx is automatically
+        invoked.  That is, while:
+          !ls
+        causes ipython to simply issue system('ls'), typing
+          !!ls
+        is a shorthand equivalent to:
+          %sx ls
+        
+        2) %sx differs from %sc in that %sx automatically splits into a list,
+        like '%sc -l'.  The reason for this is to make it as easy as possible
+        to process line-oriented shell output via further python commands.
+        %sc is meant to provide much finer control, but requires more
+        typing.
+
+        3) Just like %sc -l, this is a list with special attributes:
+
+          .l (or .list) : value as list.
+          .n (or .nlstr): value as newline-separated string.
+          .s (or .spstr): value as whitespace-separated string.
+
+        This is very useful when trying to use such lists as arguments to
+        system commands."""
+
+        if parameter_s:
+            out,err = self.shell.getoutputerror(parameter_s)
+            if err:
+                print >> Term.cerr,err
+            return SList(out.split('\n'))
+
+    def magic_bg(self, parameter_s=''):
+        """Run a job in the background, in a separate thread.
+
+        For example,
+
+          %bg myfunc(x,y,z=1)
+
+        will execute 'myfunc(x,y,z=1)' in a background thread.  As soon as the
+        execution starts, a message will be printed indicating the job
+        number.  If your job number is 5, you can use
+
+          myvar = jobs.result(5)  or  myvar = jobs[5].result
+
+        to assign this result to variable 'myvar'.
+
+        IPython has a job manager, accessible via the 'jobs' object.  You can
+        type jobs? to get more information about it, and use jobs.<TAB> to see
+        its attributes.  All attributes not starting with an underscore are
+        meant for public use.
+
+        In particular, look at the jobs.new() method, which is used to create
+        new jobs.  This magic %bg function is just a convenience wrapper
+        around jobs.new(), for expression-based jobs.  If you want to create a
+        new job with an explicit function object and arguments, you must call
+        jobs.new() directly.
+
+        The jobs.new docstring also describes in detail several important
+        caveats associated with a thread-based model for background job
+        execution.  Type jobs.new? for details.
+
+        You can check the status of all jobs with jobs.status().
+
+        The jobs variable is set by IPython into the Python builtin namespace.
+        If you ever declare a variable named 'jobs', you will shadow this
+        name.  You can either delete your global jobs variable to regain
+        access to the job manager, or make a new name and assign it manually
+        to the manager (stored in IPython's namespace).  For example, to
+        assign the job manager to the Jobs name, use:
+
+          Jobs = __builtins__.jobs"""
+        
+        self.shell.jobs.new(parameter_s,self.shell.user_ns)
+        
+    def magic_bookmark(self, parameter_s=''):
+        """Manage IPython's bookmark system.
+
+        %bookmark <name>       - set bookmark to current dir
+        %bookmark <name> <dir> - set bookmark to <dir>
+        %bookmark -l           - list all bookmarks
+        %bookmark -d <name>    - remove bookmark
+        %bookmark -r           - remove all bookmarks
+
+        You can later on access a bookmarked folder with:
+          %cd -b <name>
+        or simply '%cd <name>' if there is no directory called <name> AND
+        there is such a bookmark defined.
+
+        Your bookmarks persist through IPython sessions, but they are
+        associated with each profile."""
+
+        opts,args = self.parse_options(parameter_s,'drl',mode='list')
+        if len(args) > 2:
+            error('You can only give at most two arguments')
+            return
+
+        bkms = self.shell.persist.get('bookmarks',{})
+            
+        if opts.has_key('d'):
+            try:
+                todel = args[0]
+            except IndexError:
+                error('You must provide a bookmark to delete')
+            else:
+                try:
+                    del bkms[todel]
+                except:
+                    error("Can't delete bookmark '%s'" % todel)
+        elif opts.has_key('r'):
+            bkms = {}
+        elif opts.has_key('l'):
+            bks = bkms.keys()
+            bks.sort()
+            if bks:
+                size = max(map(len,bks))
+            else:
+                size = 0
+            fmt = '%-'+str(size)+'s -> %s'
+            print 'Current bookmarks:'
+            for bk in bks:
+                print fmt % (bk,bkms[bk])
+        else:
+            if not args:
+                error("You must specify the bookmark name")
+            elif len(args)==1:
+                bkms[args[0]] = os.getcwd()
+            elif len(args)==2:
+                bkms[args[0]] = args[1]
+        self.persist['bookmarks'] = bkms
+# end Magic
diff --git a/IPython/OInspect.py b/IPython/OInspect.py
new file mode 100644
index 0000000..dfe72a1
--- /dev/null
+++ b/IPython/OInspect.py
@@ -0,0 +1,398 @@
+# -*- coding: utf-8 -*-
+"""Tools for inspecting Python objects.
+
+Uses syntax highlighting for presenting the various information elements.
+
+Similar in spirit to the inspect module, but all calls take a name argument to
+reference the name under which an object is being read.
+
+$Id: OInspect.py 575 2005-04-08 14:16:44Z fperez $
+"""
+
+#*****************************************************************************
+#       Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
+#
+#  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
+
+__all__ = ['Inspector','InspectColors']
+
+# stdlib modules
+import inspect,linecache,types,StringIO,string
+
+# IPython's own
+from IPython.Itpl import itpl
+from IPython.genutils import page,indent,Term
+from IPython import PyColorize
+from IPython.ColorANSI import *
+
+#****************************************************************************
+# Builtin color schemes
+
+Colors = TermColors  # just a shorthand
+
+# Build a few color schemes
+NoColor = ColorScheme(
+    'NoColor',{
+    'header' : Colors.NoColor,
+    'normal' : Colors.NoColor  # color off (usu. Colors.Normal)
+    }  )
+
+LinuxColors = ColorScheme(
+    'Linux',{
+    'header' : Colors.LightRed,
+    'normal' : Colors.Normal  # color off (usu. Colors.Normal)
+    } )
+
+LightBGColors = ColorScheme(
+    'LightBG',{
+    'header' : Colors.Red,
+    'normal' : Colors.Normal  # color off (usu. Colors.Normal)
+    }  )
+
+# Build table of color schemes (needed by the parser)
+InspectColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
+                                 'Linux')
+
+#****************************************************************************
+# Auxiliary functions
+def getdoc(obj):
+    """Stable wrapper around inspect.getdoc.
+
+    This can't crash because of attribute problems.
+
+    It also attempts to call a getdoc() method on the given object.  This
+    allows objects which provide their docstrings via non-standard mechanisms
+    (like Pyro proxies) to still be inspected by ipython's ? system."""
+
+    ds = None  # default return value
+    try:
+        ds = inspect.getdoc(obj)
+    except:
+        # Harden against an inspect failure, which can occur with
+        # SWIG-wrapped extensions.
+        pass
+    # Allow objects to offer customized documentation via a getdoc method:
+    try:
+        ds2 = obj.getdoc()
+    except:
+        pass
+    else:
+        # if we get extra info, we add it to the normal docstring.
+        if ds is None:
+            ds = ds2
+        else:
+            ds = '%s\n%s' % (ds,ds2)
+    return ds
+
+#****************************************************************************
+# Class definitions
+
+class myStringIO(StringIO.StringIO):
+    """Adds a writeln method to normal StringIO."""
+    def writeln(self,*arg,**kw):
+        """Does a write() and then a write('\n')"""
+        self.write(*arg,**kw)
+        self.write('\n')
+
+class Inspector:
+    def __init__(self,color_table,code_color_table,scheme):
+        self.color_table = color_table
+        self.parser = PyColorize.Parser(code_color_table,out='str')
+        self.format = self.parser.format
+        self.set_active_scheme(scheme)
+
+    def __getargspec(self,obj):
+        """Get the names and default values of a function's arguments.
+
+        A tuple of four things is returned: (args, varargs, varkw, defaults).
+        'args' is a list of the argument names (it may contain nested lists).
+        'varargs' and 'varkw' are the names of the * and ** arguments or None.
+        'defaults' is an n-tuple of the default values of the last n arguments.
+
+        Modified version of inspect.getargspec from the Python Standard
+        Library."""
+
+        if inspect.isfunction(obj):
+            func_obj = obj
+        elif inspect.ismethod(obj):
+            func_obj = obj.im_func
+        else:
+            raise TypeError, 'arg is not a Python function'
+        args, varargs, varkw = inspect.getargs(func_obj.func_code)
+        return args, varargs, varkw, func_obj.func_defaults
+
+    def __getdef(self,obj,oname=''):
+        """Return the definition header for any callable object.
+
+        If any exception is generated, None is returned instead and the
+        exception is suppressed."""
+        
+        try:
+            return oname + inspect.formatargspec(*self.__getargspec(obj))
+        except:
+            return None
+ 
+    def __head(self,h):
+        """Return a header string with proper colors."""
+        return '%s%s%s' % (self.color_table.active_colors.header,h,
+                           self.color_table.active_colors.normal)
+
+    def set_active_scheme(self,scheme):
+        self.color_table.set_active_scheme(scheme)
+        self.parser.color_table.set_active_scheme(scheme)
+    
+    def noinfo(self,msg,oname):
+        """Generic message when no information is found."""
+        print 'No %s found' % msg,
+        if oname:
+            print 'for %s' % oname
+        else:
+            print
+            
+    def pdef(self,obj,oname=''):
+        """Print the definition header for any callable object.
+
+        If the object is a class, print the constructor information."""
+
+        if not callable(obj):
+            print 'Object is not callable.'
+            return
+
+        header = ''
+        if type(obj) is types.ClassType:
+            header = self.__head('Class constructor information:\n')
+            obj = obj.__init__
+        elif type(obj) is types.InstanceType:
+            obj = obj.__call__
+
+        output = self.__getdef(obj,oname)
+        if output is None:
+            self.noinfo('definition header',oname)
+        else:
+            print >>Term.cout, header,self.format(output),
+
+    def pdoc(self,obj,oname='',formatter = None):
+        """Print the docstring for any object.
+
+        Optional:
+        -formatter: a function to run the docstring through for specially
+        formatted docstrings."""
+        
+        head = self.__head  # so that itpl can find it even if private
+        ds = getdoc(obj)
+        if formatter:
+            ds = formatter(ds)
+        if type(obj) is types.ClassType:
+            init_ds = getdoc(obj.__init__)
+            output = itpl('$head("Class Docstring:")\n'
+                          '$indent(ds)\n'
+                          '$head("Constructor Docstring"):\n'
+                          '$indent(init_ds)')
+        elif type(obj) is types.InstanceType and hasattr(obj,'__call__'):
+            call_ds = getdoc(obj.__call__)
+            if call_ds:
+                output = itpl('$head("Class Docstring:")\n$indent(ds)\n'
+                              '$head("Calling Docstring:")\n$indent(call_ds)')
+            else:
+                output = ds
+        else:
+            output = ds
+        if output is None:
+            self.noinfo('documentation',oname)
+            return
+        page(output)
+
+    def psource(self,obj,oname=''):
+        """Print the source code for an object."""
+
+        # Flush the source cache because inspect can return out-of-date source
+        linecache.checkcache()
+        try:
+            src = inspect.getsource(obj) 
+        except:
+            self.noinfo('source',oname)
+        else:
+            page(self.format(src))
+
+    def pfile(self,obj,oname=''):
+        """Show the whole file where an object was defined."""
+        try:
+            sourcelines,lineno = inspect.getsourcelines(obj)
+        except:
+            self.noinfo('file',oname)
+        else:
+            # run contents of file through pager starting at line
+            # where the object is defined            
+            page(self.format(open(inspect.getabsfile(obj)).read()),lineno)
+
+    def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
+        """Show detailed information about an object.
+
+        Optional arguments:
+        
+        - oname: name of the variable pointing to the object.
+
+        - formatter: special formatter for docstrings (see pdoc)
+
+        - info: a structure with some information fields which may have been
+        precomputed already.
+
+        - detail_level: if set to 1, more information is given.
+        """
+
+        obj_type = type(obj)
+
+        header = self.__head
+        if info is None:
+            ismagic = 0
+            isalias = 0
+            ospace = ''
+        else:
+            ismagic = info.ismagic
+            isalias = info.isalias
+            ospace = info.namespace
+        # Get docstring, special-casing aliases:
+        if isalias:
+            ds = "Alias to the system command:\n  %s" % obj[1]
+        else:
+            ds = getdoc(obj)
+        if formatter is not None:
+            ds = formatter(ds)
+
+        # store output in a list which gets joined with \n at the end.
+        out = myStringIO()
+        
+        string_max = 200 # max size of strings to show (snipped if longer)
+        shalf = int((string_max -5)/2)
+
+        if ismagic:
+            obj_type_name = 'Magic function'
+        elif isalias:
+            obj_type_name = 'System alias'
+        else:
+            obj_type_name = obj_type.__name__
+        out.writeln(header('Type:\t\t')+obj_type_name)
+
+        try:
+            bclass = obj.__class__
+            out.writeln(header('Base Class:\t')+str(bclass))
+        except: pass
+
+        # String form, but snip if too long in ? form (full in ??)
+        try:
+            ostr = str(obj)
+            str_head = 'String Form:'
+            if not detail_level and len(ostr)>string_max:
+                ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
+                ostr = ("\n" + " " * len(str_head.expandtabs())).\
+                       join(map(string.strip,ostr.split("\n")))
+            if ostr.find('\n') > -1:
+                # Print multi-line strings starting at the next line.
+                str_sep = '\n'
+            else:
+                str_sep = '\t'
+            out.writeln("%s%s%s" % (header(str_head),str_sep,ostr))
+        except:
+            pass
+
+        if ospace:
+            out.writeln(header('Namespace:\t')+ospace)
+
+        # Length (for strings and lists)
+        try:
+            length = str(len(obj))
+            out.writeln(header('Length:\t\t')+length)
+        except: pass
+
+        # Filename where object was defined
+        try:
+            file = inspect.getabsfile(obj)
+            if file.endswith('<string>'):
+                file = 'Dynamically generated function. No source code available.'
+            out.writeln(header('File:\t\t')+file)
+        except: pass
+
+        # reconstruct the function definition and print it:
+        defln = self.__getdef(obj,oname)
+        if defln:
+            out.write(header('Definition:\t')+self.format(defln))
+ 
+        # Docstrings only in detail 0 mode, since source contains them (we
+        # avoid repetitions).  If source fails, we add them back, see below.
+        if ds and detail_level == 0:
+                out.writeln(header('Docstring:\n') + indent(ds))
+
+        # Original source code for any callable
+        if detail_level:
+            # Flush the source cache because inspect can return out-of-date source
+            linecache.checkcache()
+            try:
+                source = self.format(inspect.getsource(obj))
+                out.write(header('Source:\n')+source.rstrip())
+            except:
+                if ds:
+                    out.writeln(header('Docstring:\n') + indent(ds))
+
+        # Constructor docstring for classes
+        if obj_type is types.ClassType:
+            # reconstruct the function definition and print it:
+            try:
+                obj_init =  obj.__init__
+            except AttributeError:
+                init_def = init_ds = None
+            else:
+                init_def = self.__getdef(obj_init,oname)
+                init_ds  = getdoc(obj_init)
+
+            if init_def or init_ds:
+                out.writeln(header('\nConstructor information:'))
+                if init_def:
+                    out.write(header('Definition:\t')+ self.format(init_def))
+                if init_ds:
+                    out.writeln(header('Docstring:\n') + indent(init_ds))
+        # and class docstring for instances:
+        elif obj_type is types.InstanceType:
+
+            # First, check whether the instance docstring is identical to the
+            # class one, and print it separately if they don't coincide.  In
+            # most cases they will, but it's nice to print all the info for
+            # objects which use instance-customized docstrings.
+            if ds:
+                class_ds = getdoc(obj.__class__)
+                if class_ds and ds != class_ds:
+                    out.writeln(header('Class Docstring:\n') +
+                                indent(class_ds))
+
+            # Next, try to show constructor docstrings
+            try:
+                init_ds = getdoc(obj.__init__)
+            except AttributeError:
+                init_ds = None
+            if init_ds:
+                out.writeln(header('Constructor Docstring:\n') +
+                            indent(init_ds))
+
+            # Call form docstring for callable instances
+            if hasattr(obj,'__call__'):
+                out.writeln(header('Callable:\t')+'Yes')
+                call_def = self.__getdef(obj.__call__,oname)
+                if call_def is None:
+                    out.write(header('Call def:\t')+
+                              'Calling definition not available.')
+                else:
+                    out.write(header('Call def:\t')+self.format(call_def))
+                call_ds = getdoc(obj.__call__)
+                if call_ds:
+                    out.writeln(header('Call docstring:\n') + indent(call_ds))
+
+        # Finally send to printer/pager
+        output = out.getvalue()
+        if output:
+            page(output)
+        # end pinfo
diff --git a/IPython/OutputTrap.py b/IPython/OutputTrap.py
new file mode 100644
index 0000000..670aa5a
--- /dev/null
+++ b/IPython/OutputTrap.py
@@ -0,0 +1,262 @@
+# -*- coding: utf-8 -*-
+"""Class to trap stdout and stderr and log them separately.
+
+$Id: OutputTrap.py 542 2005-03-18 09:16:04Z fperez $"""
+
+#*****************************************************************************
+#       Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
+#
+#  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
+
+import exceptions,sys
+from cStringIO import StringIO
+
+class OutputTrapError(exceptions.Exception):
+    """Exception for OutputTrap class."""
+
+    def __init__(self,args=None):
+        exceptions.Exception.__init__(self)
+        self.args = args
+
+class OutputTrap:
+
+    """Class to trap standard output and standard error. They get logged in
+    StringIO objects which are available as <instance>.out and
+    <instance>.err. The class also offers summary methods which format this
+    data a bit.
+
+    A word of caution: because it blocks messages, using this class can make
+    debugging very tricky. If you are having bizarre problems silently, try
+    turning your output traps off for a while. You can call the constructor
+    with the parameter debug=1 for these cases. This turns actual trapping
+    off, but you can keep the rest of your code unchanged (this has already
+    been a life saver).
+
+    Example:
+
+    # config: trapper with a line of dots as log separator (final '\\n' needed)
+    config = OutputTrap('Config','Out ','Err ','.'*80+'\\n')
+
+    # start trapping output
+    config.trap_all()
+
+    # now all output is logged ...
+    # do stuff...
+
+    # output back to normal:
+    config.release_all()
+
+    # print all that got logged:
+    print config.summary()
+
+    # print individual raw data:
+    print config.out.getvalue()
+    print config.err.getvalue()
+    """
+
+    def __init__(self,name='Generic Output Trap',
+                 out_head='Standard Output. ',err_head='Standard Error. ',
+                 sum_sep='\n',debug=0,trap_out=0,trap_err=0,
+                 quiet_out=0,quiet_err=0):
+        self.name = name
+        self.out_head = out_head
+        self.err_head = err_head
+        self.sum_sep = sum_sep
+        self.out = StringIO()
+        self.err = StringIO()
+        self.out_save = None
+        self.err_save = None
+        self.debug = debug
+        self.quiet_out = quiet_out
+        self.quiet_err = quiet_err
+        if trap_out:
+            self.trap_out()
+        if trap_err:
+            self.trap_err()
+
+    def trap_out(self):
+        """Trap and log stdout."""
+        if sys.stdout is self.out:
+            raise OutputTrapError,'You are already trapping stdout.'
+        if not self.debug:
+            self._out_save = sys.stdout
+            sys.stdout = self.out
+
+    def release_out(self):
+        """Release stdout."""
+        if not self.debug:
+            if not sys.stdout is self.out:
+                raise OutputTrapError,'You are not trapping stdout.'
+            sys.stdout = self._out_save
+            self.out_save = None
+
+    def summary_out(self):
+        """Return as a string the log from stdout."""
+        out = self.out.getvalue()
+        if out:
+            if self.quiet_out:
+                return out
+            else:
+                return self.out_head + 'Log by '+ self.name + ':\n' + out
+        else:
+            return ''
+
+    def flush_out(self):
+        """Flush the stdout log. All data held in the log is lost."""
+
+        self.out.close()
+        self.out = StringIO()
+
+    def trap_err(self):
+        """Trap and log stderr."""
+        if sys.stderr is self.err:
+            raise OutputTrapError,'You are already trapping stderr.'
+        if not self.debug:
+            self._err_save = sys.stderr
+            sys.stderr = self.err
+
+    def release_err(self):
+        """Release stderr."""
+        if not self.debug:
+            if not sys.stderr is self.err:
+                raise OutputTrapError,'You are not trapping stderr.'
+            sys.stderr = self._err_save
+            self.err_save = None
+
+    def summary_err(self):
+        """Return as a string the log from stderr."""
+        err = self.err.getvalue()
+        if err:
+            if self.quiet_err:
+                return err
+            else:
+                return self.err_head + 'Log by '+ self.name + ':\n' + err
+        else:
+            return ''
+
+    def flush_err(self):
+        """Flush the stdout log. All data held in the log is lost."""
+
+        self.err.close()
+        self.err = StringIO()
+
+    def trap_all(self):
+        """Trap and log both stdout and stderr.
+
+        Cacthes and discards OutputTrapError exceptions raised."""
+        try:
+            self.trap_out()
+        except OutputTrapError:
+            pass
+        try:
+            self.trap_err()
+        except OutputTrapError:
+            pass
+
+    def release_all(self):
+        """Release both stdout and stderr.
+
+        Cacthes and discards OutputTrapError exceptions raised."""
+        try:
+            self.release_out()
+        except OutputTrapError:
+            pass
+        try:
+            self.release_err()
+        except OutputTrapError:
+            pass
+        
+    def summary_all(self):
+        """Return as a string the log from stdout and stderr, prepending a separator
+        to each (defined in __init__ as sum_sep)."""
+        sum = ''
+        sout = self.summary_out()
+        if sout:
+            sum += self.sum_sep + sout
+        serr = self.summary_err()
+        if serr:
+            sum += '\n'+self.sum_sep + serr
+        return sum
+
+    def flush_all(self):
+        """Flush stdout and stderr"""
+        self.flush_out()
+        self.flush_err()
+
+    # a few shorthands
+    trap = trap_all
+    release = release_all
+    summary = summary_all
+    flush = flush_all
+# end OutputTrap
+
+
+#****************************************************************************
+# Module testing. Incomplete, I'm lazy...
+
+def _test_all():
+
+    """Module testing functions, activated when the module is called as a
+    script (not imported)."""
+
+    # Put tests for this module in here.
+    # Define them as nested functions so they don't clobber the
+    # pydoc-generated docs
+
+    def _test_():
+        name = ''
+        print '#'*50+'\nRunning test for ' + name
+        # ...
+        print 'Finished test for '+ name +'\n'+'#'*50
+
+    def _test_OutputTrap():
+        trap = OutputTrap(name = 'Test Trap', sum_sep = '.'*50+'\n',
+                          out_head = 'SOut. ', err_head = 'SErr. ')
+
+        name = 'OutputTrap class'
+        print '#'*50+'\nRunning test for ' + name
+        print 'Trapping out'
+        trap.trap_out()
+        print >>sys.stdout, '>>stdout. stdout is trapped.'
+        print >>sys.stderr, '>>stderr. stdout is trapped.'
+        trap.release_out()
+        print trap.summary_out()
+
+        print 'Trapping err'
+        trap.trap_err()
+        print >>sys.stdout, '>>stdout. stderr is trapped.'
+        print >>sys.stderr, '>>stderr. stderr is trapped.'
+        trap.release_err()
+        print trap.summary_err()
+
+        print 'Trapping all (no flushing)'
+        trap.trap_all()
+        print >>sys.stdout, '>>stdout. stdout/err is trapped.'
+        print >>sys.stderr, '>>stderr. stdout/err is trapped.'
+        trap.release_all()
+        print trap.summary_all()
+
+        print 'Trapping all (flushing first)'
+        trap.flush()
+        trap.trap_all()
+        print >>sys.stdout, '>>stdout. stdout/err is trapped.'
+        print >>sys.stderr, '>>stderr. stdout/err is trapped.'
+        trap.release_all()
+        print trap.summary_all()
+        print 'Finished test for '+ name +'\n'+'#'*50
+
+    # call the actual tests here:
+    _test_OutputTrap()
+
+
+if __name__=="__main__":
+    # _test_all() # XXX BROKEN.
+    pass
+
+#************************ end of file <OutputTrap.py> ************************
diff --git a/IPython/Prompts.py b/IPython/Prompts.py
new file mode 100644
index 0000000..361e8ac
--- /dev/null
+++ b/IPython/Prompts.py
@@ -0,0 +1,574 @@
+# -*- coding: utf-8 -*-
+"""
+Classes for handling input/output prompts.
+
+$Id: Prompts.py 564 2005-03-26 22:43:58Z fperez $"""
+
+#*****************************************************************************
+#       Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
+#
+#  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
+
+#****************************************************************************
+# Required modules
+import __builtin__
+import os,sys,socket
+import time
+from pprint import pprint,pformat
+
+# IPython's own
+from IPython.genutils import *
+from IPython.Struct import Struct
+from IPython.Magic import Macro
+from IPython.Itpl import ItplNS
+from IPython import ColorANSI
+
+#****************************************************************************
+#Color schemes for Prompts.
+
+PromptColors = ColorANSI.ColorSchemeTable()
+InputColors = ColorANSI.InputTermColors  # just a shorthand
+Colors = ColorANSI.TermColors  # just a shorthand
+
+PromptColors.add_scheme(ColorANSI.ColorScheme(
+    'NoColor',
+    in_prompt  = InputColors.NoColor,  # Input prompt
+    in_number  = InputColors.NoColor,  # Input prompt number
+    in_prompt2 = InputColors.NoColor, # Continuation prompt
+    in_normal  = InputColors.NoColor,  # color off (usu. Colors.Normal)
+    
+    out_prompt = Colors.NoColor, # Output prompt
+    out_number = Colors.NoColor, # Output prompt number
+
+    normal = Colors.NoColor  # color off (usu. Colors.Normal)
+    ))
+# make some schemes as instances so we can copy them for modification easily:
+__PColLinux =  ColorANSI.ColorScheme(
+    'Linux',
+    in_prompt  = InputColors.Green,
+    in_number  = InputColors.LightGreen,
+    in_prompt2 = InputColors.Green,
+    in_normal  = InputColors.Normal,  # color off (usu. Colors.Normal)
+
+    out_prompt = Colors.Red,
+    out_number = Colors.LightRed,
+
+    normal = Colors.Normal
+    )
+# Don't forget to enter it into the table!
+PromptColors.add_scheme(__PColLinux)
+# Slightly modified Linux for light backgrounds
+__PColLightBG  = ColorANSI.ColorScheme('LightBG',**__PColLinux.colors.dict().copy())
+
+__PColLightBG.colors.update(
+    in_prompt  = InputColors.Blue,
+    in_number  = InputColors.LightBlue,
+    in_prompt2 = InputColors.Blue
+)
+PromptColors.add_scheme(__PColLightBG)
+
+del Colors,InputColors
+
+#-----------------------------------------------------------------------------
+def multiple_replace(dict, text):
+    """ Replace in 'text' all occurences of any key in the given
+    dictionary by its corresponding value.  Returns the new string."""
+
+    # Function by Xavier Defrang, originally found at:
+    # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81330
+
+    # Create a regular expression  from the dictionary keys
+    regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))
+    # For each match, look-up corresponding value in dictionary
+    return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text)
+
+#-----------------------------------------------------------------------------
+# Special characters that can be used in prompt templates, mainly bash-like
+
+# If $HOME isn't defined (Windows), make it an absurd string so that it can
+# never be expanded out into '~'.  Basically anything which can never be a
+# reasonable directory name will do, we just want the $HOME -> '~' operation
+# to become a no-op.  We pre-compute $HOME here so it's not done on every
+# prompt call.
+
+# FIXME:
+
+# - This should be turned into a class which does proper namespace management,
+# since the prompt specials need to be evaluated in a certain namespace.
+# Currently it's just globals, which need to be managed manually by code
+# below.
+
+# - I also need to split up the color schemes from the prompt specials
+# somehow.  I don't have a clean design for that quite yet.
+
+HOME = os.environ.get("HOME","//////:::::ZZZZZ,,,~~~")
+
+# We precompute a few more strings here for the prompt_specials, which are
+# fixed once ipython starts.  This reduces the runtime overhead of computing
+# prompt strings.
+USER           = os.environ.get("USER")
+HOSTNAME       = socket.gethostname()
+HOSTNAME_SHORT = HOSTNAME.split(".")[0]
+ROOT_SYMBOL    = "$#"[os.name=='nt' or os.getuid()==0]
+
+prompt_specials_color = {
+    # Prompt/history count
+    '%n' : '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
+    '\\#': '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
+    # Prompt/history count, with the actual digits replaced by dots.  Used
+    # mainly in continuation prompts (prompt_in2)
+    '\\D': '${"."*len(str(self.cache.prompt_count))}',
+    # Current working directory
+    '\\w': '${os.getcwd()}',
+    # Current time
+    '\\t' : '${time.strftime("%H:%M:%S")}',
+    # Basename of current working directory.
+    # (use os.sep to make this portable across OSes)
+    '\\W' : '${os.getcwd().split("%s")[-1]}' % os.sep,
+    # These X<N> are an extension to the normal bash prompts.  They return
+    # N terms of the path, after replacing $HOME with '~'
+    '\\X0': '${os.getcwd().replace("%s","~")}' % HOME,
+    '\\X1': '${self.cwd_filt(1)}',
+    '\\X2': '${self.cwd_filt(2)}',
+    '\\X3': '${self.cwd_filt(3)}',
+    '\\X4': '${self.cwd_filt(4)}',
+    '\\X5': '${self.cwd_filt(5)}',
+    # Y<N> are similar to X<N>, but they show '~' if it's the directory
+    # N+1 in the list.  Somewhat like %cN in tcsh.
+    '\\Y0': '${self.cwd_filt2(0)}',
+    '\\Y1': '${self.cwd_filt2(1)}',
+    '\\Y2': '${self.cwd_filt2(2)}',
+    '\\Y3': '${self.cwd_filt2(3)}',
+    '\\Y4': '${self.cwd_filt2(4)}',
+    '\\Y5': '${self.cwd_filt2(5)}',
+    # Hostname up to first .
+    '\\h': HOSTNAME_SHORT,
+    # Full hostname
+    '\\H': HOSTNAME,
+    # Username of current user
+    '\\u': USER,
+    # Escaped '\'
+    '\\\\': '\\',
+    # Newline
+    '\\n': '\n',
+    # Carriage return
+    '\\r': '\r',
+    # Release version
+    '\\v': __version__,
+    # Root symbol ($ or #)
+    '\\$': ROOT_SYMBOL,
+    }
+
+# A copy of the prompt_specials dictionary but with all color escapes removed,
+# so we can correctly compute the prompt length for the auto_rewrite method.
+prompt_specials_nocolor = prompt_specials_color.copy()
+prompt_specials_nocolor['%n'] = '${self.cache.prompt_count}'
+prompt_specials_nocolor['\\#'] = '${self.cache.prompt_count}'
+
+# Add in all the InputTermColors color escapes as valid prompt characters.
+# They all get added as \\C_COLORNAME, so that we don't have any conflicts
+# with a color name which may begin with a letter used by any other of the
+# allowed specials.  This of course means that \\C will never be allowed for
+# anything else.
+input_colors = ColorANSI.InputTermColors
+for _color in dir(input_colors):
+    if _color[0] != '_':
+        c_name = '\\C_'+_color
+        prompt_specials_color[c_name] = getattr(input_colors,_color)
+        prompt_specials_nocolor[c_name] = ''
+
+# we default to no color for safety.  Note that prompt_specials is a global
+# variable used by all prompt objects.
+prompt_specials = prompt_specials_nocolor
+
+#-----------------------------------------------------------------------------
+def str_safe(arg):
+    """Convert to a string, without ever raising an exception.
+
+    If str(arg) fails, <ERROR: ... > is returned, where ... is the exception
+    error message."""
+    
+    try:
+        return str(arg)
+    except Exception,msg:
+        return '<ERROR: %s>' % msg
+
+class BasePrompt:
+    """Interactive prompt similar to Mathematica's."""
+    def __init__(self,cache,sep,prompt,pad_left=False):
+
+        # Hack: we access information about the primary prompt through the
+        # cache argument.  We need this, because we want the secondary prompt
+        # to be aligned with the primary one.  Color table info is also shared
+        # by all prompt classes through the cache.  Nice OO spaghetti code!
+        self.cache = cache
+        self.sep = sep
+        
+        # regexp to count the number of spaces at the end of a prompt
+        # expression, useful for prompt auto-rewriting
+        self.rspace = re.compile(r'(\s*)$')
+        # Flag to left-pad prompt strings to match the length of the primary
+        # prompt
+        self.pad_left = pad_left
+        # Set template to create each actual prompt (where numbers change)
+        self.p_template = prompt
+        self.set_p_str()
+
+    def set_p_str(self):
+        """ Set the interpolating prompt strings.
+
+        This must be called every time the color settings change, because the
+        prompt_specials global may have changed."""
+
+        import os,time  # needed in locals for prompt string handling
+        loc = locals()
+        self.p_str = ItplNS('%s%s%s' %
+                            ('${self.sep}${self.col_p}',
+                             multiple_replace(prompt_specials, self.p_template),
+                             '${self.col_norm}'),self.cache.user_ns,loc)
+        
+        self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
+                                                     self.p_template),
+                                    self.cache.user_ns,loc)
+
+    def write(self,msg):  # dbg
+        sys.stdout.write(msg)
+        return ''
+
+    def __str__(self):
+        """Return a string form of the prompt.
+
+        This for is useful for continuation and output prompts, since it is
+        left-padded to match lengths with the primary one (if the
+        self.pad_left attribute is set)."""
+
+        out_str = str_safe(self.p_str)
+        if self.pad_left:
+            # We must find the amount of padding required to match lengths,
+            # taking the color escapes (which are invisible on-screen) into
+            # account.
+            esc_pad = len(out_str) - len(str_safe(self.p_str_nocolor))
+            format = '%%%ss' % (len(str(self.cache.last_prompt))+esc_pad)
+            return format % out_str
+        else:
+            return out_str
+
+    # these path filters are put in as methods so that we can control the
+    # namespace where the prompt strings get evaluated
+    def cwd_filt(self,depth):
+        """Return the last depth elements of the current working directory.
+
+        $HOME is always replaced with '~'.
+        If depth==0, the full path is returned."""
+
+        cwd = os.getcwd().replace(HOME,"~")
+        out = os.sep.join(cwd.split(os.sep)[-depth:])
+        if out:
+            return out
+        else:
+            return os.sep
+
+    def cwd_filt2(self,depth):
+        """Return the last depth elements of the current working directory.
+
+        $HOME is always replaced with '~'.
+        If depth==0, the full path is returned."""
+
+        cwd = os.getcwd().replace(HOME,"~").split(os.sep)
+        if '~' in cwd and len(cwd) == depth+1:
+            depth += 1
+        out = os.sep.join(cwd[-depth:])
+        if out:
+            return out
+        else:
+            return os.sep
+
+class Prompt1(BasePrompt):
+    """Input interactive prompt similar to Mathematica's."""
+
+    def __init__(self,cache,sep='\n',prompt='In [\\#]: ',pad_left=True):
+        BasePrompt.__init__(self,cache,sep,prompt,pad_left)
+
+    def set_colors(self):
+        self.set_p_str()
+        Colors = self.cache.color_table.active_colors # shorthand
+        self.col_p = Colors.in_prompt
+        self.col_num = Colors.in_number
+        self.col_norm = Colors.in_normal
+        # We need a non-input version of these escapes for the '--->'
+        # auto-call prompts used in the auto_rewrite() method.
+        self.col_p_ni = self.col_p.replace('\001','').replace('\002','') 
+        self.col_norm_ni = Colors.normal        
+        
+    def __str__(self):
+        self.cache.prompt_count += 1
+        self.cache.last_prompt = str_safe(self.p_str_nocolor).split('\n')[-1]
+        return str_safe(self.p_str)
+
+    def auto_rewrite(self):
+        """Print a string of the form '--->' which lines up with the previous
+        input string. Useful for systems which re-write the user input when
+        handling automatically special syntaxes."""
+
+        curr = str(self.cache.last_prompt)
+        nrspaces = len(self.rspace.search(curr).group())
+        return '%s%s>%s%s' % (self.col_p_ni,'-'*(len(curr)-nrspaces-1),
+                              ' '*nrspaces,self.col_norm_ni)
+
+class PromptOut(BasePrompt):
+    """Output interactive prompt similar to Mathematica's."""
+
+    def __init__(self,cache,sep='',prompt='Out[\\#]: ',pad_left=True):
+        BasePrompt.__init__(self,cache,sep,prompt,pad_left)
+        if not self.p_template:
+            self.__str__ = lambda: ''
+
+    def set_colors(self):
+        self.set_p_str()
+        Colors = self.cache.color_table.active_colors # shorthand
+        self.col_p = Colors.out_prompt
+        self.col_num = Colors.out_number
+        self.col_norm = Colors.normal
+
+class Prompt2(BasePrompt):
+    """Interactive continuation prompt."""
+    
+    def __init__(self,cache,prompt='   .\\D.: ',pad_left=True):
+        self.cache = cache
+        self.p_template = prompt
+        self.pad_left = pad_left
+        self.set_p_str()
+
+    def set_p_str(self):
+        import os,time  # needed in locals for prompt string handling
+        loc = locals()
+        self.p_str = ItplNS('%s%s%s' %
+                            ('${self.col_p2}',
+                             multiple_replace(prompt_specials, self.p_template),
+                             '$self.col_norm'),
+                            self.cache.user_ns,loc)
+        self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
+                                                     self.p_template),
+                                    self.cache.user_ns,loc)
+
+    def set_colors(self):
+        self.set_p_str()
+        Colors = self.cache.color_table.active_colors
+        self.col_p2 = Colors.in_prompt2
+        self.col_norm = Colors.in_normal
+        # FIXME (2004-06-16) HACK: prevent crashes for users who haven't
+        # updated their prompt_in2 definitions.  Remove eventually.
+        self.col_p = Colors.out_prompt
+        self.col_num = Colors.out_number
+
+#-----------------------------------------------------------------------------
+class CachedOutput:
+    """Class for printing output from calculations while keeping a cache of
+    reults. It dynamically creates global variables prefixed with _ which
+    contain these results.
+
+    Meant to be used as a sys.displayhook replacement, providing numbered
+    prompts and cache services.
+
+    Initialize with initial and final values for cache counter (this defines
+    the maximum size of the cache."""
+
+    def __init__(self,cache_size,Pprint,colors='NoColor',input_sep='\n',
+                 output_sep='\n',output_sep2='',user_ns={},
+                 ps1 = None, ps2 = None,ps_out = None,
+                 input_hist = None,pad_left=True):
+
+        cache_size_min = 20
+        if cache_size <= 0:
+            self.do_full_cache = 0
+            cache_size = 0
+        elif cache_size < cache_size_min:
+            self.do_full_cache = 0
+            cache_size = 0
+            warn('caching was disabled (min value for cache size is %s).' %
+                 cache_size_min,level=3)
+        else:
+            self.do_full_cache = 1
+
+        self.cache_size = cache_size
+        self.input_sep = input_sep
+
+        # we need a reference to the user-level namespace
+        self.user_ns = user_ns
+        # and to the user's input
+        self.input_hist = input_hist
+
+        # Set input prompt strings and colors
+        if cache_size == 0:
+            if ps1.find('%n') > -1 or ps1.find('\\#') > -1: ps1 = '>>> '
+            if ps2.find('%n') > -1 or ps2.find('\\#') > -1: ps2 = '... '
+        self.ps1_str = self._set_prompt_str(ps1,'In [\\#]: ','>>> ')
+        self.ps2_str = self._set_prompt_str(ps2,'   .\\D.: ','... ')
+        self.ps_out_str = self._set_prompt_str(ps_out,'Out[\\#]: ','')
+
+        self.prompt1 = Prompt1(self,sep=input_sep,prompt=self.ps1_str,
+                               pad_left=pad_left)
+        self.prompt2 = Prompt2(self,prompt=self.ps2_str,pad_left=pad_left)
+        self.prompt_out = PromptOut(self,sep='',prompt=self.ps_out_str,
+                                    pad_left=pad_left)
+        self.color_table = PromptColors
+        self.set_colors(colors)
+
+        # other more normal stuff
+        # b/c each call to the In[] prompt raises it by 1, even the first.
+        self.prompt_count = 0
+        self.cache_count = 1
+        # Store the last prompt string each time, we need it for aligning
+        # continuation and auto-rewrite prompts
+        self.last_prompt = ''
+        self.entries = [None]  # output counter starts at 1 for the user
+        self.Pprint = Pprint
+        self.output_sep = output_sep
+        self.output_sep2 = output_sep2
+        self._,self.__,self.___ = '','',''
+        self.pprint_types = map(type,[(),[],{}])
+        
+        # these are deliberately global:
+        to_user_ns = {'_':self._,'__':self.__,'___':self.___}
+        self.user_ns.update(to_user_ns)
+
+    def _set_prompt_str(self,p_str,cache_def,no_cache_def):
+        if p_str is None:
+            if self.do_full_cache:
+                return cache_def
+            else:
+                return no_cache_def
+        else:
+            return p_str
+                
+    def set_colors(self,colors):
+        """Set the active color scheme and configure colors for the three
+        prompt subsystems."""
+
+        # FIXME: the prompt_specials global should be gobbled inside this
+        # class instead.  Do it when cleaning up the whole 3-prompt system.
+        global prompt_specials
+        if colors.lower()=='nocolor':
+            prompt_specials = prompt_specials_nocolor
+        else:
+            prompt_specials = prompt_specials_color
+        
+        self.color_table.set_active_scheme(colors)
+        self.prompt1.set_colors()
+        self.prompt2.set_colors()
+        self.prompt_out.set_colors()
+
+    def __call__(self,arg=None):
+        """Printing with history cache management.
+        
+        This is invoked everytime the interpreter needs to print, and is
+        activated by setting the variable sys.displayhook to it."""
+
+        # If something injected a '_' variable in __builtin__, delete
+        # ipython's automatic one so we don't clobber that.  gettext() in
+        # particular uses _, so we need to stay away from it.
+        if '_' in __builtin__.__dict__:
+            try:
+                del self.user_ns['_']
+            except KeyError:
+                pass
+        if arg is not None:
+            # first handle the cache and counters
+            self.update(arg)
+            # do not print output if input ends in ';'
+            if self.input_hist[self.prompt_count].endswith(';\n'):
+                return
+            # don't use print, puts an extra space
+            Term.cout.write(self.output_sep)
+            if self.do_full_cache:
+                Term.cout.write(str(self.prompt_out))
+
+            if isinstance(arg,Macro):
+                print 'Executing Macro...'
+                # in case the macro takes a long time to execute
+                Term.cout.flush()
+                exec arg.value in self.user_ns
+                return None
+
+            # and now call a possibly user-defined print mechanism
+            self.display(arg)
+            Term.cout.write(self.output_sep2)
+            Term.cout.flush()
+
+    def _display(self,arg):
+        """Default printer method, uses pprint.
+
+        This can be over-ridden by the users to implement special formatting
+        of certain types of output."""
+
+        if self.Pprint:
+            # The following is an UGLY kludge, b/c python fails to properly
+            # identify instances of classes imported in the user namespace
+            # (they have different memory locations, I guess). Structs are
+            # essentially dicts but pprint doesn't know what to do with them.
+            try:
+                if arg.__class__.__module__ == 'Struct' and \
+                   arg.__class__.__name__ == 'Struct':
+                    out = 'Struct:\n%s' % pformat(arg.dict())
+                else:
+                    out = pformat(arg)
+            except:
+                out = pformat(arg)
+            if '\n' in out:
+                # So that multi-line strings line up with the left column of
+                # the screen, instead of having the output prompt mess up
+                # their first line.                
+                Term.cout.write('\n')
+            print >>Term.cout, out
+        else:
+            print >>Term.cout, arg
+
+    # Assign the default display method:
+    display = _display
+
+    def update(self,arg):
+        #print '***cache_count', self.cache_count # dbg
+        if self.cache_count >= self.cache_size and self.do_full_cache:
+            self.flush()
+        # Don't overwrite '_' and friends if '_' is in __builtin__ (otherwise
+        # we cause buggy behavior for things like gettext).
+        if '_' not in __builtin__.__dict__:
+            self.___ = self.__
+            self.__ = self._
+            self._ = arg
+            self.user_ns.update({'_':self._,'__':self.__,'___':self.___})
+            
+        # hackish access to top-level  namespace to create _1,_2... dynamically
+        to_main = {}
+        if self.do_full_cache:
+            self.cache_count += 1
+            self.entries.append(arg)
+            new_result = '_'+`self.prompt_count`
+            to_main[new_result] = self.entries[-1]
+        self.user_ns.update(to_main)
+        self.user_ns['_oh'][self.prompt_count] = arg
+
+    def flush(self):
+        if not self.do_full_cache:
+            raise ValueError,"You shouldn't have reached the cache flush "\
+                  "if full caching is not enabled!"
+        warn('Output cache limit (currently '+\
+              `self.cache_count`+' entries) hit.\n'
+             'Flushing cache and resetting history counter...\n'
+             'The only history variables available will be _,__,___ and _1\n'
+             'with the current result.')
+        # delete auto-generated vars from global namespace
+        for n in range(1,self.prompt_count + 1):
+            key = '_'+`n`
+            try:
+                del self.user_ns[key]
+            except: pass
+        self.prompt_count = 1
+        self.cache_count = 1
diff --git a/IPython/PyColorize.py b/IPython/PyColorize.py
new file mode 100755
index 0000000..1481725
--- /dev/null
+++ b/IPython/PyColorize.py
@@ -0,0 +1,255 @@
+# -*- coding: utf-8 -*-
+"""
+    Class and program to colorize python source code for ANSI terminals.
+
+    Based on an HTML code highlighter by Jurgen Hermann found at:
+    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52298
+
+    Modifications by Fernando Perez (fperez@colorado.edu).
+
+    Information on the original HTML highlighter follows:
+    
+    MoinMoin - Python Source Parser
+
+    Title:olorize Python source using the built-in tokenizer
+           
+    Submitter: Jurgen Hermann
+    Last Updated:2001/04/06
+           
+    Version no:1.2
+
+    Description:
+
+    This code is part of MoinMoin (http://moin.sourceforge.net/) and converts
+    Python source code to HTML markup, rendering comments, keywords,
+    operators, numeric and string literals in different colors.
+
+    It shows how to use the built-in keyword, token and tokenize modules to
+    scan Python source code and re-emit it with no changes to its original
+    formatting (which is the hard part).
+
+    $Id: PyColorize.py 485 2005-01-27 19:15:39Z fperez $"""
+
+__all__ = ['ANSICodeColors','Parser']
+
+_scheme_default = 'Linux'
+
+# Imports
+import string, sys, os, cStringIO
+import keyword, token, tokenize
+
+from IPython.ColorANSI import *
+
+#############################################################################
+### Python Source Parser (does Hilighting)
+#############################################################################
+
+_KEYWORD = token.NT_OFFSET + 1
+_TEXT    = token.NT_OFFSET + 2
+
+#****************************************************************************
+# Builtin color schemes
+
+Colors = TermColors  # just a shorthand
+
+# Build a few color schemes
+NoColor = ColorScheme(
+    'NoColor',{
+    token.NUMBER     : Colors.NoColor,
+    token.OP         : Colors.NoColor,
+    token.STRING     : Colors.NoColor,
+    tokenize.COMMENT : Colors.NoColor,
+    token.NAME       : Colors.NoColor,
+    token.ERRORTOKEN : Colors.NoColor,
+
+    _KEYWORD         : Colors.NoColor,
+    _TEXT            : Colors.NoColor,
+
+    'normal'         : Colors.NoColor  # color off (usu. Colors.Normal)
+    }  )
+
+LinuxColors = ColorScheme(
+    'Linux',{
+    token.NUMBER     : Colors.LightCyan,
+    token.OP         : Colors.Yellow,
+    token.STRING     : Colors.LightBlue,
+    tokenize.COMMENT : Colors.LightRed,
+    token.NAME       : Colors.White,
+    token.ERRORTOKEN : Colors.Red,
+
+    _KEYWORD         : Colors.LightGreen,
+    _TEXT            : Colors.Yellow,
+
+    'normal'         : Colors.Normal  # color off (usu. Colors.Normal)
+    } )
+
+LightBGColors = ColorScheme(
+    'LightBG',{
+    token.NUMBER     : Colors.Cyan,
+    token.OP         : Colors.Blue,
+    token.STRING     : Colors.Blue,
+    tokenize.COMMENT : Colors.Red,
+    token.NAME       : Colors.Black,
+    token.ERRORTOKEN : Colors.Red,
+
+    _KEYWORD         : Colors.Green,
+    _TEXT            : Colors.Blue,
+
+    'normal'         : Colors.Normal  # color off (usu. Colors.Normal)
+    }  )
+
+# Build table of color schemes (needed by the parser)
+ANSICodeColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
+                                  _scheme_default)
+
+class Parser:
+    """ Format colored Python source.
+    """
+
+    def __init__(self, color_table=None,out = sys.stdout):
+        """ Create a parser with a specified color table and output channel.
+
+        Call format() to process code.
+        """
+        self.color_table = color_table and color_table or ANSICodeColors
+        self.out = out
+
+    def format(self, raw, out = None, scheme = ''):
+        """ Parse and send the colored source.
+
+        If out and scheme are not specified, the defaults (given to
+        constructor) are used.
+
+        out should be a file-type object. Optionally, out can be given as the
+        string 'str' and the parser will automatically return the output in a
+        string."""
+        
+        self.raw = string.strip(string.expandtabs(raw))
+        string_output = 0
+        if out == 'str' or self.out == 'str':
+            out_old = self.out
+            self.out = cStringIO.StringIO()
+            string_output = 1
+        elif out is not None:
+            self.out = out
+        # local shorthand
+        colors = self.color_table[scheme].colors
+        self.colors = colors # put in object so __call__ sees it
+        # store line offsets in self.lines
+        self.lines = [0, 0]
+        pos = 0
+        while 1:
+            pos = string.find(self.raw, '\n', pos) + 1
+            if not pos: break
+            self.lines.append(pos)
+        self.lines.append(len(self.raw))
+
+        # parse the source and write it
+        self.pos = 0
+        text = cStringIO.StringIO(self.raw)
+        #self.out.write('<pre><font face="Courier New">')
+        try:
+            tokenize.tokenize(text.readline, self)
+        except tokenize.TokenError, ex:
+            msg = ex[0]
+            line = ex[1][0]
+            self.out.write("%s\n\n*** ERROR: %s%s%s\n" %
+                           (colors[token.ERRORTOKEN],
+                            msg, self.raw[self.lines[line]:],
+                            colors.normal)
+                           )
+        self.out.write(colors.normal+'\n')
+        if string_output:
+            output = self.out.getvalue()
+            self.out = out_old
+            return output
+
+    def __call__(self, toktype, toktext, (srow,scol), (erow,ecol), line):
+        """ Token handler, with syntax highlighting."""
+
+        # local shorthand
+        colors = self.colors
+
+        # line separator, so this works across platforms
+        linesep = os.linesep
+
+        # calculate new positions
+        oldpos = self.pos
+        newpos = self.lines[srow] + scol
+        self.pos = newpos + len(toktext)
+
+        # handle newlines
+        if toktype in [token.NEWLINE, tokenize.NL]:
+            self.out.write(linesep)
+            return
+
+        # send the original whitespace, if needed
+        if newpos > oldpos:
+            self.out.write(self.raw[oldpos:newpos])
+
+        # skip indenting tokens
+        if toktype in [token.INDENT, token.DEDENT]:
+            self.pos = newpos
+            return
+
+        # map token type to a color group
+        if token.LPAR <= toktype and toktype <= token.OP:
+            toktype = token.OP
+        elif toktype == token.NAME and keyword.iskeyword(toktext):
+            toktype = _KEYWORD
+        color = colors.get(toktype, colors[_TEXT])
+
+        #print '<%s>' % toktext,    # dbg
+
+        # Triple quoted strings must be handled carefully so that backtracking
+        # in pagers works correctly. We need color terminators on _each_ line.
+        if linesep in toktext:
+            toktext = toktext.replace(linesep, '%s%s%s' %
+                                      (colors.normal,linesep,color))
+
+        # send text
+        self.out.write('%s%s%s' % (color,toktext,colors.normal))
+            
+def main():
+    """Colorize a python file using ANSI color escapes and print to stdout.
+
+    Usage:
+      %s [-s scheme] filename
+
+    Options:
+
+      -s scheme: give the color scheme to use. Currently only 'Linux'
+      (default) and 'LightBG' and 'NoColor' are implemented (give without
+      quotes).  """  
+
+    def usage():
+        print >> sys.stderr, main.__doc__ % sys.argv[0]
+        sys.exit(1)
+        
+    # FIXME: rewrite this to at least use getopt
+    try:
+        if sys.argv[1] == '-s':
+            scheme_name = sys.argv[2]
+            del sys.argv[1:3]
+        else:
+            scheme_name = _scheme_default
+        
+    except:
+        usage()
+
+    try:
+        fname = sys.argv[1]
+    except:
+        usage()
+        
+    # write colorized version to stdout
+    parser = Parser()
+    try:
+        parser.format(file(fname).read(),scheme = scheme_name)
+    except IOError,msg:
+        # if user reads through a pager and quits, don't print traceback
+        if msg.args != (32,'Broken pipe'):
+            raise
+
+if __name__ == "__main__":
+    main()
diff --git a/IPython/Release.py b/IPython/Release.py
new file mode 100644
index 0000000..a6b5db0
--- /dev/null
+++ b/IPython/Release.py
@@ -0,0 +1,69 @@
+# -*- coding: utf-8 -*-
+"""Release data for the IPython project.
+
+$Id: Release.py 605 2005-06-09 14:09:03Z fperez $"""
+
+#*****************************************************************************
+#       Copyright (C) 2001-2005 Fernando Perez <fperez@colorado.edu>
+#
+#       Copyright (c) 2001 Janko Hauser <jhauser@zscout.de> and Nathaniel Gray
+#       <n8gray@caltech.edu>
+#
+#  Distributed under the terms of the BSD License.  The full license is in
+#  the file COPYING, distributed as part of this software.
+#*****************************************************************************
+
+# Name of the package for release purposes.  This is the name which labels
+# the tarballs and RPMs made by distutils, so it's best to lowercase it.
+name = 'ipython'
+
+# For versions with substrings (like 0.6.7_rc1), use _ but NOT -, since
+# bdist_rpm chokes on dashes in the version string.
+version = '0.6.16_cvs'
+
+description = "An enhanced interactive Python shell."
+
+long_description = \
+"""
+IPython provides a replacement for the interactive Python interpreter with
+extra functionality.
+
+Main features:
+
+ * Comprehensive object introspection.
+
+ * Input history, persistent across sessions.
+
+ * Caching of output results during a session with automatically generated
+   references.
+
+ * Readline based name completion.
+
+ * Extensible system of 'magic' commands for controlling the environment and
+   performing many tasks related either to IPython or the operating system.
+
+ * Configuration system with easy switching between different setups (simpler
+   than changing $PYTHONSTARTUP environment variables every time).
+
+ * Session logging and reloading.
+
+ * Extensible syntax processing for special purpose situations.
+
+ * Access to the system shell with user-extensible alias system.
+
+ * Easily embeddable in other Python programs.
+
+ * Integrated access to the pdb debugger and the Python profiler. """
+
+license = 'BSD'
+
+authors = {'Fernando' : ('Fernando Perez','fperez@colorado.edu'),
+           'Janko'    : ('Janko Hauser','jhauser@zscout.de'),
+           'Nathan'   : ('Nathaniel Gray','n8gray@caltech.edu')
+           }
+
+url = 'http://ipython.scipy.org'
+
+platforms = ['Linux','Mac OSX','Windows XP/2000/NT','Windows 95/98/ME']
+
+keywords = ['Interactive','Interpreter','Shell']
diff --git a/IPython/Shell.py b/IPython/Shell.py
new file mode 100644
index 0000000..6e95fed
--- /dev/null
+++ b/IPython/Shell.py
@@ -0,0 +1,894 @@
+# -*- coding: utf-8 -*-
+"""IPython Shell classes.
+
+All the matplotlib support code was co-developed with John Hunter,
+matplotlib's author.
+
+$Id: Shell.py 605 2005-06-09 14:09:03Z fperez $"""
+
+#*****************************************************************************
+#       Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
+#
+#  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
+
+# Code begins
+import __main__
+import __builtin__
+import sys
+import os
+import code
+import threading
+import signal
+
+import IPython
+from IPython.iplib import InteractiveShell
+from IPython.ipmaker import make_IPython
+from IPython.genutils import Term,warn,error,flag_calls
+from IPython.Struct import Struct
+from IPython.Magic import Magic
+from IPython import ultraTB
+
+# global flag to pass around information about Ctrl-C without exceptions
+KBINT = False
+
+# global flag to turn on/off Tk support.
+USE_TK = False
+
+#-----------------------------------------------------------------------------
+# This class is trivial now, but I want to have it in to publish a clean
+# interface. Later when the internals are reorganized, code that uses this
+# shouldn't have to change.
+
+class IPShell:
+    """Create an IPython instance."""
+    
+    def __init__(self,argv=None,user_ns=None,debug=1,
+                 shell_class=InteractiveShell):
+        self.IP = make_IPython(argv,user_ns=user_ns,debug=debug,
+                               shell_class=shell_class)
+
+    def mainloop(self,sys_exit=0,banner=None):
+        self.IP.mainloop(banner)
+        if sys_exit:
+            sys.exit()
+
+#-----------------------------------------------------------------------------
+class IPShellEmbed:
+    """Allow embedding an IPython shell into a running program.
+
+    Instances of this class are callable, with the __call__ method being an
+    alias to the embed() method of an InteractiveShell instance.
+
+    Usage (see also the example-embed.py file for a running example):
+
+    ipshell = IPShellEmbed([argv,banner,exit_msg,rc_override])
+
+    - argv: list containing valid command-line options for IPython, as they
+    would appear in sys.argv[1:].
+
+    For example, the following command-line options:
+
+      $ ipython -prompt_in1 'Input <\\#>' -colors LightBG
+
+    would be passed in the argv list as:
+
+      ['-prompt_in1','Input <\\#>','-colors','LightBG']
+
+    - banner: string which gets printed every time the interpreter starts.
+
+    - exit_msg: string which gets printed every time the interpreter exits.
+
+    - rc_override: a dict or Struct of configuration options such as those
+    used by IPython. These options are read from your ~/.ipython/ipythonrc
+    file when the Shell object is created. Passing an explicit rc_override
+    dict with any options you want allows you to override those values at
+    creation time without having to modify the file. This way you can create
+    embeddable instances configured in any way you want without editing any
+    global files (thus keeping your interactive IPython configuration
+    unchanged).
+
+    Then the ipshell instance can be called anywhere inside your code:
+    
+    ipshell(header='') -> Opens up an IPython shell.
+
+    - header: string printed by the IPython shell upon startup. This can let
+    you know where in your code you are when dropping into the shell. Note
+    that 'banner' gets prepended to all calls, so header is used for
+    location-specific information.
+
+    For more details, see the __call__ method below.
+
+    When the IPython shell is exited with Ctrl-D, normal program execution
+    resumes.
+
+    This functionality was inspired by a posting on comp.lang.python by cmkl
+    <cmkleffner@gmx.de> on Dec. 06/01 concerning similar uses of pyrepl, and
+    by the IDL stop/continue commands."""
+
+    def __init__(self,argv=None,banner='',exit_msg=None,rc_override=None):
+        """Note that argv here is a string, NOT a list."""
+        self.set_banner(banner)
+        self.set_exit_msg(exit_msg)
+        self.set_dummy_mode(0)
+
+        # sys.displayhook is a global, we need to save the user's original
+        # Don't rely on __displayhook__, as the user may have changed that.
+        self.sys_displayhook_ori = sys.displayhook
+
+        # save readline completer status
+        try:
+            #print 'Save completer',sys.ipcompleter  # dbg
+            self.sys_ipcompleter_ori = sys.ipcompleter
+        except:
+            pass # not nested with IPython
+        
+        # FIXME. Passing user_ns breaks namespace handling.
+        #self.IP = make_IPython(argv,user_ns=__main__.__dict__)
+        self.IP = make_IPython(argv,rc_override=rc_override,embedded=True)
+
+        self.IP.name_space_init()
+        # mark this as an embedded instance so we know if we get a crash
+        # post-mortem
+        self.IP.rc.embedded = 1
+        # copy our own displayhook also
+        self.sys_displayhook_embed = sys.displayhook
+        # and leave the system's display hook clean
+        sys.displayhook = self.sys_displayhook_ori
+        # don't use the ipython crash handler so that user exceptions aren't
+        # trapped
+        sys.excepthook = ultraTB.FormattedTB(color_scheme = self.IP.rc.colors,
+                                             mode = self.IP.rc.xmode,
+                                             call_pdb = self.IP.rc.pdb)
+        self.restore_system_completer()
+
+    def restore_system_completer(self):
+        """Restores the readline completer which was in place.
+
+        This allows embedded IPython within IPython not to disrupt the
+        parent's completion.
+        """
+        
+        try:
+            self.IP.readline.set_completer(self.sys_ipcompleter_ori)
+            sys.ipcompleter = self.sys_ipcompleter_ori
+        except:
+            pass
+
+    def __call__(self,header='',local_ns=None,global_ns=None,dummy=None):
+        """Activate the interactive interpreter.
+
+        __call__(self,header='',local_ns=None,global_ns,dummy=None) -> Start
+        the interpreter shell with the given local and global namespaces, and
+        optionally print a header string at startup.
+
+        The shell can be globally activated/deactivated using the
+        set/get_dummy_mode methods. This allows you to turn off a shell used
+        for debugging globally.
+
+        However, *each* time you call the shell you can override the current
+        state of dummy_mode with the optional keyword parameter 'dummy'. For
+        example, if you set dummy mode on with IPShell.set_dummy_mode(1), you
+        can still have a specific call work by making it as IPShell(dummy=0).
+
+        The optional keyword parameter dummy controls whether the call
+        actually does anything.  """
+
+        # Allow the dummy parameter to override the global __dummy_mode
+        if dummy or (dummy != 0 and self.__dummy_mode):
+            return
+
+        # Set global subsystems (display,completions) to our values
+        sys.displayhook = self.sys_displayhook_embed
+        if self.IP.has_readline:
+            self.IP.readline.set_completer(self.IP.Completer.complete)
+
+        if self.banner and header:
+            format = '%s\n%s\n'
+        else:
+            format = '%s%s\n'
+        banner =  format % (self.banner,header)
+
+        # Call the embedding code with a stack depth of 1 so it can skip over
+        # our call and get the original caller's namespaces.
+        self.IP.embed_mainloop(banner,local_ns,global_ns,stack_depth=1)
+
+        if self.exit_msg:
+            print self.exit_msg
+            
+        # Restore global systems (display, completion)
+        sys.displayhook = self.sys_displayhook_ori
+        self.restore_system_completer()
+    
+    def set_dummy_mode(self,dummy):
+        """Sets the embeddable shell's dummy mode parameter.
+
+        set_dummy_mode(dummy): dummy = 0 or 1.
+
+        This parameter is persistent and makes calls to the embeddable shell
+        silently return without performing any action. This allows you to
+        globally activate or deactivate a shell you're using with a single call.
+
+        If you need to manually"""
+
+        if dummy not in [0,1]:
+            raise ValueError,'dummy parameter must be 0 or 1'
+        self.__dummy_mode = dummy
+
+    def get_dummy_mode(self):
+        """Return the current value of the dummy mode parameter.
+        """
+        return self.__dummy_mode
+    
+    def set_banner(self,banner):
+        """Sets the global banner.
+
+        This banner gets prepended to every header printed when the shell
+        instance is called."""
+
+        self.banner = banner
+
+    def set_exit_msg(self,exit_msg):
+        """Sets the global exit_msg.
+
+        This exit message gets printed upon exiting every time the embedded
+        shell is called. It is None by default. """
+
+        self.exit_msg = exit_msg
+
+#-----------------------------------------------------------------------------
+def sigint_handler (signum,stack_frame):
+    """Sigint handler for threaded apps.
+
+    This is a horrible hack to pass information about SIGINT _without_ using
+    exceptions, since I haven't been able to properly manage cross-thread
+    exceptions in GTK/WX.  In fact, I don't think it can be done (or at least
+    that's my understanding from a c.l.py thread where this was discussed)."""
+
+    global KBINT
+    
+    print '\nKeyboardInterrupt - Press <Enter> to continue.',
+    Term.cout.flush()
+    # Set global flag so that runsource can know that Ctrl-C was hit
+    KBINT = True
+
+class MTInteractiveShell(InteractiveShell):
+    """Simple multi-threaded shell."""
+
+    # Threading strategy taken from:
+    # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65109, by Brian
+    # McErlean and John Finlay.  Modified with corrections by Antoon Pardon,
+    # from the pygtk mailing list, to avoid lockups with system calls.
+
+    def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
+                 user_ns = None, banner2='',**kw):
+        """Similar to the normal InteractiveShell, but with threading control"""
+        
+        IPython.iplib.InteractiveShell.__init__(self,name,usage,rc,user_ns,banner2)
+
+        # Locking control variable
+        self.thread_ready = threading.Condition()
+
+        # Stuff to do at closing time
+        self._kill = False
+        on_kill = kw.get('on_kill')
+        if on_kill is None:
+            on_kill = []
+        # Check that all things to kill are callable:
+        for t in on_kill:
+            if not callable(t):
+                raise TypeError,'on_kill must be a list of callables'
+        self.on_kill = on_kill
+
+    def runsource(self, source, filename="<input>", symbol="single"):
+        """Compile and run some source in the interpreter.
+
+        Modified version of code.py's runsource(), to handle threading issues.
+        See the original for full docstring details."""
+
+        global KBINT
+        
+        # If Ctrl-C was typed, we reset the flag and return right away
+        if KBINT:
+            KBINT = False
+            return False
+        
+        try:
+            code = self.compile(source, filename, symbol)
+        except (OverflowError, SyntaxError, ValueError):
+            # Case 1
+            self.showsyntaxerror(filename)
+            return False
+
+        if code is None:
+            # Case 2
+            return True
+
+        # Case 3
+        # Store code in self, so the execution thread can handle it
+        self.thread_ready.acquire()
+        self.code_to_run_src = source
+        self.code_to_run = code
+        self.thread_ready.wait()  # Wait until processed in timeout interval
+        self.thread_ready.release()
+
+        return False
+
+    def runcode(self):
+        """Execute a code object.
+
+        Multithreaded wrapper around IPython's runcode()."""
+
+        # lock thread-protected stuff
+        self.thread_ready.acquire()
+
+        # Install sigint handler
+        try:
+            signal.signal(signal.SIGINT, sigint_handler)
+        except SystemError:
+            # This happens under Windows, which seems to have all sorts
+            # of problems with signal handling.  Oh well...
+            pass
+
+        if self._kill:
+            print >>Term.cout, 'Closing threads...',
+            Term.cout.flush()
+            for tokill in self.on_kill:
+                tokill()
+            print >>Term.cout, 'Done.'
+
+        # Run pending code by calling parent class
+        if self.code_to_run is not None:
+            self.thread_ready.notify()
+            InteractiveShell.runcode(self,self.code_to_run)
+            
+        # We're done with thread-protected variables
+        self.thread_ready.release()
+        # This MUST return true for gtk threading to work
+        return True
+
+    def kill (self):
+        """Kill the thread, returning when it has been shut down."""
+        self.thread_ready.acquire()
+        self._kill = True
+        self.thread_ready.release()
+
+class MatplotlibShellBase:
+    """Mixin class to provide the necessary modifications to regular IPython
+    shell classes for matplotlib support.
+
+    Given Python's MRO, this should be used as the FIRST class in the
+    inheritance hierarchy, so that it overrides the relevant methods."""
+    
+    def _matplotlib_config(self,name):
+        """Return various items needed to setup the user's shell with matplotlib"""
+
+        # Initialize matplotlib to interactive mode always
+        import matplotlib
+        from matplotlib import backends
+        matplotlib.interactive(True)
+
+        def use(arg):
+            """IPython wrapper for matplotlib's backend switcher.
+
+            In interactive use, we can not allow switching to a different
+            interactive backend, since thread conflicts will most likely crash
+            the python interpreter.  This routine does a safety check first,
+            and refuses to perform a dangerous switch.  It still allows
+            switching to non-interactive backends."""
+
+            if arg in backends.interactive_bk and arg != self.mpl_backend:
+                m=('invalid matplotlib backend switch.\n'
+                   'This script attempted to switch to the interactive '
+                   'backend: `%s`\n'
+                   'Your current choice of interactive backend is: `%s`\n\n'
+                   'Switching interactive matplotlib backends at runtime\n'
+                   'would crash the python interpreter, '
+                   'and IPython has blocked it.\n\n'
+                   'You need to either change your choice of matplotlib backend\n'
+                   'by editing your .matplotlibrc file, or run this script as a \n'
+                   'standalone file from the command line, not using IPython.\n' %
+                   (arg,self.mpl_backend) )
+                raise RuntimeError, m
+            else:
+                self.mpl_use(arg)
+                self.mpl_use._called = True
+        
+        self.matplotlib = matplotlib
+
+        # Take control of matplotlib's error handling, which can normally
+        # lock up the python interpreter when raw_input() is called
+        import matplotlib.backends as backend
+        backend.error_msg = error
+        
+        # we'll handle the mainloop, tell show not to
+        import matplotlib.backends
+        matplotlib.backends.show._needmain = False
+        self.mpl_backend = matplotlib.rcParams['backend']
+
+        # we also need to block switching of interactive backends by use()
+        self.mpl_use = matplotlib.use
+        self.mpl_use._called = False
+        # overwrite the original matplotlib.use with our wrapper
+        matplotlib.use = use
+
+        # We need to detect at runtime whether show() is called by the user.
+        # For this, we wrap it into a decorator which adds a 'called' flag.
+        backend.draw_if_interactive = flag_calls(backend.draw_if_interactive)
+
+        # This must be imported last in the matplotlib series, after
+        # backend/interactivity choices have been made
+        try:
+            import matplotlib.pylab as pylab
+            self.pylab = pylab
+            self.pylab_name = 'pylab'
+        except ImportError:
+            import matplotlib.matlab as matlab            
+            self.pylab = matlab
+            self.pylab_name = 'matlab'
+
+        # Build a user namespace initialized with matplotlib/matlab features.
+        user_ns = {'__name__':'__main__',
+                   '__builtins__' : __builtin__ }
+
+        # Be careful not to remove the final \n in the code string below, or
+        # things will break badly with py22 (I think it's a python bug, 2.3 is
+        # OK).
+        pname = self.pylab_name # Python can't interpolate dotted var names
+        exec ("import matplotlib\n"
+              "import matplotlib.%(pname)s as %(pname)s\n"
+              "from matplotlib.%(pname)s import *\n" % locals()) in user_ns
+        
+        # Build matplotlib info banner
+        b="""
+  Welcome to pylab, a matplotlib-based Python environment.
+  For more information, type 'help(pylab)'.
+"""
+        return user_ns,b
+
+    def mplot_exec(self,fname,*where,**kw):
+        """Execute a matplotlib script.
+
+        This is a call to execfile(), but wrapped in safeties to properly
+        handle interactive rendering and backend switching."""
+
+        #print '*** Matplotlib runner ***' # dbg
+        # turn off rendering until end of script
+        isInteractive = self.matplotlib.rcParams['interactive']
+        self.matplotlib.interactive(False)
+        self.safe_execfile(fname,*where,**kw)
+        self.matplotlib.interactive(isInteractive)
+        # make rendering call now, if the user tried to do it
+        if self.pylab.draw_if_interactive.called:
+            self.pylab.draw()
+            self.pylab.draw_if_interactive.called = False
+                
+        # if a backend switch was performed, reverse it now
+        if self.mpl_use._called:
+            self.matplotlib.rcParams['backend'] = self.mpl_backend
+        
+    def magic_run(self,parameter_s=''):
+        Magic.magic_run(self,parameter_s,runner=self.mplot_exec)
+
+    # Fix the docstring so users see the original as well
+    magic_run.__doc__ = "%s\n%s" % (Magic.magic_run.__doc__,
+                                    "\n        *** Modified %run for Matplotlib,"
+                                    " with proper interactive handling ***")
+
+# Now we provide 2 versions of a matplotlib-aware IPython base shells, single
+# and multithreaded.  Note that these are meant for internal use, the IPShell*
+# classes below are the ones meant for public consumption.
+
+class MatplotlibShell(MatplotlibShellBase,InteractiveShell):
+    """Single-threaded shell with matplotlib support."""
+
+    def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
+                 user_ns = None, **kw):
+        user_ns,b2 = self._matplotlib_config(name)
+        InteractiveShell.__init__(self,name,usage,rc,user_ns,banner2=b2,**kw)
+
+class MatplotlibMTShell(MatplotlibShellBase,MTInteractiveShell):
+    """Multi-threaded shell with matplotlib support."""
+
+    def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
+                 user_ns = None, **kw):
+        user_ns,b2 = self._matplotlib_config(name)
+        MTInteractiveShell.__init__(self,name,usage,rc,user_ns,banner2=b2,**kw)
+
+#-----------------------------------------------------------------------------
+# Utility functions for the different GUI enabled IPShell* classes.
+
+def get_tk():
+    """Tries to import Tkinter and returns a withdrawn Tkinter root
+    window.  If Tkinter is already imported or not available, this
+    returns None.  This function calls `hijack_tk` underneath.
+    """
+    if not USE_TK or sys.modules.has_key('Tkinter'):
+        return None
+    else:
+        try:
+            import Tkinter
+        except ImportError:
+            return None
+        else:
+            hijack_tk()
+            r = Tkinter.Tk()
+            r.withdraw()
+            return r
+
+def hijack_tk():
+    """Modifies Tkinter's mainloop with a dummy so when a module calls
+    mainloop, it does not block.
+
+    """
+    def misc_mainloop(self, n=0):
+        pass
+    def tkinter_mainloop(n=0):
+        pass
+    
+    import Tkinter
+    Tkinter.Misc.mainloop = misc_mainloop
+    Tkinter.mainloop = tkinter_mainloop
+
+def update_tk(tk):
+    """Updates the Tkinter event loop.  This is typically called from
+    the respective WX or GTK mainloops.
+    """    
+    if tk:
+        tk.update()
+
+def hijack_wx():
+    """Modifies wxPython's MainLoop with a dummy so user code does not
+    block IPython.  The hijacked mainloop function is returned.
+    """    
+    def dummy_mainloop(*args, **kw):
+        pass
+    import wxPython
+    ver = wxPython.__version__
+    orig_mainloop = None
+    if ver[:3] >= '2.5':
+        import wx
+        if hasattr(wx, '_core_'): core = getattr(wx, '_core_')
+        elif hasattr(wx, '_core'): core = getattr(wx, '_core')
+        else: raise AttributeError('Could not find wx core module')
+        orig_mainloop = core.PyApp_MainLoop
+        core.PyApp_MainLoop = dummy_mainloop
+    elif ver[:3] == '2.4':
+        orig_mainloop = wxPython.wxc.wxPyApp_MainLoop
+        wxPython.wxc.wxPyApp_MainLoop = dummy_mainloop
+    else:
+        warn("Unable to find either wxPython version 2.4 or >= 2.5.")
+    return orig_mainloop
+
+def hijack_gtk():
+    """Modifies pyGTK's mainloop with a dummy so user code does not
+    block IPython.  This function returns the original `gtk.mainloop`
+    function that has been hijacked.
+
+    NOTE: Make sure you import this *AFTER* you call
+    pygtk.require(...).
+    """    
+    def dummy_mainloop(*args, **kw):
+        pass
+    import gtk
+    if gtk.pygtk_version >= (2,4,0): orig_mainloop = gtk.main
+    else:                            orig_mainloop = gtk.mainloop
+    gtk.mainloop = dummy_mainloop
+    gtk.main = dummy_mainloop
+    return orig_mainloop
+
+#-----------------------------------------------------------------------------
+# The IPShell* classes below are the ones meant to be run by external code as
+# IPython instances.  Note that unless a specific threading strategy is
+# desired, the factory function start() below should be used instead (it
+# selects the proper threaded class).
+
+class IPShellGTK(threading.Thread):
+    """Run a gtk mainloop() in a separate thread.
+    
+    Python commands can be passed to the thread where they will be executed.
+    This is implemented by periodically checking for passed code using a
+    GTK timeout callback."""
+    
+    TIMEOUT = 100 # Millisecond interval between timeouts.
+
+    def __init__(self,argv=None,user_ns=None,debug=1,
+                 shell_class=MTInteractiveShell):
+
+        import pygtk
+        pygtk.require("2.0")
+        import gtk
+        
+        self.gtk = gtk
+        self.gtk_mainloop = hijack_gtk()
+
+        # Allows us to use both Tk and GTK.
+        self.tk = get_tk()
+        
+        if gtk.pygtk_version >= (2,4,0): mainquit = self.gtk.main_quit
+        else:                            mainquit = self.gtk.mainquit
+
+        self.IP = make_IPython(argv,user_ns=user_ns,debug=debug,
+                               shell_class=shell_class,
+                               on_kill=[mainquit])
+        threading.Thread.__init__(self)
+
+    def run(self):
+        self.IP.mainloop()
+        self.IP.kill()
+
+    def mainloop(self):
+
+        if self.gtk.pygtk_version >= (2,4,0):
+            import gobject
+            gobject.timeout_add(self.TIMEOUT, self.on_timer)
+        else:
+            self.gtk.timeout_add(self.TIMEOUT, self.on_timer)
+
+        if sys.platform != 'win32':
+            try:
+                if self.gtk.gtk_version[0] >= 2:
+                    self.gtk.threads_init()
+            except AttributeError:
+                pass
+            except RuntimeError:
+                error('Your pyGTK likely has not been compiled with '
+                      'threading support.\n'
+                      'The exception printout is below.\n'
+                      'You can either rebuild pyGTK with threads, or '
+                      'try using \n'
+                      'matplotlib with a different backend (like Tk or WX).\n'
+                      'Note that matplotlib will most likely not work in its '
+                      'current state!')
+                self.IP.InteractiveTB()
+        self.start()
+        self.gtk.threads_enter()
+        self.gtk_mainloop()
+        self.gtk.threads_leave()
+        self.join()
+
+    def on_timer(self):
+        update_tk(self.tk)
+        return self.IP.runcode()
+        
+
+class IPShellWX(threading.Thread):
+    """Run a wx mainloop() in a separate thread.
+    
+    Python commands can be passed to the thread where they will be executed.
+    This is implemented by periodically checking for passed code using a
+    GTK timeout callback."""
+    
+    TIMEOUT = 100 # Millisecond interval between timeouts.
+
+    def __init__(self,argv=None,user_ns=None,debug=1,
+                 shell_class=MTInteractiveShell):
+
+        import wxPython.wx as wx
+
+        threading.Thread.__init__(self)
+        self.wx = wx
+        self.wx_mainloop = hijack_wx()
+
+        # Allows us to use both Tk and GTK.
+        self.tk = get_tk()
+        
+        self.IP = make_IPython(argv,user_ns=user_ns,debug=debug,
+                               shell_class=shell_class,
+                               on_kill=[self.wxexit])
+        self.app = None
+
+    def wxexit(self, *args):
+        if self.app is not None:
+            self.app.agent.timer.Stop()
+            self.app.ExitMainLoop()
+
+    def run(self):
+        self.IP.mainloop()
+        self.IP.kill()
+
+    def mainloop(self):
+        
+        self.start()
+
+        class TimerAgent(self.wx.wxMiniFrame):
+            wx = self.wx
+            IP = self.IP
+            tk = self.tk
+            def __init__(self, parent, interval):
+                style = self.wx.wxDEFAULT_FRAME_STYLE | self.wx.wxTINY_CAPTION_HORIZ
+                self.wx.wxMiniFrame.__init__(self, parent, -1, ' ', pos=(200, 200),
+                                             size=(100, 100),style=style)
+                self.Show(False)
+                self.interval = interval
+                self.timerId = self.wx.wxNewId()                                
+
+            def StartWork(self):
+                self.timer = self.wx.wxTimer(self, self.timerId)
+                self.wx.EVT_TIMER(self,  self.timerId, self.OnTimer)
+                self.timer.Start(self.interval)
+
+            def OnTimer(self, event):
+                update_tk(self.tk)
+                self.IP.runcode()
+
+        class App(self.wx.wxApp):
+            wx = self.wx
+            TIMEOUT = self.TIMEOUT
+            def OnInit(self):
+                'Create the main window and insert the custom frame'
+                self.agent = TimerAgent(None, self.TIMEOUT)
+                self.agent.Show(self.wx.false)
+                self.agent.StartWork()
+                return self.wx.true
+        
+        self.app = App(redirect=False)
+        self.wx_mainloop(self.app)
+        self.join()
+
+
+class IPShellQt(threading.Thread):
+    """Run a Qt event loop in a separate thread.
+    
+    Python commands can be passed to the thread where they will be executed.
+    This is implemented by periodically checking for passed code using a
+    Qt timer / slot."""
+    
+    TIMEOUT = 100 # Millisecond interval between timeouts.
+
+    def __init__(self,argv=None,user_ns=None,debug=0,
+                 shell_class=MTInteractiveShell):
+        
+        import qt
+
+        class newQApplication:
+            def __init__( self ):
+                self.QApplication = qt.QApplication
+                
+            def __call__( *args, **kwargs ):
+                return qt.qApp
+
+            def exec_loop( *args, **kwargs ):
+                pass
+
+            def __getattr__( self, name ):
+                return getattr( self.QApplication, name )
+          
+        qt.QApplication = newQApplication()
+
+        # Allows us to use both Tk and QT.
+        self.tk = get_tk()
+
+        self.IP = make_IPython(argv,user_ns=user_ns,debug=debug,
+                               shell_class=shell_class,
+                               on_kill=[qt.qApp.exit])
+        
+        threading.Thread.__init__(self)
+
+    def run(self):
+        #sys.excepthook = self.IP.excepthook # dbg
+        self.IP.mainloop()
+        self.IP.kill()
+
+    def mainloop(self):
+        import qt, sys
+        if qt.QApplication.startingUp():
+          a = qt.QApplication.QApplication( sys.argv )
+        self.timer = qt.QTimer()
+        qt.QObject.connect( self.timer, qt.SIGNAL( 'timeout()' ), self.on_timer )
+
+        self.start()
+        self.timer.start( self.TIMEOUT, True )
+        while True:
+            if self.IP._kill: break
+            qt.qApp.exec_loop()
+        self.join()
+
+    def on_timer(self):
+        update_tk(self.tk)
+        result = self.IP.runcode()
+        self.timer.start( self.TIMEOUT, True )
+        return result
+
+# A set of matplotlib public IPython shell classes, for single-threaded
+# (Tk* and FLTK* backends) and multithreaded (GTK* and WX* backends) use.
+class IPShellMatplotlib(IPShell):
+    """Subclass IPShell with MatplotlibShell as the internal shell.
+
+    Single-threaded class, meant for the Tk* and FLTK* backends.
+
+    Having this on a separate class simplifies the external driver code."""
+    
+    def __init__(self,argv=None,user_ns=None,debug=1):
+        IPShell.__init__(self,argv,user_ns,debug,shell_class=MatplotlibShell)
+
+class IPShellMatplotlibGTK(IPShellGTK):
+    """Subclass IPShellGTK with MatplotlibMTShell as the internal shell.
+
+    Multi-threaded class, meant for the GTK* backends."""
+    
+    def __init__(self,argv=None,user_ns=None,debug=1):
+        IPShellGTK.__init__(self,argv,user_ns,debug,shell_class=MatplotlibMTShell)
+
+class IPShellMatplotlibWX(IPShellWX):
+    """Subclass IPShellWX with MatplotlibMTShell as the internal shell.
+
+    Multi-threaded class, meant for the WX* backends."""
+    
+    def __init__(self,argv=None,user_ns=None,debug=1):
+        IPShellWX.__init__(self,argv,user_ns,debug,shell_class=MatplotlibMTShell)
+
+class IPShellMatplotlibQt(IPShellQt):
+    """Subclass IPShellQt with MatplotlibMTShell as the internal shell.
+
+    Multi-threaded class, meant for the Qt* backends."""
+    
+    def __init__(self,argv=None,user_ns=None,debug=1):
+        IPShellQt.__init__(self,argv,user_ns,debug,shell_class=MatplotlibMTShell)
+
+#-----------------------------------------------------------------------------
+# Factory functions to actually start the proper thread-aware shell
+
+def _matplotlib_shell_class():
+    """Factory function to handle shell class selection for matplotlib.
+
+    The proper shell class to use depends on the matplotlib backend, since
+    each backend requires a different threading strategy."""
+
+    try:
+        import matplotlib
+    except ImportError:
+        error('matplotlib could NOT be imported!  Starting normal IPython.')
+        sh_class = IPShell
+    else:
+        backend = matplotlib.rcParams['backend']
+        if backend.startswith('GTK'):
+            sh_class = IPShellMatplotlibGTK
+        elif backend.startswith('WX'):
+            sh_class = IPShellMatplotlibWX
+        elif backend.startswith('Qt'):
+            sh_class = IPShellMatplotlibQt
+        else:
+            sh_class = IPShellMatplotlib
+    #print 'Using %s with the %s backend.' % (sh_class,backend) # dbg
+    return sh_class
+
+# This is the one which should be called by external code.
+def start():
+    """Return a running shell instance, dealing with threading options.
+
+    This is a factory function which will instantiate the proper IPython shell
+    based on the user's threading choice.  Such a selector is needed because
+    different GUI toolkits require different thread handling details."""
+
+    global USE_TK
+    # Crude sys.argv hack to extract the threading options.
+    if len(sys.argv) > 1:
+        if len(sys.argv) > 2:
+            arg2 = sys.argv[2]
+            if arg2.endswith('-tk'):
+                USE_TK = True
+        arg1 = sys.argv[1]
+        if arg1.endswith('-gthread'):
+            shell = IPShellGTK
+        elif arg1.endswith( '-qthread' ):
+            shell = IPShellQt
+        elif arg1.endswith('-wthread'):
+            shell = IPShellWX
+        elif arg1.endswith('-pylab'):
+            shell = _matplotlib_shell_class()
+        else:
+            shell = IPShell
+    else:
+        shell = IPShell
+    return shell()
+
+# Some aliases for backwards compatibility
+IPythonShell = IPShell
+IPythonShellEmbed = IPShellEmbed
+#************************ End of file <Shell.py> ***************************
diff --git a/IPython/Struct.py b/IPython/Struct.py
new file mode 100644
index 0000000..da316f9
--- /dev/null
+++ b/IPython/Struct.py
@@ -0,0 +1,376 @@
+# -*- coding: utf-8 -*-
+"""Mimic C structs with lots of extra functionality.
+
+$Id: Struct.py 410 2004-11-04 07:58:17Z fperez $"""
+
+#*****************************************************************************
+#       Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
+#
+#  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
+
+__all__ = ['Struct']
+
+import types
+from IPython.genutils import list2dict2
+
+class Struct:
+    """Class to mimic C structs but also provide convenient dictionary-like
+    functionality.
+
+    Instances can be initialized with a dictionary, a list of key=value pairs
+    or both. If both are present, the dictionary must come first.
+
+    Because Python classes provide direct assignment to their members, it's
+    easy to overwrite normal methods (S.copy = 1 would destroy access to
+    S.copy()). For this reason, all builtin method names are protected and
+    can't be assigned to. An attempt to do s.copy=1 or s['copy']=1 will raise
+    a KeyError exception. If you really want to, you can bypass this
+    protection by directly assigning to __dict__: s.__dict__['copy']=1 will
+    still work. Doing this will break functionality, though. As in most of
+    Python, namespace protection is weakly enforced, so feel free to shoot
+    yourself if you really want to.
+
+    Note that this class uses more memory and is *much* slower than a regular
+    dictionary, so be careful in situations where memory or performance are
+    critical. But for day to day use it should behave fine. It is particularly
+    convenient for storing configuration data in programs.
+
+    +,+=,- and -= are implemented. +/+= do merges (non-destructive updates),
+    -/-= remove keys from the original. See the method descripitions.
+
+    This class allows a quick access syntax: both s.key and s['key'] are
+    valid.  This syntax has a limitation: each 'key' has to be explicitly
+    accessed by its original name. The normal s.key syntax doesn't provide
+    access to the keys via variables whose values evaluate to the desired
+    keys. An example should clarify this:
+
+    Define a dictionary and initialize both with dict and k=v pairs:
+    >>> d={'a':1,'b':2}
+    >>> s=Struct(d,hi=10,ho=20)
+    The return of __repr__ can be used to create a new instance:
+    >>> s
+    Struct({'ho': 20, 'b': 2, 'hi': 10, 'a': 1})
+    __str__ (called by print) shows it's not quite a regular dictionary:
+    >>> print s
+    Struct {a: 1, b: 2, hi: 10, ho: 20}
+    Access by explicitly named key with dot notation:
+    >>> s.a
+    1
+    Or like a dictionary:
+    >>> s['a']
+    1
+    If you want a variable to hold the key value, only dictionary access works:
+    >>> key='hi'
+    >>> s.key
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in ?
+    AttributeError: Struct instance has no attribute 'key'
+    >>> s[key]
+    10
+
+    Another limitation of the s.key syntax (and Struct(key=val)
+    initialization): keys can't be numbers. But numeric keys can be used and
+    accessed using the dictionary syntax. Again, an example:
+
+    This doesn't work:
+    >>> s=Struct(4='hi')
+    SyntaxError: keyword can't be an expression
+    But this does:
+    >>> s=Struct()
+    >>> s[4]='hi'
+    >>> s
+    Struct({4: 'hi'})
+    >>> s[4]
+    'hi'
+    """
+
+    # Attributes to which __setitem__ and __setattr__ will block access.
+    # Note: much of this will be moot in Python 2.2 and will be done in a much
+    # cleaner way.
+    __protected = ('copy dict dictcopy get has_attr has_key items keys '
+                   'merge popitem setdefault update values '
+                   '__make_dict __dict_invert ').split()
+
+    def __init__(self,dict=None,**kw):
+        """Initialize with a dictionary, another Struct, or by giving
+        explicitly the list of attributes.
+
+        Both can be used, but the dictionary must come first:
+        Struct(dict), Struct(k1=v1,k2=v2) or Struct(dict,k1=v1,k2=v2).
+        """
+        if dict is None:
+            dict = {}
+        if isinstance(dict,Struct):
+            dict = dict.dict()
+        elif dict and  type(dict) is not types.DictType:
+            raise TypeError,\
+                  'Initialize with a dictionary or key=val pairs.'
+        dict.update(kw)
+        # do the updating by hand to guarantee that we go through the
+        # safety-checked __setitem__
+        for k,v in dict.items():
+            self[k] = v
+
+    def __setitem__(self,key,value):
+        """Used when struct[key] = val calls are made."""
+        if key in Struct.__protected:
+            raise KeyError,'Key '+`key`+' is a protected key of class Struct.'
+        self.__dict__[key] = value
+
+    def __setattr__(self, key, value):
+        """Used when struct.key = val calls are made."""
+        self.__setitem__(key,value)
+
+    def __str__(self):
+        """Gets called by print."""
+        
+        return 'Struct('+str(self.__dict__)+')'
+
+    def __repr__(self):
+        """Gets called by repr.
+        
+        A Struct can be recreated with S_new=eval(repr(S_old))."""
+        return 'Struct('+str(self.__dict__)+')'
+
+    def __getitem__(self,key):
+        """Allows struct[key] access."""
+        return self.__dict__[key]
+
+    def __contains__(self,key):
+        """Allows use of the 'in' operator."""
+        return self.__dict__.has_key(key)
+
+    def __iadd__(self,other):
+        """S += S2 is a shorthand for S.merge(S2)."""
+        self.merge(other)
+        return self
+
+    def __add__(self,other):
+        """S + S2 -> New Struct made form S and S.merge(S2)"""
+        Sout = self.copy()
+        Sout.merge(other)
+        return Sout
+
+    def __sub__(self,other):
+        """Return S1-S2, where all keys in S2 have been deleted (if present)
+        from S1."""
+        Sout = self.copy()
+        Sout -= other
+        return Sout
+
+    def __isub__(self,other):
+        """Do in place S = S - S2, meaning all keys in S2 have been deleted
+        (if present) from S1."""
+
+        for k in other.keys():
+            if self.has_key(k):
+                del self.__dict__[k]
+
+    def __make_dict(self,__loc_data__,**kw):
+        "Helper function for update and merge. Return a dict from data."
+
+        if __loc_data__ == None:
+            dict = {}
+        elif type(__loc_data__) is types.DictType:
+            dict = __loc_data__
+        elif isinstance(__loc_data__,Struct):
+            dict = __loc_data__.__dict__
+        else:
+            raise TypeError, 'Update with a dict, a Struct or key=val pairs.'
+        if kw:
+            dict.update(kw)
+        return dict
+
+    def __dict_invert(self,dict):
+        """Helper function for merge. Takes a dictionary whose values are
+        lists and returns a dict. with the elements of each list as keys and
+        the original keys as values."""
+
+        outdict = {}
+        for k,lst in dict.items():
+            if type(lst) is types.StringType:
+                lst = lst.split()
+            for entry in lst:
+                outdict[entry] = k
+        return outdict
+
+    def clear(self):
+        """Clear all attributes."""
+        self.__dict__.clear()
+
+    def copy(self):
+        """Return a (shallow) copy of a Struct."""
+        return Struct(self.__dict__.copy())
+
+    def dict(self):
+        """Return the Struct's dictionary."""
+        return self.__dict__
+
+    def dictcopy(self):
+        """Return a (shallow) copy of the Struct's dictionary."""
+        return self.__dict__.copy()
+
+    def popitem(self):
+        """S.popitem() -> (k, v), remove and return some (key, value) pair as
+        a 2-tuple; but raise KeyError if S is empty."""
+        return self.__dict__.popitem()
+
+    def update(self,__loc_data__=None,**kw):
+        """Update (merge) with data from another Struct or from a dictionary.
+        Optionally, one or more key=value pairs can be given at the end for
+        direct update."""
+
+        # The funny name __loc_data__ is to prevent a common variable name which
+        # could be a fieled of a Struct to collide with this parameter. The problem
+        # would arise if the function is called with a keyword with this same name
+        # that a user means to add as a Struct field.
+        newdict = Struct.__make_dict(self,__loc_data__,**kw)
+        for k,v in newdict.items():
+            self[k] = v
+
+    def merge(self,__loc_data__=None,__conflict_solve=None,**kw):
+        """S.merge(data,conflict,k=v1,k=v2,...) -> merge data and k=v into S.
+
+        This is similar to update(), but much more flexible.  First, a dict is
+        made from data+key=value pairs. When merging this dict with the Struct
+        S, the optional dictionary 'conflict' is used to decide what to do.
+
+        If conflict is not given, the default behavior is to preserve any keys
+        with their current value (the opposite of the update method's
+        behavior).
+
+        conflict is a dictionary of binary functions which will be used to
+        solve key conflicts. It must have the following structure:
+
+          conflict == { fn1 : [Skey1,Skey2,...], fn2 : [Skey3], etc }
+
+        Values must be lists or whitespace separated strings which are
+        automatically converted to lists of strings by calling string.split().
+
+        Each key of conflict is a function which defines a policy for
+        resolving conflicts when merging with the input data. Each fn must be
+        a binary function which returns the desired outcome for a key
+        conflict. These functions will be called as fn(old,new).
+
+        An example is probably in order. Suppose you are merging the struct S
+        with a dict D and the following conflict policy dict:
+
+            S.merge(D,{fn1:['a','b',4], fn2:'key_c key_d'})
+
+        If the key 'a' is found in both S and D, the merge method will call:
+
+            S['a'] = fn1(S['a'],D['a'])
+
+        As a convenience, merge() provides five (the most commonly needed)
+        pre-defined policies: preserve, update, add, add_flip and add_s. The
+        easiest explanation is their implementation:
+
+          preserve = lambda old,new: old
+          update   = lambda old,new: new
+          add      = lambda old,new: old + new
+          add_flip = lambda old,new: new + old  # note change of order!
+          add_s    = lambda old,new: old + ' ' + new  # only works for strings!
+
+        You can use those four words (as strings) as keys in conflict instead
+        of defining them as functions, and the merge method will substitute
+        the appropriate functions for you. That is, the call
+
+          S.merge(D,{'preserve':'a b c','add':[4,5,'d'],my_function:[6]})
+
+        will automatically substitute the functions preserve and add for the
+        names 'preserve' and 'add' before making any function calls.
+
+        For more complicated conflict resolution policies, you still need to
+        construct your own functions. """
+
+        data_dict = Struct.__make_dict(self,__loc_data__,**kw)
+
+        # policies for conflict resolution: two argument functions which return
+        # the value that will go in the new struct
+        preserve = lambda old,new: old
+        update   = lambda old,new: new
+        add      = lambda old,new: old + new
+        add_flip = lambda old,new: new + old  # note change of order!
+        add_s    = lambda old,new: old + ' ' + new
+
+        # default policy is to keep current keys when there's a conflict
+        conflict_solve = list2dict2(self.keys(),default = preserve)
+
+        # the conflict_solve dictionary is given by the user 'inverted': we
+        # need a name-function mapping, it comes as a function -> names
+        # dict. Make a local copy (b/c we'll make changes), replace user
+        # strings for the three builtin policies and invert it.
+        if __conflict_solve:
+            inv_conflict_solve_user = __conflict_solve.copy()
+            for name, func in [('preserve',preserve), ('update',update),
+                               ('add',add), ('add_flip',add_flip), ('add_s',add_s)]:
+                if name in inv_conflict_solve_user.keys():
+                    inv_conflict_solve_user[func] = inv_conflict_solve_user[name]
+                    del inv_conflict_solve_user[name]
+            conflict_solve.update(Struct.__dict_invert(self,inv_conflict_solve_user))
+        #print 'merge. conflict_solve: '; pprint(conflict_solve) # dbg
+        # after Python 2.2, use iterators: for key in data_dict will then work
+        #print '*'*50,'in merger. conflict_solver:';  pprint(conflict_solve)
+        for key in data_dict.keys():
+            if key not in self:
+                self[key] = data_dict[key]
+            else:
+                self[key] = conflict_solve[key](self[key],data_dict[key])
+
+    def has_key(self,key):
+        """Like has_key() dictionary method."""
+        return self.__dict__.has_key(key)
+
+    def hasattr(self,key):
+        """hasattr function available as a method.
+
+        Implemented like has_key, to make sure that all available keys in the
+        internal dictionary of the Struct appear also as attributes (even
+        numeric keys)."""
+        return self.__dict__.has_key(key)
+
+    def items(self):
+        """Return the items in the Struct's dictionary, in the same format
+        as a call to {}.items()."""
+        return self.__dict__.items()
+
+    def keys(self):
+        """Return the keys in the Struct's dictionary, in the same format
+        as a call to {}.keys()."""
+        return self.__dict__.keys()
+
+    def values(self,keys=None):
+        """Return the values in the Struct's dictionary, in the same format
+        as a call to {}.values().
+
+        Can be called with an optional argument keys, which must be a list or
+        tuple of keys. In this case it returns only the values corresponding
+        to those keys (allowing a form of 'slicing' for Structs)."""
+        if not keys:
+            return self.__dict__.values()
+        else:
+            ret=[]
+            for k in keys:
+                ret.append(self[k])
+            return ret
+
+    def get(self,attr,val=None):
+        """S.get(k[,d]) -> S[k] if S.has_key(k), else d.  d defaults to None."""
+        try:
+            return self[attr]
+        except KeyError:
+            return val
+
+    def setdefault(self,attr,val=None):
+        """S.setdefault(k[,d]) -> S.get(k,d), also set S[k]=d if not S.has_key(k)"""
+        if not self.has_key(attr):
+            self[attr] = val
+        return self.get(attr,val)
+# end class Struct
+
diff --git a/IPython/UserConfig/ipythonrc b/IPython/UserConfig/ipythonrc
new file mode 100644
index 0000000..4062050
--- /dev/null
+++ b/IPython/UserConfig/ipythonrc
@@ -0,0 +1,546 @@
+# -*- Mode: Shell-Script -*-  Not really, but shows comments correctly
+# $Id: ipythonrc 596 2005-06-01 17:01:13Z fperez $
+
+#***************************************************************************
+#
+# Configuration file for IPython -- ipythonrc format
+#
+# The format of this file is simply one of 'key value' lines.
+# Lines containing only whitespace at the beginning and then a # are ignored
+# as comments. But comments can NOT be put on lines with data.
+
+# The meaning and use of each key are explained below.
+
+#---------------------------------------------------------------------------
+# Section: included files
+
+# Put one or more *config* files (with the syntax of this file) you want to
+# include. For keys with a unique value the outermost file has precedence. For
+# keys with multiple values, they all get assembled into a list which then
+# gets loaded by IPython.
+
+# In this file, all lists of things should simply be space-separated.
+
+# This allows you to build hierarchies of files which recursively load
+# lower-level services. If this is your main ~/.ipython/ipythonrc file, you
+# should only keep here basic things you always want available. Then you can
+# include it in every other special-purpose config file you create.
+include 
+
+#---------------------------------------------------------------------------
+# Section: startup setup
+
+# These are mostly things which parallel a command line option of the same
+# name.
+
+# Keys in this section should only appear once. If any key from this section
+# is encountered more than once, the last value remains, all earlier ones get
+# discarded.
+
+# Automatic calling of callable objects.  If set to true, callable objects are
+# automatically called when invoked at the command line, even if you don't
+# type parentheses.  IPython adds the parentheses for you.  For example:
+
+#In [1]: str 45
+#------> str(45)
+#Out[1]: '45'
+
+# IPython reprints your line with '---->' indicating that it added
+# parentheses.  While this option is very convenient for interactive use, it
+# may occasionally cause problems with objects which have side-effects if
+# called unexpectedly.  Set it to 0 if you want to disable it.
+
+# Note that even with autocall off, you can still use '/' at the start of a
+# line to treat the first argument on the command line as a function and add
+# parentheses to it:
+
+#In [8]: /str 43
+#------> str(43)
+#Out[8]: '43'
+
+autocall 1
+
+# Auto-indent. IPython can recognize lines ending in ':' and indent the next
+# line, while also un-indenting automatically after 'raise' or 'return'.  
+
+# This feature uses the readline library, so it will honor your ~/.inputrc
+# configuration (or whatever file your INPUTRC variable points to).  Adding
+# the following lines to your .inputrc file can make indent/unindenting more
+# convenient (M-i indents, M-u unindents):
+
+#  $if Python
+#  "\M-i": "    "
+#  "\M-u": "\d\d\d\d"
+#  $endif
+
+# The feature is potentially a bit dangerous, because it can cause problems
+# with pasting of indented code (the pasted code gets re-indented on each
+# line).  But it's a huge time-saver when working interactively.  The magic
+# function @autoindent allows you to toggle it on/off at runtime.
+
+autoindent 1
+
+# Auto-magic. This gives you access to all the magic functions without having
+# to prepend them with an @ sign. If you define a variable with the same name
+# as a magic function (say who=1), you will need to access the magic function
+# with @ (@who in this example). However, if later you delete your variable
+# (del who), you'll recover the automagic calling form.
+
+# Considering that many magic functions provide a lot of shell-like
+# functionality, automagic gives you something close to a full Python+system
+# shell environment (and you can extend it further if you want).
+
+automagic 1
+
+# Size of the output cache. After this many entries are stored, the cache will
+# get flushed. Depending on the size of your intermediate calculations, you
+# may have memory problems if you make it too big, since keeping things in the
+# cache prevents Python from reclaiming the memory for old results. Experiment
+# with a value that works well for you.
+
+# If you choose cache_size 0 IPython will revert to python's regular >>>
+# unnumbered prompt. You will still have _, __ and ___ for your last three
+# results, but that will be it.  No dynamic _1, _2, etc. will be created. If
+# you are running on a slow machine or with very limited memory, this may
+# help.
+
+cache_size 1000
+
+# Classic mode: Setting 'classic 1' you lose many of IPython niceties,
+# but that's your choice! Classic 1 -> same as IPython -classic.
+# Note that this is _not_ the normal python interpreter, it's simply
+# IPython emulating most of the classic interpreter's behavior.
+classic 0
+
+# colors - Coloring option for prompts and traceback printouts.
+
+# Currently available schemes: NoColor, Linux, LightBG.
+
+# This option allows coloring the prompts and traceback printouts. This
+# requires a terminal which can properly handle color escape sequences. If you
+# are having problems with this, use the NoColor scheme (uses no color escapes
+# at all).
+
+# The Linux option works well in linux console type environments: dark
+# background with light fonts.
+
+# LightBG is similar to Linux but swaps dark/light colors to be more readable
+# in light background terminals.
+
+# keep uncommented only the one you want:
+colors Linux
+#colors LightBG
+#colors NoColor
+
+########################
+# Note to Windows users
+#
+# Color and readline support is avaialble to Windows users via Gary Bishop's
+# readline library.  You can find Gary's tools at
+# http://sourceforge.net/projects/uncpythontools.
+# Note that his readline module requires in turn the ctypes library, available
+# at http://starship.python.net/crew/theller/ctypes.
+########################
+
+# color_info: IPython can display information about objects via a set of
+# functions, and optionally can use colors for this, syntax highlighting
+# source code and various other elements. This information is passed through a
+# pager (it defaults to 'less' if $PAGER is not set). 
+
+# If your pager has problems, try to setting it to properly handle escapes
+# (see the less manpage for detail), or disable this option.  The magic
+# function @color_info allows you to toggle this interactively for testing.
+
+color_info 1
+
+# confirm_exit: set to 1 if you want IPython to confirm when you try to exit
+# with an EOF (Control-d in Unix, Control-Z/Enter in Windows). Note that using
+# the magic functions @Exit or @Quit you can force a direct exit, bypassing
+# any confirmation.
+
+confirm_exit 1
+
+# Use deep_reload() as a substitute for reload() by default. deep_reload() is
+# still available as dreload() and appears as a builtin.
+
+deep_reload 0
+
+# Which editor to use with the @edit command. If you leave this at 0, IPython
+# will honor your EDITOR environment variable. Since this editor is invoked on
+# the fly by ipython and is meant for editing small code snippets, you may
+# want to use a small, lightweight editor here.
+
+# For Emacs users, setting up your Emacs server properly as described in the
+# manual is a good idea. An alternative is to use jed, a very light editor
+# with much of the feel of Emacs (though not as powerful for heavy-duty work).
+
+editor 0
+
+# log 1 -> same as ipython -log. This automatically logs to ./ipython.log
+log 0
+
+# Same as ipython -Logfile YourLogfileName. 
+# Don't use with log 1 (use one or the other)
+logfile ''
+
+# banner 0 -> same as ipython -nobanner
+banner 1
+
+# messages 0 -> same as ipython -nomessages
+messages 1
+
+# Automatically call the pdb debugger after every uncaught exception. If you
+# are used to debugging using pdb, this puts you automatically inside of it
+# after any call (either in IPython or in code called by it) which triggers an
+# exception which goes uncaught.
+pdb 0
+
+# Enable the pprint module for printing. pprint tends to give a more readable
+# display (than print) for complex nested data structures.
+pprint 1
+
+# Prompt strings
+
+# Most bash-like escapes can be used to customize IPython's prompts, as well as
+# a few additional ones which are IPython-specific.  All valid prompt escapes
+# are described in detail in the Customization section of the IPython HTML/PDF
+# manual.
+
+# Use \# to represent the current prompt number, and quote them to protect
+# spaces.
+prompt_in1 'In [\#]: '
+
+# \D is replaced by as many dots as there are digits in the
+# current value of \#.
+prompt_in2 '   .\D.: '
+
+prompt_out 'Out[\#]: '
+
+# Select whether to left-pad the output prompts to match the length of the
+# input ones.  This allows you for example to use a simple '>' as an output
+# prompt, and yet have the output line up with the input.  If set to false,
+# the output prompts will be unpadded (flush left).
+prompts_pad_left 1
+
+# quick 1 -> same as ipython -quick
+quick 0
+
+# Use the readline library (1) or not (0). Most users will want this on, but
+# if you experience strange problems with line management (mainly when using
+# IPython inside Emacs buffers) you may try disabling it. Not having it on
+# prevents you from getting command history with the arrow keys, searching and
+# name completion using TAB.
+
+readline 1
+
+# Screen Length: number of lines of your screen. This is used to control
+# printing of very long strings. Strings longer than this number of lines will
+# be paged with the less command instead of directly printed.
+
+# The default value for this is 0, which means IPython will auto-detect your
+# screen size every time it needs to print. If for some reason this isn't
+# working well (it needs curses support), specify it yourself. Otherwise don't
+# change the default.
+
+screen_length 0
+
+# Prompt separators for input and output.
+# Use \n for newline explicitly, without quotes.
+# Use 0 (like at the cmd line) to turn off a given separator.
+
+# The structure of prompt printing is:
+# (SeparateIn)Input....
+# (SeparateOut)Output...
+# (SeparateOut2),   # that is, no newline is printed after Out2
+# By choosing these you can organize your output any way you want.
+
+separate_in \n
+separate_out 0
+separate_out2 0
+
+# 'nosep 1' is a shorthand for '-SeparateIn 0 -SeparateOut 0 -SeparateOut2 0'.
+# Simply removes all input/output separators, overriding the choices above.
+nosep 0
+
+# xmode - Exception reporting mode. 
+
+# Valid modes: Plain, Context and Verbose.
+
+# Plain: similar to python's normal traceback printing.
+
+# Context: prints 5 lines of context source code around each line in the
+# traceback.
+
+# Verbose: similar to Context, but additionally prints the variables currently
+# visible where the exception happened (shortening their strings if too
+# long). This can potentially be very slow, if you happen to have a huge data
+# structure whose string representation is complex to compute. Your computer
+# may appear to freeze for a while with cpu usage at 100%. If this occurs, you
+# can cancel the traceback with Ctrl-C (maybe hitting it more than once).
+
+#xmode Plain
+xmode Context
+#xmode Verbose
+
+# multi_line_specials: if true, allow magics, aliases and shell escapes (via
+# !cmd) to be used in multi-line input (like for loops).  For example, if you
+# have this active, the following is valid in IPython:
+#
+#In [17]: for i in range(3):
+#   ....:     mkdir $i
+#   ....:     !touch $i/hello
+#   ....:     ls -l $i
+
+multi_line_specials 1
+
+#---------------------------------------------------------------------------
+# Section: Readline configuration (readline is not available for MS-Windows)
+
+# This is done via the following options:
+
+# (i) readline_parse_and_bind: this option can appear as many times as you
+# want, each time defining a string to be executed via a
+# readline.parse_and_bind() command. The syntax for valid commands of this
+# kind can be found by reading the documentation for the GNU readline library,
+# as these commands are of the kind which readline accepts in its
+# configuration file.
+
+# The TAB key can be used to complete names at the command line in one of two
+# ways: 'complete' and 'menu-complete'. The difference is that 'complete' only
+# completes as much as possible while 'menu-complete' cycles through all
+# possible completions. Leave the one you prefer uncommented.
+
+readline_parse_and_bind tab: complete
+#readline_parse_and_bind tab: menu-complete
+
+# This binds Control-l to printing the list of all possible completions when
+# there is more than one (what 'complete' does when hitting TAB twice, or at
+# the first TAB if show-all-if-ambiguous is on)
+readline_parse_and_bind "\C-l": possible-completions
+
+# This forces readline to automatically print the above list when tab
+# completion is set to 'complete'. You can still get this list manually by
+# using the key bound to 'possible-completions' (Control-l by default) or by
+# hitting TAB twice. Turning this on makes the printing happen at the first
+# TAB.
+readline_parse_and_bind set show-all-if-ambiguous on
+
+# If you have TAB set to complete names, you can rebind any key (Control-o by
+# default) to insert a true TAB character.
+readline_parse_and_bind "\C-o": tab-insert
+
+# These commands allow you to indent/unindent easily, with the 4-space
+# convention of the Python coding standards.  Since IPython's internal
+# auto-indent system also uses 4 spaces, you should not change the number of
+# spaces in the code below.
+readline_parse_and_bind "\M-i": "    "
+readline_parse_and_bind "\M-o": "\d\d\d\d"
+readline_parse_and_bind "\M-I": "\d\d\d\d"
+
+# Bindings for incremental searches in the history. These searches use the
+# string typed so far on the command line and search anything in the previous
+# input history containing them.
+readline_parse_and_bind "\C-r": reverse-search-history
+readline_parse_and_bind "\C-s": forward-search-history
+
+# Bindings for completing the current line in the history of previous
+# commands. This allows you to recall any previous command by typing its first
+# few letters and hitting Control-p, bypassing all intermediate commands which
+# may be in the history (much faster than hitting up-arrow 50 times!)
+readline_parse_and_bind "\C-p": history-search-backward
+readline_parse_and_bind "\C-n": history-search-forward
+
+# I also like to have the same functionality on the plain arrow keys. If you'd
+# rather have the arrows use all the history (and not just match what you've
+# typed so far), comment out or delete the next two lines.
+readline_parse_and_bind "\e[A": history-search-backward
+readline_parse_and_bind "\e[B": history-search-forward
+
+# (ii) readline_remove_delims: a string of characters to be removed from the
+# default word-delimiters list used by readline, so that completions may be
+# performed on strings which contain them.
+
+readline_remove_delims -/~
+
+# (iii) readline_merge_completions: whether to merge the result of all
+# possible completions or not.  If true, IPython will complete filenames,
+# python names and aliases and return all possible completions.  If you set it
+# to false, each completer is used at a time, and only if it doesn't return
+# any completions is the next one used.
+
+# The default order is: [python_matches, file_matches, alias_matches]
+
+readline_merge_completions 1
+
+# (iv) readline_omit__names: normally hitting <tab> after a '.' in a name
+# will complete all attributes of an object, including all the special methods
+# whose names start with single or double underscores (like __getitem__ or
+# __class__).
+
+# This variable allows you to control this completion behavior:
+
+# readline_omit__names 1 -> completion will omit showing any names starting
+# with two __, but it will still show names starting with one _.
+
+# readline_omit__names 2 -> completion will omit all names beginning with one
+# _ (which obviously means filtering out the double __ ones).
+
+# Even when this option is set, you can still see those names by explicitly
+# typing a _ after the period and hitting <tab>: 'name._<tab>' will always
+# complete attribute names starting with '_'.
+
+# This option is off by default so that new users see all attributes of any
+# objects they are dealing with.
+
+readline_omit__names 0
+
+#---------------------------------------------------------------------------
+# Section: modules to be loaded with 'import ...'
+
+# List, separated by spaces, the names of the modules you want to import
+
+# Example:
+# import_mod sys os
+# will produce internally the statements
+# import sys
+# import os
+
+# Each import is executed in its own try/except block, so if one module
+# fails to load the others will still be ok.
+
+import_mod 
+
+#---------------------------------------------------------------------------
+# Section: modules to import some functions from: 'from ... import ...'
+
+# List, one per line, the modules for which you want only to import some
+# functions. Give the module name first and then the name of functions to be
+# imported from that module.
+
+# Example:
+
+# import_some IPython.genutils timing timings
+# will produce internally the statement
+# from IPython.genutils import timing, timings
+
+# timing() and timings() are two IPython utilities for timing the execution of
+# your own functions, which you may find useful.  Just commment out the above
+# line if you want to test them.
+
+# If you have more than one modules_some line, each gets its own try/except
+# block (like modules, see above).
+
+import_some 
+
+#---------------------------------------------------------------------------
+# Section: modules to import all from : 'from ... import *'
+
+# List (same syntax as import_mod above) those modules for which you want to
+# import all functions. Remember, this is a potentially dangerous thing to do,
+# since it is very easy to overwrite names of things you need. Use with
+# caution.
+
+# Example:
+# import_all sys os
+# will produce internally the statements
+# from sys import *
+# from os import *
+
+# As before, each will be called in a separate try/except block.
+
+import_all 
+
+#---------------------------------------------------------------------------
+# Section: Python code to execute.
+
+# Put here code to be explicitly executed (keep it simple!)
+# Put one line of python code per line. All whitespace is removed (this is a
+# feature, not a bug), so don't get fancy building loops here.
+# This is just for quick convenient creation of things you want available.
+
+# Example:
+# execute x = 1
+# execute print 'hello world'; y = z = 'a'
+# will produce internally
+# x = 1
+# print 'hello world'; y = z = 'a'
+# and each *line* (not each statement, we don't do python syntax parsing) is
+# executed in its own try/except block.
+
+execute 
+
+# Note for the adventurous: you can use this to define your own names for the
+# magic functions, by playing some namespace tricks:
+
+# execute __IPYTHON__.magic_pf = __IPYTHON__.magic_profile
+
+# defines @pf as a new name for @profile.
+
+#---------------------------------------------------------------------------
+# Section: Pyhton files to load and execute.
+
+# Put here the full names of files you want executed with execfile(file).  If
+# you want complicated initialization, just write whatever you want in a
+# regular python file and load it from here.
+
+# Filenames defined here (which *must* include the extension) are searched for
+# through all of sys.path. Since IPython adds your .ipython directory to
+# sys.path, they can also be placed in your .ipython dir and will be
+# found. Otherwise (if you want to execute things not in .ipyton nor in
+# sys.path) give a full path (you can use ~, it gets expanded)
+
+# Example:
+# execfile file1.py ~/file2.py
+# will generate
+# execfile('file1.py')
+# execfile('_path_to_your_home/file2.py')
+
+# As before, each file gets its own try/except block.
+
+execfile
+
+# If you are feeling adventurous, you can even add functionality to IPython
+# through here. IPython works through a global variable called __ip which
+# exists at the time when these files are read. If you know what you are doing
+# (read the source) you can add functions to __ip in files loaded here. 
+
+# The file example-magic.py contains a simple but correct example. Try it:
+
+# execfile example-magic.py
+
+# Look at the examples in IPython/iplib.py for more details on how these magic
+# functions need to process their arguments.
+
+#---------------------------------------------------------------------------
+# Section: aliases for system shell commands
+
+# Here you can define your own names for system commands. The syntax is
+# similar to that of the builtin @alias function:
+
+# alias alias_name command_string
+
+# The resulting aliases are auto-generated magic functions (hence usable as
+# @alias_name)
+
+# For example:
+
+# alias myls ls -la
+
+# will define 'myls' as an alias for executing the system command 'ls -la'.
+# This allows you to customize IPython's environment to have the same aliases
+# you are accustomed to from your own shell.
+
+# You can also define aliases with parameters using %s specifiers (one per
+# parameter):
+
+# alias parts echo first %s second %s
+
+# will give you in IPython:
+# >>> @parts A B
+# first A second B
+
+# Use one 'alias' statement per alias you wish to define.
+
+# alias 
+
+#************************* end of file <ipythonrc> ************************
diff --git a/IPython/UserConfig/ipythonrc-math b/IPython/UserConfig/ipythonrc-math
new file mode 100644
index 0000000..c32bcd1
--- /dev/null
+++ b/IPython/UserConfig/ipythonrc-math
@@ -0,0 +1,36 @@
+# -*- Mode: Shell-Script -*-  Not really, but shows comments correctly
+#***************************************************************************
+#
+# Configuration file for ipython -- ipythonrc format
+#
+# The format of this file is one of 'key value' lines.
+# Lines containing only whitespace at the beginning and then a # are ignored
+# as comments. But comments can NOT be put on lines with data.
+#***************************************************************************
+
+# This is an example of a 'profile' file which includes a base file and adds
+# some customizaton for a particular purpose.
+
+# If this file is found in the user's ~/.ipython directory as ipythonrc-math,
+# it can be loaded by calling passing the '-profile math' (or '-p math')
+# option to IPython.
+
+# This example is a light customization to have ipython have basic math functions
+# readily available, effectively making the python prompt a very capable scientific
+# calculator
+
+# include base config and only add some extras
+include ipythonrc
+
+# load the complex math functions but keep them in a separate namespace
+import_mod cmath
+
+# from ... import *
+# load the real math functions in the global namespace for convenience
+import_all math
+
+# from ... import ...
+import_some
+
+# code to execute
+execute print "*** math functions available globally, cmath as a module"
diff --git a/IPython/UserConfig/ipythonrc-numeric b/IPython/UserConfig/ipythonrc-numeric
new file mode 100644
index 0000000..1700ca0
--- /dev/null
+++ b/IPython/UserConfig/ipythonrc-numeric
@@ -0,0 +1,57 @@
+# -*- Mode: Shell-Script -*-  Not really, but shows comments correctly
+#***************************************************************************
+#
+# Configuration file for ipython -- ipythonrc format
+#
+# The format of this file is one of 'key value' lines.
+# Lines containing only whitespace at the beginning and then a # are ignored
+# as comments. But comments can NOT be put on lines with data.
+#***************************************************************************
+
+# This is an example of a 'profile' file which includes a base file and adds
+# some customizaton for a particular purpose.
+
+# If this file is found in the user's ~/.ipython directory as
+# ipythonrc-numeric, it can be loaded by calling passing the '-profile
+# numeric' (or '-p numeric') option to IPython.
+
+# A simple alias numpy -> 'ipython -p numeric' makes life very convenient.
+
+# This example is meant to load several modules to turn IPython into a very
+# capable environment for high-end numerical work, similar to IDL or MatLab
+# but with the beauty and flexibility of the Python language.
+
+# Load the user's basic configuration
+include ipythonrc
+
+# import ...
+
+# Load Numeric by itself so that 'help Numeric' works
+import_mod Numeric
+
+# from ... import *
+# GnuplotRuntime loads Gnuplot and adds enhancements for use in IPython
+import_all Numeric IPython.numutils IPython.GnuplotInteractive
+
+# a simple line at zero, often useful for an x-axis
+execute xaxis=gpfunc('0',title='',with='lines lt -1')
+
+# Below are optional things off by default. Uncomment them if desired.
+
+# MA (MaskedArray) modifies the Numeric printing mechanism so that huge arrays
+# are only summarized and not printed (which may freeze the machine for a
+# _long_ time).
+
+#import_mod MA
+
+
+# gracePlot is a Python interface to the plotting package Grace.
+# For more details go to: http://www.idyll.org/~n8gray/code/index.html
+# Uncomment lines below if you have grace and its python support code
+
+#import_mod gracePlot 
+#execute grace = gracePlot.gracePlot  # alias to make gracePlot instances
+#execute print '*** grace is an alias for gracePlot.gracePlot'
+
+# Files to execute
+execfile
diff --git a/IPython/UserConfig/ipythonrc-physics b/IPython/UserConfig/ipythonrc-physics
new file mode 100644
index 0000000..fe2bc64
--- /dev/null
+++ b/IPython/UserConfig/ipythonrc-physics
@@ -0,0 +1,43 @@
+# -*- Mode: Shell-Script -*-  Not really, but shows comments correctly
+#***************************************************************************
+#
+# Configuration file for ipython -- ipythonrc format
+#
+# The format of this file is one of 'key value' lines.
+# Lines containing only whitespace at the beginning and then a # are ignored
+# as comments. But comments can NOT be put on lines with data.
+#***************************************************************************
+
+# If this file is found in the user's ~/.ipython directory as
+# ipythonrc-physics, it can be loaded by calling passing the '-profile
+# physics' (or '-p physics') option to IPython.
+
+# This profile loads modules useful for doing interactive calculations with
+# physical quantities (with units). It relies on modules from Konrad Hinsen's
+# ScientificPython (http://starship.python.net/crew/hinsen/)
+
+# First load basic user configuration
+include ipythonrc
+
+# import ...
+# Module with alternate input syntax for PhysicalQuantity objects.
+import_mod IPython.Extensions.PhysicalQInput
+
+# from ... import *
+# math CANNOT be imported after PhysicalQInteractive. It will override the
+# functions defined there.
+import_all math IPython.Extensions.PhysicalQInteractive
+
+# from ... import ...
+import_some  
+
+# code
+execute q = PhysicalQuantityInteractive
+execute g = PhysicalQuantityInteractive('9.8 m/s**2')
+ececute rad = pi/180.
+execute print '*** q is an alias for PhysicalQuantityInteractive'
+execute print '*** g = 9.8 m/s^2 has been defined'
+execute print '*** rad = pi/180  has been defined'
+
+# Files to execute
+execfile 
diff --git a/IPython/UserConfig/ipythonrc-pysh b/IPython/UserConfig/ipythonrc-pysh
new file mode 100644
index 0000000..2c7d204
--- /dev/null
+++ b/IPython/UserConfig/ipythonrc-pysh
@@ -0,0 +1,94 @@
+# -*- Mode: Shell-Script -*-  Not really, but shows comments correctly
+#***************************************************************************
+# Configuration file for ipython -- ipythonrc format
+#
+# The format of this file is one of 'key value' lines.
+# Lines containing only whitespace at the beginning and then a # are ignored
+# as comments.  But comments can NOT be put on lines with data.
+#***************************************************************************
+
+# If this file is found in the user's ~/.ipython directory as ipythonrc-pysh,
+# it can be loaded by calling passing the '-profile pysh' (or '-p pysh')
+# option to IPython.
+
+# This profile turns IPython into a lightweight system shell with python
+# syntax.
+
+# We only set a few options here, the rest is done in the companion pysh.py
+# file.  In the future _all_ of IPython's configuration will be done via
+# proper python code.
+
+############################################################################
+# First load common user configuration
+include ipythonrc
+
+############################################################################
+# Load all the actual syntax extensions for shell-like operation, which live
+# in the InterpreterExec standard extension.
+import_all IPython.Extensions.InterpreterExec
+
+############################################################################
+# PROMPTS
+#
+# Configure prompt for more shell-like usage.
+
+# Most bash-like escapes can be used to customize IPython's prompts, as well as
+# a few additional ones which are IPython-specific.  All valid prompt escapes
+# are described in detail in the Customization section of the IPython HTML/PDF
+# manual.
+
+prompt_in1 '\C_LightGreen\u@\h\C_LightBlue[\C_LightCyan\Y1\C_LightBlue]\C_Green|\#> '
+prompt_in2 '\C_Green|\C_LightGreen\D\C_Green> '
+prompt_out '<\#> '
+
+# Here's a more complex prompt, showing the hostname and more path depth (\Y3)
+#prompt_in1 '\C_LightRed\u\C_Blue@\C_Red\h\C_LightBlue[\C_LightCyan\Y3\C_LightBlue]\C_LightGreen\#> '
+
+# Select whether to left-pad the output prompts to match the length of the
+# input ones.  This allows you for example to use a simple '>' as an output
+# prompt, and yet have the output line up with the input.  If set to false,
+# the output prompts will be unpadded (flush left).
+prompts_pad_left 1
+
+
+# Remove all blank lines in between prompts, like a normal shell.
+separate_in 0
+separate_out 0
+separate_out2 0
+
+# Allow special syntax (!, magics and aliases) in multiline input
+multi_line_specials 1
+
+############################################################################
+# ALIASES
+
+# Declare some common aliases. Type alias? at an ipython prompt for details on
+# the syntax, use @unalias to delete existing aliases.
+
+# Don't go too crazy here, the file pysh.py called below runs @rehash, which
+# loads ALL of your $PATH as aliases (except for Python keywords and
+# builtins).
+
+# Some examples:
+
+# A simple alias without arguments
+#alias cl clear
+
+# An alias which expands the full line before the end of the alias.  This
+# lists only directories:
+#alias ldir pwd;ls -oF --color %l | grep /$
+
+# An alias with two positional arguments:
+#alias parts echo 'First <%s> Second <%s>'
+
+# In use these two aliases give (note that ldir is already built into IPython
+# for Unix):
+
+#fperez[IPython]16> ldir
+#/usr/local/home/fperez/ipython/ipython/IPython
+#drwxr-xr-x  2 fperez  4096 Jun 21 01:01 CVS/
+#drwxr-xr-x  3 fperez  4096 Jun 21 01:10 Extensions/
+#drwxr-xr-x  3 fperez  4096 Jun 21 01:27 UserConfig/
+
+#fperez[IPython]17> parts Hello world and goodbye
+#First <Hello> Second <world> and goodbye
diff --git a/IPython/UserConfig/ipythonrc-scipy b/IPython/UserConfig/ipythonrc-scipy
new file mode 100644
index 0000000..76d55f2
--- /dev/null
+++ b/IPython/UserConfig/ipythonrc-scipy
@@ -0,0 +1,43 @@
+# -*- Mode: Shell-Script -*-  Not really, but shows comments correctly
+#***************************************************************************
+#
+# Configuration file for ipython -- ipythonrc format
+#
+# The format of this file is one of 'key value' lines.
+# Lines containing only whitespace at the beginning and then a # are ignored
+# as comments. But comments can NOT be put on lines with data.
+#***************************************************************************
+
+# This is an example of a 'profile' file which includes a base file and adds
+# some customizaton for a particular purpose.
+
+# If this file is found in the user's ~/.ipython directory as ipythonrc-scipy,
+# it can be loaded by calling passing the '-profile scipy' (or '-p scipy')
+# option to IPython.
+
+# This example is meant to load several modules to turn ipython into a very
+# capable environment for high-end numerical work, similar to IDL or MatLab
+# but with the beauty of the Python language.
+
+# load our basic configuration with generic options
+include ipythonrc
+
+# import ...
+# Load SciPy by itself so that 'help scipy' works
+import_mod scipy
+
+# from ... import ...
+import_some
+
+# Now we load all of SciPy
+# from ... import *
+import_all scipy IPython.numutils
+
+# code 
+execute print 'Welcome to the SciPy Scientific Computing Environment.'
+execute scipy.alter_numeric()
+
+# File with alternate printer system for Numeric Arrays.
+# Files in the 'Extensions' directory will be found by IPython automatically
+# (otherwise give the explicit path):
+execfile Extensions/numeric_formats.py
diff --git a/IPython/UserConfig/ipythonrc-tutorial b/IPython/UserConfig/ipythonrc-tutorial
new file mode 100644
index 0000000..6c97569
--- /dev/null
+++ b/IPython/UserConfig/ipythonrc-tutorial
@@ -0,0 +1,37 @@
+# -*- Mode: Shell-Script -*-  Not really, but shows comments correctly
+#***************************************************************************
+#
+# Configuration file for ipython -- ipythonrc format
+#
+# The format of this file is one of 'key value' lines.
+# Lines containing only whitespace at the beginning and then a # are ignored
+# as comments. But comments can NOT be put on lines with data.
+#***************************************************************************
+
+# If this file is found in the user's ~/.ipython directory as
+# ipythonrc-tutorial, it can be loaded by calling passing the '-profile
+# tutorial' (or '-p tutorial') option to IPython.
+
+# This profile loads a special input line filter to allow typing lines which
+# begin with '>>> ' or '... '. These two strings, if present at the start of
+# the input line, are stripped. This allows for direct pasting of code from
+# examples such as those available in the standard Python tutorial.
+
+# First load basic user configuration
+include ipythonrc
+
+# import ...
+# Module with alternate input syntax for pasting python input
+import_mod IPython.Extensions.InterpreterPasteInput
+
+# from ... import *
+import_all
+
+# from ... import ...
+import_some  
+
+# code
+execute
+
+# Files to execute
+execfile
diff --git a/IPython/__init__.py b/IPython/__init__.py
new file mode 100644
index 0000000..ff74c49
--- /dev/null
+++ b/IPython/__init__.py
@@ -0,0 +1,63 @@
+# -*- coding: utf-8 -*-
+"""
+IPython -- An enhanced Interactive Python
+
+One of Python's nicest features is its interactive interpreter. This allows
+very fast testing of ideas without the overhead of creating test files as is
+typical in most programming languages. However, the interpreter supplied with
+the standard Python distribution is fairly primitive (and IDLE isn't really
+much better).
+
+IPython tries to:
+
+  i - provide an efficient environment for interactive work in Python
+  programming. It tries to address what we see as shortcomings of the standard
+  Python prompt, and adds many features to make interactive work much more
+  efficient.
+
+  ii - offer a flexible framework so that it can be used as the base
+  environment for other projects and problems where Python can be the
+  underlying language. Specifically scientific environments like Mathematica,
+  IDL and Mathcad inspired its design, but similar ideas can be useful in many
+  fields. Python is a fabulous language for implementing this kind of system
+  (due to its dynamic and introspective features), and with suitable libraries
+  entire systems could be built leveraging Python's power.
+
+  iii - serve as an embeddable, ready to go interpreter for your own programs.
+
+IPython requires Python 2.2 or newer.
+
+$Id: __init__.py 530 2005-03-02 07:11:15Z fperez $"""
+
+#*****************************************************************************
+#       Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
+#
+#  Distributed under the terms of the BSD License.  The full license is in
+#  the file COPYING, distributed as part of this software.
+#*****************************************************************************
+
+# Enforce proper version requirements
+import sys
+if sys.version[0:3] < '2.2':
+    raise ImportError, 'Python Version 2.2 or above is required.'
+        
+# Define what gets imported with a 'from IPython import *'
+__all__ = ['deep_reload','genutils','ultraTB','DPyGetOpt','Itpl','hooks',
+           'ConfigLoader','OutputTrap','Release','Struct','Shell']
+
+# Load __all__ in IPython namespace so that a simple 'import IPython' gives
+# access to them via IPython.<name>
+glob,loc = globals(),locals()
+for name in __all__:
+    __import__(name,glob,loc,[])
+
+# Release data
+from IPython import Release # do it explicitly so pydoc can see it - pydoc bug
+__author__  = '%s <%s>\n%s <%s>\n%s <%s>' % \
+              ( Release.authors['Fernando'] + Release.authors['Janko'] + \
+                Release.authors['Nathan'] )
+__license__ = Release.license
+__version__ = Release.version
+
+# Namespace cleanup
+del name,glob,loc
diff --git a/IPython/background_jobs.py b/IPython/background_jobs.py
new file mode 100644
index 0000000..aaa2c81
--- /dev/null
+++ b/IPython/background_jobs.py
@@ -0,0 +1,504 @@
+# -*- coding: utf-8 -*-
+"""Manage background (threaded) jobs conveniently from an interactive shell.
+
+This module provides a BackgroundJobManager class.  This is the main class
+meant for public usage, it implements an object which can create and manage
+new background jobs.
+
+It also provides the actual job classes managed by these BackgroundJobManager
+objects, see their docstrings below.
+
+
+This system was inspired by discussions with B. Granger and the
+BackgroundCommand class described in the book Python Scripting for
+Computational Science, by H. P. Langtangen:
+
+http://folk.uio.no/hpl/scripting
+
+(although ultimately no code from this text was used, as IPython's system is a
+separate implementation).
+
+$Id: background_jobs.py 515 2005-02-15 07:41:41Z fperez $
+"""
+
+#*****************************************************************************
+#       Copyright (C) 2005 Fernando Perez <fperez@colorado.edu>
+#
+#  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
+
+# Code begins
+import threading,sys
+
+from IPython.ultraTB import AutoFormattedTB
+from IPython.genutils import warn,error
+
+# declares Python 2.2 compatibility symbols:
+try:
+    basestring
+except NameError:
+    import types
+    basestring = (types.StringType, types.UnicodeType)
+    True = 1==1
+    False = 1==0
+
+class BackgroundJobManager:
+    """Class to manage a pool of backgrounded threaded jobs.
+
+    Below, we assume that 'jobs' is a BackgroundJobManager instance.
+    
+    Usage summary (see the method docstrings for details):
+
+      jobs.new(...) -> start a new job
+      
+      jobs() or jobs.status() -> print status summary of all jobs
+
+      jobs[N] -> returns job number N.
+
+      foo = jobs[N].result -> assign to variable foo the result of job N
+
+      jobs[N].traceback() -> print the traceback of dead job N
+
+      jobs.remove(N) -> remove (finished) job N
+
+      jobs.flush_finished() -> remove all finished jobs
+      
+    As a convenience feature, BackgroundJobManager instances provide the
+    utility result and traceback methods which retrieve the corresponding
+    information from the jobs list:
+
+      jobs.result(N) <--> jobs[N].result
+      jobs.traceback(N) <--> jobs[N].traceback()
+
+    While this appears minor, it allows you to use tab completion
+    interactively on the job manager instance.
+
+    In interactive mode, IPython provides the magic fuction %bg for quick
+    creation of backgrounded expression-based jobs. Type bg? for details."""
+
+    def __init__(self):
+        # Lists for job management
+        self.jobs_run  = []
+        self.jobs_comp = []
+        self.jobs_dead = []
+        # A dict of all jobs, so users can easily access any of them
+        self.jobs_all = {}
+        # For reporting
+        self._comp_report = []
+        self._dead_report = []
+        # Store status codes locally for fast lookups
+        self._s_created   = BackgroundJobBase.stat_created_c
+        self._s_running   = BackgroundJobBase.stat_running_c
+        self._s_completed = BackgroundJobBase.stat_completed_c
+        self._s_dead      = BackgroundJobBase.stat_dead_c
+
+    def new(self,func_or_exp,*args,**kwargs):
+        """Add a new background job and start it in a separate thread.
+
+        There are two types of jobs which can be created:
+
+        1. Jobs based on expressions which can be passed to an eval() call.
+        The expression must be given as a string.  For example:
+
+          job_manager.new('myfunc(x,y,z=1)'[,glob[,loc]])
+
+        The given expression is passed to eval(), along with the optional
+        global/local dicts provided.  If no dicts are given, they are
+        extracted automatically from the caller's frame.
+        
+        A Python statement is NOT a valid eval() expression.  Basically, you
+        can only use as an eval() argument something which can go on the right
+        of an '=' sign and be assigned to a variable.
+
+        For example,"print 'hello'" is not valid, but '2+3' is.
+
+        2. Jobs given a function object, optionally passing additional
+        positional arguments:
+
+          job_manager.new(myfunc,x,y)
+
+        The function is called with the given arguments.
+
+        If you need to pass keyword arguments to your function, you must
+        supply them as a dict named kw:
+
+          job_manager.new(myfunc,x,y,kw=dict(z=1))
+
+        The reason for this assymmetry is that the new() method needs to
+        maintain access to its own keywords, and this prevents name collisions
+        between arguments to new() and arguments to your own functions.
+
+        In both cases, the result is stored in the job.result field of the
+        background job object.
+
+
+        Notes and caveats:
+
+        1. All threads running share the same standard output.  Thus, if your
+        background jobs generate output, it will come out on top of whatever
+        you are currently writing.  For this reason, background jobs are best
+        used with silent functions which simply return their output.
+
+        2. Threads also all work within the same global namespace, and this
+        system does not lock interactive variables.  So if you send job to the
+        background which operates on a mutable object for a long time, and
+        start modifying that same mutable object interactively (or in another
+        backgrounded job), all sorts of bizarre behaviour will occur.
+
+        3. If a background job is spending a lot of time inside a C extension
+        module which does not release the Python Global Interpreter Lock
+        (GIL), this will block the IPython prompt.  This is simply because the
+        Python interpreter can only switch between threads at Python
+        bytecodes.  While the execution is inside C code, the interpreter must
+        simply wait unless the extension module releases the GIL.
+
+        4. There is no way, due to limitations in the Python threads library,
+        to kill a thread once it has started."""
+        
+        if callable(func_or_exp):
+            kw  = kwargs.get('kw',{})
+            job = BackgroundJobFunc(func_or_exp,*args,**kw)
+        elif isinstance(func_or_exp,basestring):
+            if not args:
+                frame = sys._getframe(1)
+                glob, loc = frame.f_globals, frame.f_locals
+            elif len(args)==1:
+                glob = loc = args[0]
+            elif len(args)==2:
+                glob,loc = args
+            else:
+                raise ValueError,\
+                      'Expression jobs take at most 2 args (globals,locals)'
+            job = BackgroundJobExpr(func_or_exp,glob,loc)
+        else:
+            raise
+        jkeys = self.jobs_all.keys()
+        if jkeys:
+            job.num = max(jkeys)+1
+        else:
+            job.num = 0
+        self.jobs_run.append(job)
+        self.jobs_all[job.num] = job
+        print 'Starting job # %s in a separate thread.' % job.num
+        job.start()
+        return job
+
+    def __getitem__(self,key):
+        return self.jobs_all[key]
+
+    def __call__(self):
+        """An alias to self.status(),
+
+        This allows you to simply call a job manager instance much like the
+        Unix jobs shell command."""
+
+        return self.status()
+
+    def _update_status(self):
+        """Update the status of the job lists.
+
+        This method moves finished jobs to one of two lists:
+          - self.jobs_comp: jobs which completed successfully
+          - self.jobs_dead: jobs which finished but died.
+
+        It also copies those jobs to corresponding _report lists.  These lists
+        are used to report jobs completed/dead since the last update, and are
+        then cleared by the reporting function after each call."""
+        
+        run,comp,dead = self._s_running,self._s_completed,self._s_dead
+        jobs_run = self.jobs_run
+        for num in range(len(jobs_run)):
+            job  = jobs_run[num]
+            stat = job.stat_code
+            if stat == run:
+                continue
+            elif stat == comp:
+                self.jobs_comp.append(job)
+                self._comp_report.append(job)
+                jobs_run[num] = False
+            elif stat == dead:
+                self.jobs_dead.append(job)
+                self._dead_report.append(job)
+                jobs_run[num] = False
+        self.jobs_run = filter(None,self.jobs_run)
+
+    def _group_report(self,group,name):
+        """Report summary for a given job group.
+
+        Return True if the group had any elements."""
+
+        if group:
+            print '%s jobs:' % name
+            for job in group:
+                print '%s : %s' % (job.num,job)
+            print
+            return True
+
+    def _group_flush(self,group,name):
+        """Flush a given job group
+
+        Return True if the group had any elements."""
+
+        njobs = len(group)
+        if njobs:
+            plural = {1:''}.setdefault(njobs,'s')
+            print 'Flushing %s %s job%s.' % (njobs,name,plural)
+            group[:] = []
+            return True
+        
+    def _status_new(self):
+        """Print the status of newly finished jobs.
+
+        Return True if any new jobs are reported.
+
+        This call resets its own state every time, so it only reports jobs
+        which have finished since the last time it was called."""
+
+        self._update_status()
+        new_comp = self._group_report(self._comp_report,'Completed')
+        new_dead = self._group_report(self._dead_report,
+                                      'Dead, call job.traceback() for details')
+        self._comp_report[:] = []
+        self._dead_report[:] = []
+        return new_comp or new_dead
+                
+    def status(self,verbose=0):
+        """Print a status of all jobs currently being managed."""
+
+        self._update_status()
+        self._group_report(self.jobs_run,'Running')
+        self._group_report(self.jobs_comp,'Completed')
+        self._group_report(self.jobs_dead,'Dead')
+        # Also flush the report queues
+        self._comp_report[:] = []
+        self._dead_report[:] = []
+
+    def remove(self,num):
+        """Remove a finished (completed or dead) job."""
+
+        try:
+            job = self.jobs_all[num]
+        except KeyError:
+            error('Job #%s not found' % num)
+        else:
+            stat_code = job.stat_code
+            if stat_code == self._s_running:
+                error('Job #%s is still running, it can not be removed.' % num)
+                return
+            elif stat_code == self._s_completed:
+                self.jobs_comp.remove(job)
+            elif stat_code == self._s_dead:
+                self.jobs_dead.remove(job)
+
+    def flush_finished(self):
+        """Flush all jobs finished (completed and dead) from lists.
+
+        Running jobs are never flushed.
+
+        It first calls _status_new(), to update info. If any jobs have
+        completed since the last _status_new() call, the flush operation
+        aborts."""
+
+        if self._status_new():
+            error('New jobs completed since last '\
+                  '_status_new(), aborting flush.')
+            return
+
+        # Remove the finished jobs from the master dict
+        jobs_all = self.jobs_all
+        for job in self.jobs_comp+self.jobs_dead:
+            del(jobs_all[job.num])
+
+        # Now flush these lists completely
+        fl_comp = self._group_flush(self.jobs_comp,'Completed')
+        fl_dead = self._group_flush(self.jobs_dead,'Dead')
+        if not (fl_comp or fl_dead):
+            print 'No jobs to flush.'
+
+    def result(self,num):
+        """result(N) -> return the result of job N."""
+        try:
+            return self.jobs_all[num].result
+        except KeyError:
+            error('Job #%s not found' % num)
+
+    def traceback(self,num):
+        try:
+            self.jobs_all[num].traceback()
+        except KeyError:
+            error('Job #%s not found' % num)
+
+
+class BackgroundJobBase(threading.Thread):
+    """Base class to build BackgroundJob classes.
+
+    The derived classes must implement:
+
+    - Their own __init__, since the one here raises NotImplementedError.  The
+    derived constructor must call self._init() at the end, to provide common
+    initialization.
+
+    - A strform attribute used in calls to __str__.
+
+    - A call() method, which will make the actual execution call and must
+    return a value to be held in the 'result' field of the job object."""
+
+    # Class constants for status, in string and as numerical codes (when
+    # updating jobs lists, we don't want to do string comparisons).  This will
+    # be done at every user prompt, so it has to be as fast as possible
+    stat_created   = 'Created'; stat_created_c = 0
+    stat_running   = 'Running'; stat_running_c = 1
+    stat_completed = 'Completed'; stat_completed_c = 2
+    stat_dead      = 'Dead (Exception), call job.traceback() for details'
+    stat_dead_c = -1
+
+    def __init__(self):
+        raise NotImplementedError, \
+              "This class can not be instantiated directly."
+
+    def _init(self):
+        """Common initialization for all BackgroundJob objects"""
+        
+        for attr in ['call','strform']:
+            assert hasattr(self,attr), "Missing attribute <%s>" % attr
+        
+        # The num tag can be set by an external job manager
+        self.num = None
+      
+        self.status    = BackgroundJobBase.stat_created
+        self.stat_code = BackgroundJobBase.stat_created_c
+        self.finished  = False
+        self.result    = '<BackgroundJob has not completed>'
+        # reuse the ipython traceback handler if we can get to it, otherwise
+        # make a new one
+        try:
+            self._make_tb = __IPYTHON__.InteractiveTB.text
+        except:
+            self._make_tb = AutoFormattedTB(mode = 'Context',
+                                           color_scheme='NoColor',
+                                           tb_offset = 1).text
+        # Hold a formatted traceback if one is generated.
+        self._tb = None
+        
+        threading.Thread.__init__(self)
+
+    def __str__(self):
+        return self.strform
+
+    def __repr__(self):
+        return '<BackgroundJob: %s>' % self.strform
+
+    def traceback(self):
+        print self._tb
+        
+    def run(self):
+        try:
+            self.status    = BackgroundJobBase.stat_running
+            self.stat_code = BackgroundJobBase.stat_running_c
+            self.result    = self.call()
+        except:
+            self.status    = BackgroundJobBase.stat_dead
+            self.stat_code = BackgroundJobBase.stat_dead_c
+            self.finished  = None
+            self.result    = ('<BackgroundJob died, call job.traceback() for details>')
+            self._tb       = self._make_tb()
+        else:
+            self.status    = BackgroundJobBase.stat_completed
+            self.stat_code = BackgroundJobBase.stat_completed_c
+            self.finished  = True
+
+class BackgroundJobExpr(BackgroundJobBase):
+    """Evaluate an expression as a background job (uses a separate thread)."""
+
+    def __init__(self,expression,glob=None,loc=None):
+        """Create a new job from a string which can be fed to eval().
+
+        global/locals dicts can be provided, which will be passed to the eval
+        call."""
+
+        # fail immediately if the given expression can't be compiled
+        self.code = compile(expression,'<BackgroundJob compilation>','eval')
+                
+        if glob is None:
+            glob = {}
+        if loc is None:
+            loc = {}
+            
+        self.expression = self.strform = expression
+        self.glob = glob
+        self.loc = loc
+        self._init()
+        
+    def call(self):
+        return eval(self.code,self.glob,self.loc)
+
+class BackgroundJobFunc(BackgroundJobBase):
+    """Run a function call as a background job (uses a separate thread)."""
+
+    def __init__(self,func,*args,**kwargs):
+        """Create a new job from a callable object.
+
+        Any positional arguments and keyword args given to this constructor
+        after the initial callable are passed directly to it."""
+
+        assert callable(func),'first argument must be callable'
+        
+        if args is None:
+            args = []
+        if kwargs is None:
+            kwargs = {}
+        
+        self.func = func
+        self.args = args
+        self.kwargs = kwargs
+        # The string form will only include the function passed, because
+        # generating string representations of the arguments is a potentially
+        # _very_ expensive operation (e.g. with large arrays).
+        self.strform = str(func)
+        self._init()
+
+    def call(self):
+        return self.func(*self.args,**self.kwargs)
+
+
+if __name__=='__main__':
+
+    import time
+
+    def sleepfunc(interval=2,*a,**kw):
+        args = dict(interval=interval,
+                    args=a,
+                    kwargs=kw)
+        time.sleep(interval)
+        return args
+
+    def diefunc(interval=2,*a,**kw):
+        time.sleep(interval)
+        die
+
+    def printfunc(interval=1,reps=5):
+        for n in range(reps):
+            time.sleep(interval)
+            print 'In the background...'
+
+    jobs = BackgroundJobManager()
+    # first job will have # 0
+    jobs.new(sleepfunc,4)
+    jobs.new(sleepfunc,kw={'reps':2})
+    # This makes a job which will die
+    jobs.new(diefunc,1)
+    jobs.new('printfunc(1,3)')
+
+    # after a while, you can get the traceback of a dead job.  Run the line
+    # below again interactively until it prints a traceback (check the status
+    # of the job):
+    print jobs[1].status
+    jobs[1].traceback()
+    
+    # Run this line again until the printed result changes
+    print "The result of job #0 is:",jobs[0].result
diff --git a/IPython/deep_reload.py b/IPython/deep_reload.py
new file mode 100644
index 0000000..eb8dd11
--- /dev/null
+++ b/IPython/deep_reload.py
@@ -0,0 +1,184 @@
+# -*- coding: utf-8 -*-
+"""
+A module to change reload() so that it acts recursively.
+To enable it type:
+    >>> import __builtin__, deep_reload
+    >>> __builtin__.reload = deep_reload.reload
+You can then disable it with:
+    >>> __builtin__.reload = deep_reload.original_reload
+    
+Alternatively, you can add a dreload builtin alongside normal reload with:
+    >>> __builtin__.dreload = deep_reload.reload
+    
+This code is almost entirely based on knee.py from the standard library.
+
+$Id: deep_reload.py 410 2004-11-04 07:58:17Z fperez $"""
+
+#*****************************************************************************
+#       Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
+#
+#  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 # do it explicitly so pydoc can see it - pydoc bug
+__author__  = '%s <%s>' %  Release.authors['Nathan']
+__license__ = Release.license
+__version__ = "0.5"
+__date__    = "21 August 2001"
+
+import sys, imp, __builtin__
+
+# Replacement for __import__()
+def deep_import_hook(name, globals=None, locals=None, fromlist=None):
+    parent = determine_parent(globals)
+    q, tail = find_head_package(parent, name)
+    m = load_tail(q, tail)
+    if not fromlist:
+        return q
+    if hasattr(m, "__path__"):
+        ensure_fromlist(m, fromlist)
+    return m
+
+def determine_parent(globals):
+    if not globals or  not globals.has_key("__name__"):
+        return None
+    pname = globals['__name__']
+    if globals.has_key("__path__"):
+        parent = sys.modules[pname]
+        assert globals is parent.__dict__
+        return parent
+    if '.' in pname:
+        i = pname.rfind('.')
+        pname = pname[:i]
+        parent = sys.modules[pname]
+        assert parent.__name__ == pname
+        return parent
+    return None
+
+def find_head_package(parent, name):
+    # Import the first
+    if '.' in name:
+        # 'some.nested.package' -> head = 'some', tail = 'nested.package'
+        i = name.find('.')
+        head = name[:i]
+        tail = name[i+1:]
+    else:
+        # 'packagename' -> head = 'packagename', tail = ''
+        head = name
+        tail = ""
+    if parent:
+        # If this is a subpackage then qname = parent's name + head
+        qname = "%s.%s" % (parent.__name__, head)
+    else:
+        qname = head
+    q = import_module(head, qname, parent)
+    if q: return q, tail
+    if parent:
+        qname = head
+        parent = None
+        q = import_module(head, qname, parent)
+        if q: return q, tail
+    raise ImportError, "No module named " + qname
+
+def load_tail(q, tail):
+    m = q
+    while tail:
+        i = tail.find('.')
+        if i < 0: i = len(tail)
+        head, tail = tail[:i], tail[i+1:]
+
+        # fperez: fix dotted.name reloading failures by changing:
+        #mname = "%s.%s" % (m.__name__, head)
+        # to:
+        mname = m.__name__
+        # This needs more testing!!! (I don't understand this module too well)
+        
+        #print '** head,tail=|%s|->|%s|, mname=|%s|' % (head,tail,mname)  # dbg
+        m = import_module(head, mname, m)
+        if not m:
+            raise ImportError, "No module named " + mname
+    return m
+
+def ensure_fromlist(m, fromlist, recursive=0):
+    for sub in fromlist:
+        if sub == "*":
+            if not recursive:
+                try:
+                    all = m.__all__
+                except AttributeError:
+                    pass
+                else:
+                    ensure_fromlist(m, all, 1)
+            continue
+        if sub != "*" and not hasattr(m, sub):
+            subname = "%s.%s" % (m.__name__, sub)
+            submod = import_module(sub, subname, m)
+            if not submod:
+                raise ImportError, "No module named " + subname
+
+# Need to keep track of what we've already reloaded to prevent cyclic evil
+found_now = {}
+
+def import_module(partname, fqname, parent):
+    global found_now
+    if found_now.has_key(fqname):
+        try:
+            return sys.modules[fqname]    
+        except KeyError:
+            pass
+    
+    print 'Reloading', fqname #, sys.excepthook is sys.__excepthook__, \
+            #sys.displayhook is sys.__displayhook__
+    
+    found_now[fqname] = 1
+    try:
+        fp, pathname, stuff = imp.find_module(partname,
+                                              parent and parent.__path__)
+    except ImportError:
+        return None
+        
+    try:
+        m = imp.load_module(fqname, fp, pathname, stuff)
+    finally:
+        if fp: fp.close()
+        
+    if parent:
+        setattr(parent, partname, m)
+
+    return m
+
+def deep_reload_hook(module):
+    name = module.__name__
+    if '.' not in name:
+        return import_module(name, name, None)
+    i = name.rfind('.')
+    pname = name[:i]
+    parent = sys.modules[pname]
+    return import_module(name[i+1:], name, parent)
+
+# Save the original hooks
+original_reload = __builtin__.reload
+
+# Replacement for reload()
+def reload(module, exclude=['sys', '__builtin__', '__main__']):
+    """Recursively reload all modules used in the given module.  Optionally
+    takes a list of modules to exclude from reloading.  The default exclude
+    list contains sys, __main__, and __builtin__, to prevent, e.g., resetting 
+    display, exception, and io hooks.
+    """
+    global found_now
+    for i in exclude:
+        found_now[i] = 1
+    original_import = __builtin__.__import__
+    __builtin__.__import__ = deep_import_hook    
+    try:
+        ret = deep_reload_hook(module)
+    finally:
+        __builtin__.__import__ = original_import
+        found_now = {}
+    return ret
+
+# Uncomment the following to automatically activate deep reloading whenever
+# this module is imported
+#__builtin__.reload = reload
diff --git a/IPython/genutils.py b/IPython/genutils.py
new file mode 100644
index 0000000..8682525
--- /dev/null
+++ b/IPython/genutils.py
@@ -0,0 +1,1519 @@
+# -*- coding: utf-8 -*-
+"""
+General purpose utilities.
+
+This is a grab-bag of stuff I find useful in most programs I write. Some of
+these things are also convenient when working at the command line.
+
+$Id: genutils.py 543 2005-03-18 09:23:48Z fperez $"""
+
+#*****************************************************************************
+#       Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
+#
+#  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
+
+#****************************************************************************
+# required modules
+import __main__
+import types,commands,time,sys,os,re,shutil
+import tempfile
+from IPython.Itpl import Itpl,itpl,printpl
+from IPython import DPyGetOpt
+
+#****************************************************************************
+# Exceptions
+class Error(Exception):
+    """Base class for exceptions in this module."""
+    pass
+
+#----------------------------------------------------------------------------
+class Stream:
+    """Simple class to hold the various I/O streams in Term"""
+
+    def __init__(self,stream,name):
+        self.stream = stream
+        self.name = name
+        try:
+            self.fileno = stream.fileno()
+        except AttributeError:
+            msg = ("Stream <%s> looks suspicious: it lacks a 'fileno' attribute."
+                   % name)
+            print >> sys.stderr, 'WARNING:',msg
+        try:
+            self.mode = stream.mode
+        except AttributeError:
+            msg = ("Stream <%s> looks suspicious: it lacks a 'mode' attribute."
+                   % name)
+            print >> sys.stderr, 'WARNING:',msg
+
+class Term:
+    """ Term holds the file or file-like objects for handling I/O operations.
+
+    These are normally just sys.stdin, sys.stdout and sys.stderr but for
+    Windows they can can replaced to allow editing the strings before they are
+    displayed."""
+
+    # In the future, having IPython channel all its I/O operations through
+    # this class will make it easier to embed it into other environments which
+    # are not a normal terminal (such as a GUI-based shell)
+    in_s  = Stream(sys.stdin,'cin')
+    out_s = Stream(sys.stdout,'cout')
+    err_s = Stream(sys.stderr,'cerr')
+
+    # Store the three streams in (err,out,in) order so that if we need to reopen
+    # them, the error channel is reopened first to provide info.
+    streams = [err_s,out_s,in_s]
+
+    # The class globals should be the actual 'bare' streams for normal I/O to work
+    cin  = streams[2].stream
+    cout = streams[1].stream
+    cerr = streams[0].stream
+    
+    def reopen_all(cls):
+        """Reopen all streams if necessary.
+
+        This should only be called if it is suspected that someting closed
+        accidentally one of the I/O streams."""
+
+        any_closed = 0
+
+        for sn in range(len(cls.streams)):
+            st = cls.streams[sn]
+            if st.stream.closed:
+                any_closed = 1
+                new_stream = os.fdopen(os.dup(st.fileno), st.mode,0)
+                cls.streams[sn] = Stream(new_stream,st.name)
+                print >> cls.streams[0].stream, \
+                      '\nWARNING:\nStream Term.%s had to be reopened!' % st.name
+
+        # Rebuild the class globals
+        cls.cin = cls.streams[2].stream
+        cls.cout = cls.streams[1].stream
+        cls.cerr = cls.streams[0].stream
+
+    reopen_all = classmethod(reopen_all)
+
+    def set_stdout(cls,stream):
+        """Set the stream """
+        cls.cout = stream
+    set_stdout = classmethod(set_stdout)
+
+    def set_stderr(cls,stream):
+        cls.cerr = stream
+    set_stderr = classmethod(set_stderr)
+
+# Windows-specific code to load Gary Bishop's readline and configure it
+# automatically for the users
+# Note: os.name on cygwin returns posix, so this should only pick up 'native'
+# windows.  Cygwin returns 'cygwin' for sys.platform.
+if os.name == 'nt':
+    try:
+        import readline
+    except ImportError:
+        pass
+    else:
+        try:
+            _out = readline.GetOutputFile()
+        except AttributeError:
+            pass
+        else:
+            Term.set_stdout(_out)
+            Term.set_stderr(_out)
+            del _out
+
+#****************************************************************************
+# Generic warning/error printer, used by everything else
+def warn(msg,level=2,exit_val=1):
+    """Standard warning printer. Gives formatting consistency.
+
+    Output is sent to Term.cerr (sys.stderr by default).
+    
+    Options:
+    
+    -level(2): allows finer control:
+      0 -> Do nothing, dummy function.
+      1 -> Print message.
+      2 -> Print 'WARNING:' + message. (Default level).
+      3 -> Print 'ERROR:' + message.
+      4 -> Print 'FATAL ERROR:' + message and trigger a sys.exit(exit_val).
+
+    -exit_val (1): exit value returned by sys.exit() for a level 4
+    warning. Ignored for all other levels."""
+    
+    if level>0:
+        header = ['','','WARNING: ','ERROR: ','FATAL ERROR: ']
+        print >> Term.cerr, '%s%s' % (header[level],msg)
+        if level == 4:
+            print >> Term.cerr,'Exiting.\n'
+            sys.exit(exit_val)
+
+def info(msg):
+    """Equivalent to warn(msg,level=1)."""
+
+    warn(msg,level=1)
+
+def error(msg):
+    """Equivalent to warn(msg,level=3)."""
+
+    warn(msg,level=3)
+
+def fatal(msg,exit_val=1):
+    """Equivalent to warn(msg,exit_val=exit_val,level=4)."""
+
+    warn(msg,exit_val=exit_val,level=4)
+
+#----------------------------------------------------------------------------
+StringTypes = types.StringTypes
+
+# Basic timing functionality
+
+# If possible (Unix), use the resource module instead of time.clock()
+try:
+    import resource
+    def clock():
+        """clock() -> floating point number
+
+        Return the CPU time in seconds (user time only, system time is
+        ignored) since the start of the process.  This is done via a call to
+        resource.getrusage, so it avoids the wraparound problems in
+        time.clock()."""
+        
+        return resource.getrusage(resource.RUSAGE_SELF)[0]
+    
+    def clock2():
+        """clock2() -> (t_user,t_system)
+
+        Similar to clock(), but return a tuple of user/system times."""
+        return resource.getrusage(resource.RUSAGE_SELF)[:2]
+
+except ImportError:
+    clock = time.clock
+    def clock2():
+        """Under windows, system CPU time can't be measured.
+
+        This just returns clock() and zero."""
+        return time.clock(),0.0
+
+def timings_out(reps,func,*args,**kw):
+    """timings_out(reps,func,*args,**kw) -> (t_total,t_per_call,output)
+
+    Execute a function reps times, return a tuple with the elapsed total
+    CPU time in seconds, the time per call and the function's output.
+
+    Under Unix, the return value is the sum of user+system time consumed by
+    the process, computed via the resource module.  This prevents problems
+    related to the wraparound effect which the time.clock() function has.
+    
+    Under Windows the return value is in wall clock seconds. See the
+    documentation for the time module for more details."""
+
+    reps = int(reps)
+    assert reps >=1, 'reps must be >= 1'
+    if reps==1:
+        start = clock()
+        out = func(*args,**kw)
+        tot_time = clock()-start
+    else:
+        rng = xrange(reps-1) # the last time is executed separately to store output
+        start = clock()
+        for dummy in rng: func(*args,**kw)
+        out = func(*args,**kw)  # one last time
+        tot_time = clock()-start
+    av_time = tot_time / reps
+    return tot_time,av_time,out
+
+def timings(reps,func,*args,**kw):
+    """timings(reps,func,*args,**kw) -> (t_total,t_per_call)
+
+    Execute a function reps times, return a tuple with the elapsed total CPU
+    time in seconds and the time per call. These are just the first two values
+    in timings_out()."""
+
+    return timings_out(reps,func,*args,**kw)[0:2]
+
+def timing(func,*args,**kw):
+    """timing(func,*args,**kw) -> t_total
+
+    Execute a function once, return the elapsed total CPU time in
+    seconds. This is just the first value in timings_out()."""
+
+    return timings_out(1,func,*args,**kw)[0]
+
+#****************************************************************************
+# file and system
+
+def system(cmd,verbose=0,debug=0,header=''):
+    """Execute a system command, return its exit status.
+
+    Options:
+
+    - verbose (0): print the command to be executed.
+    
+    - debug (0): only print, do not actually execute.
+
+    - header (''): Header to print on screen prior to the executed command (it
+    is only prepended to the command, no newlines are added).
+
+    Note: a stateful version of this function is available through the
+    SystemExec class."""
+
+    stat = 0
+    if verbose or debug: print header+cmd
+    sys.stdout.flush()
+    if not debug: stat = os.system(cmd)
+    return stat
+
+def shell(cmd,verbose=0,debug=0,header=''):
+    """Execute a command in the system shell, always return None.
+
+    Options:
+
+    - verbose (0): print the command to be executed.
+    
+    - debug (0): only print, do not actually execute.
+
+    - header (''): Header to print on screen prior to the executed command (it
+    is only prepended to the command, no newlines are added).
+
+    Note: this is similar to genutils.system(), but it returns None so it can
+    be conveniently used in interactive loops without getting the return value
+    (typically 0) printed many times."""
+
+    stat = 0
+    if verbose or debug: print header+cmd
+    # flush stdout so we don't mangle python's buffering
+    sys.stdout.flush()
+    if not debug:
+        os.system(cmd)
+
+def getoutput(cmd,verbose=0,debug=0,header='',split=0):
+    """Dummy substitute for perl's backquotes.
+
+    Executes a command and returns the output.
+
+    Accepts the same arguments as system(), plus:
+
+    - split(0): if true, the output is returned as a list split on newlines.
+
+    Note: a stateful version of this function is available through the
+    SystemExec class."""
+
+    if verbose or debug: print header+cmd
+    if not debug:
+        output = commands.getoutput(cmd)
+        if split:
+            return output.split('\n')
+        else:
+            return output
+
+def getoutputerror(cmd,verbose=0,debug=0,header='',split=0):
+    """Return (standard output,standard error) of executing cmd in a shell.
+
+    Accepts the same arguments as system(), plus:
+
+    - split(0): if true, each of stdout/err is returned as a list split on
+    newlines.
+
+    Note: a stateful version of this function is available through the
+    SystemExec class."""
+
+    if verbose or debug: print header+cmd
+    if not cmd:
+        if split:
+            return [],[]
+        else:
+            return '',''
+    if not debug:
+        pin,pout,perr = os.popen3(cmd)
+        tout = pout.read().rstrip()
+        terr = perr.read().rstrip()
+        pin.close()
+        pout.close()
+        perr.close()
+        if split:
+            return tout.split('\n'),terr.split('\n')
+        else:
+            return tout,terr
+
+# for compatibility with older naming conventions
+xsys = system
+bq = getoutput
+
+class SystemExec:
+    """Access the system and getoutput functions through a stateful interface.
+
+    Note: here we refer to the system and getoutput functions from this
+    library, not the ones from the standard python library.
+    
+    This class offers the system and getoutput functions as methods, but the
+    verbose, debug and header parameters can be set for the instance (at
+    creation time or later) so that they don't need to be specified on each
+    call.
+
+    For efficiency reasons, there's no way to override the parameters on a
+    per-call basis other than by setting instance attributes. If you need
+    local overrides, it's best to directly call system() or getoutput().
+
+    The following names are provided as alternate options:
+     - xsys: alias to system
+     - bq: alias to getoutput
+
+    An instance can then be created as:
+     >>> sysexec = SystemExec(verbose=1,debug=0,header='Calling: ')
+
+    And used as:
+     >>> sysexec.xsys('pwd')
+     >>> dirlist = sysexec.bq('ls -l')
+    """
+    
+    def __init__(self,verbose=0,debug=0,header='',split=0):
+        """Specify the instance's values for verbose, debug and header."""
+        setattr_list(self,'verbose debug header split')
+
+    def system(self,cmd):
+        """Stateful interface to system(), with the same keyword parameters."""
+
+        system(cmd,self.verbose,self.debug,self.header)
+
+    def shell(self,cmd):
+        """Stateful interface to shell(), with the same keyword parameters."""
+
+        shell(cmd,self.verbose,self.debug,self.header)
+
+    xsys = system  # alias
+
+    def getoutput(self,cmd):
+        """Stateful interface to getoutput()."""
+
+        return getoutput(cmd,self.verbose,self.debug,self.header,self.split)
+
+    def getoutputerror(self,cmd):
+        """Stateful interface to getoutputerror()."""
+
+        return getoutputerror(cmd,self.verbose,self.debug,self.header,self.split)
+
+    bq = getoutput  # alias
+
+#-----------------------------------------------------------------------------
+def mutex_opts(dict,ex_op):
+    """Check for presence of mutually exclusive keys in a dict.
+
+    Call: mutex_opts(dict,[[op1a,op1b],[op2a,op2b]...]"""
+    for op1,op2 in ex_op:
+        if op1 in dict and op2 in dict:
+            raise ValueError,'\n*** ERROR in Arguments *** '\
+                  'Options '+op1+' and '+op2+' are mutually exclusive.'
+
+#-----------------------------------------------------------------------------
+def filefind(fname,alt_dirs = None):
+    """Return the given filename either in the current directory, if it
+    exists, or in a specified list of directories.
+
+    ~ expansion is done on all file and directory names.
+
+    Upon an unsuccessful search, raise an IOError exception."""
+
+    if alt_dirs is None:
+        try:
+            alt_dirs = get_home_dir()
+        except HomeDirError:
+            alt_dirs = os.getcwd()
+    search = [fname] + list_strings(alt_dirs)
+    search = map(os.path.expanduser,search)
+    #print 'search list for',fname,'list:',search  # dbg
+    fname = search[0]
+    if os.path.isfile(fname):
+        return fname
+    for direc in search[1:]:
+        testname = os.path.join(direc,fname)
+        #print 'testname',testname  # dbg
+        if os.path.isfile(testname):
+            return testname
+    raise IOError,'File' + `fname` + \
+          ' not found in current or supplied directories:' + `alt_dirs`
+
+#----------------------------------------------------------------------------
+def target_outdated(target,deps):
+    """Determine whether a target is out of date.
+
+    target_outdated(target,deps) -> 1/0
+
+    deps: list of filenames which MUST exist.
+    target: single filename which may or may not exist.
+
+    If target doesn't exist or is older than any file listed in deps, return
+    true, otherwise return false.
+    """
+    try:
+        target_time = os.path.getmtime(target)
+    except os.error:
+        return 1
+    for dep in deps:
+        dep_time = os.path.getmtime(dep)
+        if dep_time > target_time:
+            #print "For target",target,"Dep failed:",dep # dbg
+            #print "times (dep,tar):",dep_time,target_time # dbg
+            return 1
+    return 0
+
+#-----------------------------------------------------------------------------
+def target_update(target,deps,cmd):
+    """Update a target with a given command given a list of dependencies.
+
+    target_update(target,deps,cmd) -> runs cmd if target is outdated.
+
+    This is just a wrapper around target_outdated() which calls the given
+    command if target is outdated."""
+
+    if target_outdated(target,deps):
+        xsys(cmd)
+
+#----------------------------------------------------------------------------
+def unquote_ends(istr):
+    """Remove a single pair of quotes from the endpoints of a string."""
+
+    if not istr:
+        return istr
+    if (istr[0]=="'" and istr[-1]=="'") or \
+       (istr[0]=='"' and istr[-1]=='"'):
+        return istr[1:-1]
+    else:
+        return istr
+
+#----------------------------------------------------------------------------
+def process_cmdline(argv,names=[],defaults={},usage=''):
+    """ Process command-line options and arguments.
+
+    Arguments:
+
+    - argv: list of arguments, typically sys.argv.
+    
+    - names: list of option names. See DPyGetOpt docs for details on options
+    syntax.
+
+    - defaults: dict of default values.
+
+    - usage: optional usage notice to print if a wrong argument is passed.
+
+    Return a dict of options and a list of free arguments."""
+
+    getopt = DPyGetOpt.DPyGetOpt()
+    getopt.setIgnoreCase(0)
+    getopt.parseConfiguration(names)
+
+    try:
+        getopt.processArguments(argv)
+    except:
+        print usage
+        warn(`sys.exc_value`,level=4)
+
+    defaults.update(getopt.optionValues)
+    args = getopt.freeValues
+    
+    return defaults,args
+
+#----------------------------------------------------------------------------
+def optstr2types(ostr):
+    """Convert a string of option names to a dict of type mappings.
+
+    optstr2types(str) -> {None:'string_opts',int:'int_opts',float:'float_opts'}
+
+    This is used to get the types of all the options in a string formatted
+    with the conventions of DPyGetOpt. The 'type' None is used for options
+    which are strings (they need no further conversion). This function's main
+    use is to get a typemap for use with read_dict().
+    """
+
+    typeconv = {None:'',int:'',float:''}
+    typemap = {'s':None,'i':int,'f':float}
+    opt_re = re.compile(r'([\w]*)([^:=]*:?=?)([sif]?)')
+
+    for w in ostr.split():
+        oname,alias,otype = opt_re.match(w).groups()
+        if otype == '' or alias == '!':   # simple switches are integers too
+            otype = 'i'
+        typeconv[typemap[otype]] += oname + ' '
+    return typeconv
+
+#----------------------------------------------------------------------------
+def read_dict(filename,type_conv=None,**opt):
+
+    """Read a dictionary of key=value pairs from an input file, optionally
+    performing conversions on the resulting values.
+
+    read_dict(filename,type_conv,**opt) -> dict
+
+    Only one value per line is accepted, the format should be
+     # optional comments are ignored
+     key value\n
+
+    Args:
+
+      - type_conv: A dictionary specifying which keys need to be converted to
+      which types. By default all keys are read as strings. This dictionary
+      should have as its keys valid conversion functions for strings
+      (int,long,float,complex, or your own).  The value for each key
+      (converter) should be a whitespace separated string containing the names
+      of all the entries in the file to be converted using that function. For
+      keys to be left alone, use None as the conversion function (only needed
+      with purge=1, see below).
+
+      - opt: dictionary with extra options as below (default in parens)
+
+        purge(0): if set to 1, all keys *not* listed in type_conv are purged out
+        of the dictionary to be returned. If purge is going to be used, the
+        set of keys to be left as strings also has to be explicitly specified
+        using the (non-existent) conversion function None.
+
+        fs(None): field separator. This is the key/value separator to be used
+        when parsing the file. The None default means any whitespace [behavior
+        of string.split()].
+
+        strip(0): if 1, strip string values of leading/trailinig whitespace.
+
+        warn(1): warning level if requested keys are not found in file.
+          - 0: silently ignore.
+          - 1: inform but proceed.
+          - 2: raise KeyError exception.
+
+        no_empty(0): if 1, remove keys with whitespace strings as a value.
+
+        unique([]): list of keys (or space separated string) which can't be
+        repeated. If one such key is found in the file, each new instance
+        overwrites the previous one. For keys not listed here, the behavior is
+        to make a list of all appearances.
+
+    Example:
+    If the input file test.ini has:
+      i 3
+      x 4.5
+      y 5.5
+      s hi ho
+    Then:
+
+    >>> type_conv={int:'i',float:'x',None:'s'}
+    >>> read_dict('test.ini')
+    {'i': '3', 's': 'hi ho', 'x': '4.5', 'y': '5.5'}
+    >>> read_dict('test.ini',type_conv)
+    {'i': 3, 's': 'hi ho', 'x': 4.5, 'y': '5.5'}
+    >>> read_dict('test.ini',type_conv,purge=1)
+    {'i': 3, 's': 'hi ho', 'x': 4.5}
+    """
+
+    # starting config
+    opt.setdefault('purge',0)
+    opt.setdefault('fs',None)  # field sep defaults to any whitespace
+    opt.setdefault('strip',0)
+    opt.setdefault('warn',1)
+    opt.setdefault('no_empty',0)
+    opt.setdefault('unique','')
+    if type(opt['unique']) in StringTypes:
+        unique_keys = qw(opt['unique'])
+    elif type(opt['unique']) in (types.TupleType,types.ListType):
+        unique_keys = opt['unique']
+    else:
+        raise ValueError, 'Unique keys must be given as a string, List or Tuple'
+
+    dict = {}
+    # first read in table of values as strings
+    file = open(filename,'r')
+    for line in file.readlines():
+        line = line.strip()
+        if len(line) and line[0]=='#': continue
+        if len(line)>0:
+            lsplit = line.split(opt['fs'],1)
+            try:
+                key,val = lsplit
+            except ValueError:
+                key,val = lsplit[0],''
+            key = key.strip()
+            if opt['strip']: val = val.strip()
+            if val == "''" or val == '""': val = ''
+            if opt['no_empty'] and (val=='' or val.isspace()):
+                continue
+            # if a key is found more than once in the file, build a list
+            # unless it's in the 'unique' list. In that case, last found in file
+            # takes precedence. User beware.
+            try:
+                if dict[key] and key in unique_keys:
+                    dict[key] = val
+                elif type(dict[key]) is types.ListType:
+                    dict[key].append(val)
+                else:
+                    dict[key] = [dict[key],val]
+            except KeyError:
+                dict[key] = val
+    # purge if requested
+    if opt['purge']:
+        accepted_keys = qwflat(type_conv.values())
+        for key in dict.keys():
+            if key in accepted_keys: continue
+            del(dict[key])
+    # now convert if requested
+    if type_conv==None: return dict
+    conversions = type_conv.keys()
+    try: conversions.remove(None)
+    except: pass
+    for convert in conversions:
+        for val in qw(type_conv[convert]):
+            try:
+                dict[val] = convert(dict[val])
+            except KeyError,e:
+                if opt['warn'] == 0:
+                    pass
+                elif opt['warn'] == 1:
+                    print >>sys.stderr, 'Warning: key',val,\
+                          'not found in file',filename
+                elif opt['warn'] == 2:
+                    raise KeyError,e
+                else:
+                    raise ValueError,'Warning level must be 0,1 or 2'
+
+    return dict
+
+#----------------------------------------------------------------------------
+def flag_calls(func):
+    """Wrap a function to detect and flag when it gets called.
+
+    This is a decorator which takes a function and wraps it in a function with
+    a 'called' attribute. wrapper.called is initialized to False.
+
+    The wrapper.called attribute is set to False right before each call to the
+    wrapped function, so if the call fails it remains False.  After the call
+    completes, wrapper.called is set to True and the output is returned.
+
+    Testing for truth in wrapper.called allows you to determine if a call to
+    func() was attempted and succeeded."""
+    
+    def wrapper(*args,**kw):
+        wrapper.called = False
+        out = func(*args,**kw)
+        wrapper.called = True
+        return out
+
+    wrapper.called = False
+    wrapper.__doc__ = func.__doc__
+    return wrapper
+
+#----------------------------------------------------------------------------
+class HomeDirError(Error):
+    pass
+
+def get_home_dir():
+    """Return the closest possible equivalent to a 'home' directory.
+
+    We first try $HOME.  Absent that, on NT it's $HOMEDRIVE\$HOMEPATH.
+
+    Currently only Posix and NT are implemented, a HomeDirError exception is
+    raised for all other OSes. """ #'
+
+    try:
+        return os.environ['HOME']
+    except KeyError:
+        if os.name == 'posix':
+            raise HomeDirError,'undefined $HOME, IPython can not proceed.'
+        elif os.name == 'nt':
+            # For some strange reason, win9x returns 'nt' for os.name.
+            try:
+                return os.path.join(os.environ['HOMEDRIVE'],os.environ['HOMEPATH'])
+            except:
+                try:
+                    # Use the registry to get the 'My Documents' folder.
+                    import _winreg as wreg
+                    key = wreg.OpenKey(wreg.HKEY_CURRENT_USER,
+                                       "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders")
+                    homedir = wreg.QueryValueEx(key,'Personal')[0]
+                    key.Close()
+                    return homedir
+                except:
+                    return 'C:\\'
+        elif os.name == 'dos':
+            # Desperate, may do absurd things in classic MacOS. May work under DOS.
+            return 'C:\\'
+        else:
+            raise HomeDirError,'support for your operating system not implemented.'
+
+#****************************************************************************
+# strings and text
+
+class LSString(str):
+    """String derivative with a special access attributes.
+
+    These are normal strings, but with the special attributes:
+
+        .l (or .list) : value as list (split on newlines).
+        .n (or .nlstr): original value (the string itself).
+        .s (or .spstr): value as whitespace-separated string.
+        
+    Any values which require transformations are computed only once and
+    cached.
+
+    Such strings are very useful to efficiently interact with the shell, which
+    typically only understands whitespace-separated options for commands."""
+
+    def get_list(self):
+        try:
+            return self.__list
+        except AttributeError:
+            self.__list = self.split('\n')
+            return self.__list
+
+    l = list = property(get_list)
+
+    def get_spstr(self):
+        try:
+            return self.__spstr
+        except AttributeError:
+            self.__spstr = self.replace('\n',' ')
+            return self.__spstr
+
+    s = spstr = property(get_spstr)
+
+    def get_nlstr(self):
+        return self
+
+    n = nlstr = property(get_nlstr)
+
+class SList(list):
+    """List derivative with a special access attributes.
+
+    These are normal lists, but with the special attributes:
+
+        .l (or .list) : value as list (the list itself).
+        .n (or .nlstr): value as a string, joined on newlines.
+        .s (or .spstr): value as a string, joined on spaces.
+
+    Any values which require transformations are computed only once and
+    cached."""
+
+    def get_list(self):
+        return self
+
+    l = list = property(get_list)
+
+    def get_spstr(self):
+        try:
+            return self.__spstr
+        except AttributeError:
+            self.__spstr = ' '.join(self)
+            return self.__spstr
+
+    s = spstr = property(get_spstr)
+
+    def get_nlstr(self):
+        try:
+            return self.__nlstr
+        except AttributeError:
+            self.__nlstr = '\n'.join(self)
+            return self.__nlstr
+
+    n = nlstr = property(get_nlstr)
+
+def raw_input_multi(header='', ps1='==> ', ps2='..> ',terminate_str = '.'):
+    """Take multiple lines of input.
+
+    A list with each line of input as a separate element is returned when a
+    termination string is entered (defaults to a single '.'). Input can also
+    terminate via EOF (^D in Unix, ^Z-RET in Windows).
+
+    Lines of input which end in \\ are joined into single entries (and a
+    secondary continuation prompt is issued as long as the user terminates
+    lines with \\). This allows entering very long strings which are still
+    meant to be treated as single entities.
+    """
+
+    try:
+        if header:
+            header += '\n'
+        lines = [raw_input(header + ps1)]
+    except EOFError:
+        return []
+    terminate = [terminate_str]
+    try:
+        while lines[-1:] != terminate:
+            new_line = raw_input(ps1)
+            while new_line.endswith('\\'):
+                new_line = new_line[:-1] + raw_input(ps2)
+            lines.append(new_line)
+                
+        return lines[:-1]  # don't return the termination command
+    except EOFError:
+        print
+        return lines
+
+#----------------------------------------------------------------------------
+def raw_input_ext(prompt='',  ps2='... '):
+    """Similar to raw_input(), but accepts extended lines if input ends with \\."""
+
+    line = raw_input(prompt)
+    while line.endswith('\\'):
+        line = line[:-1] + raw_input(ps2)
+    return line
+
+#----------------------------------------------------------------------------
+def ask_yes_no(prompt,default=None):
+    """Asks a question and returns an integer 1/0 (y/n) answer.
+
+    If default is given (one of 'y','n'), it is used if the user input is
+    empty. Otherwise the question is repeated until an answer is given.
+    If EOF occurs 20 times consecutively, the default answer is assumed,
+    or if there is no default, an exception is raised to prevent infinite
+    loops.
+
+    Valid answers are: y/yes/n/no (match is not case sensitive)."""
+
+    answers = {'y':1,'n':0,'yes':1,'no':0}
+    ans = None
+    eofs, max_eofs = 0, 20
+    while ans not in answers.keys():
+        try:
+            ans = raw_input(prompt+' ').lower()
+            if not ans:  # response was an empty string
+                ans = default
+            eofs = 0
+        except (EOFError,KeyboardInterrupt):
+            eofs = eofs + 1
+            if eofs >= max_eofs:
+                if default in answers.keys():
+                    ans = default
+                else:
+                    raise
+            
+    return answers[ans]
+
+#----------------------------------------------------------------------------
+class EvalDict:
+    """
+    Emulate a dict which evaluates its contents in the caller's frame.
+
+    Usage:
+    >>>number = 19
+    >>>text = "python"
+    >>>print "%(text.capitalize())s %(number/9.0).1f rules!" % EvalDict()
+    """
+
+    # This version is due to sismex01@hebmex.com on c.l.py, and is basically a
+    # modified (shorter) version of:
+    # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66018 by
+    # Skip Montanaro (skip@pobox.com).
+
+    def __getitem__(self, name):
+        frame = sys._getframe(1)
+        return eval(name, frame.f_globals, frame.f_locals)
+
+EvalString = EvalDict  # for backwards compatibility
+#----------------------------------------------------------------------------
+def qw(words,flat=0,sep=None,maxsplit=-1):
+    """Similar to Perl's qw() operator, but with some more options.
+
+    qw(words,flat=0,sep=' ',maxsplit=-1) -> words.split(sep,maxsplit)
+
+    words can also be a list itself, and with flat=1, the output will be
+    recursively flattened. Examples:
+
+    >>> qw('1 2')
+    ['1', '2']
+    >>> qw(['a b','1 2',['m n','p q']])
+    [['a', 'b'], ['1', '2'], [['m', 'n'], ['p', 'q']]]
+    >>> qw(['a b','1 2',['m n','p q']],flat=1)
+    ['a', 'b', '1', '2', 'm', 'n', 'p', 'q']    """
+
+    if type(words) in StringTypes:
+        return [word.strip() for word in words.split(sep,maxsplit)
+                if word and not word.isspace() ]
+    if flat:
+        return flatten(map(qw,words,[1]*len(words)))
+    return map(qw,words)
+
+#----------------------------------------------------------------------------
+def qwflat(words,sep=None,maxsplit=-1):
+    """Calls qw(words) in flat mode. It's just a convenient shorthand."""
+    return qw(words,1,sep,maxsplit)
+
+#-----------------------------------------------------------------------------
+def list_strings(arg):
+    """Always return a list of strings, given a string or list of strings
+    as input."""
+
+    if type(arg) in StringTypes: return [arg]
+    else: return arg
+
+#----------------------------------------------------------------------------
+def grep(pat,list,case=1):
+    """Simple minded grep-like function.
+    grep(pat,list) returns occurrences of pat in list, None on failure.
+
+    It only does simple string matching, with no support for regexps. Use the
+    option case=0 for case-insensitive matching."""
+
+    # This is pretty crude. At least it should implement copying only references
+    # to the original data in case it's big. Now it copies the data for output.
+    out=[]
+    if case:
+        for term in list:
+            if term.find(pat)>-1: out.append(term)
+    else:
+        lpat=pat.lower()
+        for term in list:
+            if term.lower().find(lpat)>-1: out.append(term)
+
+    if len(out): return out
+    else: return None
+
+#----------------------------------------------------------------------------
+def dgrep(pat,*opts):
+    """Return grep() on dir()+dir(__builtins__).
+
+    A very common use of grep() when working interactively."""
+
+    return grep(pat,dir(__main__)+dir(__main__.__builtins__),*opts)
+
+#----------------------------------------------------------------------------
+def idgrep(pat):
+    """Case-insensitive dgrep()"""
+
+    return dgrep(pat,0)
+
+#----------------------------------------------------------------------------
+def igrep(pat,list):
+    """Synonym for case-insensitive grep."""
+
+    return grep(pat,list,case=0)
+
+#----------------------------------------------------------------------------
+def indent(str,nspaces=4,ntabs=0):
+    """Indent a string a given number of spaces or tabstops.
+    
+    indent(str,nspaces=4,ntabs=0) -> indent str by ntabs+nspaces.
+    """
+    if str is None:
+        return
+    ind = '\t'*ntabs+' '*nspaces
+    outstr = '%s%s' % (ind,str.replace(os.linesep,os.linesep+ind))
+    if outstr.endswith(os.linesep+ind):
+        return outstr[:-len(ind)]
+    else:
+        return outstr
+    
+#-----------------------------------------------------------------------------
+def native_line_ends(filename,backup=1):
+    """Convert (in-place) a file to line-ends native to the current OS.
+
+    If the optional backup argument is given as false, no backup of the
+    original file is left.  """
+
+    backup_suffixes = {'posix':'~','dos':'.bak','nt':'.bak','mac':'.bak'}
+
+    bak_filename = filename + backup_suffixes[os.name]
+
+    original = open(filename).read()
+    shutil.copy2(filename,bak_filename)
+    try:
+        new = open(filename,'wb')
+        new.write(os.linesep.join(original.splitlines()))
+        new.write(os.linesep) # ALWAYS put an eol at the end of the file
+        new.close()
+    except:
+        os.rename(bak_filename,filename)
+    if not backup:
+        try:
+            os.remove(bak_filename)
+        except:
+            pass
+    
+#----------------------------------------------------------------------------
+def get_pager_cmd(pager_cmd = None):
+    """Return a pager command.
+
+    Makes some attempts at finding an OS-correct one."""
+    
+    if os.name == 'posix':
+        default_pager_cmd = 'less -r'  # -r for color control sequences
+    elif os.name in ['nt','dos']:
+        default_pager_cmd = 'type'
+
+    if pager_cmd is None:
+        try:
+            pager_cmd = os.environ['PAGER']
+        except:
+            pager_cmd = default_pager_cmd
+    return pager_cmd
+
+#-----------------------------------------------------------------------------
+def get_pager_start(pager,start):
+    """Return the string for paging files with an offset.
+
+    This is the '+N' argument which less and more (under Unix) accept.
+    """
+
+    if pager in ['less','more']:
+        if start:
+            start_string = '+' + str(start)
+        else:
+            start_string = ''
+    else:
+        start_string = ''
+    return start_string
+
+#----------------------------------------------------------------------------
+def page_dumb(strng,start=0,screen_lines=25):
+    """Very dumb 'pager' in Python, for when nothing else works.
+
+    Only moves forward, same interface as page(), except for pager_cmd and
+    mode."""
+
+    out_ln  = strng.splitlines()[start:]
+    screens = chop(out_ln,screen_lines-1)
+    if len(screens) == 1:
+        print >>Term.cout, os.linesep.join(screens[0])
+    else:
+        for scr in screens[0:-1]:
+            print >>Term.cout, os.linesep.join(scr)
+            ans = raw_input('---Return to continue, q to quit--- ')
+            if ans.lower().startswith('q'):
+                return
+        print >>Term.cout, os.linesep.join(screens[-1])
+
+#----------------------------------------------------------------------------
+def page(strng,start=0,screen_lines=0,pager_cmd = None):
+    """Print a string, piping through a pager after a certain length.
+
+    The screen_lines parameter specifies the number of *usable* lines of your
+    terminal screen (total lines minus lines you need to reserve to show other
+    information).
+
+    If you set screen_lines to a number <=0, page() will try to auto-determine
+    your screen size and will only use up to (screen_size+screen_lines) for
+    printing, paging after that. That is, if you want auto-detection but need
+    to reserve the bottom 3 lines of the screen, use screen_lines = -3, and for
+    auto-detection without any lines reserved simply use screen_lines = 0.
+
+    If a string won't fit in the allowed lines, it is sent through the
+    specified pager command. If none given, look for PAGER in the environment,
+    and ultimately default to less.
+
+    If no system pager works, the string is sent through a 'dumb pager'
+    written in python, very simplistic.
+    """
+    
+    # Ugly kludge, but calling curses.initscr() flat out crashes in emacs
+    TERM = os.environ.get('TERM','dumb')
+    if TERM in ['dumb','emacs'] and os.name != 'nt':
+        print strng
+        return
+    # chop off the topmost part of the string we don't want to see
+    str_lines = strng.split(os.linesep)[start:]
+    str_toprint = os.linesep.join(str_lines)
+    num_newlines = len(str_lines)
+    len_str = len(str_toprint)
+    
+    # Dumb heuristics to guesstimate number of on-screen lines the string
+    # takes.  Very basic, but good enough for docstrings in reasonable
+    # terminals. If someone later feels like refining it, it's not hard.
+    numlines = max(num_newlines,int(len_str/80)+1)
+
+    screen_lines_def = 25 # default value if we can't auto-determine
+
+    # auto-determine screen size
+    if screen_lines <= 0:
+        if TERM=='xterm':
+            try:
+                import curses
+                if hasattr(curses,'initscr'):
+                    use_curses = 1
+                else:
+                    use_curses = 0
+            except ImportError:
+                use_curses = 0
+        else:
+            # curses causes problems on many terminals other than xterm.
+            use_curses = 0
+        if use_curses:
+                scr = curses.initscr()
+                screen_lines_real,screen_cols = scr.getmaxyx()
+                curses.endwin()
+                screen_lines += screen_lines_real
+                #print '***Screen size:',screen_lines_real,'lines x',\
+                #screen_cols,'columns.' # dbg
+        else:
+                screen_lines += screen_lines_def
+
+    #print 'numlines',numlines,'screenlines',screen_lines  # dbg
+    if numlines <= screen_lines :
+        #print '*** normal print'  # dbg
+        print >>Term.cout, str_toprint
+    else:
+        # Try to open pager and default to internal one if that fails.
+        # All failure modes are tagged as 'retval=1', to match the return
+        # value of a failed system command.  If any intermediate attempt
+        # sets retval to 1, at the end we resort to our own page_dumb() pager.
+        pager_cmd = get_pager_cmd(pager_cmd)
+        pager_cmd += ' ' + get_pager_start(pager_cmd,start)
+        if os.name == 'nt':
+            if pager_cmd.startswith('type'):
+                # The default WinXP 'type' command is failing on complex strings.
+                retval = 1
+            else:
+                tmpname = tempfile.mktemp('.txt')
+                tmpfile = file(tmpname,'wt')
+                tmpfile.write(strng)
+                tmpfile.close()
+                cmd = "%s < %s" % (pager_cmd,tmpname)
+                if os.system(cmd):
+                  retval = 1
+                else:
+                  retval = None
+                os.remove(tmpname)
+        else:
+            try:
+                retval = None
+                # if I use popen4, things hang. No idea why.
+                #pager,shell_out = os.popen4(pager_cmd)
+                pager = os.popen(pager_cmd,'w')
+                pager.write(strng)
+                pager.close()
+                retval = pager.close()  # success returns None
+            except IOError,msg:  # broken pipe when user quits
+                if msg.args == (32,'Broken pipe'):
+                    retval = None
+                else:
+                    retval = 1
+            except OSError:
+                # Other strange problems, sometimes seen in Win2k/cygwin
+                retval = 1
+        if retval is not None:
+            page_dumb(strng,screen_lines=screen_lines)
+
+#----------------------------------------------------------------------------
+def page_file(fname,start = 0, pager_cmd = None):
+    """Page a file, using an optional pager command and starting line.
+    """
+
+    pager_cmd = get_pager_cmd(pager_cmd)
+    pager_cmd += ' ' + get_pager_start(pager_cmd,start)
+
+    try:
+        if os.environ['TERM'] in ['emacs','dumb']:
+            raise EnvironmentError
+        xsys(pager_cmd + ' ' + fname)
+    except:
+        try:
+            if start > 0:
+                start -= 1
+            page(open(fname).read(),start)
+        except:
+            print 'Unable to show file',`fname`
+
+#----------------------------------------------------------------------------
+def snip_print(str,width = 75,print_full = 0,header = ''):
+    """Print a string snipping the midsection to fit in width.
+
+    print_full: mode control:
+      - 0: only snip long strings
+      - 1: send to page() directly.
+      - 2: snip long strings and ask for full length viewing with page()
+    Return 1 if snipping was necessary, 0 otherwise."""
+
+    if print_full == 1:
+        page(header+str)
+        return 0
+
+    print header,
+    if len(str) < width:
+        print str
+        snip = 0
+    else:
+        whalf = int((width -5)/2)
+        print str[:whalf] + ' <...> ' + str[-whalf:]
+        snip = 1
+    if snip and print_full == 2:
+        if raw_input(header+' Snipped. View (y/n)? [N]').lower() == 'y':
+            page(str)
+    return snip
+
+#****************************************************************************
+# lists, dicts and structures
+
+def belong(candidates,checklist):
+    """Check whether a list of items appear in a given list of options.
+
+    Returns a list of 1 and 0, one for each candidate given."""
+
+    return [x in checklist for x in candidates]
+
+#----------------------------------------------------------------------------
+def uniq_stable(elems):
+    """uniq_stable(elems) -> list
+
+    Return from an iterable, a list of all the unique elements in the input,
+    but maintaining the order in which they first appear.
+
+    A naive solution to this problem which just makes a dictionary with the
+    elements as keys fails to respect the stability condition, since
+    dictionaries are unsorted by nature.
+
+    Note: All elements in the input must be valid dictionary keys for this
+    routine to work, as it internally uses a dictionary for efficiency
+    reasons."""
+    
+    unique = []
+    unique_dict = {}
+    for nn in elems:
+        if nn not in unique_dict:
+            unique.append(nn)
+            unique_dict[nn] = None
+    return unique
+
+#----------------------------------------------------------------------------
+class NLprinter:
+    """Print an arbitrarily nested list, indicating index numbers.
+
+    An instance of this class called nlprint is available and callable as a
+    function.
+    
+    nlprint(list,indent=' ',sep=': ') -> prints indenting each level by 'indent'
+    and using 'sep' to separate the index from the value. """
+
+    def __init__(self):
+        self.depth = 0
+    
+    def __call__(self,lst,pos='',**kw):
+        """Prints the nested list numbering levels."""
+        kw.setdefault('indent',' ')
+        kw.setdefault('sep',': ')
+        kw.setdefault('start',0)
+        kw.setdefault('stop',len(lst))
+        # we need to remove start and stop from kw so they don't propagate
+        # into a recursive call for a nested list.
+        start = kw['start']; del kw['start']
+        stop = kw['stop']; del kw['stop']
+        if self.depth == 0 and 'header' in kw.keys():
+            print kw['header']
+            
+        for idx in range(start,stop):
+            elem = lst[idx]
+            if type(elem)==type([]):
+                self.depth += 1
+                self.__call__(elem,itpl('$pos$idx,'),**kw)
+                self.depth -= 1
+            else:
+                printpl(kw['indent']*self.depth+'$pos$idx$kw["sep"]$elem')
+
+nlprint = NLprinter()
+#----------------------------------------------------------------------------
+def all_belong(candidates,checklist):
+    """Check whether a list of items ALL appear in a given list of options.
+
+    Returns a single 1 or 0 value."""
+
+    return 1-(0 in [x in checklist for x in candidates])
+
+#----------------------------------------------------------------------------
+def sort_compare(lst1,lst2,inplace = 1):
+    """Sort and compare two lists.
+
+    By default it does it in place, thus modifying the lists. Use inplace = 0
+    to avoid that (at the cost of temporary copy creation)."""
+    if not inplace:
+        lst1 = lst1[:]
+        lst2 = lst2[:]
+    lst1.sort(); lst2.sort()
+    return lst1 == lst2
+
+#----------------------------------------------------------------------------
+def mkdict(**kwargs):
+    """Return a dict from a keyword list.
+
+    It's just syntactic sugar for making ditcionary creation more convenient:
+    # the standard way
+    >>>data = { 'red' : 1, 'green' : 2, 'blue' : 3 }
+    # a cleaner way
+    >>>data = dict(red=1, green=2, blue=3)
+
+    If you need more than this, look at the Struct() class."""
+
+    return kwargs
+
+#----------------------------------------------------------------------------
+def list2dict(lst):
+    """Takes a list of (key,value) pairs and turns it into a dict."""
+
+    dic = {}
+    for k,v in lst: dic[k] = v
+    return dic
+
+#----------------------------------------------------------------------------
+def list2dict2(lst,default=''):
+    """Takes a list and turns it into a dict.
+    Much slower than list2dict, but more versatile. This version can take
+    lists with sublists of arbitrary length (including sclars)."""
+
+    dic = {}
+    for elem in lst:
+        if type(elem) in (types.ListType,types.TupleType):
+            size = len(elem)
+            if  size == 0:
+                pass
+            elif size == 1:
+                dic[elem] = default
+            else:
+                k,v = elem[0], elem[1:]
+                if len(v) == 1: v = v[0]
+                dic[k] = v
+        else:
+            dic[elem] = default
+    return dic
+
+#----------------------------------------------------------------------------
+def flatten(seq):
+    """Flatten a list of lists (NOT recursive, only works for 2d lists)."""
+
+    # bug in python??? (YES. Fixed in 2.2, let's leave the kludgy fix in).
+
+    # if the x=0 isn't made, a *global* variable x is left over after calling
+    # this function, with the value of the last element in the return
+    # list. This does seem like a bug big time to me.
+
+    # the problem is fixed with the x=0, which seems to force the creation of
+    # a local name
+
+    x = 0 
+    return [x for subseq in seq for x in subseq]
+
+#----------------------------------------------------------------------------
+def get_slice(seq,start=0,stop=None,step=1):
+    """Get a slice of a sequence with variable step. Specify start,stop,step."""
+    if stop == None:
+        stop = len(seq)
+    item = lambda i: seq[i]
+    return map(item,xrange(start,stop,step))
+
+#----------------------------------------------------------------------------
+def chop(seq,size):
+    """Chop a sequence into chunks of the given size."""
+    chunk = lambda i: seq[i:i+size]
+    return map(chunk,xrange(0,len(seq),size))
+
+#----------------------------------------------------------------------------
+def with(object, **args):
+    """Set multiple attributes for an object, similar to Pascal's with.
+
+    Example:
+    with(jim,
+         born = 1960,
+         haircolour = 'Brown',
+         eyecolour = 'Green')
+
+    Credit: Greg Ewing, in
+    http://mail.python.org/pipermail/python-list/2001-May/040703.html"""
+
+    object.__dict__.update(args)
+
+#----------------------------------------------------------------------------
+def setattr_list(obj,alist,nspace = None):
+    """Set a list of attributes for an object taken from a namespace.
+
+    setattr_list(obj,alist,nspace) -> sets in obj all the attributes listed in
+    alist with their values taken from nspace, which must be a dict (something
+    like locals() will often do) If nspace isn't given, locals() of the
+    *caller* is used, so in most cases you can omit it.
+
+    Note that alist can be given as a string, which will be automatically
+    split into a list on whitespace. If given as a list, it must be a list of
+    *strings* (the variable names themselves), not of variables."""
+
+    # this grabs the local variables from the *previous* call frame -- that is
+    # the locals from the function that called setattr_list().
+    # - snipped from weave.inline()
+    if nspace is None:
+        call_frame = sys._getframe().f_back
+        nspace = call_frame.f_locals
+
+    if type(alist) in StringTypes:
+        alist = alist.split()
+    for attr in alist:
+        val = eval(attr,nspace)
+        setattr(obj,attr,val)
+
+#----------------------------------------------------------------------------
+def getattr_list(obj,alist,*args):
+    """getattr_list(obj,alist[, default]) -> attribute list.
+
+    Get a list of named attributes for an object. When a default argument is
+    given, it is returned when the attribute doesn't exist; without it, an
+    exception is raised in that case.
+
+    Note that alist can be given as a string, which will be automatically
+    split into a list on whitespace. If given as a list, it must be a list of
+    *strings* (the variable names themselves), not of variables."""
+
+    if type(alist) in StringTypes:
+        alist = alist.split()
+    if args:
+        if len(args)==1:
+            default = args[0]
+            return map(lambda attr: getattr(obj,attr,default),alist)
+        else:
+            raise ValueError,'getattr_list() takes only one optional argument'
+    else:
+        return map(lambda attr: getattr(obj,attr),alist)
+    
+#----------------------------------------------------------------------------
+def map_method(method,object_list,*argseq,**kw):
+    """map_method(method,object_list,*args,**kw) -> list
+
+    Return a list of the results of applying the methods to the items of the
+    argument sequence(s).  If more than one sequence is given, the method is
+    called with an argument list consisting of the corresponding item of each
+    sequence. All sequences must be of the same length.
+
+    Keyword arguments are passed verbatim to all objects called.
+
+    This is Python code, so it's not nearly as fast as the builtin map()."""
+
+    out_list = []
+    idx = 0
+    for object in object_list:
+        try:
+            handler = getattr(object, method)
+        except AttributeError:
+            out_list.append(None)
+        else:
+            if argseq:
+                args = map(lambda lst:lst[idx],argseq)
+                #print 'ob',object,'hand',handler,'ar',args # dbg
+                out_list.append(handler(args,**kw))
+            else:
+                out_list.append(handler(**kw))
+        idx += 1
+    return out_list
+
+#----------------------------------------------------------------------------
+# Proposed popitem() extension, written as a method
+
+class NotGiven: pass
+
+def popkey(dct,key,default=NotGiven):
+    """Return dct[key] and delete dct[key].
+
+    If default is given, return it if dct[key] doesn't exist, otherwise raise
+    KeyError.  """
+
+    try:
+        val = dct[key]
+    except KeyError:
+        if default is NotGiven:
+            raise
+        else:
+            return default
+    else:
+        del dct[key]
+        return val
+#*************************** end of file <genutils.py> **********************
+
diff --git a/IPython/hooks.py b/IPython/hooks.py
new file mode 100644
index 0000000..1c02757
--- /dev/null
+++ b/IPython/hooks.py
@@ -0,0 +1,72 @@
+"""hooks for IPython.
+
+In Python, it is possible to overwrite any method of any object if you really
+want to.  But IPython exposes a few 'hooks', methods which are _designed_ to
+be overwritten by users for customization purposes.  This module defines the
+default versions of all such hooks, which get used by IPython if not
+overridden by the user.
+
+hooks are simple functions, but they should be declared with 'self' as their
+first argument, because when activated they are registered into IPython as
+instance methods.  The self argument will be the IPython running instance
+itself, so hooks have full access to the entire IPython object.
+
+If you wish to define a new hook and activate it, you need to put the
+necessary code into a python file which can be either imported or execfile()'d
+from within your ipythonrc configuration.
+
+For example, suppose that you have a module called 'myiphooks' in your
+PYTHONPATH, which contains the following definition:
+
+import os
+def calljed(self,filename, linenum):
+    "My editor hook calls the jed editor directly."
+    print "Calling my own editor, jed ..."
+    os.system('jed +%d %s' % (linenum,filename))
+
+You can then execute the following line of code to make it the new IPython
+editor hook, after having imported 'myiphooks':
+
+ip_set_hook('editor',myiphooks.calljed)
+
+The ip_set_hook function is put by IPython into the builtin namespace, so it
+is always available from all running code.
+
+$Id: hooks.py 535 2005-03-02 08:42:25Z fperez $"""
+
+#*****************************************************************************
+#       Copyright (C) 2005 Fernando Perez. <fperez@colorado.edu>
+#
+#  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
+
+import os
+
+# List here all the default hooks.  For now it's just the editor, but over
+# time we'll move here all the public API for user-accessible things.
+__all__ = ['editor']
+
+def editor(self,filename, linenum):
+    """Open the default editor at the given filename and linenumber.
+
+    This is IPython's default editor hook, you can use it as an example to
+    write your own modified one.  To set your own editor function as the
+    new editor hook, call ip_set_hook('editor',yourfunc)."""
+
+    # IPython configures a default editor at startup by reading $EDITOR from
+    # the environment, and falling back on vi (unix) or notepad (win32).
+    editor = self.rc.editor
+    
+    # marker for at which line to open the file (for existing objects)
+    if linenum is None or editor=='notepad':
+        linemark = ''
+    else:
+        linemark = '+%d' % linenum
+    # Call the actual editor
+    os.system('%s %s %s' % (editor,linemark,filename))
diff --git a/IPython/iplib.py b/IPython/iplib.py
new file mode 100644
index 0000000..434c709
--- /dev/null
+++ b/IPython/iplib.py
@@ -0,0 +1,2084 @@
+# -*- coding: utf-8 -*-
+"""
+IPython -- An enhanced Interactive Python
+
+Requires Python 2.1 or newer.
+
+This file contains all the classes and helper functions specific to IPython.
+
+$Id: iplib.py 602 2005-06-09 03:02:30Z fperez $
+"""
+
+#*****************************************************************************
+#       Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
+#       Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
+#
+#  Distributed under the terms of the BSD License.  The full license is in
+#  the file COPYING, distributed as part of this software.
+#
+# Note: this code originally subclassed code.InteractiveConsole from the
+# Python standard library.  Over time, much of that class has been copied
+# verbatim here for modifications which could not be accomplished by
+# subclassing.  The Python License (sec. 2) allows for this, but it's always
+# nice to acknowledge credit where credit is due.
+#*****************************************************************************
+
+#****************************************************************************
+# Modules and globals
+
+from __future__ import generators  # for 2.2 backwards-compatibility
+
+from IPython import Release
+__author__  = '%s <%s>\n%s <%s>' % \
+              ( Release.authors['Janko'] + Release.authors['Fernando'] )
+__license__ = Release.license
+__version__ = Release.version
+
+# Python standard modules
+import __main__
+import __builtin__
+import exceptions
+import keyword
+import new
+import os, sys, shutil
+import code, glob, types, re
+import string, StringIO
+import inspect, pydoc
+import bdb, pdb
+import UserList # don't subclass list so this works with Python2.1
+from pprint import pprint, pformat
+import cPickle as pickle
+import traceback
+
+# IPython's own modules
+import IPython
+from IPython import OInspect,PyColorize,ultraTB
+from IPython.ultraTB import ColorScheme,ColorSchemeTable  # too long names
+from IPython.Logger import Logger
+from IPython.Magic import Magic,magic2python,shlex_split
+from IPython.usage import cmd_line_usage,interactive_usage
+from IPython.Struct import Struct
+from IPython.Itpl import Itpl,itpl,printpl,ItplNS,itplns
+from IPython.FakeModule import FakeModule
+from IPython.background_jobs import BackgroundJobManager
+from IPython.genutils import *
+
+# Global pointer to the running 
+
+# store the builtin raw_input globally, and use this always, in case user code
+# overwrites it (like wx.py.PyShell does)
+raw_input_original = raw_input
+
+# declares Python 2.2 compatibility symbols:
+try:
+    enumerate
+except NameError:
+    def enumerate(obj):
+        i = -1
+        for item in obj:
+            i += 1
+            yield i, item
+#****************************************************************************
+# Some utility function definitions
+
+class Bunch: pass
+
+def esc_quotes(strng):
+    """Return the input string with single and double quotes escaped out"""
+
+    return strng.replace('"','\\"').replace("'","\\'")
+
+def import_fail_info(mod_name,fns=None):
+    """Inform load failure for a module."""
+
+    if fns == None:
+        warn("Loading of %s failed.\n" % (mod_name,))
+    else:
+        warn("Loading of %s from %s failed.\n" % (fns,mod_name))
+
+def qw_lol(indata):
+    """qw_lol('a b') -> [['a','b']],
+    otherwise it's just a call to qw().
+
+    We need this to make sure the modules_some keys *always* end up as a
+    list of lists."""
+
+    if type(indata) in StringTypes:
+        return [qw(indata)]
+    else:
+        return qw(indata)
+
+def ipmagic(arg_s):
+    """Call a magic function by name.
+
+    Input: a string containing the name of the magic function to call and any
+    additional arguments to be passed to the magic.
+
+    ipmagic('name -opt foo bar') is equivalent to typing at the ipython
+    prompt:
+
+    In[1]: %name -opt foo bar
+
+    To call a magic without arguments, simply use ipmagic('name').
+
+    This provides a proper Python function to call IPython's magics in any
+    valid Python code you can type at the interpreter, including loops and
+    compound statements.  It is added by IPython to the Python builtin
+    namespace upon initialization."""
+
+    args = arg_s.split(' ',1)
+    magic_name = args[0]
+    if magic_name.startswith(__IPYTHON__.ESC_MAGIC):
+        magic_name = magic_name[1:]
+    try:
+        magic_args = args[1]
+    except IndexError:
+        magic_args = ''
+    fn = getattr(__IPYTHON__,'magic_'+magic_name,None)
+    if fn is None:
+        error("Magic function `%s` not found." % magic_name)
+    else:
+        magic_args = __IPYTHON__.var_expand(magic_args)
+        return fn(magic_args)
+
+def ipalias(arg_s):
+    """Call an alias by name.
+
+    Input: a string containing the name of the alias to call and any
+    additional arguments to be passed to the magic.
+
+    ipalias('name -opt foo bar') is equivalent to typing at the ipython
+    prompt:
+
+    In[1]: name -opt foo bar
+
+    To call an alias without arguments, simply use ipalias('name').
+
+    This provides a proper Python function to call IPython's aliases in any
+    valid Python code you can type at the interpreter, including loops and
+    compound statements.  It is added by IPython to the Python builtin
+    namespace upon initialization."""
+
+    args = arg_s.split(' ',1)
+    alias_name = args[0]
+    try:
+        alias_args = args[1]
+    except IndexError:
+        alias_args = ''
+    if alias_name in __IPYTHON__.alias_table:
+        __IPYTHON__.call_alias(alias_name,alias_args)
+    else:
+        error("Alias `%s` not found." % alias_name)
+
+#-----------------------------------------------------------------------------
+# Local use classes
+try:
+    from IPython import FlexCompleter
+
+    class MagicCompleter(FlexCompleter.Completer):
+        """Extension of the completer class to work on %-prefixed lines."""
+
+        def __init__(self,shell,namespace=None,omit__names=0,alias_table=None):
+            """MagicCompleter() -> completer
+
+            Return a completer object suitable for use by the readline library
+            via readline.set_completer().
+
+            Inputs:
+
+            - shell: a pointer to the ipython shell itself.  This is needed
+            because this completer knows about magic functions, and those can
+            only be accessed via the ipython instance.
+
+            - namespace: an optional dict where completions are performed.
+            
+            - The optional omit__names parameter sets the completer to omit the
+            'magic' names (__magicname__) for python objects unless the text
+            to be completed explicitly starts with one or more underscores.
+
+            - If alias_table is supplied, it should be a dictionary of aliases
+            to complete. """
+
+            FlexCompleter.Completer.__init__(self,namespace)
+            self.magic_prefix = shell.name+'.magic_'
+            self.magic_escape = shell.ESC_MAGIC
+            self.readline = FlexCompleter.readline
+            delims = self.readline.get_completer_delims()
+            delims = delims.replace(self.magic_escape,'')
+            self.readline.set_completer_delims(delims)
+            self.get_line_buffer = self.readline.get_line_buffer
+            self.omit__names = omit__names
+            self.merge_completions = shell.rc.readline_merge_completions
+            
+            if alias_table is None:
+                alias_table = {}
+            self.alias_table = alias_table
+            # Regexp to split filenames with spaces in them
+            self.space_name_re = re.compile(r'([^\\] )')
+            # Hold a local ref. to glob.glob for speed
+            self.glob = glob.glob
+            # Special handling of backslashes needed in win32 platforms
+            if sys.platform == "win32":
+                self.clean_glob = self._clean_glob_win32
+            else:
+                self.clean_glob = self._clean_glob
+            self.matchers = [self.python_matches,
+                             self.file_matches,
+                             self.alias_matches,
+                             self.python_func_kw_matches]
+
+        # Code contributed by Alex Schmolck, for ipython/emacs integration
+        def all_completions(self, text):
+            """Return all possible completions for the benefit of emacs."""
+            
+            completions = []
+            try:
+                for i in xrange(sys.maxint):
+                    res = self.complete(text, i)
+
+                    if not res: break
+
+                    completions.append(res)
+            #XXX workaround for ``notDefined.<tab>``
+            except NameError:
+                pass
+            return completions
+        # /end Alex Schmolck code.
+
+        def _clean_glob(self,text):
+            return self.glob("%s*" % text)
+            
+        def _clean_glob_win32(self,text):
+            return [f.replace("\\","/")
+                    for f in self.glob("%s*" % text)]            
+
+        def file_matches(self, text):
+            """Match filneames, expanding ~USER type strings.
+
+            Most of the seemingly convoluted logic in this completer is an
+            attempt to handle filenames with spaces in them.  And yet it's not
+            quite perfect, because Python's readline doesn't expose all of the
+            GNU readline details needed for this to be done correctly.
+
+            For a filename with a space in it, the printed completions will be
+            only the parts after what's already been typed (instead of the
+            full completions, as is normally done).  I don't think with the
+            current (as of Python 2.3) Python readline it's possible to do
+            better."""
+            
+            #print 'Completer->file_matches: <%s>' % text # dbg
+
+            # chars that require escaping with backslash - i.e. chars
+            # that readline treats incorrectly as delimiters, but we
+            # don't want to treat as delimiters in filename matching
+            # when escaped with backslash
+            
+            protectables = ' ()[]{}'
+
+            def protect_filename(s):
+                return "".join([(ch in protectables and '\\' + ch or ch)
+                                for ch in s])
+
+            lbuf = self.get_line_buffer()[:self.readline.get_endidx()]
+            open_quotes = 0  # track strings with open quotes
+            try:
+                lsplit = shlex_split(lbuf)[-1]
+            except ValueError:
+                # typically an unmatched ", or backslash without escaped char.
+                if lbuf.count('"')==1:
+                    open_quotes = 1
+                    lsplit = lbuf.split('"')[-1]
+                elif lbuf.count("'")==1:
+                    open_quotes = 1
+                    lsplit = lbuf.split("'")[-1]
+                else:
+                    return None
+            except IndexError:
+                # tab pressed on empty line
+                lsplit = ""
+
+            if lsplit != protect_filename(lsplit):
+                # if protectables are found, do matching on the whole escaped
+                # name
+                has_protectables = 1
+                text0,text = text,lsplit
+            else:
+                has_protectables = 0
+                text = os.path.expanduser(text)
+            
+            if text == "":
+                return [protect_filename(f) for f in self.glob("*")]
+
+            m0 = self.clean_glob(text.replace('\\',''))
+            if has_protectables:
+                # If we had protectables, we need to revert our changes to the
+                # beginning of filename so that we don't double-write the part
+                # of the filename we have so far
+                len_lsplit = len(lsplit)
+                matches = [text0 + protect_filename(f[len_lsplit:]) for f in m0]
+            else:
+                if open_quotes:
+                    # if we have a string with an open quote, we don't need to
+                    # protect the names at all (and we _shouldn't_, as it
+                    # would cause bugs when the filesystem call is made).
+                    matches = m0
+                else:
+                    matches = [protect_filename(f) for f in m0]
+            if len(matches) == 1 and os.path.isdir(matches[0]):
+                # Takes care of links to directories also.  Use '/'
+                # explicitly, even under Windows, so that name completions
+                # don't end up escaped.
+                matches[0] += '/'
+            return matches
+
+        def alias_matches(self, text):
+            """Match internal system aliases"""
+            #print 'Completer->alias_matches:',text # dbg
+            text = os.path.expanduser(text)
+            aliases =  self.alias_table.keys()
+            if text == "":
+                return aliases
+            else:
+                return [alias for alias in aliases if alias.startswith(text)]
+            
+        def python_matches(self,text):
+            """Match attributes or global python names"""
+            #print 'Completer->python_matches' # dbg
+            if "." in text:
+                try:
+                    matches = self.attr_matches(text)
+                    if text.endswith('.') and self.omit__names:
+                        if self.omit__names == 1:
+                            # true if txt is _not_ a __ name, false otherwise:
+                            no__name = (lambda txt:
+                                        re.match(r'.*\.__.*?__',txt) is None)
+                        else:
+                            # true if txt is _not_ a _ name, false otherwise:
+                            no__name = (lambda txt:
+                                        re.match(r'.*\._.*?',txt) is None)
+                        matches = filter(no__name, matches)
+                except NameError:
+                    # catches <undefined attributes>.<tab>
+                    matches = []
+            else:
+                matches = self.global_matches(text)
+                # this is so completion finds magics when automagic is on:
+                if matches == [] and not text.startswith(os.sep):
+                    matches = self.attr_matches(self.magic_prefix+text)
+            return matches
+
+        def _default_arguments(self, obj):
+            """Return the list of default arguments of obj if it is callable,
+            or empty list otherwise."""
+            
+            if not (inspect.isfunction(obj) or inspect.ismethod(obj)):
+                # for classes, check for __init__,__new__
+                if inspect.isclass(obj):
+                    obj = (getattr(obj,'__init__',None) or
+                           getattr(obj,'__new__',None))
+                # for all others, check if they are __call__able
+                elif hasattr(obj, '__call__'):
+                    obj = obj.__call__
+                # XXX: is there a way to handle the builtins ?
+            try:
+                args,_,_1,defaults = inspect.getargspec(obj)
+                if defaults:
+                    return args[-len(defaults):]
+            except TypeError: pass
+            return []
+
+        def python_func_kw_matches(self,text):
+            """Match named parameters (kwargs) of the last open function"""
+
+            if "." in text: # a parameter cannot be dotted
+                return []
+            try: regexp = self.__funcParamsRegex
+            except AttributeError:
+                regexp = self.__funcParamsRegex = re.compile(r'''
+                    '.*?' |    # single quoted strings or
+                    ".*?" |    # double quoted strings or
+                    \w+   |    # identifier
+                    \S         # other characters
+                    ''', re.VERBOSE | re.DOTALL)
+            # 1. find the nearest identifier that comes before an unclosed
+            # parenthesis e.g. for "foo (1+bar(x), pa", the candidate is "foo"
+            tokens = regexp.findall(self.get_line_buffer())
+            tokens.reverse()
+            iterTokens = iter(tokens); openPar = 0
+            for token in iterTokens:
+                if token == ')':
+                    openPar -= 1
+                elif token == '(':
+                    openPar += 1
+                    if openPar > 0:
+                        # found the last unclosed parenthesis
+                        break
+            else:
+                return []
+            # 2. Concatenate any dotted names (e.g. "foo.bar" for "foo.bar(x, pa" )
+            ids = []
+            isId = re.compile(r'\w+$').match
+            while True:
+                try:
+                    ids.append(iterTokens.next())
+                    if not isId(ids[-1]):
+                        ids.pop(); break
+                    if not iterTokens.next() == '.':
+                        break
+                except StopIteration:
+                    break
+            # lookup the candidate callable matches either using global_matches
+            # or attr_matches for dotted names
+            if len(ids) == 1:
+                callableMatches = self.global_matches(ids[0])
+            else:
+                callableMatches = self.attr_matches('.'.join(ids[::-1]))
+            argMatches = []
+            for callableMatch in callableMatches:
+                try: namedArgs = self._default_arguments(eval(callableMatch,
+                                                             self.namespace))
+                except: continue
+                for namedArg in namedArgs:
+                    if namedArg.startswith(text):
+                        argMatches.append("%s=" %namedArg)
+            return argMatches
+
+        def complete(self, text, state):
+            """Return the next possible completion for 'text'.
+
+            This is called successively with state == 0, 1, 2, ... until it
+            returns None.  The completion should begin with 'text'.  """
+            
+            #print '\n*** COMPLETE: <%s> (%s)' % (text,state)  # dbg
+            magic_escape = self.magic_escape
+            magic_prefix = self.magic_prefix
+            
+            try:
+                if text.startswith(magic_escape):
+                    text = text.replace(magic_escape,magic_prefix)
+                elif text.startswith('~'):
+                    text = os.path.expanduser(text)
+                if state == 0:
+                    # Extend the list of completions with the results of each
+                    # matcher, so we return results to the user from all
+                    # namespaces.
+                    if self.merge_completions:
+                        self.matches = []
+                        for matcher in self.matchers:
+                            self.matches.extend(matcher(text))
+                    else:
+                        for matcher in self.matchers:
+                            self.matches = matcher(text)
+                            if self.matches:
+                                break
+                        
+                try:
+                    return self.matches[state].replace(magic_prefix,magic_escape)
+                except IndexError:
+                    return None
+            except:
+                # If completion fails, don't annoy the user.
+                pass
+
+except ImportError:
+    pass  # no readline support
+
+except KeyError:
+    pass  # Windows doesn't set TERM, it doesn't matter
+
+
+class InputList(UserList.UserList):
+    """Class to store user input.
+
+    It's basically a list, but slices return a string instead of a list, thus
+    allowing things like (assuming 'In' is an instance):
+
+    exec In[4:7]
+
+    or
+
+    exec In[5:9] + In[14] + In[21:25]"""
+
+    def __getslice__(self,i,j):
+        return ''.join(UserList.UserList.__getslice__(self,i,j))
+
+#****************************************************************************
+# Local use exceptions
+class SpaceInInput(exceptions.Exception):
+    pass
+
+#****************************************************************************
+# Main IPython class
+
+class InteractiveShell(code.InteractiveConsole, Logger, Magic):
+    """An enhanced console for Python."""
+
+    def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
+                 user_ns = None,banner2='',
+                 custom_exceptions=((),None)):
+
+        # Put a reference to self in builtins so that any form of embedded or
+        # imported code can test for being inside IPython.
+        __builtin__.__IPYTHON__ = self
+
+        # And load into builtins ipmagic/ipalias as well
+        __builtin__.ipmagic = ipmagic
+        __builtin__.ipalias = ipalias
+
+        # Add to __builtin__ other parts of IPython's public API
+        __builtin__.ip_set_hook = self.set_hook
+
+        # Keep in the builtins a flag for when IPython is active.  We set it
+        # with setdefault so that multiple nested IPythons don't clobber one
+        # another.  Each will increase its value by one upon being activated,
+        # which also gives us a way to determine the nesting level.
+        __builtin__.__dict__.setdefault('__IPYTHON__active',0)
+
+        # Inform the user of ipython's fast exit magics.
+        _exit = ' Use %Exit or %Quit to exit without confirmation.'
+        __builtin__.exit += _exit
+        __builtin__.quit += _exit
+
+        # Create the namespace where the user will operate:
+
+        # FIXME. For some strange reason, __builtins__ is showing up at user
+        # level as a dict instead of a module. This is a manual fix, but I
+        # should really track down where the problem is coming from. Alex
+        # Schmolck reported this problem first.
+
+        # A useful post by Alex Martelli on this topic:
+        # Re: inconsistent value from __builtins__
+        # Von: Alex Martelli <aleaxit@yahoo.com>
+        # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
+        # Gruppen: comp.lang.python
+        # Referenzen: 1
+
+        # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
+        # > >>> print type(builtin_check.get_global_binding('__builtins__'))
+        # > <type 'dict'>
+        # > >>> print type(__builtins__)
+        # > <type 'module'>
+        # > Is this difference in return value intentional?
+
+        # Well, it's documented that '__builtins__' can be either a dictionary
+        # or a module, and it's been that way for a long time. Whether it's
+        # intentional (or sensible), I don't know. In any case, the idea is that
+        # if you need to access the built-in namespace directly, you should start
+        # with "import __builtin__" (note, no 's') which will definitely give you
+        # a module. Yeah, it's somewhat confusing:-(.
+        
+        if user_ns is None:
+            # Set __name__ to __main__ to better match the behavior of the
+            # normal interpreter.
+            self.user_ns = {'__name__'     :'__main__',
+                            '__builtins__' : __builtin__,
+                            }
+        else:
+            self.user_ns = user_ns
+
+        # The user namespace MUST have a pointer to the shell itself.
+        self.user_ns[name] = self
+
+        # We need to insert into sys.modules something that looks like a
+        # module but which accesses the IPython namespace, for shelve and
+        # pickle to work interactively. Normally they rely on getting
+        # everything out of __main__, but for embedding purposes each IPython
+        # instance has its own private namespace, so we can't go shoving
+        # everything into __main__.
+
+        try:
+            main_name = self.user_ns['__name__']
+        except KeyError:
+            raise KeyError,'user_ns dictionary MUST have a "__name__" key'
+        else:
+            #print "pickle hack in place"  # dbg
+            sys.modules[main_name] = FakeModule(self.user_ns)
+
+        # List of input with multi-line handling.
+        # Fill its zero entry, user counter starts at 1
+        self.input_hist = InputList(['\n'])
+
+        # list of visited directories
+        self.dir_hist = [os.getcwd()]
+
+        # dict of output history
+        self.output_hist = {}
+
+        # dict of names to be treated as system aliases.  Each entry in the
+        # alias table must be a 2-tuple of the form (N,name), where N is the
+        # number of positional arguments of the alias.
+        self.alias_table = {}
+
+        # dict of things NOT to alias (keywords and builtins)
+        self.no_alias = {}
+        for key in keyword.kwlist:
+            self.no_alias[key] = 1
+        self.no_alias.update(__builtin__.__dict__)
+        
+        # make global variables for user access to these
+        self.user_ns['_ih'] = self.input_hist
+        self.user_ns['_oh'] = self.output_hist
+        self.user_ns['_dh'] = self.dir_hist
+
+        # user aliases to input and output histories
+        self.user_ns['In']  = self.input_hist
+        self.user_ns['Out'] = self.output_hist
+
+        # Store the actual shell's name
+        self.name = name
+
+        # Object variable to store code object waiting execution.  This is
+        # used mainly by the multithreaded shells, but it can come in handy in
+        # other situations.  No need to use a Queue here, since it's a single
+        # item which gets cleared once run.
+        self.code_to_run = None
+        self.code_to_run_src = ''  # corresponding source
+        
+        # Job manager (for jobs run as background threads)
+        self.jobs = BackgroundJobManager()
+        # Put the job manager into builtins so it's always there.
+        __builtin__.jobs = self.jobs
+
+        # escapes for automatic behavior on the command line
+        self.ESC_SHELL = '!'
+        self.ESC_HELP  = '?'
+        self.ESC_MAGIC = '%'
+        self.ESC_QUOTE = ','
+        self.ESC_QUOTE2 = ';'
+        self.ESC_PAREN = '/'
+
+        # And their associated handlers
+        self.esc_handlers = {self.ESC_PAREN:self.handle_auto,
+                             self.ESC_QUOTE:self.handle_auto,
+                             self.ESC_QUOTE2:self.handle_auto,
+                             self.ESC_MAGIC:self.handle_magic,
+                             self.ESC_HELP:self.handle_help,
+                             self.ESC_SHELL:self.handle_shell_escape,
+                             }
+
+        # class initializations
+        code.InteractiveConsole.__init__(self,locals = self.user_ns)
+        Logger.__init__(self,log_ns = self.user_ns)
+        Magic.__init__(self,self)
+
+        # an ugly hack to get a pointer to the shell, so I can start writing
+        # magic code via this pointer instead of the current mixin salad.
+        Magic.set_shell(self,self)
+
+        # hooks holds pointers used for user-side customizations
+        self.hooks = Struct()
+        
+        # Set all default hooks, defined in the IPython.hooks module.
+        hooks = IPython.hooks
+        for hook_name in hooks.__all__:
+            self.set_hook(hook_name,getattr(hooks,hook_name))
+
+        # Flag to mark unconditional exit
+        self.exit_now = False
+
+        self.usage_min =  """\
+        An enhanced console for Python.
+        Some of its features are:
+        - Readline support if the readline library is present.
+        - Tab completion in the local namespace.
+        - Logging of input, see command-line options.
+        - System shell escape via ! , eg !ls.
+        - Magic commands, starting with a % (like %ls, %pwd, %cd, etc.)
+        - Keeps track of locally defined variables via %who, %whos.
+        - Show object information with a ? eg ?x or x? (use ?? for more info).
+        """
+        if usage: self.usage = usage
+        else: self.usage = self.usage_min
+
+        # Storage
+        self.rc = rc   # This will hold all configuration information
+        self.inputcache = []
+        self._boundcache = []
+        self.pager = 'less'
+        # temporary files used for various purposes.  Deleted at exit.
+        self.tempfiles = []
+
+        # for pushd/popd management
+        try:
+            self.home_dir = get_home_dir()
+        except HomeDirError,msg:
+            fatal(msg)
+
+        self.dir_stack = [os.getcwd().replace(self.home_dir,'~')]
+
+        # Functions to call the underlying shell.
+
+        # utility to expand user variables via Itpl
+        self.var_expand = lambda cmd: str(ItplNS(cmd.replace('#','\#'),
+                                                 self.user_ns))
+        # The first is similar to os.system, but it doesn't return a value,
+        # and it allows interpolation of variables in the user's namespace.
+        self.system = lambda cmd: shell(self.var_expand(cmd),
+                                        header='IPython system call: ',
+                                        verbose=self.rc.system_verbose)
+        # These are for getoutput and getoutputerror:
+        self.getoutput = lambda cmd: \
+                         getoutput(self.var_expand(cmd),
+                                   header='IPython system call: ',
+                                   verbose=self.rc.system_verbose)
+        self.getoutputerror = lambda cmd: \
+                              getoutputerror(str(ItplNS(cmd.replace('#','\#'),
+                                                        self.user_ns)),
+                                             header='IPython system call: ',
+                                             verbose=self.rc.system_verbose)
+ 
+        # RegExp for splitting line contents into pre-char//first
+        # word-method//rest.  For clarity, each group in on one line.
+
+        # WARNING: update the regexp if the above escapes are changed, as they
+        # are hardwired in.
+
+        # Don't get carried away with trying to make the autocalling catch too
+        # much:  it's better to be conservative rather than to trigger hidden
+        # evals() somewhere and end up causing side effects.
+
+        self.line_split = re.compile(r'^([\s*,;/])'
+                                     r'([\?\w\.]+\w*\s*)'
+                                     r'(\(?.*$)')
+
+        # Original re, keep around for a while in case changes break something
+        #self.line_split = re.compile(r'(^[\s*!\?%,/]?)'
+        #                             r'(\s*[\?\w\.]+\w*\s*)'
+        #                             r'(\(?.*$)')
+
+        # RegExp to identify potential function names
+        self.re_fun_name = re.compile(r'[a-zA-Z_]([a-zA-Z0-9_.]*) *$')
+        # RegExp to exclude strings with this start from autocalling
+        self.re_exclude_auto = re.compile('^[!=()<>,\*/\+-]|^is ')
+        # try to catch also methods for stuff in lists/tuples/dicts: off
+        # (experimental). For this to work, the line_split regexp would need
+        # to be modified so it wouldn't break things at '['. That line is
+        # nasty enough that I shouldn't change it until I can test it _well_.
+        #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
+
+        # keep track of where we started running (mainly for crash post-mortem)
+        self.starting_dir = os.getcwd()
+
+        # Attributes for Logger mixin class, make defaults here
+        self._dolog = 0
+        self.LOG = ''
+        self.LOGDEF = '.InteractiveShell.log'
+        self.LOGMODE = 'over'
+        self.LOGHEAD = Itpl(
+"""#log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE ***
+#log# DO NOT CHANGE THIS LINE OR THE TWO BELOW
+#log# opts = $self.rc.opts
+#log# args = $self.rc.args
+#log# It is safe to make manual edits below here.
+#log#-----------------------------------------------------------------------
+""")
+        # Various switches which can be set
+        self.CACHELENGTH = 5000  # this is cheap, it's just text
+        self.BANNER = "Python %(version)s on %(platform)s\n" % sys.__dict__
+        self.banner2 = banner2
+
+        # TraceBack handlers:
+        # Need two, one for syntax errors and one for other exceptions.
+        self.SyntaxTB = ultraTB.ListTB(color_scheme='NoColor')
+        # This one is initialized with an offset, meaning we always want to
+        # remove the topmost item in the traceback, which is our own internal
+        # code. Valid modes: ['Plain','Context','Verbose']
+        self.InteractiveTB = ultraTB.AutoFormattedTB(mode = 'Plain',
+                                                     color_scheme='NoColor',
+                                                     tb_offset = 1)
+        # and add any custom exception handlers the user may have specified
+        self.set_custom_exc(*custom_exceptions)
+
+        # Object inspector
+        ins_colors = OInspect.InspectColors
+        code_colors = PyColorize.ANSICodeColors
+        self.inspector = OInspect.Inspector(ins_colors,code_colors,'NoColor')
+        self.autoindent = 0
+
+        # Make some aliases automatically
+        # Prepare list of shell aliases to auto-define
+        if os.name == 'posix':            
+            auto_alias = ('mkdir mkdir', 'rmdir rmdir',
+                          'mv mv -i','rm rm -i','cp cp -i',
+                          'cat cat','less less','clear clear',
+                          # a better ls
+                          'ls ls -F',
+                          # long ls
+                          'll ls -lF',
+                          # color ls
+                          'lc ls -F -o --color',
+                          # ls normal files only
+                          'lf ls -F -o --color %l | grep ^-',
+                          # ls symbolic links 
+                          'lk ls -F -o --color %l | grep ^l',
+                          # directories or links to directories,
+                          'ldir ls -F -o --color %l | grep /$',
+                          # things which are executable
+                          'lx ls -F -o --color %l | grep ^-..x',
+                          )
+        elif os.name in ['nt','dos']:
+            auto_alias = ('dir dir /on', 'ls dir /on',
+                          'ddir dir /ad /on', 'ldir dir /ad /on',
+                          'mkdir mkdir','rmdir rmdir','echo echo',
+                          'ren ren','cls cls','copy copy')
+        else:
+            auto_alias = ()
+        self.auto_alias = map(lambda s:s.split(None,1),auto_alias)
+        # Call the actual (public) initializer
+        self.init_auto_alias()
+    # end __init__
+
+    def set_hook(self,name,hook):
+        """set_hook(name,hook) -> sets an internal IPython hook.
+
+        IPython exposes some of its internal API as user-modifiable hooks.  By
+        resetting one of these hooks, you can modify IPython's behavior to
+        call at runtime your own routines."""
+
+        # At some point in the future, this should validate the hook before it
+        # accepts it.  Probably at least check that the hook takes the number
+        # of args it's supposed to.
+        setattr(self.hooks,name,new.instancemethod(hook,self,self.__class__))
+
+    def set_custom_exc(self,exc_tuple,handler):
+        """set_custom_exc(exc_tuple,handler)
+
+        Set a custom exception handler, which will be called if any of the
+        exceptions in exc_tuple occur in the mainloop (specifically, in the
+        runcode() method.
+
+        Inputs:
+
+          - exc_tuple: a *tuple* of valid exceptions to call the defined
+          handler for.  It is very important that you use a tuple, and NOT A
+          LIST here, because of the way Python's except statement works.  If
+          you only want to trap a single exception, use a singleton tuple:
+
+            exc_tuple == (MyCustomException,)
+
+          - handler: this must be defined as a function with the following
+          basic interface: def my_handler(self,etype,value,tb).
+
+          This will be made into an instance method (via new.instancemethod)
+          of IPython itself, and it will be called if any of the exceptions
+          listed in the exc_tuple are caught.  If the handler is None, an
+          internal basic one is used, which just prints basic info.
+
+        WARNING: by putting in your own exception handler into IPython's main
+        execution loop, you run a very good chance of nasty crashes.  This
+        facility should only be used if you really know what you are doing."""
+
+        assert type(exc_tuple)==type(()) , \
+               "The custom exceptions must be given AS A TUPLE."
+
+        def dummy_handler(self,etype,value,tb):
+            print '*** Simple custom exception handler ***'
+            print 'Exception type :',etype
+            print 'Exception value:',value
+            print 'Traceback      :',tb
+            print 'Source code    :',self.code_to_run_src
+
+        if handler is None: handler = dummy_handler
+
+        self.CustomTB = new.instancemethod(handler,self,self.__class__)
+        self.custom_exceptions = exc_tuple
+
+    def set_custom_completer(self,completer,pos=0):
+        """set_custom_completer(completer,pos=0)
+
+        Adds a new custom completer function.
+
+        The position argument (defaults to 0) is the index in the completers
+        list where you want the completer to be inserted."""
+
+        newcomp = new.instancemethod(completer,self.Completer,
+                                     self.Completer.__class__)
+        self.Completer.matchers.insert(pos,newcomp)
+
+    def post_config_initialization(self):
+        """Post configuration init method
+
+        This is called after the configuration files have been processed to
+        'finalize' the initialization."""
+        
+        # dynamic data that survives through sessions
+        # XXX make the filename a config option?
+        persist_base = 'persist'
+        if self.rc.profile:
+            persist_base += '_%s' % self.rc.profile
+        self.persist_fname =  os.path.join(self.rc.ipythondir,persist_base)
+
+        try:
+            self.persist = pickle.load(file(self.persist_fname))
+        except:
+            self.persist = {}
+            
+    def init_auto_alias(self):
+        """Define some aliases automatically.
+
+        These are ALL parameter-less aliases"""
+        for alias,cmd in self.auto_alias:
+            self.alias_table[alias] = (0,cmd)
+
+    def alias_table_validate(self,verbose=0):
+        """Update information about the alias table.
+
+        In particular, make sure no Python keywords/builtins are in it."""
+
+        no_alias = self.no_alias
+        for k in self.alias_table.keys():
+            if k in no_alias:
+                del self.alias_table[k]
+                if verbose:
+                    print ("Deleting alias <%s>, it's a Python "
+                           "keyword or builtin." % k)
+    
+    def set_autoindent(self,value=None):
+        """Set the autoindent flag, checking for readline support.
+
+        If called with no arguments, it acts as a toggle."""
+
+        if not self.has_readline:
+            if os.name == 'posix':
+                warn("The auto-indent feature requires the readline library")
+            self.autoindent = 0
+            return
+        if value is None:
+            self.autoindent = not self.autoindent
+        else:
+            self.autoindent = value
+
+    def rc_set_toggle(self,rc_field,value=None):
+        """Set or toggle a field in IPython's rc config. structure.
+
+        If called with no arguments, it acts as a toggle.
+
+        If called with a non-existent field, the resulting AttributeError
+        exception will propagate out."""
+
+        rc_val = getattr(self.rc,rc_field)
+        if value is None:
+            value = not rc_val
+        setattr(self.rc,rc_field,value)
+
+    def user_setup(self,ipythondir,rc_suffix,mode='install'):
+        """Install the user configuration directory.
+
+        Can be called when running for the first time or to upgrade the user's
+        .ipython/ directory with the mode parameter. Valid modes are 'install'
+        and 'upgrade'."""
+
+        def wait():
+            try:
+                raw_input("Please press <RETURN> to start IPython.")
+            except EOFError:
+                print >> Term.cout
+            print '*'*70
+
+        cwd = os.getcwd()  # remember where we started
+        glb = glob.glob
+        print '*'*70
+        if mode == 'install':
+            print \
+"""Welcome to IPython. I will try to create a personal configuration directory
+where you can customize many aspects of IPython's functionality in:\n"""
+        else:
+            print 'I am going to upgrade your configuration in:'
+
+        print ipythondir
+
+        rcdirend = os.path.join('IPython','UserConfig')
+        cfg = lambda d: os.path.join(d,rcdirend)
+        try:
+            rcdir = filter(os.path.isdir,map(cfg,sys.path))[0]
+        except IOError:
+            warning = """
+Installation error. IPython's directory was not found.
+
+Check the following:
+
+The ipython/IPython directory should be in a directory belonging to your
+PYTHONPATH environment variable (that is, it should be in a directory
+belonging to sys.path). You can copy it explicitly there or just link to it.
+
+IPython will proceed with builtin defaults.
+"""
+            warn(warning)
+            wait()
+            return
+
+        if mode == 'install':
+            try:
+                shutil.copytree(rcdir,ipythondir)
+                os.chdir(ipythondir)
+                rc_files = glb("ipythonrc*")
+                for rc_file in rc_files:
+                    os.rename(rc_file,rc_file+rc_suffix)
+            except:
+                warning = """
+
+There was a problem with the installation:
+%s
+Try to correct it or contact the developers if you think it's a bug.
+IPython will proceed with builtin defaults.""" % sys.exc_info()[1]
+                warn(warning)
+                wait()
+                return
+
+        elif mode == 'upgrade':
+            try:
+                os.chdir(ipythondir)
+            except:
+                print """
+Can not upgrade: changing to directory %s failed. Details:
+%s
+""" % (ipythondir,sys.exc_info()[1])
+                wait()
+                return
+            else:
+                sources = glb(os.path.join(rcdir,'[A-Za-z]*'))
+                for new_full_path in sources:
+                    new_filename = os.path.basename(new_full_path)
+                    if new_filename.startswith('ipythonrc'):
+                        new_filename = new_filename + rc_suffix
+                    # The config directory should only contain files, skip any
+                    # directories which may be there (like CVS)
+                    if os.path.isdir(new_full_path):
+                        continue
+                    if os.path.exists(new_filename):
+                        old_file = new_filename+'.old'
+                        if os.path.exists(old_file):
+                            os.remove(old_file)
+                        os.rename(new_filename,old_file)
+                    shutil.copy(new_full_path,new_filename)
+        else:
+            raise ValueError,'unrecognized mode for install:',`mode`
+
+        # Fix line-endings to those native to each platform in the config
+        # directory.
+        try:
+            os.chdir(ipythondir)
+        except:
+            print """
+Problem: changing to directory %s failed.
+Details:
+%s
+
+Some configuration files may have incorrect line endings.  This should not
+cause any problems during execution.  """ % (ipythondir,sys.exc_info()[1])
+            wait()
+        else:
+            for fname in glb('ipythonrc*'):
+                try:
+                    native_line_ends(fname,backup=0)
+                except IOError:
+                    pass
+
+        if mode == 'install':
+            print """
+Successful installation!
+
+Please read the sections 'Initial Configuration' and 'Quick Tips' in the
+IPython manual (there are both HTML and PDF versions supplied with the
+distribution) to make sure that your system environment is properly configured
+to take advantage of IPython's features."""
+        else:
+            print """
+Successful upgrade!
+
+All files in your directory:
+%(ipythondir)s
+which would have been overwritten by the upgrade were backed up with a .old
+extension.  If you had made particular customizations in those files you may
+want to merge them back into the new files.""" % locals()
+        wait()
+        os.chdir(cwd)
+        # end user_setup()
+
+    def atexit_operations(self):
+        """This will be executed at the time of exit.
+
+        Saving of persistent data should be performed here. """
+
+        # input history
+        self.savehist()
+
+        # Cleanup all tempfiles left around
+        for tfile in self.tempfiles:
+            try:
+                os.unlink(tfile)
+            except OSError:
+                pass
+
+        # save the "persistent data" catch-all dictionary
+        try:
+            pickle.dump(self.persist, open(self.persist_fname,"w"))
+        except:
+            print "*** ERROR *** persistent data saving failed."
+        
+    def savehist(self):
+        """Save input history to a file (via readline library)."""
+        try:
+            self.readline.write_history_file(self.histfile)
+        except:
+            print 'Unable to save IPython command history to file: ' + \
+                  `self.histfile`
+
+    def pre_readline(self):
+        """readline hook to be used at the start of each line.
+
+        Currently it handles auto-indent only."""
+        
+        self.readline.insert_text(' '* self.readline_indent)
+
+    def init_readline(self):
+        """Command history completion/saving/reloading."""
+        try:
+            import readline
+            self.Completer = MagicCompleter(self,
+                                            self.user_ns,
+                                            self.rc.readline_omit__names,
+                                            self.alias_table)
+        except ImportError,NameError:
+            # If FlexCompleter failed to import, MagicCompleter won't be 
+            # defined.  This can happen because of a problem with readline
+            self.has_readline = 0
+            # no point in bugging windows users with this every time:
+            if os.name == 'posix':
+                warn('Readline services not available on this platform.')
+        else:
+            import atexit
+
+            # Platform-specific configuration
+            if os.name == 'nt':
+                # readline under Windows modifies the default exit behavior
+                # from being Ctrl-Z/Return to the Unix Ctrl-D one.
+                __builtin__.exit = __builtin__.quit = \
+                     ('Use Ctrl-D (i.e. EOF) to exit. '
+                      'Use %Exit or %Quit to exit without confirmation.')
+                self.readline_startup_hook = readline.set_pre_input_hook
+            else:
+                self.readline_startup_hook = readline.set_startup_hook
+
+            # Load user's initrc file (readline config)
+            inputrc_name = os.environ.get('INPUTRC')
+            if inputrc_name is None:
+                home_dir = get_home_dir()
+                if home_dir is not None:
+                    inputrc_name = os.path.join(home_dir,'.inputrc')
+            if os.path.isfile(inputrc_name):
+                try:
+                    readline.read_init_file(inputrc_name)
+                except:
+                    warn('Problems reading readline initialization file <%s>'
+                         % inputrc_name)
+            
+            self.has_readline = 1
+            self.readline = readline
+            self.readline_indent = 0  # for auto-indenting via readline
+            # save this in sys so embedded copies can restore it properly
+            sys.ipcompleter = self.Completer.complete
+            readline.set_completer(self.Completer.complete)
+
+            # Configure readline according to user's prefs
+            for rlcommand in self.rc.readline_parse_and_bind:
+                readline.parse_and_bind(rlcommand)
+
+            # remove some chars from the delimiters list
+            delims = readline.get_completer_delims()
+            delims = delims.translate(string._idmap,
+                                      self.rc.readline_remove_delims)
+            readline.set_completer_delims(delims)
+            # otherwise we end up with a monster history after a while:
+            readline.set_history_length(1000)
+            try:
+                #print '*** Reading readline history'  # dbg
+                readline.read_history_file(self.histfile)
+            except IOError:
+                pass  # It doesn't exist yet.
+
+            atexit.register(self.atexit_operations)
+            del atexit
+
+        # Configure auto-indent for all platforms
+        self.set_autoindent(self.rc.autoindent)
+
+    def showsyntaxerror(self, filename=None):
+        """Display the syntax error that just occurred.
+
+        This doesn't display a stack trace because there isn't one.
+
+        If a filename is given, it is stuffed in the exception instead
+        of what was there before (because Python's parser always uses
+        "<string>" when reading from a string).
+        """
+        type, value, sys.last_traceback = sys.exc_info()
+        sys.last_type = type
+        sys.last_value = value
+        if filename and type is SyntaxError:
+            # Work hard to stuff the correct filename in the exception
+            try:
+                msg, (dummy_filename, lineno, offset, line) = value
+            except:
+                # Not the format we expect; leave it alone
+                pass
+            else:
+                # Stuff in the right filename
+                try:
+                    # Assume SyntaxError is a class exception
+                    value = SyntaxError(msg, (filename, lineno, offset, line))
+                except:
+                    # If that failed, assume SyntaxError is a string
+                    value = msg, (filename, lineno, offset, line)
+        self.SyntaxTB(type,value,[])
+
+    def debugger(self):
+        """Call the pdb debugger."""
+
+        if not self.rc.pdb:
+            return
+        pdb.pm()
+
+    def showtraceback(self,exc_tuple = None):
+        """Display the exception that just occurred."""
+
+        # Though this won't be called by syntax errors in the input line,
+        # there may be SyntaxError cases whith imported code.
+        if exc_tuple is None:
+            type, value, tb = sys.exc_info()
+        else:
+            type, value, tb = exc_tuple
+        if type is SyntaxError:
+            self.showsyntaxerror()
+        else:
+            sys.last_type = type
+            sys.last_value = value
+            sys.last_traceback = tb
+            self.InteractiveTB()
+            if self.InteractiveTB.call_pdb and self.has_readline:
+                # pdb mucks up readline, fix it back
+                self.readline.set_completer(self.Completer.complete)
+
+    def update_cache(self, line):
+        """puts line into cache"""
+        self.inputcache.insert(0, line) # This copies the cache every time ... :-(
+        if len(self.inputcache) >= self.CACHELENGTH:
+            self.inputcache.pop()    # This not :-)
+
+    def name_space_init(self):
+        """Create local namespace."""
+        # We want this to be a method to facilitate embedded initialization.
+        code.InteractiveConsole.__init__(self,self.user_ns)
+
+    def mainloop(self,banner=None):
+        """Creates the local namespace and starts the mainloop.
+
+        If an optional banner argument is given, it will override the
+        internally created default banner."""
+        
+        self.name_space_init()
+        if self.rc.c:  # Emulate Python's -c option
+            self.exec_init_cmd()
+        if banner is None:
+            if self.rc.banner:
+                banner = self.BANNER+self.banner2
+            else:
+                banner = ''
+        self.interact(banner)
+
+    def exec_init_cmd(self):
+        """Execute a command given at the command line.
+
+        This emulates Python's -c option."""
+
+        sys.argv = ['-c']
+        self.push(self.rc.c)
+
+    def embed_mainloop(self,header='',local_ns=None,global_ns=None,stack_depth=0):
+        """Embeds IPython into a running python program.
+
+        Input:
+
+          - header: An optional header message can be specified.
+
+          - local_ns, global_ns: working namespaces. If given as None, the
+          IPython-initialized one is updated with __main__.__dict__, so that
+          program variables become visible but user-specific configuration
+          remains possible.
+
+          - stack_depth: specifies how many levels in the stack to go to
+          looking for namespaces (when local_ns and global_ns are None).  This
+          allows an intermediate caller to make sure that this function gets
+          the namespace from the intended level in the stack.  By default (0)
+          it will get its locals and globals from the immediate caller.
+
+        Warning: it's possible to use this in a program which is being run by
+        IPython itself (via %run), but some funny things will happen (a few
+        globals get overwritten). In the future this will be cleaned up, as
+        there is no fundamental reason why it can't work perfectly."""
+
+        # Patch for global embedding to make sure that things don't overwrite
+        # user globals accidentally. Thanks to Richard <rxe@renre-europe.com>
+        # FIXME. Test this a bit more carefully (the if.. is new)
+        if local_ns is None and global_ns is None:
+            self.user_ns.update(__main__.__dict__)
+
+        # Get locals and globals from caller
+        if local_ns is None or global_ns is None:
+            call_frame = sys._getframe(stack_depth).f_back
+
+            if local_ns is None:
+                local_ns = call_frame.f_locals
+            if global_ns is None:
+                global_ns = call_frame.f_globals
+
+        # Update namespaces and fire up interpreter
+        self.user_ns.update(local_ns)
+        self.interact(header)
+
+        # Remove locals from namespace
+        for k in local_ns.keys():
+            del self.user_ns[k]
+
+    def interact(self, banner=None):
+        """Closely emulate the interactive Python console.
+
+        The optional banner argument specify the banner to print
+        before the first interaction; by default it prints a banner
+        similar to the one printed by the real Python interpreter,
+        followed by the current class name in parentheses (so as not
+        to confuse this with the real interpreter -- since it's so
+        close!).
+
+        """
+        cprt = 'Type "copyright", "credits" or "license" for more information.'
+        if banner is None:
+            self.write("Python %s on %s\n%s\n(%s)\n" %
+                       (sys.version, sys.platform, cprt,
+                        self.__class__.__name__))
+        else:
+            self.write(banner)
+
+        more = 0
+
+        # Mark activity in the builtins
+        __builtin__.__dict__['__IPYTHON__active'] += 1
+        while 1:
+            # This is set by a call to %Exit or %Quit
+            if self.exit_now:
+                break
+            try:
+                if more:
+                    prompt = self.outputcache.prompt2
+                    if self.autoindent:
+                        self.readline_startup_hook(self.pre_readline)
+                else:
+                    prompt = self.outputcache.prompt1
+                try:
+                    line = self.raw_input(prompt)
+                    if self.autoindent:
+                        self.readline_startup_hook(None)
+                except EOFError:
+                    if self.autoindent:
+                        self.readline_startup_hook(None)
+                    self.write("\n")
+                    if self.rc.confirm_exit:
+                        if ask_yes_no('Do you really want to exit ([y]/n)?','y'):
+                            break
+                    else:
+                        break
+                else:
+                    more = self.push(line)
+                    # Auto-indent management
+                    if self.autoindent:
+                        if line:
+                            ini_spaces = re.match('^(\s+)',line)
+                            if ini_spaces:
+                                nspaces = ini_spaces.end()
+                            else:
+                                nspaces = 0
+                            self.readline_indent = nspaces
+
+                            if line[-1] == ':':
+                                self.readline_indent += 4
+                            elif re.match(r'^\s+raise|^\s+return',line):
+                                self.readline_indent -= 4
+                        else:
+                            self.readline_indent = 0
+
+            except KeyboardInterrupt:
+                self.write("\nKeyboardInterrupt\n")
+                self.resetbuffer()
+                more = 0
+                # keep cache in sync with the prompt counter:
+                self.outputcache.prompt_count -= 1
+
+                if self.autoindent:
+                    self.readline_indent = 0
+
+            except bdb.BdbQuit:
+                warn("The Python debugger has exited with a BdbQuit exception.\n"
+                     "Because of how pdb handles the stack, it is impossible\n"
+                     "for IPython to properly format this particular exception.\n"
+                     "IPython will resume normal operation.")
+            except:
+                # We should never get here except in fairly bizarre situations
+                # (or b/c of an IPython bug). One reasonable exception is if
+                # the user sets stdin/out/err to a broken object (or closes
+                # any of them!)
+
+                fixed_in_out_err = 0
+
+                # Call the Term I/O class and have it reopen any stream which
+                # the user might have closed.
+                Term.reopen_all()
+
+                # Do the same manually for sys.stderr/out/in
+                
+                # err first, so we can print at least warnings
+                if sys.__stderr__.closed:
+                    sys.__stderr__ = os.fdopen(os.dup(2),'w',0)
+                    fixed_err_err = 1
+                    print >> sys.__stderr__,"""
+WARNING:
+sys.__stderr__ was closed!
+I've tried to reopen it, but bear in mind that things may not work normally
+from now.  In particular, readline support may have broken.
+"""
+                # Next, check stdin/out    
+                if sys.__stdin__.closed:
+                    sys.__stdin__ = os.fdopen(os.dup(0),'r',0)
+                    fixed_in_out_err = 1
+                    print >> sys.__stderr__,"""
+WARNING:
+sys.__stdin__ was closed!
+I've tried to reopen it, but bear in mind that things may not work normally
+from now.  In particular, readline support may have broken.
+"""
+                if sys.__stdout__.closed:
+                    sys.__stdout__ = os.fdopen(os.dup(1),'w',0)
+                    fixed_in_out_err = 1
+                    print >> sys.__stderr__,"""
+WARNING:
+sys.__stdout__ was closed!
+I've tried to reopen it, but bear in mind that things may not work normally
+from now.  In particular, readline support may have broken.
+"""
+
+                # Now, check mismatch of objects
+                if sys.stdin is not sys.__stdin__:
+                    sys.stdin = sys.__stdin__
+                    fixed_in_out_err = 1
+                    print >> sys.__stderr__,"""
+WARNING:
+sys.stdin has been reset to sys.__stdin__.
+There seemed to be a problem with your sys.stdin.
+"""
+                if sys.stdout is not sys.__stdout__:
+                    sys.stdout = sys.__stdout__
+                    fixed_in_out_err = 1
+                    print >> sys.__stderr__,"""
+WARNING:
+sys.stdout has been reset to sys.__stdout__.
+There seemed to be a problem with your sys.stdout.
+"""
+
+                if sys.stderr is not sys.__stderr__:
+                    sys.stderr = sys.__stderr__
+                    fixed_in_out_err = 1
+                    print >> sys.__stderr__,"""
+WARNING:
+sys.stderr has been reset to sys.__stderr__.
+There seemed to be a problem with your sys.stderr.
+"""
+                # If the problem wasn't a broken out/err, it's an IPython bug
+                # I wish we could ask the user whether to crash or not, but
+                # calling any function at this point messes up the stack.
+                if not fixed_in_out_err:
+                    raise
+                
+        # We are off again...
+        __builtin__.__dict__['__IPYTHON__active'] -= 1
+
+    def excepthook(self, type, value, tb):
+      """One more defense for GUI apps that call sys.excepthook.
+
+      GUI frameworks like wxPython trap exceptions and call
+      sys.excepthook themselves.  I guess this is a feature that
+      enables them to keep running after exceptions that would
+      otherwise kill their mainloop. This is a bother for IPython
+      which excepts to catch all of the program exceptions with a try:
+      except: statement.
+
+      Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
+      any app directly invokes sys.excepthook, it will look to the user like
+      IPython crashed.  In order to work around this, we can disable the
+      CrashHandler and replace it with this excepthook instead, which prints a
+      regular traceback using our InteractiveTB.  In this fashion, apps which
+      call sys.excepthook will generate a regular-looking exception from
+      IPython, and the CrashHandler will only be triggered by real IPython
+      crashes.
+
+      This hook should be used sparingly, only in places which are not likely
+      to be true IPython errors.
+      """
+      
+      self.InteractiveTB(type, value, tb, tb_offset=0)
+      if self.InteractiveTB.call_pdb and self.has_readline:
+          self.readline.set_completer(self.Completer.complete)
+
+    def call_alias(self,alias,rest=''):
+        """Call an alias given its name and the rest of the line.
+
+        This function MUST be given a proper alias, because it doesn't make
+        any checks when looking up into the alias table.  The caller is
+        responsible for invoking it only with a valid alias."""
+
+        #print 'ALIAS: <%s>+<%s>' % (alias,rest) # dbg
+        nargs,cmd = self.alias_table[alias]
+        # Expand the %l special to be the user's input line
+        if cmd.find('%l') >= 0:
+            cmd = cmd.replace('%l',rest)
+            rest = ''
+        if nargs==0:
+            # Simple, argument-less aliases
+            cmd = '%s %s' % (cmd,rest)
+        else:
+            # Handle aliases with positional arguments
+            args = rest.split(None,nargs)
+            if len(args)< nargs:
+                error('Alias <%s> requires %s arguments, %s given.' %
+                      (alias,nargs,len(args)))
+                return
+            cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
+        # Now call the macro, evaluating in the user's namespace
+        try:
+            self.system(cmd)
+        except:
+            self.showtraceback()
+
+    def runlines(self,lines):
+        """Run a string of one or more lines of source.
+
+        This method is capable of running a string containing multiple source
+        lines, as if they had been entered at the IPython prompt.  Since it
+        exposes IPython's processing machinery, the given strings can contain
+        magic calls (%magic), special shell access (!cmd), etc."""
+
+        # We must start with a clean buffer, in case this is run from an
+        # interactive IPython session (via a magic, for example).
+        self.resetbuffer()
+        lines = lines.split('\n')
+        more = 0
+        for line in lines:
+            # skip blank lines so we don't mess up the prompt counter, but do
+            # NOT skip even a blank line if we are in a code block (more is
+            # true)
+            if line or more:
+                more = self.push((self.prefilter(line,more)))
+                # IPython's runsource returns None if there was an error
+                # compiling the code.  This allows us to stop processing right
+                # away, so the user gets the error message at the right place.
+                if more is None:
+                    break
+        # final newline in case the input didn't have it, so that the code
+        # actually does get executed
+        if more:
+            self.push('\n')
+
+    def runsource(self, source, filename="<input>", symbol="single"):
+        """Compile and run some source in the interpreter.
+
+        Arguments are as for compile_command().
+
+        One several things can happen:
+
+        1) The input is incorrect; compile_command() raised an
+        exception (SyntaxError or OverflowError).  A syntax traceback
+        will be printed by calling the showsyntaxerror() method.
+
+        2) The input is incomplete, and more input is required;
+        compile_command() returned None.  Nothing happens.
+
+        3) The input is complete; compile_command() returned a code
+        object.  The code is executed by calling self.runcode() (which
+        also handles run-time exceptions, except for SystemExit).
+
+        The return value is:
+
+          - True in case 2
+
+          - False in the other cases, unless an exception is raised, where
+          None is returned instead.  This can be used by external callers to
+          know whether to continue feeding input or not.
+
+        The return value can be used to decide whether to use sys.ps1 or
+        sys.ps2 to prompt the next line."""
+        try:
+            code = self.compile(source, filename, symbol)
+        except (OverflowError, SyntaxError, ValueError):
+            # Case 1
+            self.showsyntaxerror(filename)
+            return None
+
+        if code is None:
+            # Case 2
+            return True
+
+        # Case 3
+        # We store the code source and object so that threaded shells and
+        # custom exception handlers can access all this info if needed.
+        self.code_to_run_src = source
+        self.code_to_run = code
+        # now actually execute the code object
+        if self.runcode(code) == 0:
+            return False
+        else:
+            return None
+
+    def runcode(self,code_obj):
+        """Execute a code object.
+
+        When an exception occurs, self.showtraceback() is called to display a
+        traceback.
+
+        Return value: a flag indicating whether the code to be run completed
+        successfully:
+
+          - 0: successful execution.
+          - 1: an error occurred.
+        """
+
+        # Set our own excepthook in case the user code tries to call it
+        # directly, so that the IPython crash handler doesn't get triggered
+        old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
+        outflag = 1  # happens in more places, so it's easier as default
+        try:
+            try:
+                exec code_obj in self.locals
+            finally:
+                # Reset our crash handler in place
+                sys.excepthook = old_excepthook
+        except SystemExit:
+            self.resetbuffer()
+            self.showtraceback()
+            warn( __builtin__.exit,level=1)
+        except self.custom_exceptions:
+            etype,value,tb = sys.exc_info()
+            self.CustomTB(etype,value,tb)
+        except:
+            self.showtraceback()
+        else:
+            outflag = 0
+            if code.softspace(sys.stdout, 0):
+                print
+        # Flush out code object which has been run (and source)
+        self.code_to_run = None
+        self.code_to_run_src = ''
+        return outflag
+
+    def raw_input(self, prompt=""):
+        """Write a prompt and read a line.
+
+        The returned line does not include the trailing newline.
+        When the user enters the EOF key sequence, EOFError is raised.
+
+        The base implementation uses the built-in function
+        raw_input(); a subclass may replace this with a different
+        implementation.
+        """
+        return self.prefilter(raw_input_original(prompt),
+                              prompt==self.outputcache.prompt2)
+        
+    def split_user_input(self,line):
+        """Split user input into pre-char, function part and rest."""
+
+        lsplit = self.line_split.match(line)
+        if lsplit is None:  # no regexp match returns None
+            try:
+                iFun,theRest = line.split(None,1)
+            except ValueError:
+                iFun,theRest = line,''
+            pre = re.match('^(\s*)(.*)',line).groups()[0]
+        else:
+            pre,iFun,theRest = lsplit.groups()
+
+        #print 'line:<%s>' % line # dbg
+        #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun.strip(),theRest) # dbg
+        return pre,iFun.strip(),theRest
+
+    def _prefilter(self, line, continue_prompt):
+        """Calls different preprocessors, depending on the form of line."""
+
+        # All handlers *must* return a value, even if it's blank ('').
+
+        # Lines are NOT logged here. Handlers should process the line as
+        # needed, update the cache AND log it (so that the input cache array
+        # stays synced).
+
+        # This function is _very_ delicate, and since it's also the one which
+        # determines IPython's response to user input, it must be as efficient
+        # as possible.  For this reason it has _many_ returns in it, trying
+        # always to exit as quickly as it can figure out what it needs to do.
+
+        # This function is the main responsible for maintaining IPython's
+        # behavior respectful of Python's semantics.  So be _very_ careful if
+        # making changes to anything here.
+
+        #.....................................................................
+        # Code begins
+
+        #if line.startswith('%crash'): raise RuntimeError,'Crash now!'  # dbg
+
+        # save the line away in case we crash, so the post-mortem handler can
+        # record it
+        self._last_input_line = line
+
+        #print '***line: <%s>' % line # dbg
+
+        # the input history needs to track even empty lines
+        if not line.strip():
+            if not continue_prompt:
+                self.outputcache.prompt_count -= 1
+            return self.handle_normal('',continue_prompt)
+
+        # print '***cont',continue_prompt  # dbg
+        # special handlers are only allowed for single line statements
+        if continue_prompt and not self.rc.multi_line_specials:
+            return self.handle_normal(line,continue_prompt)
+
+        # For the rest, we need the structure of the input
+        pre,iFun,theRest = self.split_user_input(line)
+        #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest)  # dbg
+
+        # First check for explicit escapes in the last/first character
+        handler = None
+        if line[-1] == self.ESC_HELP:
+            handler = self.esc_handlers.get(line[-1])  # the ? can be at the end
+        if handler is None:
+            # look at the first character of iFun, NOT of line, so we skip
+            # leading whitespace in multiline input
+            handler = self.esc_handlers.get(iFun[0:1])
+        if handler is not None:
+            return handler(line,continue_prompt,pre,iFun,theRest)
+        # Emacs ipython-mode tags certain input lines
+        if line.endswith('# PYTHON-MODE'):
+            return self.handle_emacs(line,continue_prompt)
+
+        # Next, check if we can automatically execute this thing
+
+        # Allow ! in multi-line statements if multi_line_specials is on:
+        if continue_prompt and self.rc.multi_line_specials and \
+               iFun.startswith(self.ESC_SHELL):
+            return self.handle_shell_escape(line,continue_prompt,
+                                            pre=pre,iFun=iFun,
+                                            theRest=theRest)
+
+        # Let's try to find if the input line is a magic fn
+        oinfo = None
+        if hasattr(self,'magic_'+iFun):
+            oinfo = self._ofind(iFun) # FIXME - _ofind is part of Magic
+            if oinfo['ismagic']:
+                # Be careful not to call magics when a variable assignment is
+                # being made (ls='hi', for example)
+                if self.rc.automagic and \
+                       (len(theRest)==0 or theRest[0] not in '!=()<>,') and \
+                       (self.rc.multi_line_specials or not continue_prompt):
+                    return self.handle_magic(line,continue_prompt,
+                                             pre,iFun,theRest)
+                else:
+                    return self.handle_normal(line,continue_prompt)
+
+        # If the rest of the line begins with an (in)equality, assginment or
+        # function call, we should not call _ofind but simply execute it.
+        # This avoids spurious geattr() accesses on objects upon assignment.
+        #
+        # It also allows users to assign to either alias or magic names true
+        # python variables (the magic/alias systems always take second seat to
+        # true python code).
+        if theRest and theRest[0] in '!=()':
+            return self.handle_normal(line,continue_prompt)
+
+        if oinfo is None:
+            oinfo = self._ofind(iFun) # FIXME - _ofind is part of Magic
+        
+        if not oinfo['found']:
+            return self.handle_normal(line,continue_prompt)
+        else:
+            #print 'iFun <%s> rest <%s>' % (iFun,theRest) # dbg
+            if oinfo['isalias']:
+                return self.handle_alias(line,continue_prompt,
+                                             pre,iFun,theRest)
+
+            if self.rc.autocall and \
+                   not self.re_exclude_auto.match(theRest) and \
+                   self.re_fun_name.match(iFun) and \
+                   callable(oinfo['obj']) :
+                #print 'going auto'  # dbg
+                return self.handle_auto(line,continue_prompt,pre,iFun,theRest)
+            else:
+                #print 'was callable?', callable(oinfo['obj'])  # dbg
+                return self.handle_normal(line,continue_prompt)
+
+        # If we get here, we have a normal Python line. Log and return.
+        return self.handle_normal(line,continue_prompt)
+
+    def _prefilter_dumb(self, line, continue_prompt):
+        """simple prefilter function, for debugging"""
+        return self.handle_normal(line,continue_prompt)
+
+    # Set the default prefilter() function (this can be user-overridden)
+    prefilter = _prefilter
+
+    def handle_normal(self,line,continue_prompt=None,
+                      pre=None,iFun=None,theRest=None):
+        """Handle normal input lines. Use as a template for handlers."""
+
+        self.log(line,continue_prompt)
+        self.update_cache(line)
+        return line
+
+    def handle_alias(self,line,continue_prompt=None,
+                     pre=None,iFun=None,theRest=None):
+        """Handle alias input lines. """
+
+        theRest = esc_quotes(theRest)
+        line_out = "%s%s.call_alias('%s','%s')" % (pre,self.name,iFun,theRest)
+        self.log(line_out,continue_prompt)
+        self.update_cache(line_out)
+        return line_out
+
+    def handle_shell_escape(self, line, continue_prompt=None,
+                            pre=None,iFun=None,theRest=None):
+        """Execute the line in a shell, empty return value"""
+
+        # Example of a special handler. Others follow a similar pattern.
+        if continue_prompt:  # multi-line statements
+            if iFun.startswith('!!'):
+                print 'SyntaxError: !! is not allowed in multiline statements'
+                return pre
+            else:
+                cmd = ("%s %s" % (iFun[1:],theRest)).replace('"','\\"')
+                line_out = '%s%s.system("%s")' % (pre,self.name,cmd)
+        else: # single-line input
+            if line.startswith('!!'):
+                # rewrite iFun/theRest to properly hold the call to %sx and
+                # the actual command to be executed, so handle_magic can work
+                # correctly
+                theRest = '%s %s' % (iFun[2:],theRest)
+                iFun = 'sx'
+                return self.handle_magic('%ssx %s' % (self.ESC_MAGIC,line[2:]),
+                                         continue_prompt,pre,iFun,theRest)
+            else:
+                cmd = esc_quotes(line[1:])
+                line_out = '%s.system("%s")' % (self.name,cmd)
+        # update cache/log and return
+        self.log(line_out,continue_prompt)
+        self.update_cache(line_out)   # readline cache gets normal line
+        return line_out
+
+    def handle_magic(self, line, continue_prompt=None,
+                     pre=None,iFun=None,theRest=None):
+        """Execute magic functions.
+
+        Also log them with a prepended # so the log is clean Python."""
+
+        cmd = '%sipmagic("%s")' % (pre,esc_quotes('%s %s' % (iFun,theRest)))
+        self.log(cmd,continue_prompt)
+        self.update_cache(line)
+        #print 'in handle_magic, cmd=<%s>' % cmd  # dbg
+        return cmd
+
+    def handle_auto(self, line, continue_prompt=None,
+                    pre=None,iFun=None,theRest=None):
+        """Hande lines which can be auto-executed, quoting if requested."""
+
+        #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest)  # dbg
+        
+        # This should only be active for single-line input!
+        if continue_prompt:
+            return line
+
+        if pre == self.ESC_QUOTE:
+            # Auto-quote splitting on whitespace
+            newcmd = '%s("%s")\n' % (iFun,'", "'.join(theRest.split()) )
+        elif pre == self.ESC_QUOTE2:
+            # Auto-quote whole string
+            newcmd = '%s("%s")\n' % (iFun,theRest)
+        else:
+            # Auto-paren
+            if theRest[0:1] in ('=','['):
+                # Don't autocall in these cases.  They can be either
+                # rebindings of an existing callable's name, or item access
+                # for an object which is BOTH callable and implements
+                # __getitem__.
+                return '%s %s\n' % (iFun,theRest)
+            if theRest.endswith(';'):
+                newcmd = '%s(%s);\n' % (iFun.rstrip(),theRest[:-1])
+            else:
+                newcmd = '%s(%s)\n' % (iFun.rstrip(),theRest)
+
+        print >>Term.cout, self.outputcache.prompt1.auto_rewrite() + newcmd,
+        # log what is now valid Python, not the actual user input (without the
+        # final newline)
+        self.log(newcmd.strip(),continue_prompt)
+        return newcmd
+
+    def handle_help(self, line, continue_prompt=None,
+                    pre=None,iFun=None,theRest=None):
+        """Try to get some help for the object.
+
+        obj? or ?obj   -> basic information.
+        obj?? or ??obj -> more details.
+        """
+
+        # We need to make sure that we don't process lines which would be
+        # otherwise valid python, such as "x=1 # what?"
+        try:
+            code.compile_command(line)
+        except SyntaxError:
+            # We should only handle as help stuff which is NOT valid syntax
+            if line[0]==self.ESC_HELP:
+                line = line[1:]
+            elif line[-1]==self.ESC_HELP:
+                line = line[:-1]
+            self.log('#?'+line)
+            self.update_cache(line)
+            if line:
+                self.magic_pinfo(line)
+            else:
+                page(self.usage,screen_lines=self.rc.screen_length)
+            return '' # Empty string is needed here!
+        except:
+            # Pass any other exceptions through to the normal handler
+            return self.handle_normal(line,continue_prompt)
+        else:
+            # If the code compiles ok, we should handle it normally
+            return self.handle_normal(line,continue_prompt)
+
+    def handle_emacs(self,line,continue_prompt=None,
+                    pre=None,iFun=None,theRest=None):
+        """Handle input lines marked by python-mode."""
+
+        # Currently, nothing is done.  Later more functionality can be added
+        # here if needed.
+
+        # The input cache shouldn't be updated
+
+        return line
+
+    def write(self,data):
+        """Write a string to the default output"""
+        Term.cout.write(data)
+
+    def write_err(self,data):
+        """Write a string to the default error output"""
+        Term.cerr.write(data)
+
+    def safe_execfile(self,fname,*where,**kw):
+        fname = os.path.expanduser(fname)
+
+        # find things also in current directory
+        dname = os.path.dirname(fname)
+        if not sys.path.count(dname):
+            sys.path.append(dname)
+
+        try:
+            xfile = open(fname)
+        except:
+            print >> Term.cerr, \
+                  'Could not open file <%s> for safe execution.' % fname
+            return None
+
+        kw.setdefault('islog',0)
+        kw.setdefault('quiet',1)
+        kw.setdefault('exit_ignore',0)
+        first = xfile.readline()
+        _LOGHEAD = str(self.LOGHEAD).split('\n',1)[0].strip()
+        xfile.close()
+        # line by line execution
+        if first.startswith(_LOGHEAD) or kw['islog']:
+            print 'Loading log file <%s> one line at a time...' % fname
+            if kw['quiet']:
+                stdout_save = sys.stdout
+                sys.stdout = StringIO.StringIO()
+            try:
+                globs,locs = where[0:2]
+            except:
+                try:
+                    globs = locs = where[0]
+                except:
+                    globs = locs = globals()
+            badblocks = []
+
+            # we also need to identify indented blocks of code when replaying
+            # logs and put them together before passing them to an exec
+            # statement. This takes a bit of regexp and look-ahead work in the
+            # file. It's easiest if we swallow the whole thing in memory
+            # first, and manually walk through the lines list moving the
+            # counter ourselves.
+            indent_re = re.compile('\s+\S')
+            xfile = open(fname)
+            filelines = xfile.readlines()
+            xfile.close()
+            nlines = len(filelines)
+            lnum = 0
+            while lnum < nlines:
+                line = filelines[lnum]
+                lnum += 1
+                # don't re-insert logger status info into cache
+                if line.startswith('#log#'):
+                    continue
+                elif line.startswith('#%s'% self.ESC_MAGIC):
+                    self.update_cache(line[1:])
+                    line = magic2python(line)
+                elif line.startswith('#!'):
+                    self.update_cache(line[1:])
+                else:
+                    # build a block of code (maybe a single line) for execution
+                    block = line
+                    try:
+                        next = filelines[lnum] # lnum has already incremented
+                    except:
+                        next = None
+                    while next and indent_re.match(next):
+                        block += next
+                        lnum += 1
+                        try:
+                            next = filelines[lnum]
+                        except:
+                            next = None
+                    # now execute the block of one or more lines
+                    try:
+                        exec block in globs,locs
+                        self.update_cache(block.rstrip())
+                    except SystemExit:
+                        pass
+                    except:
+                        badblocks.append(block.rstrip())
+            if kw['quiet']:  # restore stdout
+                sys.stdout.close()
+                sys.stdout = stdout_save
+            print 'Finished replaying log file <%s>' % fname
+            if badblocks:
+                print >> sys.stderr, \
+                      '\nThe following lines/blocks in file <%s> reported errors:' \
+                      % fname
+                for badline in badblocks:
+                    print >> sys.stderr, badline
+        else:  # regular file execution
+            try:
+                execfile(fname,*where)
+            except SyntaxError:
+                etype, evalue = sys.exc_info()[0:2]
+                self.SyntaxTB(etype,evalue,[])
+                warn('Failure executing file: <%s>' % fname)
+            except SystemExit,status:
+                if not kw['exit_ignore']:
+                    self.InteractiveTB()
+                    warn('Failure executing file: <%s>' % fname)
+            except:
+                self.InteractiveTB()
+                warn('Failure executing file: <%s>' % fname)
+
+#************************* end of file <iplib.py> *****************************
diff --git a/IPython/ipmaker.py b/IPython/ipmaker.py
new file mode 100644
index 0000000..cff6035
--- /dev/null
+++ b/IPython/ipmaker.py
@@ -0,0 +1,736 @@
+# -*- coding: utf-8 -*-
+"""
+IPython -- An enhanced Interactive Python
+
+Requires Python 2.1 or better.
+
+This file contains the main make_IPython() starter function.
+
+$Id: ipmaker.py 582 2005-05-13 21:20:00Z fperez $"""
+
+#*****************************************************************************
+#       Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
+#
+#  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
+
+credits._Printer__data = """
+Python: %s
+
+IPython: Fernando Perez, Janko Hauser, Nathan Gray, and many users.
+See http://ipython.scipy.org for more information.""" \
+% credits._Printer__data
+
+copyright._Printer__data += """
+
+Copyright (c) 2001-2004 Fernando Perez, Janko Hauser, Nathan Gray.
+All Rights Reserved."""
+
+#****************************************************************************
+# Required modules
+
+# From the standard library
+import __main__, __builtin__
+import os,sys,types,re
+from pprint import pprint,pformat
+
+# Our own
+from IPython import DPyGetOpt
+from IPython.Struct import Struct
+from IPython.OutputTrap import OutputTrap
+from IPython.ConfigLoader import ConfigLoader
+from IPython.iplib import InteractiveShell,qw_lol,import_fail_info
+from IPython.usage import cmd_line_usage,interactive_usage
+from IPython.Prompts import CachedOutput
+from IPython.genutils import *
+
+#-----------------------------------------------------------------------------
+def make_IPython(argv=None,user_ns=None,debug=1,rc_override=None,
+                 shell_class=InteractiveShell,embedded=False,**kw):
+    """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:
+
+    IP = shell_class('__IP',user_ns=user_ns,**kw)
+
+    # Put 'help' in the user namespace
+    try:
+        from site import _Helper
+    except ImportError:
+        # Use the _Helper class from Python 2.2 for older Python versions
+        class _Helper:
+            def __repr__(self):
+                return "Type help() for interactive help, " \
+                       "or help(object) for help about object."
+            def __call__(self, *args, **kwds):
+                import pydoc
+                return pydoc.help(*args, **kwds)
+    else:
+        IP.user_ns['help'] = _Helper()
+
+    if DEVDEBUG:
+        # For developer debugging only (global flag)
+        from IPython import ultraTB
+        sys.excepthook = ultraTB.VerboseTB(call_pdb=1)
+    else:
+        # IPython itself shouldn't crash. This will produce a detailed
+        # post-mortem if it does
+        from IPython import CrashHandler
+        sys.excepthook = CrashHandler.CrashHandler(IP)
+
+    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__,),
+"""?       -> Introduction to IPython's features.
+%magic  -> Information about IPython's 'magic' % functions.
+help    -> Python's own help system.
+object? -> Details about 'object'. ?object also works, ?? prints more.
+""" ]
+
+    IP.usage = interactive_usage
+
+    # Platform-dependent suffix and directory names
+    if os.name == 'posix':
+        rc_suffix = ''
+        ipdir_def = '.ipython'
+    else:
+        rc_suffix = '.ini'
+        ipdir_def = '_ipython'
+
+    # default directory for configuration
+    ipythondir = os.path.abspath(os.environ.get('IPYTHONDIR',
+                                 os.path.join(IP.home_dir,ipdir_def)))
+
+    # 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!)
+    cmdline_opts = ('autocall! autoindent! automagic! banner! cache_size|cs=i '
+                    'c=s classic|cl color_info! colors=s confirm_exit! '
+                    'debug! deep_reload! editor=s log|l messages! nosep pdb! '
+                    'pprint! prompt_in1|pi1=s prompt_in2|pi2=s prompt_out|po=s '
+                    '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 '
+                    'separate_out2|so2=s xmode=s '
+                    'magic_docstrings system_verbose! '
+                    'multi_line_specials!')
+
+    # 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.
+    cmdline_only = ('help ignore|i ipythondir=s Version upgrade '
+                    'gthread! qthread! wthread! pylab! tk!')
+
+    # 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,
+                      autoindent=0,
+                      automagic = 1,
+                      banner = 1,
+                      cache_size = 1000,
+                      c = '',
+                      classic = 0,
+                      colors = 'NoColor',
+                      color_info = 0,
+                      confirm_exit = 1,
+                      debug = 0,
+                      deep_reload = 0,
+                      editor = '0',
+                      help = 0,
+                      ignore = 0,
+                      ipythondir = ipythondir,
+                      log = 0,
+                      logfile = '',
+                      logplay = '',
+                      multi_line_specials = 1,
+                      messages = 1,
+                      nosep = 0,
+                      pdb = 0,
+                      pprint = 0,
+                      profile = '',
+                      prompt_in1 = 'In [\\#]:',
+                      prompt_in2 = '   .\\D.:',
+                      prompt_out = 'Out[\\#]:',
+                      prompts_pad_left = 1,
+                      quick = 0,
+                      readline = 1,
+                      readline_merge_completions = 1,
+                      readline_omit__names = 0,
+                      rcfile = 'ipythonrc' + rc_suffix,
+                      screen_length = 0,
+                      separate_in = '\n',
+                      separate_out = '\n',
+                      separate_out2 = '',
+                      system_verbose = 0,
+                      gthread = 0,
+                      qthread = 0,
+                      wthread = 0,
+                      pylab = 0,
+                      tk = 0,
+                      upgrade = 0,
+                      Version = 0,
+                      xmode = 'Verbose',
+                      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)
+    except:
+        print cmd_line_usage
+        warn('\nError in Arguments: ' + `sys.exc_value`)
+        sys.exit()
+
+    # 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()
+
+    # 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')])
+
+    # default logfilename used when -log is called.
+    IP.LOGDEF = 'ipython.log'
+
+    #---------------------------------------------------------------------------
+    # 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
+    if opts_all.profile:
+        try:
+            opts_all.rcfile = filefind('ipythonrc-' + opts_all.profile
+                                       + rc_suffix,
+                                       opts_all.ipythondir)
+        except IOError:
+           if opts_all.debug:  IP.InteractiveTB()
+           opts.profile = ''  # remove profile from options if invalid
+           warn('Profile configuration file %s not found. Ignoring request.'
+                % (opts_all.profile) )
+
+    # load the config file
+    rcfiledata = None
+    if opts_all.quick:
+        print 'Launching IPython in quick mode. No config file read.'
+    elif opts_all.classic:
+        print 'Launching IPython in classic 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
+
+    # first, create a valid config structure with the right precedence order:
+    # defaults < rcfile < command line
+    IP.rc = rc_def.copy()
+    IP.rc.update(opts_def)
+    if rcfiledata:
+        # now we can update 
+        IP.rc.update(rcfiledata)
+    IP.rc.update(opts)
+    IP.rc.update(rc_override)
+
+    # Store the original cmd line for reference:
+    IP.rc.opts = opts
+    IP.rc.args = args
+
+    # create a *runtime* Struct like rc for holding parameters which may be
+    # created and/or modified by runtime user extensions.
+    IP.runtime_rc = Struct()
+
+    # from this point on, all config should be handled through IP.rc,
+    # opts* shouldn't be used anymore.
+
+    # add personal .ipython dir to sys.path so that users can put things in
+    # there for customization
+    sys.path.append(IP.rc.ipythondir)
+    sys.path.insert(0, '') # add . to sys.path. Fix from Prabhu Ramachandran
+    
+    # update IP.rc with some special things that need manual
+    # 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!
+
+    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'
+
+    # configure readline
+    # Define the history file for saving commands in between sessions
+    if IP.rc.profile:
+        histfname = 'history-%s' % IP.rc.profile
+    else:
+        histfname = 'history'
+    IP.histfile = os.path.join(opts_all.ipythondir,histfname)
+    # Load readline proper
+    if IP.rc.readline:
+        IP.init_readline()
+
+    # update exception handlers with rc file status
+    otrap.trap_out()  # I don't want these messages ever.
+    IP.magic_xmode(IP.rc.xmode)
+    otrap.release_out()
+
+    # activate logging if requested and not reloading a log
+    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:
+        IP.magic_logstart()
+
+    # find user editor so that it we don't have to look it up constantly
+    if IP.rc.editor.strip()=='0':
+        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!
+        IP.rc.editor = ed
+
+    # Recursive reload
+    try:
+        from IPython import deep_reload
+        if IP.rc.deep_reload:
+            __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!
+    IP.internal_ns = __main__.__dict__.copy()
+
+    #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
+    if IP.rc.debug:
+        print 'Trying to execute the following configuration structure:'
+        print '(Things listed first are deeper in the inclusion tree and get'
+        print 'loaded first).\n'
+        pprint(IP.rc.__dict__)
+        
+    for mod in IP.rc.import_mod:
+        try:
+            exec 'import '+mod in IP.user_ns
+        except :
+            IP.InteractiveTB()
+            import_fail_info(mod)
+
+    for mod_fn in IP.rc.import_some:
+        if mod_fn == []: break
+        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)
+
+    for mod in IP.rc.import_all:
+        try:
+            exec 'from '+mod+' import *' in IP.user_ns
+        except :
+            IP.InteractiveTB()
+            import_fail_info(mod)
+
+    for code in IP.rc.execute:
+        try:
+            exec code in IP.user_ns
+        except:
+            IP.InteractiveTB()
+            warn('Failure executing code: ' + `code`)
+
+    # Execute the files the user wants in ipythonrc
+    for file in IP.rc.execfile:
+        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)
+
+    # Load user aliases
+    for alias in IP.rc.alias:
+        IP.magic_alias(alias)
+
+    # release stdout and stderr and save config log into a global summary
+    msg.config.release_all()
+    if IP.rc.messages:
+        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.
+    IP.user_config_ns = IP.user_ns.copy()
+
+    # Force reading a file as if it were a session log. Slower but safer.
+    if load_logplay:
+        print 'Replaying log...'
+        try:
+            if IP.rc.debug:
+                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()
+            if IP.rc.messages:
+                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.
+    
+    if not embedded and IP.rc.args:
+        name_save = IP.user_ns['__name__']
+        IP.user_ns['__name__'] = '__main__'
+        try:
+            # 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
+            for run in args:
+                IP.safe_execfile(run,IP.user_ns)
+        finally:
+            # Reset our crash handler in place
+            sys.excepthook = old_excepthook
+            
+        IP.user_ns['__name__'] = name_save
+        
+    msg.user_exec.release_all()
+    if IP.rc.messages:
+        msg.summary += msg.user_exec.summary_all()
+
+    # since we can't specify a null string on the cmd line, 0 is the equivalent:
+    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')
+
+    # 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:
+    num_lines_bot = IP.rc.separate_in.count('\n')+1
+    IP.rc.screen_length = IP.rc.screen_length - num_lines_bot
+    # Initialize cache, set in/out prompts and printing system
+    IP.outputcache = CachedOutput(IP.rc.cache_size,
+                                  IP.rc.pprint,
+                                  input_sep = IP.rc.separate_in,
+                                  output_sep = IP.rc.separate_out,
+                                  output_sep2 = IP.rc.separate_out2,
+                                  ps1 = IP.rc.prompt_in1,
+                                  ps2 = IP.rc.prompt_in2,
+                                  ps_out = IP.rc.prompt_out,
+                                  user_ns = IP.user_ns,
+                                  input_hist = IP.input_hist,
+                                  pad_left = IP.rc.prompts_pad_left)
+
+    # Set user colors (don't do it in the constructor above so that it doesn't
+    # crash if colors option is invalid)
+    IP.magic_colors(IP.rc.colors)
+    
+    # user may have over-ridden the default print hook:
+    try:
+        IP.outputcache.__class__.display = IP.hooks.display
+    except AttributeError:
+        pass
+
+    # Set calling of pdb on exceptions
+    IP.InteractiveTB.call_pdb = IP.rc.pdb
+    
+    # I don't like assigning globally to sys, because it means when embedding
+    # instances, each embedded instance overrides the previous choice. But
+    # sys.displayhook seems to be called internally by exec, so I don't see a
+    # way around it.
+    sys.displayhook = IP.outputcache
+
+    # we need to know globally if we're caching i/o or not
+    IP.do_full_cache = IP.outputcache.do_full_cache
+    
+    # configure startup banner
+    if IP.rc.c:  # regular python doesn't print the banner with -c
+        IP.rc.banner = 0
+    if IP.rc.banner:
+        IP.BANNER = '\n'.join(IP.BANNER_PARTS)
+    else:
+        IP.BANNER = ''
+
+    if IP.rc.profile: IP.BANNER += '\nIPython profile: '+IP.rc.profile+'\n'
+
+    # add message log (possibly empty)
+    IP.BANNER += msg.summary
+
+    IP.post_config_initialization()
+
+    return IP
+#************************ end of file <ipmaker.py> **************************
diff --git a/IPython/numutils.py b/IPython/numutils.py
new file mode 100644
index 0000000..4d924e9
--- /dev/null
+++ b/IPython/numutils.py
@@ -0,0 +1,305 @@
+# -*- coding: utf-8 -*-
+"""
+A set of convenient utilities for numerical work.
+
+Most of this module requires Numerical Python or is meant to be used with it.
+See http://www.pfdubois.com/numpy for details.
+
+$Id: numutils.py 486 2005-01-27 19:34:21Z fperez $"""
+
+#*****************************************************************************
+#       Copyright (C) 2001-2005 Fernando Perez <fperez@colorado.edu>
+#
+#  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
+
+__all__ = ['sum_flat','mean_flat','rms_flat','base_repr','binary_repr',
+           'amin','amax','amap','zeros_like','empty_like',
+           'frange','diagonal_matrix','identity',
+           'fromfunction_kw','log2','ispower2',
+           'norm','l1norm','l2norm','exp_safe',
+           'inf','infty','Infinity',
+           'Numeric']
+
+#****************************************************************************
+# required modules
+import __main__
+import sys,operator
+import math
+import Numeric
+from Numeric import *
+
+#*****************************************************************************
+# Globals
+
+# useful for testing infinities in results of array divisions (which don't
+# raise an exception)
+# Python, LaTeX and Mathematica names.
+inf = infty = Infinity = (array([1])/0.0)[0]
+
+#****************************************************************************
+# function definitions        
+exp_safe_MIN = math.log(2.2250738585072014e-308)
+exp_safe_MAX = 1.7976931348623157e+308
+
+def exp_safe(x):
+    """Compute exponentials which safely underflow to zero.
+
+    Slow but convenient to use. Note that NumArray will introduce proper
+    floating point exception handling with access to the underlying
+    hardware."""
+
+    if type(x) is ArrayType:
+        return exp(clip(x,exp_safe_MIN,exp_safe_MAX))
+    else:
+        return math.exp(x)
+
+def amap(fn,*args):
+    """amap(function, sequence[, sequence, ...]) -> array.
+
+    Works like map(), but it returns an array.  This is just a convenient
+    shorthand for Numeric.array(map(...))"""
+    return array(map(fn,*args))
+
+def amin(m,axis=0):
+    """amin(m,axis=0) returns the minimum of m along dimension axis.
+    """
+    return minimum.reduce(asarray(m),axis)
+
+def amax(m,axis=0):
+    """amax(m,axis=0) returns the maximum of m along dimension axis.
+    """
+    return maximum.reduce(asarray(m),axis)
+
+def zeros_like(a):
+    """Return an array of zeros of the shape and typecode of a.
+
+    If you don't explicitly need the array to be zeroed, you should instead
+    use empty_like(), which is faster as it only allocates memory."""
+
+    return zeros(a.shape,a.typecode())
+
+def empty_like(a):
+    """Return an empty (uninitialized) array of the shape and typecode of a.
+
+    Note that this does NOT initialize the returned array.  If you require
+    your array to be initialized, you should use zeros_like().
+
+    This requires Numeric.empty(), which appeared in Numeric 23.7."""
+
+    return empty(a.shape,a.typecode())
+
+def sum_flat(a):
+    """Return the sum of all the elements of a, flattened out.
+
+    It uses a.flat, and if a is not contiguous, a call to ravel(a) is made."""
+
+    if a.iscontiguous():
+        return Numeric.sum(a.flat)
+    else:
+        return Numeric.sum(ravel(a))
+
+def mean_flat(a):
+    """Return the mean of all the elements of a, flattened out."""
+
+    return sum_flat(a)/float(size(a))
+
+def rms_flat(a):
+    """Return the root mean square of all the elements of a, flattened out."""
+
+    return math.sqrt(sum_flat(absolute(a)**2)/float(size(a)))
+
+def l1norm(a):
+    """Return the l1 norm of a, flattened out.
+
+    Implemented as a separate function (not a call to norm() for speed).
+
+    Ref: http://mathworld.wolfram.com/L1-Norm.html"""
+
+    return sum_flat(absolute(a))
+
+def l2norm(a):
+    """Return the l2 norm of a, flattened out.
+
+    Implemented as a separate function (not a call to norm() for speed).
+
+    Ref: http://mathworld.wolfram.com/L2-Norm.html"""
+
+    return math.sqrt(sum_flat(absolute(a)**2))
+
+def norm(a,p=2):
+    """norm(a,p=2) -> l-p norm of a.flat
+
+    Return the l-p norm of a, considered as a flat array.  This is NOT a true
+    matrix norm, since arrays of arbitrary rank are always flattened.
+
+    p can be a number or one of the strings ('inf','Infinity') to get the
+    L-infinity norm.
+
+    Ref: http://mathworld.wolfram.com/VectorNorm.html
+         http://mathworld.wolfram.com/L-Infinity-Norm.html"""
+    
+    if p in ('inf','Infinity'):
+        return max(absolute(a).flat)
+    else:
+        return (sum_flat(absolute(a)**p))**(1.0/p)    
+    
+def frange(xini,xfin=None,delta=None,**kw):
+    """frange([start,] stop[, step, keywords]) -> array of floats
+
+    Return a Numeric array() containing a progression of floats. Similar to
+    arange(), but defaults to a closed interval.
+
+    frange(x0, x1) returns [x0, x0+1, x0+2, ..., x1]; start defaults to 0, and
+    the endpoint *is included*. This behavior is different from that of
+    range() and arange(). This is deliberate, since frange will probably be
+    more useful for generating lists of points for function evaluation, and
+    endpoints are often desired in this use. The usual behavior of range() can
+    be obtained by setting the keyword 'closed=0', in this case frange()
+    basically becomes arange().
+
+    When step is given, it specifies the increment (or decrement). All
+    arguments can be floating point numbers.
+
+    frange(x0,x1,d) returns [x0,x0+d,x0+2d,...,xfin] where xfin<=x1.
+
+    frange can also be called with the keyword 'npts'. This sets the number of
+    points the list should contain (and overrides the value 'step' might have
+    been given). arange() doesn't offer this option.
+
+    Examples:
+    >>> frange(3)
+    array([ 0.,  1.,  2.,  3.])
+    >>> frange(3,closed=0)
+    array([ 0.,  1.,  2.])
+    >>> frange(1,6,2)
+    array([1, 3, 5])
+    >>> frange(1,6.5,npts=5)
+    array([ 1.   ,  2.375,  3.75 ,  5.125,  6.5  ])
+    """
+
+    #defaults
+    kw.setdefault('closed',1)
+    endpoint = kw['closed'] != 0
+        
+    # funny logic to allow the *first* argument to be optional (like range())
+    # This was modified with a simpler version from a similar frange() found
+    # at http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66472
+    if xfin == None:
+        xfin = xini + 0.0
+        xini = 0.0
+        
+    if delta == None:
+        delta = 1.0
+
+    # compute # of points, spacing and return final list
+    try:
+        npts=kw['npts']
+        delta=(xfin-xini)/float(npts-endpoint)
+    except KeyError:
+        # round() gets npts right even with the vagaries of floating point.
+        npts=int(round((xfin-xini)/delta+endpoint))
+
+    return arange(npts)*delta+xini
+
+def diagonal_matrix(diag):
+    """Return square diagonal matrix whose non-zero elements are given by the
+    input array."""
+
+    return diag*identity(len(diag))
+
+def identity(n,rank=2,typecode='l'):
+    """identity(n,r) returns the identity matrix of shape (n,n,...,n) (rank r).
+
+    For ranks higher than 2, this object is simply a multi-index Kronecker
+    delta:
+                        /  1  if i0=i1=...=iR,
+    id[i0,i1,...,iR] = -|
+                        \  0  otherwise.
+
+    Optionally a typecode may be given (it defaults to 'l').
+
+    Since rank defaults to 2, this function behaves in the default case (when
+    only n is given) like the Numeric identity function."""
+    
+    iden = zeros((n,)*rank,typecode=typecode)
+    for i in range(n):
+        idx = (i,)*rank
+        iden[idx] = 1
+    return iden
+
+def base_repr (number, base = 2, padding = 0):
+    """Return the representation of a number in any given base."""
+    chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+    if number < base: \
+       return (padding - 1) * chars [0] + chars [int (number)]
+    max_exponent = int (math.log (number)/math.log (base))
+    max_power = long (base) ** max_exponent
+    lead_digit = int (number/max_power)
+    return chars [lead_digit] + \
+           base_repr (number - max_power * lead_digit, base, \
+                      max (padding - 1, max_exponent))
+
+def binary_repr(number, max_length = 1025):
+    """Return the binary representation of the input number as a string.
+
+    This is more efficient than using base_repr with base 2.
+
+    Increase the value of max_length for very large numbers. Note that on
+    32-bit machines, 2**1023 is the largest integer power of 2 which can be
+    converted to a Python float."""
+    
+    assert number < 2L << max_length
+    shifts = map (operator.rshift, max_length * [number], \
+                  range (max_length - 1, -1, -1))
+    digits = map (operator.mod, shifts, max_length * [2])
+    if not digits.count (1): return 0
+    digits = digits [digits.index (1):]
+    return ''.join (map (repr, digits)).replace('L','')
+
+def log2(x,ln2 = math.log(2.0)):
+    """Return the log(x) in base 2.
+    
+    This is a _slow_ function but which is guaranteed to return the correct
+    integer value if the input is an ineger exact power of 2."""
+
+    try:
+        bin_n = binary_repr(x)[1:]
+    except (AssertionError,TypeError):
+        return math.log(x)/ln2
+    else:
+        if '1' in bin_n:
+            return math.log(x)/ln2
+        else:
+            return len(bin_n)
+
+def ispower2(n):
+    """Returns the log base 2 of n if n is a power of 2, zero otherwise.
+
+    Note the potential ambiguity if n==1: 2**0==1, interpret accordingly."""
+
+    bin_n = binary_repr(n)[1:]
+    if '1' in bin_n:
+        return 0
+    else:
+        return len(bin_n)
+
+def fromfunction_kw(function, dimensions, **kwargs):
+    """Drop-in replacement for fromfunction() from Numerical Python.
+ 
+    Allows passing keyword arguments to the desired function.
+
+    Call it as (keywords are optional):
+    fromfunction_kw(MyFunction, dimensions, keywords)
+
+    The function MyFunction() is responsible for handling the dictionary of
+    keywords it will recieve."""
+
+    return function(tuple(indices(dimensions)),**kwargs)
+
+#**************************** end file <numutils.py> ************************
diff --git a/IPython/ultraTB.py b/IPython/ultraTB.py
new file mode 100644
index 0000000..43f29ec
--- /dev/null
+++ b/IPython/ultraTB.py
@@ -0,0 +1,855 @@
+# -*- coding: utf-8 -*-
+"""
+ultraTB.py -- Spice up your tracebacks!
+
+* ColorTB
+I've always found it a bit hard to visually parse tracebacks in Python.  The
+ColorTB class is a solution to that problem.  It colors the different parts of a
+traceback in a manner similar to what you would expect from a syntax-highlighting
+text editor.
+
+Installation instructions for ColorTB:
+    import sys,ultraTB
+    sys.excepthook = ultraTB.ColorTB()
+
+* VerboseTB  
+I've also included a port of Ka-Ping Yee's "cgitb.py" that produces all kinds
+of useful info when a traceback occurs.  Ping originally had it spit out HTML
+and intended it for CGI programmers, but why should they have all the fun?  I
+altered it to spit out colored text to the terminal.  It's a bit overwhelming,
+but kind of neat, and maybe useful for long-running programs that you believe
+are bug-free.  If a crash *does* occur in that type of program you want details.
+Give it a shot--you'll love it or you'll hate it.
+
+Note:
+
+  The Verbose mode prints the variables currently visible where the exception
+  happened (shortening their strings if too long). This can potentially be
+  very slow, if you happen to have a huge data structure whose string
+  representation is complex to compute. Your computer may appear to freeze for
+  a while with cpu usage at 100%. If this occurs, you can cancel the traceback
+  with Ctrl-C (maybe hitting it more than once).
+
+  If you encounter this kind of situation often, you may want to use the
+  Verbose_novars mode instead of the regular Verbose, which avoids formatting
+  variables (but otherwise includes the information and context given by
+  Verbose).
+  
+
+Installation instructions for ColorTB:
+    import sys,ultraTB
+    sys.excepthook = ultraTB.VerboseTB()
+
+Note:  Much of the code in this module was lifted verbatim from the standard
+library module 'traceback.py' and Ka-Ping Yee's 'cgitb.py'.
+
+* Color schemes
+The colors are defined in the class TBTools through the use of the
+ColorSchemeTable class. Currently the following exist:
+
+  - NoColor: allows all of this module to be used in any terminal (the color
+  escapes are just dummy blank strings).
+
+  - Linux: is meant to look good in a terminal like the Linux console (black
+  or very dark background).
+
+  - LightBG: similar to Linux but swaps dark/light colors to be more readable
+  in light background terminals.
+
+You can implement other color schemes easily, the syntax is fairly
+self-explanatory. Please send back new schemes you develop to the author for
+possible inclusion in future releases.
+
+$Id: ultraTB.py 589 2005-05-30 06:26:28Z fperez $"""
+
+#*****************************************************************************
+#       Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
+#       Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
+#
+#  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>\n%s <%s>' % (Release.authors['Nathan']+
+                                    Release.authors['Fernando'])
+__license__ = Release.license
+
+# Required modules
+import sys, os, traceback, types, string, time
+import keyword, tokenize, linecache, inspect, pydoc
+from UserDict import UserDict
+
+# IPython's own modules
+# Modified pdb which doesn't damage IPython's readline handling
+from IPython import Debugger
+
+from IPython.Struct import Struct
+from IPython.ColorANSI import *
+from IPython.genutils import Term,uniq_stable,error,info
+
+#---------------------------------------------------------------------------
+# Code begins
+
+def inspect_error():
+    """Print a message about internal inspect errors.
+
+    These are unfortunately quite common."""
+    
+    error('Internal Python error in the inspect module.\n'
+          'Below is the traceback from this internal error.\n')
+    
+class TBTools:
+    """Basic tools used by all traceback printer classes."""
+
+    def __init__(self,color_scheme = 'NoColor',call_pdb=0):
+        # Whether to call the interactive pdb debugger after printing
+        # tracebacks or not
+        self.call_pdb = call_pdb
+        if call_pdb:
+            self.pdb = Debugger.Pdb()
+        else:
+            self.pdb = None
+
+        # Create color table
+        self.ColorSchemeTable = ColorSchemeTable()
+        
+        # Populate it with color schemes
+        C = TermColors # shorthand and local lookup
+        self.ColorSchemeTable.add_scheme(ColorScheme(
+            'NoColor',
+            # The color to be used for the top line
+            topline = C.NoColor,
+
+            # The colors to be used in the traceback
+            filename = C.NoColor,
+            lineno = C.NoColor,
+            name = C.NoColor,
+            vName = C.NoColor,
+            val = C.NoColor,
+            em = C.NoColor,
+
+            # Emphasized colors for the last frame of the traceback
+            normalEm = C.NoColor,
+            filenameEm = C.NoColor,
+            linenoEm = C.NoColor,
+            nameEm = C.NoColor,
+            valEm = C.NoColor,
+
+            # Colors for printing the exception
+            excName = C.NoColor,
+            line = C.NoColor,
+            caret = C.NoColor,
+            Normal = C.NoColor
+            ))
+
+        # make some schemes as instances so we can copy them for modification easily:
+        self.ColorSchemeTable.add_scheme(ColorScheme(
+            'Linux',
+            # The color to be used for the top line
+            topline = C.LightRed,
+
+            # The colors to be used in the traceback
+            filename = C.Green,
+            lineno = C.Green,
+            name = C.Purple,
+            vName = C.Cyan,
+            val = C.Green,
+            em = C.LightCyan,
+
+            # Emphasized colors for the last frame of the traceback
+            normalEm = C.LightCyan,
+            filenameEm = C.LightGreen,
+            linenoEm = C.LightGreen,
+            nameEm = C.LightPurple,
+            valEm = C.LightBlue,
+
+            # Colors for printing the exception
+            excName = C.LightRed,
+            line = C.Yellow,
+            caret = C.White,
+            Normal = C.Normal
+            ))
+
+        # For light backgrounds, swap dark/light colors
+        self.ColorSchemeTable.add_scheme(ColorScheme(
+            'LightBG',
+            # The color to be used for the top line
+            topline = C.Red,
+
+            # The colors to be used in the traceback
+            filename = C.LightGreen,
+            lineno = C.LightGreen,
+            name = C.LightPurple,
+            vName = C.Cyan,
+            val = C.LightGreen,
+            em = C.Cyan,
+
+            # Emphasized colors for the last frame of the traceback
+            normalEm = C.Cyan,
+            filenameEm = C.Green,
+            linenoEm = C.Green,
+            nameEm = C.Purple,
+            valEm = C.Blue,
+
+            # Colors for printing the exception
+            excName = C.Red,
+            #line = C.Brown,  # brown often is displayed as yellow
+            line = C.Red,
+            caret = C.Normal,
+            Normal = C.Normal
+            ))
+
+        self.set_colors(color_scheme)
+        self.old_scheme = color_scheme  # save initial value for toggles
+
+    def set_colors(self,*args,**kw):
+        """Shorthand access to the color table scheme selector method."""
+        
+        self.ColorSchemeTable.set_active_scheme(*args,**kw)
+        # for convenience, set Colors to the active scheme
+        self.Colors = self.ColorSchemeTable.active_colors
+
+    def color_toggle(self):
+        """Toggle between the currently active color scheme and NoColor."""
+        
+        if self.ColorSchemeTable.active_scheme_name == 'NoColor':
+            self.ColorSchemeTable.set_active_scheme(self.old_scheme)
+            self.Colors = self.ColorSchemeTable.active_colors
+        else:
+            self.old_scheme = self.ColorSchemeTable.active_scheme_name
+            self.ColorSchemeTable.set_active_scheme('NoColor')
+            self.Colors = self.ColorSchemeTable.active_colors
+
+#---------------------------------------------------------------------------
+class ListTB(TBTools):
+    """Print traceback information from a traceback list, with optional color.
+        
+    Calling: requires 3 arguments:
+      (etype, evalue, elist)
+    as would be obtained by:
+      etype, evalue, tb = sys.exc_info()
+      if tb:
+        elist = traceback.extract_tb(tb)
+      else:
+        elist = None
+
+    It can thus be used by programs which need to process the traceback before
+    printing (such as console replacements based on the code module from the
+    standard library).
+
+    Because they are meant to be called without a full traceback (only a
+    list), instances of this class can't call the interactive pdb debugger."""
+
+    def __init__(self,color_scheme = 'NoColor'):
+        TBTools.__init__(self,color_scheme = color_scheme,call_pdb=0)
+        
+    def __call__(self, etype, value, elist):
+        print >> Term.cerr, self.text(etype,value,elist)
+
+    def text(self,etype, value, elist,context=5):
+        """Return a color formatted string with the traceback info."""
+
+        Colors = self.Colors
+        out_string = ['%s%s%s\n' % (Colors.topline,'-'*60,Colors.Normal)]
+        if elist:
+            out_string.append('Traceback %s(most recent call last)%s:' % \
+                                (Colors.normalEm, Colors.Normal) + '\n')
+            out_string.extend(self._format_list(elist))
+        lines = self._format_exception_only(etype, value)
+        for line in lines[:-1]:
+            out_string.append(" "+line)
+        out_string.append(lines[-1])
+        return ''.join(out_string)
+
+    def _format_list(self, extracted_list):
+        """Format a list of traceback entry tuples for printing.
+
+        Given a list of tuples as returned by extract_tb() or
+        extract_stack(), return a list of strings ready for printing.
+        Each string in the resulting list corresponds to the item with the
+        same index in the argument list.  Each string ends in a newline;
+        the strings may contain internal newlines as well, for those items
+        whose source text line is not None.
+        
+        Lifted almost verbatim from traceback.py
+        """
+
+        Colors = self.Colors
+        list = []
+        for filename, lineno, name, line in extracted_list[:-1]:
+            item = '  File %s"%s"%s, line %s%d%s, in %s%s%s\n' % \
+                    (Colors.filename, filename, Colors.Normal, 
+                     Colors.lineno, lineno, Colors.Normal,
+                     Colors.name, name, Colors.Normal)
+            if line:
+                item = item + '    %s\n' % line.strip()
+            list.append(item)
+        # Emphasize the last entry
+        filename, lineno, name, line = extracted_list[-1]
+        item = '%s  File %s"%s"%s, line %s%d%s, in %s%s%s%s\n' % \
+                (Colors.normalEm,
+                 Colors.filenameEm, filename, Colors.normalEm,
+                 Colors.linenoEm, lineno, Colors.normalEm,
+                 Colors.nameEm, name, Colors.normalEm,
+                 Colors.Normal)
+        if line:
+            item = item + '%s    %s%s\n' % (Colors.line, line.strip(),
+                                            Colors.Normal)
+        list.append(item)
+        return list
+        
+    def _format_exception_only(self, etype, value):
+        """Format the exception part of a traceback.
+
+        The arguments are the exception type and value such as given by
+        sys.last_type and sys.last_value. The return value is a list of
+        strings, each ending in a newline.  Normally, the list contains a
+        single string; however, for SyntaxError exceptions, it contains
+        several lines that (when printed) display detailed information
+        about where the syntax error occurred.  The message indicating
+        which exception occurred is the always last string in the list.
+        
+        Also lifted nearly verbatim from traceback.py
+        """
+        
+        Colors = self.Colors
+        list = []
+        if type(etype) == types.ClassType:
+            stype = Colors.excName + etype.__name__ + Colors.Normal
+        else:
+            stype = etype  # String exceptions don't get special coloring
+        if value is None:
+            list.append( str(stype) + '\n')
+        else:
+            if etype is SyntaxError:
+                try:
+                    msg, (filename, lineno, offset, line) = value
+                except:
+                    pass
+                else:
+                    #print 'filename is',filename  # dbg
+                    if not filename: filename = "<string>"
+                    list.append('%s  File %s"%s"%s, line %s%d%s\n' % \
+                            (Colors.normalEm,
+                             Colors.filenameEm, filename, Colors.normalEm,
+                             Colors.linenoEm, lineno, Colors.Normal  ))
+                    if line is not None:
+                        i = 0
+                        while i < len(line) and line[i].isspace():
+                            i = i+1
+                        list.append('%s    %s%s\n' % (Colors.line,
+                                                      line.strip(), 
+                                                      Colors.Normal))
+                        if offset is not None:
+                            s = '    '
+                            for c in line[i:offset-1]:
+                                if c.isspace():
+                                    s = s + c
+                                else:
+                                    s = s + ' '
+                            list.append('%s%s^%s\n' % (Colors.caret, s,
+                                                       Colors.Normal) )
+                        value = msg
+            s = self._some_str(value)
+            if s:
+                list.append('%s%s:%s %s\n' % (str(stype), Colors.excName,
+                                              Colors.Normal, s))
+            else:
+                list.append('%s\n' % str(stype))
+        return list
+
+    def _some_str(self, value):
+        # Lifted from traceback.py
+        try:
+            return str(value)
+        except:
+            return '<unprintable %s object>' % type(value).__name__
+
+#----------------------------------------------------------------------------
+class VerboseTB(TBTools):
+    """A port of Ka-Ping Yee's cgitb.py module that outputs color text instead
+    of HTML.  Requires inspect and pydoc.  Crazy, man.
+
+    Modified version which optionally strips the topmost entries from the
+    traceback, to be used with alternate interpreters (because their own code
+    would appear in the traceback)."""
+
+    def __init__(self,color_scheme = 'Linux',tb_offset=0,long_header=0,
+                 call_pdb = 0, include_vars=1):
+        """Specify traceback offset, headers and color scheme.
+
+        Define how many frames to drop from the tracebacks. Calling it with
+        tb_offset=1 allows use of this handler in interpreters which will have
+        their own code at the top of the traceback (VerboseTB will first
+        remove that frame before printing the traceback info)."""
+        TBTools.__init__(self,color_scheme=color_scheme,call_pdb=call_pdb)
+        self.tb_offset = tb_offset
+        self.long_header = long_header
+        self.include_vars = include_vars
+
+    def text(self, etype, evalue, etb, context=5):
+        """Return a nice text document describing the traceback."""
+
+        # some locals
+        Colors        = self.Colors   # just a shorthand + quicker name lookup
+        ColorsNormal  = Colors.Normal  # used a lot
+        indent_size   = 8  # we need some space to put line numbers before
+        indent        = ' '*indent_size
+        numbers_width = indent_size - 1 # leave space between numbers & code
+        text_repr     = pydoc.text.repr
+        exc           = '%s%s%s' % (Colors.excName, str(etype), ColorsNormal)
+        em_normal     = '%s\n%s%s' % (Colors.valEm, indent,ColorsNormal)
+        undefined     = '%sundefined%s' % (Colors.em, ColorsNormal)
+
+        # some internal-use functions
+        def eqrepr(value, repr=text_repr): return '=%s' % repr(value)
+        def nullrepr(value, repr=text_repr): return ''
+
+        # meat of the code begins
+        if type(etype) is types.ClassType:
+            etype = etype.__name__
+
+        if self.long_header:
+            # Header with the exception type, python version, and date
+            pyver = 'Python ' + string.split(sys.version)[0] + ': ' + sys.executable
+            date = time.ctime(time.time())
+            
+            head = '%s%s%s\n%s%s%s\n%s' % (Colors.topline, '-'*75, ColorsNormal,
+                                           exc, ' '*(75-len(str(etype))-len(pyver)),
+                                           pyver, string.rjust(date, 75) )
+            head += "\nA problem occured executing Python code.  Here is the sequence of function"\
+                    "\ncalls leading up to the error, with the most recent (innermost) call last."
+        else:
+            # Simplified header
+            head = '%s%s%s\n%s%s' % (Colors.topline, '-'*75, ColorsNormal,exc,
+                                     string.rjust('Traceback (most recent call last)',
+                                                  75 - len(str(etype)) ) )
+        frames = []
+        # Flush cache before calling inspect.  This helps alleviate some of the
+        # problems with python 2.3's inspect.py.
+        linecache.checkcache()
+        # Drop topmost frames if requested
+        try:
+            records = inspect.getinnerframes(etb, context)[self.tb_offset:]
+        except:
+
+            # FIXME: I've been getting many crash reports from python 2.3
+            # users, traceable to inspect.py.  If I can find a small test-case
+            # to reproduce this, I should either write a better workaround or
+            # file a bug report against inspect (if that's the real problem).
+            # So far, I haven't been able to find an isolated example to
+            # reproduce the problem.
+            inspect_error()
+            traceback.print_exc(file=Term.cerr)
+            info('\nUnfortunately, your original traceback can not be constructed.\n')
+            return ''
+
+        # build some color string templates outside these nested loops
+        tpl_link       = '%s%%s%s' % (Colors.filenameEm,ColorsNormal)
+        tpl_call       = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm,
+                                              ColorsNormal)
+        tpl_call_fail  = 'in %s%%s%s(***failed resolving arguments***)%s' % \
+                         (Colors.vName, Colors.valEm, ColorsNormal)
+        tpl_local_var  = '%s%%s%s' % (Colors.vName, ColorsNormal)
+        tpl_global_var = '%sglobal%s %s%%s%s' % (Colors.em, ColorsNormal,
+                                                 Colors.vName, ColorsNormal)
+        tpl_name_val   = '%%s %s= %%s%s' % (Colors.valEm, ColorsNormal)
+        tpl_line       = '%s%%s%s %%s' % (Colors.lineno, ColorsNormal)
+        tpl_line_em    = '%s%%s%s %%s%s' % (Colors.linenoEm,Colors.line,
+                                            ColorsNormal)
+
+        # now, loop over all records printing context and info
+        abspath = os.path.abspath
+        for frame, file, lnum, func, lines, index in records:
+            #print '*** record:',file,lnum,func,lines,index  # dbg
+            try:
+                file = file and abspath(file) or '?'
+            except OSError:
+                # if file is '<console>' or something not in the filesystem,
+                # the abspath call will throw an OSError.  Just ignore it and
+                # keep the original file string.
+                pass
+            link = tpl_link % file
+            try:
+                args, varargs, varkw, locals = inspect.getargvalues(frame)
+            except:
+                # This can happen due to a bug in python2.3.  We should be
+                # able to remove this try/except when 2.4 becomes a
+                # requirement.  Bug details at http://python.org/sf/1005466
+                inspect_error()
+                traceback.print_exc(file=Term.cerr)
+                info("\nIPython's exception reporting continues...\n")
+                
+            if func == '?':
+                call = ''
+            else:
+                # Decide whether to include variable details or not
+                var_repr = self.include_vars and eqrepr or nullrepr
+                try:
+                    call = tpl_call % (func,inspect.formatargvalues(args,
+                                                varargs, varkw,
+                                                locals,formatvalue=var_repr))
+                except KeyError:
+                    # Very odd crash from inspect.formatargvalues().  The
+                    # scenario under which it appeared was a call to
+                    # view(array,scale) in NumTut.view.view(), where scale had
+                    # been defined as a scalar (it should be a tuple). Somehow
+                    # inspect messes up resolving the argument list of view()
+                    # and barfs out. At some point I should dig into this one
+                    # and file a bug report about it.
+                    inspect_error()
+                    traceback.print_exc(file=Term.cerr)
+                    info("\nIPython's exception reporting continues...\n")
+                    call = tpl_call_fail % func
+
+            # Initialize a list of names on the current line, which the
+            # tokenizer below will populate.
+            names = []
+
+            def tokeneater(token_type, token, start, end, line):
+                """Stateful tokeneater which builds dotted names.
+
+                The list of names it appends to (from the enclosing scope) can
+                contain repeated composite names.  This is unavoidable, since
+                there is no way to disambguate partial dotted structures until
+                the full list is known.  The caller is responsible for pruning
+                the final list of duplicates before using it."""
+                
+                # build composite names
+                if token == '.':
+                    try:
+                        names[-1] += '.'
+                        # store state so the next token is added for x.y.z names
+                        tokeneater.name_cont = True
+                        return
+                    except IndexError:
+                        pass
+                if token_type == tokenize.NAME and token not in keyword.kwlist:
+                    if tokeneater.name_cont:
+                        # Dotted names
+                        names[-1] += token
+                        tokeneater.name_cont = False
+                    else:
+                        # Regular new names.  We append everything, the caller
+                        # will be responsible for pruning the list later.  It's
+                        # very tricky to try to prune as we go, b/c composite
+                        # names can fool us.  The pruning at the end is easy
+                        # to do (or the caller can print a list with repeated
+                        # names if so desired.
+                        names.append(token)
+                elif token_type == tokenize.NEWLINE:
+                    raise IndexError
+            # we need to store a bit of state in the tokenizer to build
+            # dotted names
+            tokeneater.name_cont = False
+
+            def linereader(file=file, lnum=[lnum], getline=linecache.getline):
+                line = getline(file, lnum[0])
+                lnum[0] += 1
+                return line
+
+            # Build the list of names on this line of code where the exception
+            # occurred.
+            try:
+                # This builds the names list in-place by capturing it from the
+                # enclosing scope.
+                tokenize.tokenize(linereader, tokeneater)
+            except IndexError:
+                # signals exit of tokenizer
+                pass
+            except tokenize.TokenError,msg:
+                _m = ("An unexpected error occurred while tokenizing input\n"
+                      "The following traceback may be corrupted or invalid\n"
+                      "The error message is: %s\n" % msg)
+                error(_m)
+            
+            # prune names list of duplicates, but keep the right order
+            unique_names = uniq_stable(names)
+
+            # Start loop over vars
+            lvals = []
+            if self.include_vars:
+                for name_full in unique_names:
+                    name_base = name_full.split('.',1)[0]
+                    if name_base in frame.f_code.co_varnames:
+                        if locals.has_key(name_base):
+                            try:
+                                value = repr(eval(name_full,locals))
+                            except:
+                                value = undefined
+                        else:
+                            value = undefined
+                        name = tpl_local_var % name_full
+                    else:
+                        if frame.f_globals.has_key(name_base):
+                            try:
+                                value = repr(eval(name_full,frame.f_globals))
+                            except:
+                                value = undefined
+                        else:
+                            value = undefined
+                        name = tpl_global_var % name_full
+                    lvals.append(tpl_name_val % (name,value))
+            if lvals:
+                lvals = '%s%s' % (indent,em_normal.join(lvals))
+            else:
+                lvals = ''
+
+            level = '%s %s\n' % (link,call)
+            excerpt = []
+            if index is not None:
+                i = lnum - index
+                for line in lines:
+                    if i == lnum:
+                        # This is the line with the error
+                        pad = numbers_width - len(str(i))
+                        if pad >= 3:
+                            marker = '-'*(pad-3) + '-> '
+                        elif pad == 2:
+                            marker = '> '
+                        elif pad == 1:
+                            marker = '>'
+                        else:
+                            marker = ''
+                        num = '%s%s' % (marker,i)
+                        line = tpl_line_em % (num,line)
+                    else:
+                        num = '%*s' % (numbers_width,i)
+                        line = tpl_line % (num,line)
+
+                    excerpt.append(line)
+                    if self.include_vars and i == lnum:
+                        excerpt.append('%s\n' % lvals)
+                    i += 1
+            frames.append('%s%s' % (level,''.join(excerpt)) )
+
+        # Get (safely) a string form of the exception info
+        try:
+            etype_str,evalue_str = map(str,(etype,evalue))
+        except:
+            # User exception is improperly defined.
+            etype,evalue = str,sys.exc_info()[:2]
+            etype_str,evalue_str = map(str,(etype,evalue))
+        # ... and format it
+        exception = ['%s%s%s: %s' % (Colors.excName, etype_str,
+                                     ColorsNormal, evalue_str)]
+        if type(evalue) is types.InstanceType:
+            for name in dir(evalue):
+                value = text_repr(getattr(evalue, name))
+                exception.append('\n%s%s = %s' % (indent, name, value))
+        # return all our info assembled as a single string
+        return '%s\n\n%s\n%s' % (head,'\n'.join(frames),''.join(exception[0]) )
+
+    def debugger(self):
+        """Call up the pdb debugger if desired, always clean up the tb reference.
+
+        If the call_pdb flag is set, the pdb interactive debugger is
+        invoked. In all cases, the self.tb reference to the current traceback
+        is deleted to prevent lingering references which hamper memory
+        management.
+
+        Note that each call to pdb() does an 'import readline', so if your app
+        requires a special setup for the readline completers, you'll have to
+        fix that by hand after invoking the exception handler."""
+
+        if self.call_pdb:
+            if self.pdb is None:
+                self.pdb = Debugger.Pdb()
+            # the system displayhook may have changed, restore the original for pdb
+            dhook = sys.displayhook
+            sys.displayhook = sys.__displayhook__
+            self.pdb.reset()
+            while self.tb.tb_next is not None:
+                self.tb = self.tb.tb_next
+            try:
+                self.pdb.interaction(self.tb.tb_frame, self.tb)
+            except:
+                print '*** ERROR ***'
+                print 'This version of pdb has a bug and crashed.'
+                print 'Returning to IPython...'
+            sys.displayhook = dhook
+        del self.tb
+
+    def handler(self, info=None):
+        (etype, evalue, etb) = info or sys.exc_info()
+        self.tb = etb
+        print >> Term.cerr, self.text(etype, evalue, etb)
+
+    # Changed so an instance can just be called as VerboseTB_inst() and print
+    # out the right info on its own.
+    def __call__(self, etype=None, evalue=None, etb=None):
+        """This hook can replace sys.excepthook (for Python 2.1 or higher)."""
+        if etb is not None:
+            self.handler((etype, evalue, etb))
+        else:
+            self.handler()
+        self.debugger()
+
+#----------------------------------------------------------------------------
+class FormattedTB(VerboseTB,ListTB):
+    """Subclass ListTB but allow calling with a traceback.
+
+    It can thus be used as a sys.excepthook for Python > 2.1.
+
+    Also adds 'Context' and 'Verbose' modes, not available in ListTB.
+
+    Allows a tb_offset to be specified. This is useful for situations where
+    one needs to remove a number of topmost frames from the traceback (such as
+    occurs with python programs that themselves execute other python code,
+    like Python shells).  """
+    
+    def __init__(self, mode = 'Plain', color_scheme='Linux',
+                 tb_offset = 0,long_header=0,call_pdb=0,include_vars=0):
+
+        # NEVER change the order of this list. Put new modes at the end:
+        self.valid_modes = ['Plain','Context','Verbose']
+        self.verbose_modes = self.valid_modes[1:3]
+
+        VerboseTB.__init__(self,color_scheme,tb_offset,long_header,
+                           call_pdb=call_pdb,include_vars=include_vars)
+        self.set_mode(mode)
+        
+    def _extract_tb(self,tb):
+        if tb:
+            return traceback.extract_tb(tb)
+        else:
+            return None
+
+    def text(self, etype, value, tb,context=5,mode=None):
+        """Return formatted traceback.
+
+        If the optional mode parameter is given, it overrides the current
+        mode."""
+
+        if mode is None:
+            mode = self.mode
+        if mode in self.verbose_modes:
+            # verbose modes need a full traceback
+            return VerboseTB.text(self,etype, value, tb,context=5)
+        else:
+            # We must check the source cache because otherwise we can print
+            # out-of-date source code.
+            linecache.checkcache()
+            # Now we can extract and format the exception
+            elist = self._extract_tb(tb)
+            if len(elist) > self.tb_offset:
+                del elist[:self.tb_offset]
+            return ListTB.text(self,etype,value,elist)
+
+    def set_mode(self,mode=None):
+        """Switch to the desired mode.
+
+        If mode is not specified, cycles through the available modes."""
+
+        if not mode:
+            new_idx = ( self.valid_modes.index(self.mode) + 1 ) % \
+                      len(self.valid_modes)
+            self.mode = self.valid_modes[new_idx]
+        elif mode not in self.valid_modes:
+            raise ValueError, 'Unrecognized mode in FormattedTB: <'+mode+'>\n'\
+                  'Valid modes: '+str(self.valid_modes)
+        else:
+            self.mode = mode
+        # include variable details only in 'Verbose' mode
+        self.include_vars = (self.mode == self.valid_modes[2])
+
+    # some convenient shorcuts
+    def plain(self):
+        self.set_mode(self.valid_modes[0])
+
+    def context(self):
+        self.set_mode(self.valid_modes[1])
+
+    def verbose(self):
+        self.set_mode(self.valid_modes[2])
+
+#----------------------------------------------------------------------------
+class AutoFormattedTB(FormattedTB):
+    """A traceback printer which can be called on the fly.
+
+    It will find out about exceptions by itself.
+
+    A brief example:
+    
+    AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux')
+    try:
+      ...
+    except:
+      AutoTB()  # or AutoTB(out=logfile) where logfile is an open file object
+    """
+    def __call__(self,etype=None,evalue=None,etb=None,
+                 out=None,tb_offset=None):
+        """Print out a formatted exception traceback.
+
+        Optional arguments:
+          - out: an open file-like object to direct output to.
+
+          - tb_offset: the number of frames to skip over in the stack, on a
+          per-call basis (this overrides temporarily the instance's tb_offset
+          given at initialization time.  """
+        
+        if out is None:
+            out = Term.cerr
+        if tb_offset is not None:
+            tb_offset, self.tb_offset = self.tb_offset, tb_offset
+            print >> out, self.text(etype, evalue, etb)
+            self.tb_offset = tb_offset
+        else:
+            print >> out, self.text()
+        self.debugger()
+
+    def text(self,etype=None,value=None,tb=None,context=5,mode=None):
+        if etype is None:
+            etype,value,tb = sys.exc_info()
+        self.tb = tb
+        return FormattedTB.text(self,etype,value,tb,context=5,mode=mode)
+
+#---------------------------------------------------------------------------
+# A simple class to preserve Nathan's original functionality.
+class ColorTB(FormattedTB):
+    """Shorthand to initialize a FormattedTB in Linux colors mode."""
+    def __init__(self,color_scheme='Linux',call_pdb=0):
+        FormattedTB.__init__(self,color_scheme=color_scheme,
+                             call_pdb=call_pdb)
+
+#----------------------------------------------------------------------------
+# module testing (minimal)
+if __name__ == "__main__":
+    def spam(c, (d, e)):
+        x = c + d
+        y = c * d
+        foo(x, y)
+
+    def foo(a, b, bar=1):
+        eggs(a, b + bar)
+
+    def eggs(f, g, z=globals()):
+        h = f + g
+        i = f - g
+        return h / i
+
+    print ''
+    print '*** Before ***'
+    try:
+        print spam(1, (2, 3))
+    except:
+        traceback.print_exc()
+    print ''
+    
+    handler = ColorTB()
+    print '*** ColorTB ***'
+    try:
+        print spam(1, (2, 3))
+    except:
+        apply(handler, sys.exc_info() )
+    print ''
+    
+    handler = VerboseTB()
+    print '*** VerboseTB ***'
+    try:
+        print spam(1, (2, 3))
+    except:
+        apply(handler, sys.exc_info() )
+    print ''
+    
diff --git a/IPython/usage.py b/IPython/usage.py
new file mode 100644
index 0000000..495fef8
--- /dev/null
+++ b/IPython/usage.py
@@ -0,0 +1,586 @@
+# -*- coding: utf-8 -*-
+#*****************************************************************************
+#       Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
+#
+#  Distributed under the terms of the BSD License.  The full license is in
+#  the file COPYING, distributed as part of this software.
+#*****************************************************************************
+
+# $Id: usage.py 578 2005-05-13 21:16:51Z fperez $
+
+from IPython import Release
+__author__  = '%s <%s>' % Release.authors['Fernando']
+__license__ = Release.license
+__version__ = Release.version
+
+__doc__ = """
+IPython -- An enhanced Interactive Python
+=========================================
+
+A Python shell with automatic history (input and output), dynamic object
+introspection, easier configuration, command completion, access to the system
+shell and more.
+
+IPython can also be embedded in running programs. See EMBEDDING below.
+
+
+USAGE
+       ipython [options] files
+
+       If invoked with no options, it executes all the files listed in
+       sequence and drops you into the interpreter while still acknowledging
+       any options you may have set in your ipythonrc file. This behavior is
+       different from standard Python, which when called as python -i will
+       only execute one file and will ignore your configuration setup.
+
+       Please note that some of the configuration options are not available at
+       the command line, simply because they are not practical here. Look into
+       your ipythonrc configuration file for details on those. This file
+       typically installed in the $HOME/.ipython directory.
+
+       For Windows users, $HOME resolves to C:\\Documents and
+       Settings\\YourUserName in most instances, and _ipython is used instead
+       of .ipython, since some Win32 programs have problems with dotted names
+       in directories.
+
+       In the rest of this text, we will refer to this directory as
+       IPYTHONDIR.
+
+
+SPECIAL THREADING OPTIONS
+       The following special options are ONLY valid at the  beginning  of  the
+       command line, and not later.  This is because they control the initial-
+       ization of ipython itself, before the normal option-handling  mechanism
+       is active.
+
+       -gthread, -qthread, -wthread, -pylab
+
+              Only ONE of these can be given, and it can only be given as the
+              first option passed to IPython (it will have no effect in any
+              other position).  They provide threading support for the GTK, QT
+              and WXWidgets toolkits, and for the matplotlib library.
+
+              With any of the first three options, IPython starts running a
+              separate thread for the graphical toolkit's operation, so that
+              you can open and control graphical elements from within an
+              IPython command line, without blocking.  All three provide
+              essentially the same functionality, respectively for GTK, QT and
+              WXWidgets (via their Python interfaces).
+
+              If -pylab is given, IPython loads special support for the mat-
+              plotlib library (http://matplotlib.sourceforge.net), allowing
+              interactive usage of any of its backends as defined in the
+              user's .matplotlibrc file.  It automatically activates GTK, QT
+              or WX threading for IPyhton if the choice of matplotlib backend
+              requires it.  It also modifies the %run command to correctly
+              execute (without blocking) any matplotlib-based script which
+              calls show() at the end.
+
+       -tk    The -g/q/wthread options, and -pylab (if matplotlib is
+              configured to use GTK, QT or WX), will normally block Tk
+              graphical interfaces.  This means that when GTK, QT or WX
+              threading is active, any attempt to open a Tk GUI will result in
+              a dead window, and possibly cause the Python interpreter to
+              crash.  An extra option, -tk, is available to address this
+              issue.  It can ONLY be given as a SECOND option after any of the
+              above (-gthread, -qthread, -wthread or -pylab).
+
+              If -tk is given, IPython will try to coordinate Tk threading
+              with GTK, QT or WX.  This is however potentially unreliable, and
+              you will have to test on your platform and Python configuration
+              to determine whether it works for you.  Debian users have
+              reported success, apparently due to the fact that Debian builds
+              all of Tcl, Tk, Tkinter and Python with pthreads support.  Under
+              other Linux environments (such as Fedora Core 2/3), this option
+              has caused random crashes and lockups of the Python interpreter.
+              Under other operating systems (Mac OSX and Windows), you'll need
+              to try it to find out, since currently no user reports are
+              available.
+
+              There is unfortunately no way for IPython to determine  at  run-
+              time  whether -tk will work reliably or not, so you will need to
+              do some experiments before relying on it for regular work.
+
+A WARNING ABOUT SIGNALS AND THREADS
+
+       When any of the thread systems (GTK, QT or WX) are active, either
+       directly or via -pylab with a threaded backend, it is impossible to
+       interrupt long-running Python code via Ctrl-C.  IPython can not pass
+       the KeyboardInterrupt exception (or the underlying SIGINT) across
+       threads, so any long-running process started from IPython will run to
+       completion, or will have to be killed via an external (OS-based)
+       mechanism.
+
+       To the best of my knowledge, this limitation is imposed by the Python
+       interpreter itself, and it comes from the difficulty of writing
+       portable signal/threaded code.  If any user is an expert on this topic
+       and can suggest a better solution, I would love to hear about it.  In
+       the IPython sources, look at the Shell.py module, and in particular at
+       the runcode() method.
+
+REGULAR OPTIONS
+       After the above threading options have been given, regular options  can
+       follow  in any order.  All options can be abbreviated to their shortest
+       non-ambiguous form and are case-sensitive.  One or two  dashes  can  be
+       used.   Some options have an alternate short form, indicated after a |.
+
+       Most options can also be set from your  ipythonrc  configuration  file.
+       See the provided examples for assistance.  Options given on the comman-
+       dline override the values set in the ipythonrc file.
+
+       All options with a no| prepended can be specified in ’no’ form  (-noop-
+       tion instead of -option) to turn the feature off.
+
+       -h, --help
+              Show summary of options.
+
+       -pylab This can only be given as the first option passed to IPython (it
+              will have no effect in any other position). It adds special sup-
+              port   for  the  matplotlib  library  (http://matplotlib.source-
+              forge.net), allowing interactive usage of any of its backends as
+              defined  in  the  user’s  .matplotlibrc  file.  It automatically
+              activates GTK or WX threading for IPyhton if the choice of  mat-
+              plotlib  backend requires it.  It also modifies the @run command
+              to correctly execute  (without  blocking)  any  matplotlib-based
+              script which calls show() at the end.
+
+       -no|autocall
+              Make  IPython automatically call any callable object even if you
+              didn’t type explicit parentheses. For example, ’str 43’  becomes
+              ’str(43)’ automatically.
+
+       -no|autoindent
+              Turn automatic indentation on/off.
+
+       -no|automagic
+              Make magic commands automatic (without needing their first char-
+              acter to be @).  Type @magic at  the  IPython  prompt  for  more
+              information.
+
+       -no|autoparens
+              Make  IPython automatically call any callable object even if you
+              didn’t type explicit parentheses.  For example, ’str 43’ becomes
+              ’str(43)’ automatically.
+
+       -no|banner
+              Print the intial information banner (default on).
+
+       -c <command>
+              Execute  the  given  command  string, and set sys.argv to [’c’].
+              This is similar to the -c option in  the  normal  Python  inter-
+              preter.
+
+       -cache_size|cs <n>
+              Size  of  the output cache (maximum number of entries to hold in
+              memory).  The default is 1000, you can change it permanently  in
+              your  config  file.   Setting  it  to  0 completely disables the
+              caching system, and the minimum value accepted  is  20  (if  you
+              provide  a value less than 20, it is reset to 0 and a warning is
+              issued).  This limit is defined because otherwise  you’ll  spend
+              more time re-flushing a too small cache than working.
+
+       -classic|cl
+              Gives IPython a similar feel to the classic Python prompt.
+
+       -colors <scheme>
+              Color  scheme  for  prompts  and exception reporting.  Currently
+              implemented: NoColor, Linux, and LightBG.
+
+       -no|color_info
+              IPython can display information about objects via a set of func-
+              tions, and optionally can use colors for this, syntax highlight-
+              ing source code and various other  elements.   However,  because
+              this  information  is  passed  through a pager (like ’less’) and
+              many pagers get confused with color codes, this option is off by
+              default.   You  can  test  it and turn it on permanently in your
+              ipythonrc file if it works for you.  As a reference, the  ’less’
+              pager  supplied  with  Mandrake 8.2 works ok, but that in RedHat
+              7.2 doesn’t.
+
+              Test it and turn it on permanently if it works with your system.
+              The  magic function @color_info allows you to toggle this inter-
+              actively for testing.
+
+       -no|confirm_exit
+              Set to confirm when you try to exit IPython with  an  EOF  (Con-
+              trol-D in Unix, Control-Z/Enter in Windows). Note that using the
+              magic functions @Exit or @Quit you  can  force  a  direct  exit,
+              bypassing any confirmation.
+
+       -no|debug
+              Show  information  about the loading process. Very useful to pin
+              down problems with your configuration files or  to  get  details
+              about session restores.
+
+       -no|deep_reload
+              IPython  can use the deep_reload module which reloads changes in
+              modules recursively (it replaces the reload() function,  so  you
+              don’t need to change anything to use it). deep_reload() forces a
+              full reload of modules whose code may have  changed,  which  the
+              default reload() function does not.
+
+              When  deep_reload  is off, IPython will use the normal reload(),
+              but deep_reload will still be available as dreload(). This  fea-
+              ture  is  off  by default [which means that you have both normal
+              reload() and dreload()].
+
+       -editor <name>
+              Which editor to use with the @edit command. By default,  IPython
+              will  honor  your EDITOR environment variable (if not set, vi is
+              the Unix default and notepad the Windows one). Since this editor
+              is  invoked on the fly by IPython and is meant for editing small
+              code snippets, you may want to use a small,  lightweight  editor
+              here (in case your default EDITOR is something like Emacs).
+
+       -ipythondir <name>
+              The  name  of  your  IPython configuration directory IPYTHONDIR.
+              This can also be  specified  through  the  environment  variable
+              IPYTHONDIR.
+
+       -log|l Generate  a log file of all input. The file is named ipython.log
+              in your current directory (which  prevents  logs  from  multiple
+              IPython sessions from trampling each other). You can use this to
+              later restore a session by loading your logfile as a file to  be
+              executed with option -logplay (see below).
+
+       -logfile|lf
+              Specifu the name of your logfile.
+
+       -logplay|lp
+              Replay  a previous log. For restoring a session as close as pos-
+              sible to the state you left it in, use this option  (don’t  just
+              run the logfile). With -logplay, IPython will try to reconstruct
+              the previous working environment in full, not just  execute  the
+              commands in the logfile.
+              When  a  session is restored, logging is automatically turned on
+              again with the name of the logfile it was invoked  with  (it  is
+              read  from the log header). So once you’ve turned logging on for
+              a session, you can quit IPython and reload it as many  times  as
+              you  want  and  it  will continue to log its history and restore
+              from the beginning every time.
+
+              Caveats: there are limitations in this option. The history vari-
+              ables  _i*,_* and _dh don’t get restored properly. In the future
+              we will try to implement full  session  saving  by  writing  and
+              retrieving  a failed because of inherent limitations of Python’s
+              Pickle module, so this may have to wait.
+
+       -no|messages
+              Print messages which IPython collects about its startup  process
+              (default on).
+
+       -no|pdb
+              Automatically  call the pdb debugger after every uncaught excep-
+              tion. If you are used to debugging  using  pdb,  this  puts  you
+              automatically  inside of it after any call (either in IPython or
+              in code called by it) which triggers  an  exception  which  goes
+              uncaught.
+
+       -no|pprint
+              IPython  can  optionally  use the pprint (pretty printer) module
+              for displaying results. pprint tends to give a nicer display  of
+              nested  data structures. If you like it, you can turn it on per-
+              manently in your config file (default off).
+
+       -profile|p <name>
+              Assume that your config file is ipythonrc-<name> (looks in  cur-
+              rent dir first, then in IPYTHONDIR). This is a quick way to keep
+              and load multiple config files for different  tasks,  especially
+              if  you  use  the include option of config files. You can keep a
+              basic IPYTHONDIR/ipythonrc file and then have  other  ’profiles’
+              which  include  this  one  and  load extra things for particular
+              tasks. For example:
+
+              1) $HOME/.ipython/ipythonrc : load basic things you always want.
+              2)  $HOME/.ipython/ipythonrc-math  :  load  (1)  and basic math-
+              related modules.
+              3) $HOME/.ipython/ipythonrc-numeric : load (1) and  Numeric  and
+              plotting modules.
+
+              Since  it is possible to create an endless loop by having circu-
+              lar file inclusions, IPython will stop if it reaches  15  recur-
+              sive inclusions.
+
+       -prompt_in1|pi1 <string>
+              Specify  the string used for input prompts. Note that if you are
+              using numbered prompts, the number is represented with a ’\#’ in
+              the  string.  Don’t forget to quote strings with spaces embedded
+              in them. Default: ’In [\#]:’.
+
+              Most bash-like  escapes  can  be  used  to  customize  IPython’s
+              prompts, as well as a few additional ones which are IPython-spe-
+              cific.  All valid prompt escapes are described in detail in  the
+              Customization section of the IPython HTML/PDF manual.
+
+       -prompt_in2|pi2 <string>
+              Similar  to  the  previous option, but used for the continuation
+              prompts. The special sequence ’\D’ is similar to ’\#’, but  with
+              all  digits  replaced  dots  (so  you can have your continuation
+              prompt aligned with your  input  prompt).  Default:  ’    .\D.:’
+              (note three spaces at the start for alignment with ’In [\#]’).
+
+       -prompt_out|po <string>
+              String   used   for  output  prompts,  also  uses  numbers  like
+              prompt_in1.  Default: ’Out[\#]:’.
+
+       -quick Start in bare bones mode (no config file loaded).
+
+       -rcfile <name>
+              Name of your  IPython  resource  configuration  file.   normally
+              IPython    loads   ipythonrc   (from   current   directory)   or
+              IPYTHONDIR/ipythonrc.  If the loading of your config file fails,
+              IPython  starts  with  a  bare  bones  configuration (no modules
+              loaded at all).
+
+       -no|readline
+              Use the readline library, which is needed to support  name  com-
+              pletion  and  command history, among other things. It is enabled
+              by default, but may cause  problems  for  users  of  X/Emacs  in
+              Python comint or shell buffers.
+
+              Note  that  emacs ’eterm’ buffers (opened with M-x term) support
+              IPython’s readline and syntax coloring fine, only  ’emacs’  (M-x
+              shell and C-c !)  buffers do not.
+
+       -screen_length|sl <n>
+              Number  of lines of your screen.  This is used to control print-
+              ing of very long strings.  Strings longer than  this  number  of
+              lines  will be sent through a pager instead of directly printed.
+
+              The default value for this is 0, which means IPython will  auto-
+              detect  your  screen  size  every time it needs to print certain
+              potentially long strings (this doesn’t change  the  behavior  of
+              the  ’print’  keyword,  it’s  only triggered internally). If for
+              some reason this isn’t working well (it needs  curses  support),
+              specify it yourself. Otherwise don’t change the default.
+
+       -separate_in|si <string>
+              Separator before input prompts.  Default ’0.
+
+       -separate_out|so <string>
+              Separator before output prompts.  Default: 0 (nothing).
+
+       -separate_out2|so2 <string>
+              Separator after output prompts.  Default: 0 (nothing).
+
+       -nosep Shorthand for ’-separate_in 0 -separate_out 0 -separate_out2 0’.
+              Simply removes all input/output separators.
+
+       -upgrade
+              Allows you to upgrade your  IPYTHONDIR  configuration  when  you
+              install  a  new  version  of  IPython.   Since  new versions may
+              include new command lines options or example files, this  copies
+              updated ipythonrc-type files.  However, it backs up (with a .old
+              extension) all files which it overwrites so that you  can  merge
+              back any custimizations you might have in your personal files.
+
+       -Version
+              Print version information and exit.
+
+       -xmode <modename>
+              Mode  for  exception reporting.  The valid modes are Plain, Con-
+              text, and Verbose.
+
+              - Plain: similar to python’s normal traceback printing.
+
+              - Context: prints 5 lines of context  source  code  around  each
+              line in the traceback.
+
+              - Verbose: similar to Context, but additionally prints the vari-
+              ables currently visible where the exception happened (shortening
+              their  strings if too long).  This can potentially be very slow,
+              if you happen to have a huge data structure whose string  repre-
+              sentation  is  complex  to compute.  Your computer may appear to
+              freeze for a while with cpu usage at 100%.  If this occurs,  you
+              can cancel the traceback with Ctrl-C (maybe hitting it more than
+              once).
+
+
+EMBEDDING
+       It is possible to start an IPython instance inside your own Python pro-
+       grams.  In the documentation example files there are some illustrations
+       on how to do this.
+
+       This feature allows you to evalutate  dynamically  the  state  of  your
+       code,  operate  with  your  variables, analyze them, etc.  Note however
+       that any changes you make to values while in the shell do NOT propagate
+       back  to  the running code, so it is safe to modify your values because
+       you won’t break your code in bizarre ways by doing so.
+"""
+
+cmd_line_usage = __doc__
+
+#---------------------------------------------------------------------------
+interactive_usage = """
+IPython -- An enhanced Interactive Python
+=========================================
+
+IPython offers a combination of convenient shell features, special commands
+and a history mechanism for both input (command history) and output (results
+caching, similar to Mathematica). It is intended to be a fully compatible
+replacement for the standard Python interpreter, while offering vastly
+improved functionality and flexibility.
+
+At your system command line, type 'ipython -help' to see the command line
+options available. This document only describes interactive features.
+
+Warning: IPython relies on the existence of a global variable called __IP which
+controls the shell itself. If you redefine __IP to anything, bizarre behavior
+will quickly occur.
+
+MAIN FEATURES
+
+* Access to the standard Python help. As of Python 2.1, a help system is
+  available with access to object docstrings and the Python manuals. Simply
+  type 'help' (no quotes) to access it.
+
+* Magic commands: type %magic for information on the magic subsystem.
+
+* System command aliases, via the %alias command or the ipythonrc config file.
+
+* Dynamic object information:
+
+  Typing ?word or word? prints detailed information about an object.  If
+  certain strings in the object are too long (docstrings, code, etc.) they get
+  snipped in the center for brevity.
+
+  Typing ??word or word?? gives access to the full information without
+  snipping long strings. Long strings are sent to the screen through the less
+  pager if longer than the screen, printed otherwise.
+
+  The ?/?? system gives access to the full source code for any object (if
+  available), shows function prototypes and other useful information.
+
+  If you just want to see an object's docstring, type '%pdoc object' (without
+  quotes, and without % if you have automagic on).
+
+  Both %pdoc and ?/?? give you access to documentation even on things which are
+  not explicitely defined. Try for example typing {}.get? or after import os,
+  type os.path.abspath??. The magic functions %pdef, %source and %file operate
+  similarly.
+
+* Completion in the local namespace, by typing TAB at the prompt.
+
+  At any time, hitting tab will complete any available python commands or
+  variable names, and show you a list of the possible completions if there's
+  no unambiguous one. It will also complete filenames in the current directory.
+
+  This feature requires the readline and rlcomplete modules, so it won't work
+  if your Python lacks readline support (such as under Windows).
+
+* Search previous command history in two ways (also requires readline):
+
+  - Start typing, and then use Ctrl-p (previous,up) and Ctrl-n (next,down) to
+  search through only the history items that match what you've typed so
+  far. If you use Ctrl-p/Ctrl-n at a blank prompt, they just behave like
+  normal arrow keys.
+
+  - Hit Ctrl-r: opens a search prompt. Begin typing and the system searches
+  your history for lines that match what you've typed so far, completing as
+  much as it can.
+
+* Persistent command history across sessions (readline required).
+
+* Logging of input with the ability to save and restore a working session.
+  
+* System escape with !. Typing !ls will run 'ls' in the current directory.
+
+* The reload command does a 'deep' reload of a module: changes made to the
+  module since you imported will actually be available without having to exit.
+
+* Verbose and colored exception traceback printouts. See the magic xmode and
+  xcolor functions for details (just type %magic).
+
+* Input caching system:
+
+  IPython offers numbered prompts (In/Out) with input and output caching. All
+  input is saved and can be retrieved as variables (besides the usual arrow
+  key recall).
+
+  The following GLOBAL variables always exist (so don't overwrite them!):
+  _i: stores previous input.
+  _ii: next previous.
+  _iii: next-next previous.
+  _ih : a list of all input _ih[n] is the input from line n.
+
+  Additionally, global variables named _i<n> are dynamically created (<n>
+  being the prompt counter), such that _i<n> == _ih[<n>]
+
+  For example, what you typed at prompt 14 is available as _i14 and _ih[14].
+
+  You can create macros which contain multiple input lines from this history,
+  for later re-execution, with the %macro function.
+
+  The history function %hist allows you to see any part of your input history
+  by printing a range of the _i variables. Note that inputs which contain
+  magic functions (%) appear in the history with a prepended comment. This is
+  because they aren't really valid Python code, so you can't exec them.
+
+* Output caching system:
+
+  For output that is returned from actions, a system similar to the input
+  cache exists but using _ instead of _i. Only actions that produce a result
+  (NOT assignments, for example) are cached. If you are familiar with
+  Mathematica, IPython's _ variables behave exactly like Mathematica's %
+  variables.
+
+  The following GLOBAL variables always exist (so don't overwrite them!):
+  _ (one underscore): previous output.
+  __ (two underscores): next previous.
+  ___ (three underscores): next-next previous.
+
+  Global variables named _<n> are dynamically created (<n> being the prompt
+  counter), such that the result of output <n> is always available as _<n>.
+
+  Finally, a global dictionary named _oh exists with entries for all lines
+  which generated output.
+
+* Directory history:
+
+  Your history of visited directories is kept in the global list _dh, and the
+  magic %cd command can be used to go to any entry in that list.
+
+* Auto-parentheses and auto-quotes (adapted from Nathan Gray's LazyPython)
+
+    1. Auto-parentheses
+        Callable objects (i.e. functions, methods, etc) can be invoked like
+        this (notice the commas between the arguments):
+            >>> callable_ob arg1, arg2, arg3
+        and the input will be translated to this:
+            --> callable_ob(arg1, arg2, arg3)
+        You can force auto-parentheses by using '/' as the first character
+        of a line.  For example:
+            >>> /globals             # becomes 'globals()'
+        Note that the '/' MUST be the first character on the line!  This
+        won't work:
+            >>> print /globals    # syntax error
+            
+        In most cases the automatic algorithm should work, so you should
+        rarely need to explicitly invoke /. One notable exception is if you
+        are trying to call a function with a list of tuples as arguments (the
+        parenthesis will confuse IPython):
+            In [1]: zip (1,2,3),(4,5,6)  # won't work
+        but this will work:
+            In [2]: /zip (1,2,3),(4,5,6)
+            ------> zip ((1,2,3),(4,5,6))
+            Out[2]= [(1, 4), (2, 5), (3, 6)]        
+
+        IPython tells you that it has altered your command line by
+        displaying the new command line preceded by -->.  e.g.:
+            In [18]: callable list
+            -------> callable (list) 
+
+    2. Auto-Quoting
+        You can force auto-quoting of a function's arguments by using ',' as
+        the first character of a line.  For example:
+            >>> ,my_function /home/me   # becomes my_function("/home/me")
+
+        If you use ';' instead, the whole argument is quoted as a single
+        string (while ',' splits on whitespace):
+            >>> ,my_function a b c   # becomes my_function("a","b","c")
+            >>> ;my_function a b c   # becomes my_function("a b c")
+
+        Note that the ',' MUST be the first character on the line!  This
+        won't work:
+            >>> x = ,my_function /home/me    # syntax error
+"""
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..745ee70
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,29 @@
+include README_Windows.txt
+include win32_manual_post_install.py
+
+graft scripts
+
+graft setupext
+
+graft IPython/UserConfig
+
+graft doc
+exclude doc/*.1
+exclude doc/*.lyx
+exclude doc/ChangeLog.*
+exclude doc/#*
+exclude doc/magic.tex
+exclude doc/update_magic.sh
+exclude doc/update_version.sh
+exclude doc/manual_base*
+exclude doc/manual/WARNINGS
+exclude doc/manual/*.aux
+exclude doc/manual/*.log
+exclude doc/manual/*.out
+exclude doc/manual/*.pl
+exclude doc/manual/*.tex
+
+global-exclude *~
+global-exclude *.flc
+global-exclude *.pyc
+global-exclude .dircopy.log
diff --git a/README b/README
new file mode 100644
index 0000000..3cfe159
--- /dev/null
+++ b/README
@@ -0,0 +1,12 @@
+Please see the doc/ directory for full manuals and other documents. The manual is
+prepared using the LyX system (www.lyx.org), but in the doc/manual directory
+you'll find HTML and PDF versions.
+
+These manuals normally get installed to $PREFIX/share/doc/ipython-VERSION, unless you
+redirect the installer via a --prefix/--home option.  Normally, $PREFIX is
+/usr, but your Python may be installed elsewhere.  You can see its value by
+running:
+
+python -c "import sys;print sys.prefix"
+
+# testing notes...
diff --git a/README_Windows.txt b/README_Windows.txt
new file mode 100644
index 0000000..b69bfce
--- /dev/null
+++ b/README_Windows.txt
@@ -0,0 +1,42 @@
+Notes for Windows Users
+=======================
+
+These are just minimal notes.  The manual contains more detailed
+information.
+
+Requirements
+------------
+
+IPython runs under (as far as the Windows family is concerned):
+
+- Windows XP (I think WinNT/2000 are ok): works well.  It needs:
+
+  * PyWin32, the win32 Python extensions from
+    http://starship.python.net/crew/mhammond.
+
+  * Gary Bishop's readline from 
+    http://sourceforge.net/projects/uncpythontools.
+    
+  * This in turn requires Tomas Heller's ctypes from
+    http://starship.python.net/crew/theller/ctypes.
+
+- Windows 95/98/ME: I have no idea. It should work, but I can't test.
+
+- CygWin environments should work, they are basically Posix.
+
+It needs Python 2.2 or newer.
+
+
+Installation
+------------
+
+Double-click the supplied .exe installer file.  If all goes well, that's all
+you need to do. You should now have an IPython entry in your Start Menu.
+
+In case the automatic installer does not work for some reason, you can
+download the ipython-XXX.tar.gz file, which contains the full IPython source
+distribution (the popular WinZip can read .tar.gz files). After uncompressing
+the archive, you can install it at a command terminal just like any other
+Python module, by using python setup.py install'. After this completes, you
+can run the supplied win32_manual_post_install.py script which will add
+the relevant shortcuts to your startup menu.
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000..a5d262d
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,70 @@
+ipython (0.6.4-1) unstable; urgency=low
+
+  * Fix dpatch dependency (Closes: #280505)
+
+ -- Fernando Perez <fperez@colorado.edu> Wed Nov 17 22:54:23 MST 2004
+
+ipython (0.6.3-1) unstable; urgency=low
+
+  * New upstream release (Closes: #262244, #252525)
+
+ -- Jack Moffitt <jack@xiph.org>  Wed, 22 Sep 2004 21:39:38 -0600
+
+ipython (0.6.0-1) unstable; urgency=low
+
+  * New upstream release
+
+ -- Jack Moffitt <jack@xiph.org>  Sun,  9 May 2004 17:38:00 +0200
+
+ipython (0.4.0-1.1) unstable; urgency=low
+
+  * Non maintainer upload with maintainer consensus.
+  * Updated buil-dep to depend on python-2.3 (Closes: #206653)
+  * Included encoding comment string in modules under IPython to 
+    avoid python2.3 Warnigs (upstream noticed).
+
+ -- Marco Presi (Zufus) <zufus@debian.org>  Mon, 25 Aug 2003 19:02:20 +0200
+
+ipython (0.4.0-1) unstable; urgency=low
+
+  * New upstream release (Closes #195215)
+  * Updated Build-Depends (Closes #200021)
+
+ -- Jack Moffitt <jack@xiph.org>  Fri, 25 Jul 2003 10:16:12 -0600
+
+ipython (0.2.15pre3-4) unstable; urgency=low
+
+  * Add python-dev Build-Depends (Closes: #189901)
+
+ -- Jack Moffitt <jack@babyjesus.cantcode.com>  Mon, 12 May 2003 23:33:43 -0600
+
+ipython (0.2.15pre3-3) unstable; urgency=low
+
+  * Fix for accidently converting home directory files' line ends
+    instead of just the appropriate ipython configuration files
+    (Closes: #189042)
+
+ -- Jack Moffitt <jack@xiph.org>  Mon, 14 Apr 2003 21:18:18 -0600
+
+ipython (0.2.15pre3-2) unstable; urgency=low
+
+  * Added text of the PSF license to debian/copyright.
+
+ -- Jack Moffitt <jack@xiph.org>  Sat,  5 Apr 2003 11:41:31 -0700
+
+ipython (0.2.15pre3-1) unstable; urgency=low
+
+  * Updated documentation to point to the new homepage -
+    http://ipython.scipy.org
+  * Removed doc/COPYING and doc/GNU-LGPL to fix lintian warnings
+  * Public release ready (Closes: #185789)
+
+ -- Jack Moffitt <jack@xiph.org>  Tue,  1 Apr 2003 20:53:31 -0700
+
+ipython (0.2.15pre3-0a) unstable; urgency=low
+
+  * Initial Release.
+  * This is my first Debian package
+
+ -- Jack Moffitt <jack@xiph.org>  Wed, 12 Mar 2003 21:04:22 -0700
+
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 0000000..b8626c4
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+4
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000..86a2d96
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,21 @@
+Source: ipython
+Section: devel
+Priority: optional
+Maintainer: Jack Moffitt <jack@xiph.org>
+Build-Depends-Indep: debhelper (>> 4.1.65), dpatch, python-dev
+Standards-Version: 3.6.1
+
+Package: ipython
+Architecture: all
+Depends: ${python:Depends}
+Recommends: python-numeric, python-numeric-ext
+Description: An enhanced interactive Python shell
+ IPython is an enhanced interactive Python shell.  It can be used as a
+ replacement for the standard Python shell, or it can be used as a
+ complete working environment for scientific computing (like Matlab or
+ Mathematica) when paired with the standard Python scientific and
+ numerical tools.  It supports dynamic object introspections, numbered
+ input/output prompts, a macro system, session logging, session
+ restoring, complete system shell access, verbose and colored
+ traceback reports, auto-parentheses, auto-quoting, and is
+ embeddedable in other Python programs.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 0000000..01691e5
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,204 @@
+This package was debianized by Jack Moffitt <jack@xiph.org> on
+Wed, 12 Mar 2003 20:38:14 -0700.
+
+It was downloaded from http://ipython.scipy.org/
+
+Upstream Author: Fernando Perez <fperez@colorado.edu>,
+		 Janko Hauser <jhauser@zscout.de>,
+		 Nathaniel Gray <n8gray@caltech.edu>
+
+Copyright:
+
+Most IPython code is copyright (C) 2001-2004 by Fernando Perez, Janko Hauser,
+and Nathaniel Gray.  All code is licensed under a BSD-type License except as
+explicitly mentioned below.  The full IPython license is:
+
+IPython is released under a BSD-type license.
+
+Copyright (c) 2001, 2002, 2003, 2004 Fernando Perez <fperez@colorado.edu>.
+
+Copyright (c) 2001 Janko Hauser <jhauser@zscout.de> and Nathaniel Gray
+<n8gray@caltech.edu>.
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  a. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  b. Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+
+  c. Neither the name of the copyright holders nor the names of any
+     contributors to this software may be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+
+DPyGetOpt.py is copyright (C) 2001 by Bill Bumgarner <bbum@friday.com>
+and is licensed under the MIT license, reproduced below:
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+FlexCompleter.py is copyright (C) 2001 by the Python Software
+Foundation and licensed under the terms of the Python Software
+Foundation License, reproduced below:
+
+A. HISTORY OF THE SOFTWARE
+==========================
+
+Python was created in the early 1990s by Guido van Rossum at Stichting
+Mathematisch Centrum (CWI) in the Netherlands as a successor of a
+language called ABC.  Guido is Python's principal author, although it
+includes many contributions from others.  The last version released
+from CWI was Python 1.2.  In 1995, Guido continued his work on Python
+at the Corporation for National Research Initiatives (CNRI) in Reston,
+Virginia where he released several versions of the software.  Python
+1.6 was the last of the versions released by CNRI.  In 2000, Guido and
+the Python core development team moved to BeOpen.com to form the
+BeOpen PythonLabs team.  Python 2.0 was the first and only release
+from BeOpen.com.
+
+Following the release of Python 1.6, and after Guido van Rossum left
+CNRI to work with commercial software developers, it became clear that
+the ability to use Python with software available under the GNU Public
+License (GPL) was very desirable.  CNRI and the Free Software
+Foundation (FSF) interacted to develop enabling wording changes to the
+Python license.  Python 1.6.1 is essentially the same as Python 1.6,
+with a few minor bug fixes, and with a different license that enables
+later versions to be GPL-compatible.  Python 2.1 is a derivative work
+of Python 1.6.1, as well as of Python 2.0.
+
+After Python 2.0 was released by BeOpen.com, Guido van Rossum and the
+other PythonLabs developers joined Digital Creations.  All
+intellectual property added from this point on, starting with Python
+2.1 and its alpha and beta releases, is owned by the Python Software
+Foundation (PSF), a non-profit modeled after the Apache Software
+Foundation.  See http://www.python.org/psf/ for more information about
+the PSF.
+
+Thanks to the many outside volunteers who have worked under Guido's
+direction to make these releases possible.
+
+
+B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
+===============================================================
+
+PSF LICENSE AGREEMENT
+---------------------
+
+1. This LICENSE AGREEMENT is between the Python Software Foundation
+("PSF"), and the Individual or Organization ("Licensee") accessing and
+otherwise using Python 2.1 software in source or binary form and its
+associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, PSF
+hereby grants Licensee a nonexclusive, royalty-free, world-wide
+license to reproduce, analyze, test, perform and/or display publicly,
+prepare derivative works, distribute, and otherwise use Python 2.1
+alone or in any derivative version, provided, however, that PSF's
+License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
+2001 Python Software Foundation; All Rights Reserved" are retained in
+Python 2.1 alone or in any derivative version prepared by Licensee.
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python 2.1 or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python 2.1.
+
+4. PSF is making Python 2.1 available to Licensee on an "AS IS"
+basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.1 WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+2.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A
+RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.1, OR
+ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. This License Agreement shall be governed by the federal
+intellectual property law of the United States, including without
+limitation the federal copyright law, and, to the extent such
+U.S. federal law does not apply, by the law of the Commonwealth of
+Virginia, excluding Virginia's conflict of law provisions.
+Notwithstanding the foregoing, with regard to derivative works based
+on Python 1.6.1 that incorporate non-separable material that was
+previously distributed under the GNU General Public License (GPL), the
+law of the Commonwealth of Virginia shall govern this License
+Agreement only as to issues arising under or with respect to
+Paragraphs 4, 5, and 7 of this License Agreement.  Nothing in this
+License Agreement shall be deemed to create any relationship of
+agency, partnership, or joint venture between CNRI and Licensee.  This
+License Agreement does not grant permission to use CNRI trademarks or
+trade name in a trademark sense to endorse or promote products or
+services of Licensee, or any third party.
+
+8. By clicking on the "ACCEPT" button where indicated, or by copying,
+installing or otherwise using Python 1.6.1, Licensee agrees to be
+bound by the terms and conditions of this License Agreement.
+
+        ACCEPT
+
+
+CWI PERMISSIONS STATEMENT AND DISCLAIMER
+----------------------------------------
+
+Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
+The Netherlands.  All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+Itpl.py is copyright (C) 2001 Ka-Ping Yee <ping@lfw.org> and licensed
+under the MIT license reproduced above.
diff --git a/debian/ipython.doc-base b/debian/ipython.doc-base
new file mode 100644
index 0000000..ddb97e9
--- /dev/null
+++ b/debian/ipython.doc-base
@@ -0,0 +1,14 @@
+Document: ipython
+Title: IPython Manual
+Author: Fernando Perez <fperez@colorado.edu>
+Abstract: Full documentation on all features of IPython.
+Section: devel
+
+Format: pdf
+Files: /usr/share/doc/ipython/ipython.pdf
+
+Format: HTML
+Index: /usr/share/doc/ipython/manual/index.html
+Files: /usr/share/doc/ipython/manual/*.html
+
+  
diff --git a/debian/postinst b/debian/postinst
new file mode 100644
index 0000000..96b2706
--- /dev/null
+++ b/debian/postinst
@@ -0,0 +1,13 @@
+#!/bin/sh
+set -e
+
+OLD_MODDIR=/usr/lib/python2.2/site-packages/IPython
+
+if [ $1 = "configure" ]; then
+    if [ -d $OLD_MODDIR ];then
+	echo "Removing old python2.2 modules"
+	rm -fr $OLD_MODDIR >&2 
+    fi
+fi
+
+#DEBHELPER#
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 0000000..6bb593f
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,98 @@
+#!/usr/bin/make -f
+# Sample debian/rules that uses debhelper.
+# GNU copyright 1997 to 1999 by Joey Hess.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+
+
+
+CFLAGS = -Wall -g
+
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+	CFLAGS += -O0
+else
+	CFLAGS += -O2
+endif
+ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
+	INSTALL_PROGRAM += -s
+endif
+
+configure: configure-stamp
+configure-stamp:
+	dh_testdir
+
+	python setup.py config
+
+	touch configure-stamp
+
+
+build: build-stamp
+
+build-stamp: configure-stamp 
+	dh_testdir
+
+	python setup.py build
+
+	touch build-stamp
+
+clean:
+	dh_testdir
+	dh_testroot
+	rm -f build-stamp configure-stamp
+
+	-python setup.py clean --all
+	rm -f setupext/*.pyc
+
+	dh_clean
+
+install: build
+	dh_testdir
+	dh_testroot
+	dh_clean -k
+	dh_installdirs
+
+	python setup.py install --prefix $(CURDIR)/debian/ipython/usr
+
+	# remove extra license docs that get installed
+	rm -f $(CURDIR)/debian/ipython/usr/share/doc/ipython/COPYING
+	#rm -f $(CURDIR)/debian/ipython/usr/share/doc/ipython/GNU-LGPL
+
+	# change permission on scripts
+	chmod 755 $(CURDIR)/debian/ipython/usr/share/doc/ipython/examples/example-embed.py	
+	chmod 755 $(CURDIR)/debian/ipython/usr/share/doc/ipython/examples/example-gnuplot.py
+
+binary-indep: build install
+	dh_testdir
+	dh_testroot
+	dh_installchangelogs doc/ChangeLog
+	dh_installdocs
+#	dh_installexamples
+	dh_install
+#	dh_installmenu
+#	dh_installdebconf	
+#	dh_installlogrotate
+#	dh_installemacsen
+#	dh_installpam
+#	dh_installmime
+#	dh_installinit
+#	dh_installcron
+#	dh_installinfo
+	dh_installman doc/ipython.1.gz doc/pycolor.1.gz
+	dh_compress
+	dh_fixperms
+	dh_python
+#	dh_makeshlibs
+	dh_installdeb
+#	dh_shlibdeps
+	dh_gencontrol
+	dh_md5sums
+	dh_builddeb
+
+# Build architecture-dependent files here.
+binary-arch: build install
+# We have nothing to do by default.
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
diff --git a/doc/COPYING b/doc/COPYING
new file mode 100644
index 0000000..78bb2f4
--- /dev/null
+++ b/doc/COPYING
@@ -0,0 +1,52 @@
+IPython copyright and licensing notes
+=====================================
+
+Unless indicated otherwise, files in this project are covered by a BSD-type
+license, included below.
+
+Individual authors are the holders of the copyright for their code and are
+listed in each file.
+
+Some files (DPyGetOpt.py, for example) may be licensed under different
+conditions. Ultimately each file indicates clearly the conditions under which
+its author/authors have decided to publish the code.
+
+
+IPython license
+---------------
+
+IPython is released under a BSD-type license.
+
+Copyright (c) 2001, 2002, 2003, 2004 Fernando Perez <fperez@colorado.edu>.
+
+Copyright (c) 2001 Janko Hauser <jhauser@zscout.de> and Nathaniel Gray
+<n8gray@caltech.edu>.
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  a. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  b. Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+
+  c. Neither the name of the copyright holders nor the names of any
+     contributors to this software may be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
diff --git a/doc/ChangeLog b/doc/ChangeLog
new file mode 100644
index 0000000..a77e57f
--- /dev/null
+++ b/doc/ChangeLog
@@ -0,0 +1,4243 @@
+2005-06-08  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (write/write_err): Add methods to abstract all
+	I/O a bit more.
+
+	* IPython/Shell.py (IPShellGTK.mainloop): Fix GTK deprecation
+	warning, reported by Aric Hagberg, fix by JD Hunter.
+
+2005-06-02  *** Released version 0.6.15
+
+2005-06-01  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (MagicCompleter.file_matches): Fix
+	tab-completion of filenames within open-quoted strings.  Note that
+	this requires that in ~/.ipython/ipythonrc, users change the
+	readline delimiters configuration to read:
+
+	readline_remove_delims -/~
+	
+
+2005-05-31  *** Released version 0.6.14
+
+2005-05-29  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ultraTB.py (VerboseTB.text): Fix crash for tracebacks
+	with files not on the filesystem.  Reported by Eliyahu Sandler
+	<eli@gondolin.net>
+
+2005-05-22  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py: Fix a few crashes in the --upgrade option.
+	After an initial report by LUK ShunTim <shuntim.luk@polyu.edu.hk>.
+
+2005-05-19  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (safe_execfile): close a file which could be
+	left open (causing problems in win32, which locks open files).
+	Thanks to a bug report by D Brown <dbrown2@yahoo.com>.
+
+2005-05-18  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Shell.py (MatplotlibShellBase.mplot_exec): pass all
+	keyword arguments correctly to safe_execfile().
+
+2005-05-13  Fernando Perez  <fperez@colorado.edu>
+
+	* ipython.1: Added info about Qt to manpage, and threads warning
+	to usage page (invoked with --help).
+
+	* IPython/iplib.py (MagicCompleter.python_func_kw_matches): Added
+	new matcher (it goes at the end of the priority list) to do
+	tab-completion on named function arguments.  Submitted by George
+	Sakkis <gsakkis-AT-eden.rutgers.edu>.  See the thread at
+	http://www.scipy.net/pipermail/ipython-dev/2005-April/000436.html
+	for more details.
+
+	* IPython/Magic.py (magic_run): Added new -e flag to ignore
+	SystemExit exceptions in the script being run.  Thanks to a report
+	by danny shevitz <danny_shevitz-AT-yahoo.com>, about this
+	producing very annoying behavior when running unit tests.
+
+2005-05-12  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (handle_auto): fixed auto-quoting and parens,
+	which I'd broken (again) due to a changed regexp.  In the process,
+	added ';' as an escape to auto-quote the whole line without
+	splitting its arguments.  Thanks to a report by Jerry McRae
+	<qrs0xyc02-AT-sneakemail.com>.
+
+	* IPython/ultraTB.py (VerboseTB.text): protect against rare but
+	possible crashes caused by a TokenError.  Reported by Ed Schofield
+	<schofield-AT-ftw.at>.
+	
+2005-05-06  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Shell.py (hijack_wx): Fix to work with WX v.2.6.
+
+2005-04-29  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Shell.py (IPShellQt): Thanks to Denis Rivière
+	<nudz-AT-free.fr>, Yann Cointepas <yann-AT-sapetnioc.org> and Benjamin
+	Thyreau <Benji2-AT-decideur.info>, we now have a -qthread option
+	which provides support for Qt interactive usage (similar to the
+	existing one for WX and GTK).  This had been often requested.
+
+2005-04-14  *** Released version 0.6.13
+
+2005-04-08  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic._ofind): remove docstring evaluation
+	from _ofind, which gets called on almost every input line.  Now,
+	we only try to get docstrings if they are actually going to be
+	used (the overhead of fetching unnecessary docstrings can be
+	noticeable for certain objects, such as Pyro proxies).
+
+	* IPython/iplib.py (MagicCompleter.python_matches): Change the API
+	for completers.  For some reason I had been passing them the state
+	variable, which completers never actually need, and was in
+	conflict with the rlcompleter API.  Custom completers ONLY need to
+	take the text parameter.
+
+	* IPython/Extensions/InterpreterExec.py: Fix regexp so that magics
+	work correctly in pysh.  I've also moved all the logic which used
+	to be in pysh.py here, which will prevent problems with future
+	upgrades.  However, this time I must warn users to update their
+	pysh profile to include the line
+
+	import_all IPython.Extensions.InterpreterExec
+
+	because otherwise things won't work for them.  They MUST also
+	delete pysh.py and the line
+
+	execfile pysh.py
+
+	from their ipythonrc-pysh.
+
+	* IPython/FlexCompleter.py (Completer.attr_matches): Make more
+	robust in the face of objects whose dir() returns non-strings
+	(which it shouldn't, but some broken libs like ITK do).  Thanks to
+	a patch by John Hunter (implemented differently, though).  Also
+	minor improvements by using .extend instead of + on lists.
+
+	* pysh.py: 
+
+2005-04-06  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ipmaker.py (make_IPython): Make multi_line_specials on
+	by default, so that all users benefit from it.  Those who don't
+	want it can still turn it off.
+
+	* IPython/UserConfig/ipythonrc: Add multi_line_specials to the
+	config file, I'd forgotten about this, so users were getting it
+	off by default.
+
+	* IPython/iplib.py (ipmagic): big overhaul of the magic system for
+	consistency.  Now magics can be called in multiline statements,
+	and python variables can be expanded in magic calls via $var.
+	This makes the magic system behave just like aliases or !system
+	calls.
+
+2005-03-28  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (handle_auto): cleanup to use %s instead of
+	expensive string additions for building command.  Add support for
+	trailing ';' when autocall is used.
+
+2005-03-26  Fernando Perez  <fperez@colorado.edu>
+
+	* ipython.el: Fix http://www.scipy.net/roundup/ipython/issue31.
+	Bugfix by A. Schmolck, the ipython.el maintainer.  Also make
+	ipython.el robust against prompts with any number of spaces
+	(including 0) after the ':' character.
+
+	* IPython/Prompts.py (Prompt2.set_p_str): Fix spurious space in
+	continuation prompt, which misled users to think the line was
+	already indented.  Closes debian Bug#300847, reported to me by
+	Norbert Tretkowski <tretkowski-AT-inittab.de>.
+
+2005-03-23  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Prompts.py (Prompt1.__str__): Make sure that prompts are
+	properly aligned if they have embedded newlines.
+
+	* IPython/iplib.py (runlines): Add a public method to expose
+	IPython's code execution machinery, so that users can run strings
+	as if they had been typed at the prompt interactively.
+	(InteractiveShell.__init__): Added getoutput() to the __IPYTHON__
+	methods which can call the system shell, but with python variable
+	expansion.  The three such methods are: __IPYTHON__.system,
+	.getoutput and .getoutputerror.  These need to be documented in a
+	'public API' section (to be written) of the manual.
+
+2005-03-20  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.set_custom_exc): new system
+	for custom exception handling.  This is quite powerful, and it
+	allows for user-installable exception handlers which can trap
+	custom exceptions at runtime and treat them separately from
+	IPython's default mechanisms.  At the request of Frédéric
+	Mantegazza <mantegazza-AT-ill.fr>.
+	(InteractiveShell.set_custom_completer): public API function to
+	add new completers at runtime.
+
+2005-03-19  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/OInspect.py (getdoc): Add a call to obj.getdoc(), to
+	allow objects which provide their docstrings via non-standard
+	mechanisms (like Pyro proxies) to still be inspected by ipython's
+	? system.
+
+	* IPython/iplib.py (InteractiveShell.__init__): back off the _o/_e
+	automatic capture system.  I tried quite hard to make it work
+	reliably, and simply failed.  I tried many combinations with the
+	subprocess module, but eventually nothing worked in all needed
+	cases (not blocking stdin for the child, duplicating stdout
+	without blocking, etc).  The new %sc/%sx still do capture to these
+	magical list/string objects which make shell use much more
+	conveninent, so not all is lost.
+
+	XXX - FIX MANUAL for the change above!
+
+	(runsource): I copied code.py's runsource() into ipython to modify
+	it a bit.  Now the code object and source to be executed are
+	stored in ipython.  This makes this info accessible to third-party
+	tools, like custom exception handlers.  After a request by Frédéric
+	Mantegazza <mantegazza-AT-ill.fr>.
+
+	* IPython/UserConfig/ipythonrc: Add up/down arrow keys to
+	history-search via readline (like C-p/C-n).  I'd wanted this for a
+	long time, but only recently found out how to do it.  For users
+	who already have their ipythonrc files made and want this, just
+	add:
+
+	readline_parse_and_bind "\e[A": history-search-backward
+	readline_parse_and_bind "\e[B": history-search-forward
+
+2005-03-18  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (magic_sc): %sc and %sx now use the fancy
+	LSString and SList classes which allow transparent conversions
+	between list mode and whitespace-separated string.
+	(magic_r): Fix recursion problem in %r.
+
+	* IPython/genutils.py (LSString): New class to be used for
+	automatic storage of the results of all alias/system calls in _o
+	and _e (stdout/err).  These provide a .l/.list attribute which
+	does automatic splitting on newlines.  This means that for most
+	uses, you'll never need to do capturing of output with %sc/%sx
+	anymore, since ipython keeps this always done for you.  Note that
+	only the LAST results are stored, the _o/e variables are
+	overwritten on each call.  If you need to save their contents
+	further, simply bind them to any other name.
+
+2005-03-17  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Prompts.py (BasePrompt.cwd_filt): a few more fixes for
+	prompt namespace handling.
+
+2005-03-16  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Prompts.py (CachedOutput.__init__): Fix default and
+	classic prompts to be '>>> ' (final space was missing, and it
+	trips the emacs python mode).
+	(BasePrompt.__str__): Added safe support for dynamic prompt
+	strings.  Now you can set your prompt string to be '$x', and the
+	value of x will be printed from your interactive namespace.  The
+	interpolation syntax includes the full Itpl support, so
+	${foo()+x+bar()} is a valid prompt string now, and the function
+	calls will be made at runtime.
+
+2005-03-15  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (magic_history): renamed %hist to %history, to
+	avoid name clashes in pylab.  %hist still works, it just forwards
+	the call to %history.
+
+2005-03-02  *** Released version 0.6.12
+
+2005-03-02  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (handle_magic): log magic calls properly as
+	ipmagic() function calls.
+
+	* IPython/Magic.py (magic_time): Improved %time to support
+	statements and provide wall-clock as well as CPU time.
+
+2005-02-27  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/hooks.py: New hooks module, to expose user-modifiable
+	IPython functionality in a clean manner.  For now only the editor
+	hook is actually written, and other thigns which I intend to turn
+	into proper hooks aren't yet there.  The display and prefilter
+	stuff, for example, should be hooks.  But at least now the
+	framework is in place, and the rest can be moved here with more
+	time later.  IPython had had a .hooks variable for a long time for
+	this purpose, but I'd never actually used it for anything.
+
+2005-02-26  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ipmaker.py (make_IPython): make the default ipython
+	directory be called _ipython under win32, to follow more the
+	naming peculiarities of that platform (where buggy software like
+	Visual Sourcesafe breaks with .named directories).  Reported by
+	Ville Vainio.
+
+2005-02-23  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.__init__): removed a few
+	auto_aliases for win32 which were causing problems.  Users can
+	define the ones they personally like.
+
+2005-02-21  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (magic_time): new magic to time execution of
+	expressions.  After a request by Charles Moad <cmoad-AT-indiana.edu>.
+
+2005-02-19  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ConfigLoader.py (ConfigLoader.load): Allow empty strings
+	into keys (for prompts, for example).
+
+	* IPython/Prompts.py (BasePrompt.set_p_str): Fix to allow empty
+	prompts in case users want them.  This introduces a small behavior
+	change: ipython does not automatically add a space to all prompts
+	anymore.  To get the old prompts with a space, users should add it
+	manually to their ipythonrc file, so for example prompt_in1 should
+	now read 'In [\#]: ' instead of 'In [\#]:'.
+	(BasePrompt.__init__): New option prompts_pad_left (only in rc
+	file) to control left-padding of secondary prompts.
+
+	* IPython/Magic.py (Magic.profile_missing_notice): Don't crash if
+	the profiler can't be imported.  Fix for Debian, which removed
+	profile.py because of License issues.  I applied a slightly
+	modified version of the original Debian patch at
+	http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=294500.
+
+2005-02-17  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (native_line_ends): Fix bug which would
+	cause improper line-ends under win32 b/c I was not opening files
+	in binary mode.  Bug report and fix thanks to Ville.
+
+	* IPython/iplib.py (handle_auto): Fix bug which I introduced when
+	trying to catch spurious foo[1] autocalls.  My fix actually broke
+	',/' autoquote/call with explicit escape (bad regexp).
+
+2005-02-15  *** Released version 0.6.11
+
+2005-02-14  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/background_jobs.py: New background job management
+	subsystem.  This is implemented via a new set of classes, and
+	IPython now provides a builtin 'jobs' object for background job
+	execution.  A convenience %bg magic serves as a lightweight
+	frontend for starting the more common type of calls.  This was
+	inspired by discussions with B. Granger and the BackgroundCommand
+	class described in the book Python Scripting for Computational
+	Science, by H. P. Langtangen: http://folk.uio.no/hpl/scripting
+	(although ultimately no code from this text was used, as IPython's
+	system is a separate implementation).
+
+	* IPython/iplib.py (MagicCompleter.python_matches): add new option
+	to control the completion of single/double underscore names
+	separately.  As documented in the example ipytonrc file, the
+	readline_omit__names variable can now be set to 2, to omit even
+	single underscore names.  Thanks to a patch by Brian Wong
+	<BrianWong-AT-AirgoNetworks.Com>.
+	(InteractiveShell.__init__): Fix bug which would cause foo[1] to
+	be autocalled as foo([1]) if foo were callable.  A problem for
+	things which are both callable and implement __getitem__.
+	(init_readline): Fix autoindentation for win32.  Thanks to a patch
+	by Vivian De Smedt <vivian-AT-vdesmedt.com>.
+
+2005-02-12  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ipmaker.py (make_IPython): Disabled the stout traps
+	which I had written long ago to sort out user error messages which
+	may occur during startup.  This seemed like a good idea initially,
+	but it has proven a disaster in retrospect.  I don't want to
+	change much code for now, so my fix is to set the internal 'debug'
+	flag to true everywhere, whose only job was precisely to control
+	this subsystem.  This closes issue 28 (as well as avoiding all
+	sorts of strange hangups which occur from time to time).
+
+2005-02-07  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (magic_edit): Fix 'ed -p' not working when the
+	previous call produced a syntax error.
+
+	* IPython/OInspect.py (Inspector.pinfo): Fix crash when inspecting
+	classes without constructor.
+
+2005-02-06  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (MagicCompleter.complete): Extend the list of
+	completions with the results of each matcher, so we return results
+	to the user from all namespaces.  This breaks with ipython
+	tradition, but I think it's a nicer behavior.  Now you get all
+	possible completions listed, from all possible namespaces (python,
+	filesystem, magics...)  After a request by John Hunter
+	<jdhunter-AT-nitace.bsd.uchicago.edu>.
+
+2005-02-05  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (magic_prun): Fix bug where prun would fail if
+	the call had quote characters in it (the quotes were stripped).
+
+2005-01-31  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.__init__): reduce reliance on
+	Itpl.itpl() to make the code more robust against psyco
+	optimizations.
+
+	* IPython/Itpl.py (Itpl.__str__): Use a _getframe() call instead
+	of causing an exception.  Quicker, cleaner.
+
+2005-01-28  Fernando Perez  <fperez@colorado.edu>
+
+	* scripts/ipython_win_post_install.py (install): hardcode
+	sys.prefix+'python.exe' as the executable path.  It turns out that
+	during the post-installation run, sys.executable resolves to the
+	name of the binary installer!  I should report this as a distutils
+	bug, I think.  I updated the .10 release with this tiny fix, to
+	avoid annoying the lists further.
+
+2005-01-27  *** Released version 0.6.10
+
+2005-01-27  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/numutils.py (norm): Added 'inf' as optional name for
+	L-infinity norm, included references to mathworld.com for vector
+	norm definitions.
+	(amin/amax): added amin/amax for array min/max.  Similar to what
+	pylab ships with after the recent reorganization of names.
+	(spike/spike_odd): removed deprecated spike/spike_odd functions.
+
+	* ipython.el: committed Alex's recent fixes and improvements.
+	Tested with python-mode from CVS, and it looks excellent.  Since
+	python-mode hasn't released anything in a while, I'm temporarily
+	putting a copy of today's CVS (v 4.70) of python-mode in:
+	  http://ipython.scipy.org/tmp/python-mode.el
+
+	* scripts/ipython_win_post_install.py (install): Win32 fix to use
+	sys.executable for the executable name, instead of assuming it's
+	called 'python.exe' (the post-installer would have produced broken
+	setups on systems with a differently named python binary).
+
+	* IPython/PyColorize.py (Parser.__call__): change explicit '\n'
+	references to os.linesep, to make the code more
+	platform-independent.  This is also part of the win32 coloring
+	fixes.
+
+	* IPython/genutils.py (page_dumb): Remove attempts to chop long
+	lines, which actually cause coloring bugs because the length of
+	the line is very difficult to correctly compute with embedded
+	escapes.  This was the source of all the coloring problems under
+	Win32.  I think that _finally_, Win32 users have a properly
+	working ipython in all respects.  This would never have happened
+	if not for Gary Bishop and Viktor Ransmayr's great help and work.
+
+2005-01-26  *** Released version 0.6.9
+
+2005-01-25  Fernando Perez  <fperez@colorado.edu>
+
+	* setup.py: finally, we have a true Windows installer, thanks to
+	the excellent work of Viktor Ransmayr
+	<viktor.ransmayr-AT-t-online.de>.  The docs have been updated for
+	Windows users.  The setup routine is quite a bit cleaner thanks to
+	this, and the post-install script uses the proper functions to
+	allow a clean de-installation using the standard Windows Control
+	Panel.
+	
+	* IPython/genutils.py (get_home_dir): changed to use the $HOME
+	environment variable under all OSes (including win32) if
+	available.  This will give consistency to win32 users who have set
+	this variable for any reason.  If os.environ['HOME'] fails, the
+	previous policy of using HOMEDRIVE\HOMEPATH kicks in.
+
+2005-01-24  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/numutils.py (empty_like): add empty_like(), similar to
+	zeros_like() but taking advantage of the new empty() Numeric routine.
+
+2005-01-23  *** Released version 0.6.8
+
+2005-01-22  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Shell.py (MatplotlibShellBase.mplot_exec): I removed the
+	automatic show() calls.  After discussing things with JDH, it
+	turns out there are too many corner cases where this can go wrong.
+	It's best not to try to be 'too smart', and simply have ipython
+	reproduce as much as possible the default behavior of a normal
+	python shell.
+
+	* IPython/iplib.py (InteractiveShell.__init__): Modified the
+	line-splitting regexp and _prefilter() to avoid calling getattr()
+	on assignments.  This closes
+	http://www.scipy.net/roundup/ipython/issue24.  Note that Python's
+	readline uses getattr(), so a simple <TAB> keypress is still
+	enough to trigger getattr() calls on an object.
+
+2005-01-21  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Shell.py (MatplotlibShellBase.magic_run): Fix the %run
+	docstring under pylab so it doesn't mask the original.
+
+2005-01-21  *** Released version 0.6.7
+
+2005-01-21  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Shell.py (MTInteractiveShell.runcode): Trap a crash with
+	signal handling for win32 users in multithreaded mode.
+
+2005-01-17  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/OInspect.py (Inspector.pinfo): Fix crash when inspecting
+	instances with no __init__.  After a crash report by Norbert Nemec
+	<Norbert-AT-nemec-online.de>.
+
+2005-01-14  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ultraTB.py (VerboseTB.text): Fix bug in reporting of
+	names for verbose exceptions, when multiple dotted names and the
+	'parent' object were present on the same line.
+
+2005-01-11  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (flag_calls): new utility to trap and flag
+	calls in functions.  I need it to clean up matplotlib support.
+	Also removed some deprecated code in genutils.
+
+	* IPython/Shell.py (MatplotlibShellBase.mplot_exec): small fix so
+	that matplotlib scripts called with %run, which don't call show()
+	themselves, still have their plotting windows open.
+
+2005-01-05  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Shell.py (IPShellGTK.__init__): Patch by Andrew Straw
+	<astraw-AT-caltech.edu>, to fix gtk deprecation warnings.
+
+2004-12-19  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Shell.py (MTInteractiveShell.runcode): Get rid of
+	parent_runcode, which was an eyesore.  The same result can be
+	obtained with Python's regular superclass mechanisms.
+
+2004-12-17  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_sc): Fix quote stripping problem
+	reported by Prabhu.
+	(Magic.magic_sx): direct all errors to Term.cerr (defaults to
+	sys.stderr) instead of explicitly calling sys.stderr.  This helps
+	maintain our I/O abstractions clean, for future GUI embeddings.
+
+	* IPython/genutils.py (info): added new utility for sys.stderr
+	unified info message handling (thin wrapper around warn()).
+
+	* IPython/ultraTB.py (VerboseTB.text): Fix misreported global
+	composite (dotted) names on verbose exceptions.
+	(VerboseTB.nullrepr): harden against another kind of errors which
+	Python's inspect module can trigger, and which were crashing
+	IPython.  Thanks to a report by Marco Lombardi
+	<mlombard-AT-ma010192.hq.eso.org>.
+
+2004-12-13  *** Released version 0.6.6
+
+2004-12-12  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Shell.py (IPShellGTK.mainloop): catch RuntimeErrors
+	generated by pygtk upon initialization if it was built without
+	threads (for matplotlib users).  After a crash reported by
+	Leguijt, Jaap J SIEP-EPT-RES <Jaap.Leguijt-AT-shell.com>.
+
+	* IPython/ipmaker.py (make_IPython): fix small bug in the
+	import_some parameter for multiple imports.
+
+	* IPython/iplib.py (ipmagic): simplified the interface of
+	ipmagic() to take a single string argument, just as it would be
+	typed at the IPython cmd line.
+	(ipalias): Added new ipalias() with an interface identical to
+	ipmagic().  This completes exposing a pure python interface to the
+	alias and magic system, which can be used in loops or more complex
+	code where IPython's automatic line mangling is not active.
+
+	* IPython/genutils.py (timing): changed interface of timing to
+	simply run code once, which is the most common case.  timings()
+	remains unchanged, for the cases where you want multiple runs.
+
+	* IPython/Shell.py (MatplotlibShellBase._matplotlib_config): Fix a
+	bug where Python2.2 crashes with exec'ing code which does not end
+	in a single newline.  Python 2.3 is OK, so I hadn't noticed this
+	before.
+
+2004-12-10  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_prun): changed name of option from
+	-t to -T, to accomodate the new -t flag in %run (the %run and
+	%prun options are kind of intermixed, and it's not easy to change
+	this with the limitations of python's getopt).
+
+	* IPython/Magic.py (Magic.magic_run): Added new -t option to time
+	the execution of scripts.  It's not as fine-tuned as timeit.py,
+	but it works from inside ipython (and under 2.2, which lacks
+	timeit.py).  Optionally a number of runs > 1 can be given for
+	timing very short-running code.
+
+	* IPython/genutils.py (uniq_stable): new routine which returns a
+	list of unique elements in any iterable, but in stable order of
+	appearance.  I needed this for the ultraTB fixes, and it's a handy
+	utility.
+
+	* IPython/ultraTB.py (VerboseTB.text): Fix proper reporting of
+	dotted names in Verbose exceptions.  This had been broken since
+	the very start, now x.y will properly be printed in a Verbose
+	traceback, instead of x being shown and y appearing always as an
+	'undefined global'.  Getting this to work was a bit tricky,
+	because by default python tokenizers are stateless.  Saved by
+	python's ability to easily add a bit of state to an arbitrary
+	function (without needing to build a full-blown callable object).
+
+	Also big cleanup of this code, which had horrendous runtime
+	lookups of zillions of attributes for colorization.  Moved all
+	this code into a few templates, which make it cleaner and quicker.
+
+	Printout quality was also improved for Verbose exceptions: one
+	variable per line, and memory addresses are printed (this can be
+	quite handy in nasty debugging situations, which is what Verbose
+	is for).
+
+	* IPython/ipmaker.py (make_IPython): 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.  This fixes a strange crash
+	reported by Philippe MULLER <muller-AT-irit.fr>.
+
+2004-12-09  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Shell.py (MatplotlibShellBase.use): Change pylab support
+	to reflect new names in matplotlib, which now expose the
+	matlab-compatible interface via a pylab module instead of the
+	'matlab' name.  The new code is backwards compatible, so users of
+	all matplotlib versions are OK.  Patch by J. Hunter.
+
+	* IPython/OInspect.py (Inspector.pinfo): Add to object? printing
+	of __init__ docstrings for instances (class docstrings are already
+	automatically printed).  Instances with customized docstrings
+	(indep. of the class) are also recognized and all 3 separate
+	docstrings are printed (instance, class, constructor).  After some
+	comments/suggestions by J. Hunter.
+
+2004-12-05  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (MagicCompleter.complete): Remove annoying
+	warnings when tab-completion fails and triggers an exception.
+
+2004-12-03  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (magic_prun): Fix bug where an exception would
+	be triggered when using 'run -p'.  An incorrect option flag was
+	being set ('d' instead of 'D').
+	(manpage): fix missing escaped \- sign.
+
+2004-11-30  *** Released version 0.6.5
+
+2004-11-30  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_run): Fix bug in breakpoint
+	setting with -d option.
+
+	* setup.py (docfiles): Fix problem where the doc glob I was using
+	was COMPLETELY BROKEN.  It was giving the right files by pure
+	accident, but failed once I tried to include ipython.el.  Note:
+	glob() does NOT allow you to do exclusion on multiple endings!
+
+2004-11-29  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/usage.py (__doc__): cleaned up usage docstring, by using
+	the manpage as the source.  Better formatting & consistency.
+
+	* IPython/Magic.py (magic_run): Added new -d option, to run
+	scripts under the control of the python pdb debugger.  Note that
+	this required changing the %prun option -d to -D, to avoid a clash
+	(since %run must pass options to %prun, and getopt is too dumb to
+	handle options with string values with embedded spaces).  Thanks
+	to a suggestion by Matthew Arnison <maffew-AT-cat.org.au>.
+	(magic_who_ls): added type matching to %who and %whos, so that one
+	can filter their output to only include variables of certain
+	types.  Another suggestion by Matthew.
+	(magic_whos): Added memory summaries in kb and Mb for arrays.
+	(magic_who): Improve formatting (break lines every 9 vars).
+
+2004-11-28  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Logger.py (Logger.log): Fix bug in syncing the input
+	cache when empty lines were present.
+
+2004-11-24  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/usage.py (__doc__): document the re-activated threading
+	options for WX and GTK.
+
+2004-11-23  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Shell.py (start): Added Prabhu's big patch to reactivate
+	the -wthread and -gthread options, along with a new -tk one to try
+	and coordinate Tk threading with wx/gtk.  The tk support is very
+	platform dependent, since it seems to require Tcl and Tk to be
+	built with threads (Fedora1/2 appears NOT to have it, but in
+	Prabhu's Debian boxes it works OK).  But even with some Tk
+	limitations, this is a great improvement.
+
+	* IPython/Prompts.py (prompt_specials_color): Added \t for time
+	info in user prompts.  Patch by Prabhu.
+
+2004-11-18  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (ask_yes_no): Add check for a max of 20
+	EOFErrors and bail, to avoid infinite loops if a non-terminating
+	file is fed into ipython.  Patch submitted in issue 19 by user,
+	many thanks.
+
+	* IPython/iplib.py (InteractiveShell.handle_auto): do NOT trigger
+	autoquote/parens in continuation prompts, which can cause lots of
+	problems.  Closes roundup issue 20.
+
+2004-11-17  Fernando Perez  <fperez@colorado.edu>
+
+	* debian/control (Build-Depends-Indep): Fix dpatch dependency,
+	reported as debian bug #280505.  I'm not sure my local changelog
+	entry has the proper debian format (Jack?).
+
+2004-11-08  *** Released version 0.6.4
+
+2004-11-08  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (init_readline): Fix exit message for Windows
+	when readline is active.  Thanks to a report by Eric Jones
+	<eric-AT-enthought.com>.
+
+2004-11-07  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (page): Add a trap for OSError exceptions,
+	sometimes seen by win2k/cygwin users.
+
+2004-11-06  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (interact): Change the handling of %Exit from
+	trying to propagate a SystemExit to an internal ipython flag.
+	This is less elegant than using Python's exception mechanism, but
+	I can't get that to work reliably with threads, so under -pylab
+	%Exit was hanging IPython.  Cross-thread exception handling is
+	really a bitch.  Thaks to a bug report by Stephen Walton
+	<stephen.walton-AT-csun.edu>.
+
+2004-11-04  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (raw_input_original): store a pointer to the
+	true raw_input to harden against code which can modify it
+	(wx.py.PyShell does this and would otherwise crash ipython).
+	Thanks to a bug report by Jim Flowers <james.flowers-AT-lgx.com>.
+
+	* IPython/Shell.py (MTInteractiveShell.runsource): Cleaner fix for
+	Ctrl-C problem, which does not mess up the input line.
+
+2004-11-03  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Release.py: Changed licensing to BSD, in all files.
+	(name): lowercase name for tarball/RPM release.
+
+	* IPython/OInspect.py (getdoc): wrap inspect.getdoc() safely for
+	use throughout ipython.
+
+	* IPython/Magic.py (Magic._ofind): Switch to using the new
+	OInspect.getdoc() function.
+
+	* IPython/Shell.py (sigint_handler): Hack to ignore the execution
+	of the line currently being canceled via Ctrl-C.  It's extremely
+	ugly, but I don't know how to do it better (the problem is one of
+	handling cross-thread exceptions).
+
+2004-10-28  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Shell.py (signal_handler): add signal handlers to trap
+	SIGINT and SIGSEGV in threaded code properly.  Thanks to a bug
+	report by Francesc Alted.
+
+2004-10-21  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Extensions/InterpreterExec.py (prefilter_shell): Fix @
+	to % for pysh syntax extensions.
+
+2004-10-09  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_whos): modify output of Numeric
+	arrays to print a more useful summary, without calling str(arr).
+	This avoids the problem of extremely lengthy computations which
+	occur if arr is large, and appear to the user as a system lockup
+	with 100% cpu activity.  After a suggestion by Kristian Sandberg
+	<Kristian.Sandberg@colorado.edu>.
+	(Magic.__init__): fix bug in global magic escapes not being
+	correctly set.
+
+2004-10-08  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (__license__): change to absolute imports of
+	ipython's own internal packages, to start adapting to the absolute
+	import requirement of PEP-328.
+
+	* IPython/genutils.py (__author__): Fix coding to utf-8 on all
+	files, and standardize author/license marks through the Release
+	module instead of having per/file stuff (except for files with
+	particular licenses, like the MIT/PSF-licensed codes).
+
+	* IPython/Debugger.py: remove dead code for python 2.1
+
+2004-10-04  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (ipmagic): New function for accessing magics
+	via a normal python function call.
+
+	* IPython/Magic.py (Magic.magic_magic): Change the magic escape
+	from '@' to '%', to accomodate the new @decorator syntax of python
+	2.4.
+
+2004-09-29  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Shell.py (MatplotlibShellBase.use): Added a wrapper to
+	matplotlib.use to prevent running scripts which try to switch
+	interactive backends from within ipython.  This will just crash
+	the python interpreter, so we can't allow it (but a detailed error
+	is given to the user).
+	
+2004-09-28  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Shell.py (MatplotlibShellBase.mplot_exec):
+	matplotlib-related fixes so that using @run with non-matplotlib
+	scripts doesn't pop up spurious plot windows.  This requires
+	matplotlib >= 0.63, where I had to make some changes as well.
+
+	* IPython/ipmaker.py (make_IPython): update version requirement to
+	python 2.2.
+
+	* IPython/iplib.py (InteractiveShell.mainloop): Add an optional
+	banner arg for embedded customization.
+
+	* IPython/Magic.py (Magic.__init__): big cleanup to remove all
+	explicit uses of __IP as the IPython's instance name.  Now things
+	are properly handled via the shell.name value.  The actual code
+	is a bit ugly b/c I'm doing it via a global in Magic.py, but this
+	is much better than before.  I'll clean things completely when the
+	magic stuff gets a real overhaul.
+
+	* ipython.1: small fixes, sent in by Jack Moffit.  He also sent in
+	minor changes to debian dir.
+
+	* IPython/iplib.py (InteractiveShell.__init__): Fix adding a
+	pointer to the shell itself in the interactive namespace even when
+	a user-supplied dict is provided.  This is needed for embedding
+	purposes (found by tests with Michel Sanner).
+
+2004-09-27  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/UserConfig/ipythonrc: remove []{} from
+	readline_remove_delims, so that things like [modname.<TAB> do
+	proper completion.  This disables [].TAB, but that's a less common
+	case than module names in list comprehensions, for example.
+	Thanks to a report by Andrea Riciputi.
+
+2004-09-09  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Shell.py (IPShellGTK.mainloop): reorder to avoid
+	blocking problems in win32 and osx.  Fix by John.
+
+2004-09-08  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Shell.py (IPShellWX.OnInit): Fix output redirection bug
+	for Win32 and OSX.  Fix by John Hunter.
+
+2004-08-30  *** Released version 0.6.3
+
+2004-08-30  Fernando Perez  <fperez@colorado.edu>
+
+	* setup.py (isfile): Add manpages to list of dependent files to be
+	updated.
+
+2004-08-27  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Shell.py (start): I've disabled -wthread and -gthread
+	for now.  They don't really work with standalone WX/GTK code
+	(though matplotlib IS working fine with both of those backends).
+	This will neeed much more testing.  I disabled most things with
+	comments, so turning it back on later should be pretty easy.
+
+	* IPython/iplib.py (InteractiveShell.__init__): Fix accidental
+	autocalling of expressions like r'foo', by modifying the line
+	split regexp.  Closes
+	http://www.scipy.net/roundup/ipython/issue18, reported by Nicholas
+	Riley <ipythonbugs-AT-sabi.net>.
+	(InteractiveShell.mainloop): honor --nobanner with banner
+	extensions.
+
+	* IPython/Shell.py: Significant refactoring of all classes, so
+	that we can really support ALL matplotlib backends and threading
+	models (John spotted a bug with Tk which required this).  Now we
+	should support single-threaded, WX-threads and GTK-threads, both
+	for generic code and for matplotlib.
+
+	* IPython/ipmaker.py (__call__): Changed -mpthread option to
+	-pylab, to simplify things for users.  Will also remove the pylab
+	profile, since now all of matplotlib configuration is directly
+	handled here.  This also reduces startup time.
+
+	* IPython/Shell.py (IPShellGTK.run): Fixed bug where mainloop() of
+	shell wasn't being correctly called.  Also in IPShellWX.
+
+	* IPython/iplib.py (InteractiveShell.__init__): Added option to
+	fine-tune banner.
+
+	* IPython/numutils.py (spike): Deprecate these spike functions,
+	delete (long deprecated) gnuplot_exec handler.
+
+2004-08-26  Fernando Perez  <fperez@colorado.edu>
+
+	* ipython.1: Update for threading options, plus some others which
+	were missing.
+
+	* IPython/ipmaker.py (__call__): Added -wthread option for
+	wxpython thread handling.  Make sure threading options are only
+	valid at the command line.
+
+	* scripts/ipython: moved shell selection into a factory function
+	in Shell.py, to keep the starter script to a minimum.
+
+2004-08-25  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Shell.py (IPShellWX.wxexit): fixes to WX threading, by
+	John.  Along with some recent changes he made to matplotlib, the
+	next versions of both systems should work very well together.
+
+2004-08-24  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_prun): cleanup some dead code.  I
+	tried to switch the profiling to using hotshot, but I'm getting
+	strange errors from prof.runctx() there.  I may be misreading the
+	docs, but it looks weird.  For now the profiling code will
+	continue to use the standard profiler.
+
+2004-08-23  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Shell.py (IPShellWX.__init__): Improvements to the WX
+	threaded shell, by John Hunter.  It's not quite ready yet, but
+	close.
+
+2004-08-22  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.interact): tab cleanups, also
+	in Magic and ultraTB.
+
+	* ipython.1: document threading options in manpage.
+
+	* scripts/ipython: Changed name of -thread option to -gthread,
+	since this is GTK specific.  I want to leave the door open for a
+	-wthread option for WX, which will most likely be necessary.  This
+	change affects usage and ipmaker as well.
+
+	* IPython/Shell.py (matplotlib_shell): Add a factory function to
+	handle the matplotlib shell issues.  Code by John Hunter
+	<jdhunter-AT-nitace.bsd.uchicago.edu>.
+	(IPShellMatplotlibWX.__init__): Rudimentary WX support.  It's
+	broken (and disabled for end users) for now, but it puts the
+	infrastructure in place.
+
+2004-08-21  Fernando Perez  <fperez@colorado.edu>
+
+	* ipythonrc-pylab: Add matplotlib support.
+
+	* matplotlib_config.py: new files for matplotlib support, part of
+	the pylab profile.
+
+	* IPython/usage.py (__doc__): documented the threading options.
+
+2004-08-20  Fernando Perez  <fperez@colorado.edu>
+
+	* ipython: Modified the main calling routine to handle the -thread
+	and -mpthread options.  This needs to be done as a top-level hack,
+	because it determines which class to instantiate for IPython
+	itself.
+
+	* IPython/Shell.py (MTInteractiveShell.__init__): New set of
+	classes to support multithreaded GTK operation without blocking,
+	and matplotlib with all backends.  This is a lot of still very
+	experimental code, and threads are tricky.  So it may still have a
+	few rough edges...  This code owes a lot to
+	http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65109, by
+	Brian # McErlean and John Finlay, to Antoon Pardon for fixes, and
+	to John Hunter for all the matplotlib work.
+
+	* IPython/ipmaker.py (__call__): Added -thread and -mpthread
+	options for gtk thread and matplotlib support.
+
+2004-08-16  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.__init__): don't trigger
+	autocall for things like p*q,p/q,p+q,p-q, when p is callable.  Bug
+	reported by Stephen Walton <stephen.walton-AT-csun.edu>.
+
+2004-08-11  Fernando Perez  <fperez@colorado.edu>
+
+	* setup.py (isfile): Fix build so documentation gets updated for
+	rpms (it was only done for .tgz builds).
+
+2004-08-10  Fernando Perez  <fperez@colorado.edu>
+
+	* genutils.py (Term): Fix misspell of stdin stream (sin->cin).
+
+	* iplib.py : Silence syntax error exceptions in tab-completion.
+	
+2004-08-05  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Prompts.py (Prompt2.set_colors): Fix incorrectly set
+	'color off' mark for continuation prompts.  This was causing long
+	continuation lines to mis-wrap.
+
+2004-08-01  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ipmaker.py (make_IPython): Allow the shell class used
+	for building ipython to be a parameter.  All this is necessary
+	right now to have a multithreaded version, but this insane
+	non-design will be cleaned up soon.  For now, it's a hack that
+	works.
+
+	* IPython/Shell.py (IPShell.__init__): Stop using mutable default
+	args in various places.  No bugs so far, but it's a dangerous
+	practice.
+
+2004-07-31  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (complete): ignore SyntaxError exceptions to
+	fix completion of files with dots in their names under most
+	profiles (pysh was OK because the completion order is different).
+
+2004-07-27  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.__init__): build dict of
+	keywords manually, b/c the one in keyword.py was removed in python
+	2.4.  Patch by Anakim Border <aborder-AT-users.sourceforge.net>.
+	This is NOT a bug under python 2.3 and earlier.
+
+2004-07-26  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ultraTB.py (VerboseTB.text): Add another
+	linecache.checkcache() call to try to prevent inspect.py from
+	crashing under python 2.3.  I think this fixes
+	http://www.scipy.net/roundup/ipython/issue17.
+
+2004-07-26  *** Released version 0.6.2
+
+2004-07-26  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_cd): Fix bug where 'cd -N' would
+	fail for any number.
+	(Magic.magic_bookmark): Fix bug where 'bookmark -l' would fail for
+	empty bookmarks.
+
+2004-07-26  *** Released version 0.6.1
+
+2004-07-26  Fernando Perez  <fperez@colorado.edu>
+
+	* ipython_win_post_install.py (run): Added pysh shortcut for Windows.
+
+	* IPython/iplib.py (protect_filename): Applied Ville's patch for
+	escaping '()[]{}' in filenames.
+
+	* IPython/Magic.py (shlex_split): Fix handling of '*' and '?' for
+	Python 2.2 users who lack a proper shlex.split.
+
+2004-07-19  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.init_readline): Add support
+	for reading readline's init file.  I follow the normal chain:
+	$INPUTRC is honored, otherwise ~/.inputrc is used.  Thanks to a
+	report by Mike Heeter.  This closes
+	http://www.scipy.net/roundup/ipython/issue16.
+
+2004-07-18  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (__init__): Add better handling of '\' under
+	Win32 for filenames.  After a patch by Ville.
+
+2004-07-17  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell._prefilter): fix bug where
+	autocalling would be triggered for 'foo is bar' if foo is
+	callable.  I also cleaned up the autocall detection code to use a
+	regexp, which is faster.  Bug reported by Alexander Schmolck.
+
+	* IPython/Magic.py (Magic.magic_pinfo): Fix bug where strings with
+	'?' in them would confuse the help system.  Reported by Alex
+	Schmolck.
+
+2004-07-16  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/GnuplotInteractive.py (__all__): added plot2.
+
+	* IPython/Gnuplot2.py (Gnuplot.plot2): added new function for
+	plotting dictionaries, lists or tuples of 1d arrays.
+
+	* IPython/Magic.py (Magic.magic_hist): small clenaups and
+	optimizations.
+
+	* IPython/iplib.py:Remove old Changelog info for cleanup.  This is
+	the information which was there from Janko's original IPP code:
+
+	03.05.99 20:53 porto.ifm.uni-kiel.de
+	--Started changelog.
+	--make clear do what it say it does
+	--added pretty output of lines from inputcache
+	--Made Logger a mixin class, simplifies handling of switches
+	--Added own completer class. .string<TAB> expands to last history
+	line which starts with string.  The new expansion is also present
+	with Ctrl-r from the readline library.  But this shows, who this
+	can be done for other cases.
+	--Added convention that all shell functions should accept a
+	parameter_string This opens the door for different behaviour for
+	each function. @cd is a good example of this.
+
+	04.05.99 12:12 porto.ifm.uni-kiel.de
+	--added logfile rotation
+	--added new mainloop method which freezes first the namespace
+
+	07.05.99 21:24 porto.ifm.uni-kiel.de
+	--added the docreader classes. Now there is a help system.
+	-This is only a first try. Currently it's not easy to put new
+	stuff in the indices. But this is the way to go. Info would be
+	better, but HTML is every where and not everybody has an info
+	system installed and it's not so easy to change html-docs to info.
+	--added global logfile option
+	--there is now a hook for object inspection method pinfo needs to
+	be provided for this. Can be reached by two '??'.
+
+	08.05.99 20:51 porto.ifm.uni-kiel.de
+	--added a README
+	--bug in rc file. Something has changed so functions in the rc
+	file need to reference the shell and not self. Not clear if it's a
+	bug or feature.
+	--changed rc file for new behavior
+
+2004-07-15  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Logger.py (Logger.log): fixed recent bug where the input
+	cache was falling out of sync in bizarre manners when multi-line
+	input was present.  Minor optimizations and cleanup.
+
+	(Logger): Remove old Changelog info for cleanup.  This is the
+	information which was there from Janko's original code:
+
+	Changes to Logger: - made the default log filename a parameter
+
+	- put a check for lines beginning with !@? in log(). Needed
+	(even if the handlers properly log their lines) for mid-session
+	logging activation to work properly. Without this, lines logged
+	in mid session, which get read from the cache, would end up
+	'bare' (with !@? in the open) in the log. Now they are caught
+	and prepended with a #.
+
+	* IPython/iplib.py (InteractiveShell.init_readline): added check
+	in case MagicCompleter fails to be defined, so we don't crash.
+
+2004-07-13  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Gnuplot2.py (Gnuplot.hardcopy): add automatic generation
+	of EPS if the requested filename ends in '.eps'.
+
+2004-07-04  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.handle_shell_escape): Fix
+	escaping of quotes when calling the shell.
+
+2004-07-02  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Prompts.py (CachedOutput.update): Fix problem with
+	gettext not working because we were clobbering '_'.  Fixes
+	http://www.scipy.net/roundup/ipython/issue6.
+
+2004-07-01  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_cd): integrated bookmark handling
+	into @cd.  Patch by Ville.
+
+	* IPython/iplib.py (InteractiveShell.post_config_initialization):
+	new function to store things after ipmaker runs.  Patch by Ville.
+	Eventually this will go away once ipmaker is removed and the class
+	gets cleaned up, but for now it's ok.  Key functionality here is
+	the addition of the persistent storage mechanism, a dict for
+	keeping data across sessions (for now just bookmarks, but more can
+	be implemented later).
+
+	* IPython/Magic.py (Magic.magic_bookmark): New bookmark system,
+	persistent across sections.  Patch by Ville, I modified it
+	soemwhat to allow bookmarking arbitrary dirs other than CWD.  Also
+	added a '-l' option to list all bookmarks.
+
+	* IPython/iplib.py (InteractiveShell.atexit_operations): new
+	center for cleanup.  Registered with atexit.register().  I moved
+	here the old exit_cleanup().  After a patch by Ville.
+
+	* IPython/Magic.py (get_py_filename): added '~' to the accepted
+	characters in the hacked shlex_split for python 2.2.
+
+	* IPython/iplib.py (file_matches): more fixes to filenames with
+	whitespace in them.  It's not perfect, but limitations in python's
+	readline make it impossible to go further.
+
+2004-06-29  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (file_matches): escape whitespace correctly in
+	filename completions.  Bug reported by Ville.
+
+2004-06-28  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ipmaker.py (__call__): Added per-profile histories.  Now
+	the history file will be called 'history-PROFNAME' (or just
+	'history' if no profile is loaded).  I was getting annoyed at
+	getting my Numerical work history clobbered by pysh sessions.
+
+	* IPython/iplib.py (InteractiveShell.__init__): Internal
+	getoutputerror() function so that we can honor the system_verbose
+	flag for _all_ system calls.  I also added escaping of #
+	characters here to avoid confusing Itpl.
+
+	* IPython/Magic.py (shlex_split): removed call to shell in
+	parse_options and replaced it with shlex.split().  The annoying
+	part was that in Python 2.2, shlex.split() doesn't exist, so I had
+	to backport it from 2.3, with several frail hacks (the shlex
+	module is rather limited in 2.2).  Thanks to a suggestion by Ville
+	Vainio <vivainio@kolumbus.fi>.  For Python 2.3 there should be no
+	problem.
+	
+	(Magic.magic_system_verbose): new toggle to print the actual
+	system calls made by ipython.  Mainly for debugging purposes.
+
+	* IPython/GnuplotRuntime.py (gnu_out): fix bug for cygwin, which
+	doesn't support persistence.  Reported (and fix suggested) by
+	Travis Caldwell <travis_caldwell2000@yahoo.com>.
+
+2004-06-26  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Logger.py (Logger.log): fix to handle correctly empty
+	continue prompts.
+
+	* IPython/Extensions/InterpreterExec.py (pysh): moved the pysh()
+	function (basically a big docstring) and a few more things here to
+	speedup startup. pysh.py is now very lightweight.  We want because
+	it gets execfile'd, while InterpreterExec gets imported, so
+	byte-compilation saves time.
+
+2004-06-25  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_cd): Fixed to restore usage of 'cd
+	-NUM', which was recently broken.
+
+	* IPython/iplib.py (InteractiveShell.handle_shell_escape): allow !
+	in multi-line input (but not !!, which doesn't make sense there).
+
+	* IPython/UserConfig/ipythonrc: made autoindent on by default.
+	It's just too useful, and people can turn it off in the less
+	common cases where it's a problem.
+
+2004-06-24  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell._prefilter): big change -
+	special syntaxes (like alias calling) is now allied in multi-line
+	input.  This is still _very_ experimental, but it's necessary for
+	efficient shell usage combining python looping syntax with system
+	calls.  For now it's restricted to aliases, I don't think it
+	really even makes sense to have this for magics.
+
+2004-06-23  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Extensions/InterpreterExec.py (prefilter_shell): Added
+	$var=cmd <=> @sc var=cmd and  $$var=cmd <=> @sc -l var=cmd.
+
+	* IPython/Magic.py (Magic.magic_rehashx): modified to handle
+	extensions under Windows (after code sent by Gary Bishop).  The
+	extensions considered 'executable' are stored in IPython's rc
+	structure as win_exec_ext.
+
+	* IPython/genutils.py (shell): new function, like system() but
+	without return value.  Very useful for interactive shell work.
+
+	* IPython/Magic.py (Magic.magic_unalias): New @unalias function to
+	delete aliases.
+
+	* IPython/iplib.py (InteractiveShell.alias_table_update): make
+	sure that the alias table doesn't contain python keywords.
+
+2004-06-21  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_rehash): Fix crash when
+	non-existent items are found in $PATH.  Reported by Thorsten.
+
+2004-06-20  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (complete): modified the completer so that the
+	order of priorities can be easily changed at runtime.
+
+	* IPython/Extensions/InterpreterExec.py (prefilter_shell):
+	Modified to auto-execute all lines beginning with '~', '/' or '.'.
+
+	* IPython/Magic.py (Magic.magic_sx): modified @sc and @sx to
+	expand Python variables prepended with $ in all system calls.  The
+	same was done to InteractiveShell.handle_shell_escape.  Now all
+	system access mechanisms (!, !!, @sc, @sx and aliases) allow the
+	expansion of python variables and expressions according to the
+	syntax of PEP-215 - http://www.python.org/peps/pep-0215.html.
+
+	Though PEP-215 has been rejected, a similar (but simpler) one
+	seems like it will go into Python 2.4, PEP-292 -
+	http://www.python.org/peps/pep-0292.html.
+
+	I'll keep the full syntax of PEP-215, since IPython has since the
+	start used Ka-Ping Yee's reference implementation discussed there
+	(Itpl), and I actually like the powerful semantics it offers.
+
+	In order to access normal shell variables, the $ has to be escaped
+	via an extra $.  For example:
+
+	In [7]: PATH='a python variable'
+
+	In [8]: !echo $PATH
+	a python variable
+
+	In [9]: !echo $$PATH
+	/usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
+
+	(Magic.parse_options): escape $ so the shell doesn't evaluate
+	things prematurely.
+
+	* IPython/iplib.py (InteractiveShell.call_alias): added the
+	ability for aliases to expand python variables via $.
+
+	* IPython/Magic.py (Magic.magic_rehash): based on the new alias
+	system, now there's a @rehash/@rehashx pair of magics.  These work
+	like the csh rehash command, and can be invoked at any time.  They
+	build a table of aliases to everything in the user's $PATH
+	(@rehash uses everything, @rehashx is slower but only adds
+	executable files).  With this, the pysh.py-based shell profile can
+	now simply call rehash upon startup, and full access to all
+	programs in the user's path is obtained.
+
+	* IPython/iplib.py (InteractiveShell.call_alias): The new alias
+	functionality is now fully in place.  I removed the old dynamic
+	code generation based approach, in favor of a much lighter one
+	based on a simple dict.  The advantage is that this allows me to
+	now have thousands of aliases with negligible cost (unthinkable
+	with the old system).
+
+2004-06-19  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (__init__): extended MagicCompleter class to
+	also complete (last in priority) on user aliases.
+
+	* IPython/Itpl.py (Itpl.__str__): fixed order of globals/locals in
+	call to eval.
+	(ItplNS.__init__): Added a new class which functions like Itpl,
+	but allows configuring the namespace for the evaluation to occur
+	in.
+
+2004-06-18  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.runcode): modify to print a
+	better message when 'exit' or 'quit' are typed (a common newbie
+	confusion).
+
+	* IPython/Magic.py (Magic.magic_colors): Added the runtime color
+	check for Windows users.
+
+	* IPython/iplib.py (InteractiveShell.user_setup): removed
+	disabling of colors for Windows.  I'll test at runtime and issue a
+	warning if Gary's readline isn't found, as to nudge users to
+	download it.
+
+2004-06-16  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (Stream.__init__): changed to print errors
+	to sys.stderr.  I had a circular dependency here.  Now it's
+	possible to run ipython as IDLE's shell (consider this pre-alpha,
+	since true stdout things end up in the starting terminal instead
+	of IDLE's out).
+
+	* IPython/Prompts.py (Prompt2.set_colors): prevent crashes for
+	users who haven't # updated their prompt_in2 definitions.  Remove
+	eventually.
+	(multiple_replace): added credit to original ASPN recipe.
+
+2004-06-15  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.__init__): add 'cp' to the
+	list of auto-defined aliases.
+
+2004-06-13  Fernando Perez  <fperez@colorado.edu>
+
+	* setup.py (scriptfiles): Don't trigger win_post_install unless an
+	install was really requested (so setup.py can be used for other
+	things under Windows).
+
+2004-06-10  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Logger.py (Logger.create_log): Manually remove any old
+	backup, since os.remove may fail under Windows.  Fixes bug
+	reported by Thorsten.
+
+2004-06-09  Fernando Perez  <fperez@colorado.edu>
+
+	* examples/example-embed.py: fixed all references to %n (replaced
+	with \\# for ps1/out prompts and with \\D for ps2 prompts).  Done
+	for all examples and the manual as well.
+
+2004-06-08  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Prompts.py (Prompt2.set_p_str): fixed all prompt
+	alignment and color management.  All 3 prompt subsystems now
+	inherit from BasePrompt.
+
+	* tools/release: updates for windows installer build and tag rpms
+	with python version (since paths are fixed).
+
+	* IPython/UserConfig/ipythonrc: modified to use \# instead of %n,
+	which will become eventually obsolete.  Also fixed the default
+	prompt_in2 to use \D, so at least new users start with the correct
+	defaults.
+	WARNING: Users with existing ipythonrc files will need to apply
+	this fix manually!
+
+	* setup.py: make windows installer (.exe).  This is finally the
+	integration of an old patch by Cory Dodt <dodt-AT-fcoe.k12.ca.us>,
+	which I hadn't included because it required Python 2.3 (or recent
+	distutils).
+
+	* IPython/usage.py (__doc__): update docs (and manpage) to reflect
+	usage of new '\D' escape.
+
+	* IPython/Prompts.py (ROOT_SYMBOL): Small fix for Windows (which
+	lacks os.getuid())
+	(CachedOutput.set_colors): Added the ability to turn coloring
+	on/off with @colors even for manually defined prompt colors.  It
+	uses a nasty global, but it works safely and via the generic color
+	handling mechanism.
+	(Prompt2.__init__): Introduced new escape '\D' for continuation
+	prompts. It represents the counter ('\#') as dots.
+	*** NOTE *** THIS IS A BACKWARDS-INCOMPATIBLE CHANGE.  Users will
+	need to update their ipythonrc files and replace '%n' with '\D' in
+	their prompt_in2 settings everywhere.  Sorry, but there's
+	otherwise no clean way to get all prompts to properly align.  The
+	ipythonrc shipped with IPython has been updated.
+
+2004-06-07  Fernando Perez  <fperez@colorado.edu>
+
+	* setup.py (isfile): Pass local_icons option to latex2html, so the
+	resulting HTML file is self-contained.  Thanks to
+	dryice-AT-liu.com.cn for the tip.
+
+	* pysh.py: I created a new profile 'shell', which implements a
+	_rudimentary_ IPython-based shell.  This is in NO WAY a realy
+	system shell, nor will it become one anytime soon.  It's mainly
+	meant to illustrate the use of the new flexible bash-like prompts.
+	I guess it could be used by hardy souls for true shell management,
+	but it's no tcsh/bash...  pysh.py is loaded by the 'shell'
+	profile.  This uses the InterpreterExec extension provided by
+	W.J. van der Laan <gnufnork-AT-hetdigitalegat.nl>
+
+	* IPython/Prompts.py (PromptOut.__str__): now it will correctly
+	auto-align itself with the length of the previous input prompt
+	(taking into account the invisible color escapes).
+	(CachedOutput.__init__): Large restructuring of this class.  Now
+	all three prompts (primary1, primary2, output) are proper objects,
+	managed by the 'parent' CachedOutput class.  The code is still a
+	bit hackish (all prompts share state via a pointer to the cache),
+	but it's overall far cleaner than before.
+
+	* IPython/genutils.py (getoutputerror): modified to add verbose,
+	debug and header options.  This makes the interface of all getout*
+	functions uniform.
+	(SystemExec.getoutputerror): added getoutputerror to SystemExec.
+
+	* IPython/Magic.py (Magic.default_option): added a function to
+	allow registering default options for any magic command.  This
+	makes it easy to have profiles which customize the magics globally
+	for a certain use.  The values set through this function are
+	picked up by the parse_options() method, which all magics should
+	use to parse their options.
+
+	* IPython/genutils.py (warn): modified the warnings framework to
+	use the Term I/O class.  I'm trying to slowly unify all of
+	IPython's I/O operations to pass through Term.
+
+	* IPython/Prompts.py (Prompt2._str_other): Added functionality in
+	the secondary prompt to correctly match the length of the primary
+	one for any prompt.  Now multi-line code will properly line up
+	even for path dependent prompts, such as the new ones available
+	via the prompt_specials.
+
+2004-06-06  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Prompts.py (prompt_specials): Added the ability to have
+	bash-like special sequences in the prompts, which get
+	automatically expanded.  Things like hostname, current working
+	directory and username are implemented already, but it's easy to
+	add more in the future.  Thanks to a patch by W.J. van der Laan
+	<gnufnork-AT-hetdigitalegat.nl>
+	(prompt_specials): Added color support for prompt strings, so
+	users can define arbitrary color setups for their prompts.
+
+2004-06-05  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (Term.reopen_all): Added Windows-specific
+	code to load Gary Bishop's readline and configure it
+	automatically.  Thanks to Gary for help on this.
+
+2004-06-01  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Logger.py (Logger.create_log): fix bug for logging
+	with no filename (previous fix was incomplete).
+
+2004-05-25  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.parse_options): fix bug where naked
+	parens would get passed to the shell.
+
+2004-05-20  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_prun): changed default profile
+	sort order to 'time' (the more common profiling need).
+
+	* IPython/OInspect.py (Inspector.pinfo): flush the inspect cache
+	so that source code shown is guaranteed in sync with the file on
+	disk (also changed in psource).  Similar fix to the one for
+	ultraTB on 2004-05-06.  Thanks to a bug report by Yann Le Du
+	<yann.ledu-AT-noos.fr>.
+	
+	* IPython/Magic.py (Magic.parse_options): Fixed bug where commands
+	with a single option would not be correctly parsed. Closes
+	http://www.scipy.net/roundup/ipython/issue14.  This bug had been
+	introduced in 0.6.0 (on 2004-05-06).
+
+2004-05-13  *** Released version 0.6.0
+
+2004-05-13  Fernando Perez  <fperez@colorado.edu>
+
+	* debian/: Added debian/ directory to CVS, so that debian support
+	is publicly accessible.  The debian package is maintained by Jack
+	Moffit <jack-AT-xiph.org>.
+
+	* Documentation: included the notes about an ipython-based system
+	shell (the hypothetical 'pysh') into the new_design.pdf document,
+	so that these ideas get distributed to users along with the
+	official documentation.
+
+2004-05-10  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Logger.py (Logger.create_log): fix recently introduced
+	bug (misindented line) where logstart would fail when not given an
+	explicit filename.
+
+2004-05-09  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.parse_options): skip system call when
+	there are no options to look for.  Faster, cleaner for the common
+	case.
+
+	* Documentation: many updates to the manual: describing Windows
+	support better, Gnuplot updates, credits, misc small stuff.  Also
+	updated the new_design doc a bit.
+
+2004-05-06  *** Released version 0.6.0.rc1
+
+2004-05-06  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ultraTB.py (ListTB.text): modified a ton of string +=
+	operations to use the vastly more efficient list/''.join() method.
+	(FormattedTB.text): Fix
+	http://www.scipy.net/roundup/ipython/issue12 - exception source
+	extract not updated after reload.  Thanks to Mike Salib
+	<msalib-AT-mit.edu> for pinning the source of the problem.
+	Fortunately, the solution works inside ipython and doesn't require
+	any changes to python proper.
+
+	* IPython/Magic.py (Magic.parse_options): Improved to process the
+	argument list as a true shell would (by actually using the
+	underlying system shell).  This way, all @magics automatically get
+	shell expansion for variables.  Thanks to a comment by Alex
+	Schmolck.
+
+2004-04-04  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.interact): Added a special
+	trap for a debugger quit exception, which is basically impossible
+	to handle by normal mechanisms, given what pdb does to the stack.
+	This fixes a crash reported by <fgibbons-AT-llama.med.harvard.edu>.
+
+2004-04-03  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (Term): Standardized the names of the Term
+	class streams to cin/cout/cerr, following C++ naming conventions
+	(I can't use in/out/err because 'in' is not a valid attribute
+	name).
+
+	* IPython/iplib.py (InteractiveShell.interact): don't increment
+	the prompt if there's no user input.  By Daniel 'Dang' Griffith
+	<pythondev-dang-AT-lazytwinacres.net>, after a suggestion from
+	Francois Pinard.
+
+2004-04-02  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (Stream.__init__): Modified to survive at
+	least importing in contexts where stdin/out/err aren't true file
+	objects, such as PyCrust (they lack fileno() and mode).  However,
+	the recovery facilities which rely on these things existing will
+	not work.
+
+2004-04-01  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_sx): modified (as well as @sc) to
+	use the new getoutputerror() function, so it properly
+	distinguishes stdout/err.
+
+	* IPython/genutils.py (getoutputerror): added a function to
+	capture separately the standard output and error of a command.
+	After a comment from dang on the mailing lists.  This code is
+	basically a modified version of commands.getstatusoutput(), from
+	the standard library.
+
+	* IPython/iplib.py (InteractiveShell.handle_shell_escape): added
+	'!!' as a special syntax (shorthand) to access @sx.
+
+	* IPython/Magic.py (Magic.magic_sx): new magic, to execute a shell
+	command and return its output as a list split on '\n'.
+
+2004-03-31  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/FakeModule.py (FakeModule.__init__): added __nonzero__
+	method to dictionaries used as FakeModule instances if they lack
+	it.  At least pydoc in python2.3 breaks for runtime-defined
+	functions without this hack.  At some point I need to _really_
+	understand what FakeModule is doing, because it's a gross hack.
+	But it solves Arnd's problem for now...
+
+2004-02-27  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Logger.py (Logger.create_log): Fix bug where 'rotate'
+	mode would behave erratically.  Also increased the number of
+	possible logs in rotate mod to 999.  Thanks to Rod Holland
+	<rhh@StructureLABS.com> for the report and fixes.
+	
+2004-02-26  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (page): Check that the curses module really
+	has the initscr attribute before trying to use it.  For some
+	reason, the Solaris curses module is missing this.  I think this
+	should be considered a Solaris python bug, but I'm not sure.
+
+2004-01-17  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (Stream.__init__): Changes to try to make
+	ipython robust against stdin/out/err being closed by the user.
+	This is 'user error' (and blocks a normal python session, at least
+	the stdout case).  However, Ipython should be able to survive such
+	instances of abuse as gracefully as possible.  To simplify the
+	coding and maintain compatibility with Gary Bishop's Term
+	contributions, I've made use of classmethods for this.  I think
+	this introduces a dependency on python 2.2.
+
+2004-01-13  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/numutils.py (exp_safe): simplified the code a bit and
+	removed the need for importing the kinds module altogether.
+
+2004-01-06  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_sc): Made the shell capture system
+	a magic function instead, after some community feedback.  No
+	special syntax will exist for it, but its name is deliberately
+	very short.
+
+2003-12-20  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.handle_shell_assign): Added
+	new functionality, to automagically assign the result of a shell
+	command to a variable.  I'll solicit some community feedback on
+	this before making it permanent.
+
+	* IPython/OInspect.py (Inspector.pinfo): Fix crash when info was
+	requested about callables for which inspect couldn't obtain a
+	proper argspec.  Thanks to a crash report sent by Etienne
+	Posthumus <etienne-AT-apple01.cs.vu.nl>.
+
+2003-12-09  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (page): patch for the pager to work across
+	various versions of Windows.  By Gary Bishop.
+
+2003-12-04  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Gnuplot2.py (PlotItems): Fixes for working with
+	Gnuplot.py version 1.7, whose internal names changed quite a bit.
+	While I tested this and it looks ok, there may still be corner
+	cases I've missed.
+
+2003-12-01  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell._prefilter): Fixed a bug
+	where a line like 'p,q=1,2' would fail because the automagic
+	system would be triggered for @p.
+
+	* IPython/DPyGetOpt.py (DPyGetOpt.processArguments): Tab-related
+	cleanups, code unmodified.
+
+	* IPython/genutils.py (Term): added a class for IPython to handle
+	output.  In most cases it will just be a proxy for stdout/err, but
+	having this allows modifications to be made for some platforms,
+	such as handling color escapes under Windows.  All of this code
+	was contributed by Gary Bishop, with minor modifications by me.
+	The actual changes affect many files.
+
+2003-11-30  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (file_matches): new completion code, courtesy
+	of Jeff Collins.  This enables filename completion again under
+	python 2.3, which disabled it at the C level.
+
+2003-11-11  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/numutils.py (amap): Added amap() fn.  Simple shorthand
+	for Numeric.array(map(...)), but often convenient.
+
+2003-11-05  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/numutils.py (frange): Changed a call from int() to
+	int(round()) to prevent a problem reported with arange() in the
+	numpy list.
+
+2003-10-06  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/DPyGetOpt.py (DPyGetOpt.processArguments): changed to
+	prevent crashes if sys lacks an argv attribute (it happens with
+	embedded interpreters which build a bare-bones sys module).
+	Thanks to a report/bugfix by Adam Hupp <hupp-AT-cs.wisc.edu>.
+
+2003-09-24  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic._ofind): blanket except around getattr()
+	to protect against poorly written user objects where __getattr__
+	raises exceptions other than AttributeError.  Thanks to a bug
+	report by Oliver Sander <osander-AT-gmx.de>.
+
+	* IPython/FakeModule.py (FakeModule.__repr__): this method was
+	missing.  Thanks to bug report by Ralf Schmitt <ralf-AT-brainbot.com>.
+
+2003-09-09  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell._prefilter): fix bug where
+	unpacking a list whith a callable as first element would
+	mistakenly trigger autocalling.  Thanks to a bug report by Jeffery
+	Collins.
+
+2003-08-25  *** Released version 0.5.0
+
+2003-08-22  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ultraTB.py (VerboseTB.linereader): Improved handling of
+	improperly defined user exceptions.  Thanks to feedback from Mark
+	Russell <mrussell-AT-verio.net>.
+	
+2003-08-20  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/OInspect.py (Inspector.pinfo): changed String Form
+	printing so that it would print multi-line string forms starting
+	with a new line.  This way the formatting is better respected for
+	objects which work hard to make nice string forms.
+
+	* IPython/iplib.py (InteractiveShell.handle_auto): Fix bug where
+	autocall would overtake data access for objects with both
+	__getitem__ and __call__.
+
+2003-08-19  *** Released version 0.5.0-rc1
+
+2003-08-19  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/deep_reload.py (load_tail): single tiny change here
+	seems to fix the long-standing bug of dreload() failing to work
+	for dotted names.  But this module is pretty tricky, so I may have
+	missed some subtlety.  Needs more testing!.
+
+	* IPython/ultraTB.py (VerboseTB.linereader): harden against user
+	exceptions which have badly implemented __str__ methods.
+	(VerboseTB.text): harden against inspect.getinnerframes crashing,
+	which I've been getting reports about from Python 2.3 users.  I
+	wish I had a simple test case to reproduce the problem, so I could
+	either write a cleaner workaround or file a bug report if
+	necessary.
+
+	* IPython/Magic.py (Magic.magic_edit): fixed bug where after
+	making a class 'foo', file 'foo.py' couldn't be edited.  Thanks to
+	a bug report by Tjabo Kloppenburg.
+
+	* IPython/ultraTB.py (VerboseTB.debugger): hardened against pdb
+	crashes.  Wrapped the pdb call in a blanket try/except, since pdb
+	seems rather unstable.  Thanks to a bug report by Tjabo
+	Kloppenburg <tjabo.kloppenburg-AT-unix-ag.uni-siegen.de>.
+
+	* IPython/Release.py (version): release 0.5.0-rc1.  I want to put
+	this out soon because of the critical fixes in the inner loop for
+	generators.
+
+	* IPython/Magic.py (Magic.getargspec): removed.  This (and
+	_get_def) have been obsoleted by OInspect for a long time, I
+	hadn't noticed that they were dead code.
+	(Magic._ofind): restored _ofind functionality for a few literals
+	(those in ["''",'""','[]','{}','()']).  But it won't work anymore
+	for things like "hello".capitalize?, since that would require a
+	potentially dangerous eval() again.
+
+	* IPython/iplib.py (InteractiveShell._prefilter): reorganized the
+	logic a bit more to clean up the escapes handling and minimize the
+	use of _ofind to only necessary cases.  The interactive 'feel' of
+	IPython should have improved quite a bit with the changes in
+	_prefilter and _ofind (besides being far safer than before).
+
+	* IPython/Magic.py (Magic.magic_edit): Fixed old bug (but rather
+	obscure, never reported).  Edit would fail to find the object to
+	edit under some circumstances.
+	(Magic._ofind): CRITICAL FIX.  Finally removed the eval() calls
+	which were causing double-calling of generators.  Those eval calls
+	were _very_ dangerous, since code with side effects could be
+	triggered.  As they say, 'eval is evil'...  These were the
+	nastiest evals in IPython.  Besides, _ofind is now far simpler,
+	and it should also be quite a bit faster.  Its use of inspect is
+	also safer, so perhaps some of the inspect-related crashes I've
+	seen lately with Python 2.3 might be taken care of.  That will
+	need more testing.
+
+2003-08-17  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell._prefilter): significant
+	simplifications to the logic for handling user escapes.  Faster
+	and simpler code.
+
+2003-08-14  Fernando Perez  <fperez@colorado.edu>
+
+        * IPython/numutils.py (sum_flat): rewrote to be non-recursive.
+        Now it requires O(N) storage (N=size(a)) for non-contiguous input,
+        but it should be quite a bit faster.  And the recursive version
+        generated O(log N) intermediate storage for all rank>1 arrays,
+        even if they were contiguous.
+        (l1norm): Added this function.
+        (norm):  Added this function for arbitrary norms (including
+        l-infinity).  l1 and l2 are still special cases for convenience
+        and speed.
+	
+2003-08-03  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_edit): Removed all remaining string
+	exceptions, which now raise PendingDeprecationWarnings in Python
+	2.3.  There were some in Magic and some in Gnuplot2.
+
+2003-06-30  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (page): modified to call curses only for
+	terminals where TERM=='xterm'.  After problems under many other
+	terminals were reported by Keith Beattie <KSBeattie-AT-lbl.gov>.
+
+	* IPython/iplib.py (complete): removed spurious 'print "IE"' which
+	would be triggered when readline was absent.  This was just an old
+	debugging statement I'd forgotten to take out.
+
+2003-06-20  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (clock): modified to return only user time
+	(not counting system time), after a discussion on scipy.  While
+	system time may be a useful quantity occasionally, it may much
+	more easily be skewed by occasional swapping or other similar
+	activity.
+
+2003-06-05  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/numutils.py (identity): new function, for building
+	arbitrary rank Kronecker deltas (mostly backwards compatible with
+	Numeric.identity)
+
+2003-06-03  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.handle_magic): protect
+	arguments passed to magics with spaces, to allow trailing '\' to
+	work normally (mainly for Windows users).
+
+2003-05-29  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ipmaker.py (make_IPython): Load site._Helper() as help
+	instead of pydoc.help.  This fixes a bizarre behavior where
+	printing '%s' % locals() would trigger the help system.  Now
+	ipython behaves like normal python does.  
+
+	Note that if one does 'from pydoc import help', the bizarre
+	behavior returns, but this will also happen in normal python, so
+	it's not an ipython bug anymore (it has to do with how pydoc.help
+	is implemented).
+
+2003-05-22  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/FlexCompleter.py (Completer.attr_matches): fixed to
+	return [] instead of None when nothing matches, also match to end
+	of line.  Patch by Gary Bishop.
+
+	* IPython/ipmaker.py (make_IPython): Added same sys.excepthook
+	protection as before, for files passed on the command line.  This
+	prevents the CrashHandler from kicking in if user files call into
+	sys.excepthook (such as PyQt and WxWindows have a nasty habit of
+	doing).  After a report by Kasper Souren <Kasper.Souren-AT-ircam.fr>
+
+2003-05-20  *** Released version 0.4.0
+
+2003-05-20  Fernando Perez  <fperez@colorado.edu>
+
+	* setup.py: added support for manpages.  It's a bit hackish b/c of
+	a bug in the way the bdist_rpm distutils target handles gzipped
+	manpages, but it works.  After a patch by Jack.
+
+2003-05-19  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/numutils.py: added a mockup of the kinds module, since
+	it was recently removed from Numeric.  This way, numutils will
+	work for all users even if they are missing kinds.
+
+	* IPython/Magic.py (Magic._ofind): Harden against an inspect
+	failure, which can occur with SWIG-wrapped extensions.  After a
+	crash report from Prabhu.
+
+2003-05-16  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.excepthook): New method to
+	protect ipython from user code which may call directly
+	sys.excepthook (this looks like an ipython crash to the user, even
+	when it isn't).  After a patch by Gary Bishop <gb-AT-cs.unc.edu>.
+	This is especially important to help users of WxWindows, but may
+	also be useful in other cases.
+
+	* IPython/ultraTB.py (AutoFormattedTB.__call__): Changed to allow
+	an optional tb_offset to be specified, and to preserve exception
+	info if given.  After a patch by Gary Bishop <gb-AT-cs.unc.edu>.
+
+	* ipython.1 (Default): Thanks to Jack's work, we now have manpages!
+
+2003-05-15  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.user_setup): Fix crash when
+	installing for a new user under Windows.
+
+2003-05-12  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.handle_emacs): New line
+	handler for Emacs comint-based lines.  Currently it doesn't do
+	much (but importantly, it doesn't update the history cache).  In
+	the future it may be expanded if Alex needs more functionality
+	there.
+
+	* IPython/CrashHandler.py (CrashHandler.__call__): Added platform
+	info to crash reports.
+
+	* IPython/iplib.py (InteractiveShell.mainloop): Added -c option,
+	just like Python's -c.  Also fixed crash with invalid -color
+	option value at startup. Thanks to Will French
+	<wfrench-AT-bestweb.net> for the bug report.
+
+2003-05-09  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (EvalDict.__getitem__): Renamed EvalString
+	to EvalDict (it's a mapping, after all) and simplified its code
+	quite a bit, after a nice discussion on c.l.py where Gustavo
+	Córdova <gcordova-AT-sismex.com> suggested the new version.
+
+2003-04-30  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (timings_out): modified it to reduce its
+	overhead in the common reps==1 case.
+
+2003-04-29  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (timings_out): Modified to use the resource
+	module, which avoids the wraparound problems of time.clock().
+
+2003-04-17  *** Released version 0.2.15pre4
+
+2003-04-17  Fernando Perez  <fperez@colorado.edu>
+
+	* setup.py (scriptfiles): Split windows-specific stuff over to a
+	separate file, in an attempt to have a Windows GUI installer.
+	That didn't work, but part of the groundwork is done.
+
+	* IPython/UserConfig/ipythonrc: Added M-i, M-o and M-I for
+	indent/unindent with 4 spaces.  Particularly useful in combination
+	with the new auto-indent option.
+
+2003-04-16  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py: various replacements of self.rc for
+	self.shell.rc.  A lot more remains to be done to fully disentangle
+	this class from the main Shell class.
+
+	* IPython/GnuplotRuntime.py: added checks for mouse support so
+	that we don't try to enable it if the current gnuplot doesn't
+	really support it.  Also added checks so that we don't try to
+	enable persist under Windows (where Gnuplot doesn't recognize the
+	option).
+
+	* IPython/iplib.py (InteractiveShell.interact): Added optional
+	auto-indenting code, after a patch by King C. Shu
+	<kingshu-AT-myrealbox.com>. It's off by default because it doesn't
+	get along well with pasting indented code.  If I ever figure out
+	how to make that part go well, it will become on by default.
+
+	* IPython/Prompts.py (Prompt1.auto_rewrite): Fixed bug which would
+	crash ipython if there was an unmatched '%' in the user's prompt
+	string.  Reported by Thorsten Kampe <thorsten-AT-thorstenkampe.de>.
+	
+	* IPython/iplib.py (InteractiveShell.interact): removed the
+	ability to ask the user whether he wants to crash or not at the
+	'last line' exception handler.  Calling functions at that point
+	changes the stack, and the error reports would have incorrect
+	tracebacks.
+
+	* IPython/Magic.py (Magic.magic_page): Added new @page magic, to
+	pass through a peger a pretty-printed form of any object.  After a
+	contribution by Olivier Aubert <oaubert-AT-bat710.univ-lyon1.fr>
+
+2003-04-14  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.user_setup): Fixed bug where
+	all files in ~ would be modified at first install (instead of
+	~/.ipython).  This could be potentially disastrous, as the
+	modification (make line-endings native) could damage binary files.
+	
+2003-04-10  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.handle_help): Modified to
+	handle only lines which are invalid python.  This now means that
+	lines like 'x=1 #?' execute properly.  Thanks to Jeffery Collins
+	for the bug report.
+
+2003-04-01  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.showtraceback): Fixed bug
+	where failing to set sys.last_traceback would crash pdb.pm().
+	Thanks to Jeffery D. Collins <Jeff.Collins-AT-vexcel.com> for the bug
+	report.
+
+2003-03-25  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_prun): rstrip() output of profiler
+	before printing it (it had a lot of spurious blank lines at the
+	end).
+
+	* IPython/Gnuplot2.py (Gnuplot.hardcopy): fixed bug where lpr
+	output would be sent 21 times!  Obviously people don't use this
+	too often, or I would have heard about it.
+
+2003-03-24  Fernando Perez  <fperez@colorado.edu>
+
+	* setup.py (scriptfiles): renamed the data_files parameter from
+	'base' to 'data' to fix rpm build issues.  Thanks to Ralf Ahlbrink
+	for the patch.
+
+2003-03-20  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (error): added error() and fatal()
+	functions.
+
+2003-03-18  *** Released version 0.2.15pre3
+
+2003-03-18  Fernando Perez  <fperez@colorado.edu>
+
+	* setupext/install_data_ext.py
+	(install_data_ext.initialize_options): Class contributed by Jack
+	Moffit for fixing the old distutils hack.  He is sending this to
+	the distutils folks so in the future we may not need it as a
+	private fix.
+
+	* MANIFEST.in: Extensive reorganization, based on Jack Moffit's
+	changes for Debian packaging.  See his patch for full details.
+	The old distutils hack of making the ipythonrc* files carry a
+	bogus .py extension is gone, at last.  Examples were moved to a
+	separate subdir under doc/, and the separate executable scripts
+	now live in their own directory.  Overall a great cleanup.  The
+	manual was updated to use the new files, and setup.py has been
+	fixed for this setup.
+
+	* IPython/PyColorize.py (Parser.usage): made non-executable and
+	created a pycolor wrapper around it to be included as a script.
+
+2003-03-12  *** Released version 0.2.15pre2
+
+2003-03-12  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ColorANSI.py (make_color_table): Finally fixed the
+	long-standing problem with garbage characters in some terminals.
+	The issue was really that the \001 and \002 escapes must _only_ be
+	passed to input prompts (which call readline), but _never_ to
+	normal text to be printed on screen.  I changed ColorANSI to have
+	two classes: TermColors and InputTermColors, each with the
+	appropriate escapes for input prompts or normal text.  The code in
+	Prompts.py got slightly more complicated, but this very old and
+	annoying bug is finally fixed.  
+
+	All the credit for nailing down the real origin of this problem
+	and the correct solution goes to Jack Moffit <jack-AT-xiph.org>.
+	*Many* thanks to him for spending quite a bit of effort on this.
+
+2003-03-05  *** Released version 0.2.15pre1
+
+2003-03-03  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/FakeModule.py: Moved the former _FakeModule to a
+	separate file, because it's also needed by Magic (to fix a similar
+	pickle-related issue in @run).
+
+2003-03-02  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_autocall): new magic to control
+	the autocall option at runtime.
+	(Magic.magic_dhist): changed self.user_ns to self.shell.user_ns
+	across Magic.py to start separating Magic from InteractiveShell.
+	(Magic._ofind): Fixed to return proper namespace for dotted
+	names. Before, a dotted name would always return 'not currently
+	defined', because it would find the 'parent'. s.x would be found,
+	but since 'x' isn't defined by itself, it would get confused.
+	(Magic.magic_run): Fixed pickling problems reported by Ralf
+	Ahlbrink <RAhlbrink-AT-RosenInspection.net>.  The fix was similar to
+	that I'd used when Mike Heeter reported similar issues at the
+	top-level, but now for @run.  It boils down to injecting the
+	namespace where code is being executed with something that looks
+	enough like a module to fool pickle.dump().  Since a pickle stores
+	a named reference to the importing module, we need this for
+	pickles to save something sensible.
+
+	* IPython/ipmaker.py (make_IPython): added an autocall option.
+
+	* IPython/iplib.py (InteractiveShell._prefilter): reordered all of
+	the auto-eval code.  Now autocalling is an option, and the code is
+	also vastly safer.  There is no more eval() involved at all.
+
+2003-03-01  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic._ofind): Changed interface to return a
+	dict with named keys instead of a tuple.
+
+	* IPython: Started using CVS for IPython as of 0.2.15pre1.
+
+	* setup.py (make_shortcut): Fixed message about directories
+	created during Windows installation (the directories were ok, just
+	the printed message was misleading).  Thanks to Chris Liechti
+	<cliechti-AT-gmx.net> for the heads up.
+
+2003-02-21  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell._prefilter): Fixed catching
+	of ValueError exception when checking for auto-execution.  This
+	one is raised by things like Numeric arrays arr.flat when the
+	array is non-contiguous.
+
+2003-01-31  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (SystemExec.bq): Fixed bug where bq would
+	not return any value at all (even though the command would get
+	executed).
+	(xsys): Flush stdout right after printing the command to ensure
+	proper ordering of commands and command output in the total
+	output.
+	(SystemExec/xsys/bq): Switched the names of xsys/bq and
+	system/getoutput as defaults.  The old ones are kept for
+	compatibility reasons, so no code which uses this library needs
+	changing.
+
+2003-01-27  *** Released version 0.2.14
+
+2003-01-25  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_edit): Fixed problem where
+	functions defined in previous edit sessions could not be re-edited
+	(because the temp files were immediately removed).  Now temp files
+	are removed only at IPython's exit.
+	(Magic.magic_run): Improved @run to perform shell-like expansions
+	on its arguments (~users and $VARS).  With this, @run becomes more
+	like a normal command-line.
+
+	* IPython/Shell.py (IPShellEmbed.__call__): Fixed a bunch of small
+	bugs related to embedding and cleaned up that code.  A fairly
+	important one was the impossibility to access the global namespace
+	through the embedded IPython (only local variables were visible).
+
+2003-01-14  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell._prefilter): Fixed
+	auto-calling to be a bit more conservative.  Now it doesn't get
+	triggered if any of '!=()<>' are in the rest of the input line, to
+	allow comparing callables.  Thanks to Alex for the heads up.
+
+2003-01-07  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (page): fixed estimation of the number of
+	lines in a string to be paged to simply count newlines. This
+	prevents over-guessing due to embedded escape sequences. A better
+	long-term solution would involve stripping out the control chars
+	for the count, but it's potentially so expensive I just don't
+	think it's worth doing.
+
+2002-12-19  *** Released version 0.2.14pre50
+
+2002-12-19  Fernando Perez  <fperez@colorado.edu>
+
+	* tools/release (version): Changed release scripts to inform
+	Andrea and build a NEWS file with a list of recent changes.
+
+	* IPython/ColorANSI.py (__all__): changed terminal detection
+	code. Seems to work better for xterms without breaking
+	konsole. Will need more testing to determine if WinXP and Mac OSX
+	also work ok.
+
+2002-12-18  *** Released version 0.2.14pre49
+
+2002-12-18  Fernando Perez  <fperez@colorado.edu>
+
+	* Docs: added new info about Mac OSX, from Andrea.
+
+	* IPython/Gnuplot2.py (String): Added a String PlotItem class to
+	allow direct plotting of python strings whose format is the same
+	of gnuplot data files.
+
+2002-12-16  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.interact): fixed default (y)
+	value of exit question to be acknowledged.
+
+2002-12-03  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ipmaker.py: removed generators, which had been added
+	by mistake in an earlier debugging run. This was causing trouble
+	to users of python 2.1.x. Thanks to Abel Daniel <abli-AT-freemail.hu>
+	for pointing this out.
+
+2002-11-17  Fernando Perez  <fperez@colorado.edu>
+
+	* Manual: updated the Gnuplot section.
+
+	* IPython/GnuplotRuntime.py: refactored a lot all this code, with
+	a much better split of what goes in Runtime and what goes in
+	Interactive.
+
+	* IPython/ipmaker.py: fixed bug where import_fail_info wasn't
+	being imported from iplib.
+
+	* IPython/GnuplotInteractive.py (magic_gpc): renamed @gp to @gpc
+	for command-passing. Now the global Gnuplot instance is called
+	'gp' instead of 'g', which was really a far too fragile and
+	common name.
+
+	* IPython/Gnuplot2.py (eps_fix_bbox): added this to fix broken
+	bounding boxes generated by Gnuplot for square plots.
+
+	* IPython/genutils.py (popkey): new function added. I should
+	suggest this on c.l.py as a dict method, it seems useful.
+
+	* IPython/Gnuplot2.py (Gnuplot.plot): Overhauled plot and replot
+	to transparently handle PostScript generation. MUCH better than
+	the previous plot_eps/replot_eps (which I removed now). The code
+	is also fairly clean and well documented now (including
+	docstrings).
+
+2002-11-13  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_edit): fixed docstring
+	(inconsistent with options).
+
+	* IPython/Gnuplot2.py (Gnuplot.hardcopy): hardcopy had been
+	manually disabled, I don't know why. Fixed it.
+	(Gnuplot._plot_eps): added new plot_eps/replot_eps to get directly
+	eps output.
+
+2002-11-12  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (ask_yes_no): trap EOF and ^C so that they
+	don't propagate up to caller. Fixes crash reported by François
+	Pinard.
+
+2002-11-09  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ipmaker.py (make_IPython): fixed problem with writing
+	history file for new users.
+	(make_IPython): fixed bug where initial install would leave the
+	user running in the .ipython dir.
+	(make_IPython): fixed bug where config dir .ipython would be
+	created regardless of the given -ipythondir option. Thanks to Cory
+	Dodt <cdodt-AT-fcoe.k12.ca.us> for the bug report.
+
+	* IPython/genutils.py (ask_yes_no): new function for asking yes/no
+	type confirmations. Will need to use it in all of IPython's code
+	consistently.
+	
+	* IPython/CrashHandler.py (CrashHandler.__call__): changed the
+	context to print 31 lines instead of the default 5. This will make
+	the crash reports extremely detailed in case the problem is in
+	libraries I don't have access to.
+
+	* IPython/iplib.py (InteractiveShell.interact): changed the 'last
+	line of defense' code to still crash, but giving users fair
+	warning. I don't want internal errors to go unreported: if there's
+	an internal problem, IPython should crash and generate a full
+	report.
+
+2002-11-08  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.interact): added code to trap
+	otherwise uncaught exceptions which can appear if people set
+	sys.stdout to something badly broken. Thanks to a crash report
+	from henni-AT-mail.brainbot.com.
+
+2002-11-04  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.interact): added
+	__IPYTHON__active to the builtins. It's a flag which goes on when
+	the interaction starts and goes off again when it stops. This
+	allows embedding code to detect being inside IPython. Before this
+	was done via __IPYTHON__, but that only shows that an IPython
+	instance has been created.
+
+	* IPython/Magic.py (Magic.magic_env): I realized that in a
+	UserDict, instance.data holds the data as a normal dict. So I
+	modified @env to return os.environ.data instead of rebuilding a
+	dict by hand.
+
+2002-11-02  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (warn): changed so that level 1 prints no
+	header. Level 2 is now the default (with 'WARNING' header, as
+	before). I think I tracked all places where changes were needed in
+	IPython, but outside code using the old level numbering may have
+	broken.
+
+	* IPython/iplib.py (InteractiveShell.runcode): added this to
+	handle the tracebacks in SystemExit traps correctly. The previous
+	code (through interact) was printing more of the stack than
+	necessary, showing IPython internal code to the user.
+
+	* IPython/UserConfig/ipythonrc.py: Made confirm_exit 1 by
+	default. Now that the default at the confirmation prompt is yes,
+	it's not so intrusive. François' argument that ipython sessions
+	tend to be complex enough not to lose them from an accidental C-d,
+	is a valid one.
+
+	* IPython/iplib.py (InteractiveShell.interact): added a
+	showtraceback() call to the SystemExit trap, and modified the exit
+	confirmation to have yes as the default.
+
+	* IPython/UserConfig/ipythonrc.py: removed 'session' option from
+	this file. It's been gone from the code for a long time, this was
+	simply leftover junk.
+
+2002-11-01  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/UserConfig/ipythonrc.py: new confirm_exit option
+	added. If set, IPython now traps EOF and asks for
+	confirmation. After a request by François Pinard.
+
+	* IPython/Magic.py (Magic.magic_Exit): New @Exit and @Quit instead
+	of @abort, and with a new (better) mechanism for handling the
+	exceptions.
+
+2002-10-27  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/usage.py (__doc__): updated the --help information and
+	the ipythonrc file to indicate that -log generates
+	./ipython.log. Also fixed the corresponding info in @logstart.
+	This and several other fixes in the manuals thanks to reports by
+	François Pinard <pinard-AT-iro.umontreal.ca>.
+	
+	* IPython/Logger.py (Logger.switch_log): Fixed error message to
+	refer to @logstart (instead of @log, which doesn't exist).
+
+	* IPython/iplib.py (InteractiveShell._prefilter): fixed
+	AttributeError crash. Thanks to Christopher Armstrong
+	<radix-AT-twistedmatrix.com> for the report/fix. This bug had been
+	introduced recently (in 0.2.14pre37) with the fix to the eval
+	problem mentioned below.
+	
+2002-10-17  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ConfigLoader.py (ConfigLoader.load): Fixes for Windows
+	installation. Thanks to Leonardo Santagada <retype-AT-terra.com.br>.
+
+	* IPython/iplib.py (InteractiveShell._prefilter): Many changes to
+	this function to fix a problem reported by Alex Schmolck. He saw
+	it with list comprehensions and generators, which were getting
+	called twice. The real problem was an 'eval' call in testing for
+	automagic which was evaluating the input line silently. 
+
+	This is a potentially very nasty bug, if the input has side
+	effects which must not be repeated. The code is much cleaner now,
+	without any blanket 'except' left and with a regexp test for
+	actual function names. 
+
+	But an eval remains, which I'm not fully comfortable with. I just
+	don't know how to find out if an expression could be a callable in
+	the user's namespace without doing an eval on the string. However
+	that string is now much more strictly checked so that no code
+	slips by, so the eval should only happen for things that can
+	really be only function/method names.
+
+2002-10-15  Fernando Perez  <fperez@colorado.edu>
+
+	* Updated LyX to 1.2.1 so I can work on the docs again. Added Mac
+	OSX information to main manual, removed README_Mac_OSX file from
+	distribution. Also updated credits for recent additions.
+
+2002-10-10  Fernando Perez  <fperez@colorado.edu>
+
+	* README_Mac_OSX: Added a README for Mac OSX users for fixing
+	terminal-related issues. Many thanks to Andrea Riciputi
+	<andrea.riciputi-AT-libero.it> for writing it.
+
+	* IPython/UserConfig/ipythonrc.py: Fixes to various small issues,
+	thanks to Thorsten Kampe <thorsten-AT-thorstenkampe.de>.
+
+	* setup.py (make_shortcut): Fixes for Windows installation. Thanks
+	to Fredrik Kant <fredrik.kant-AT-front.com> and Syver Enstad
+	<syver-en-AT-online.no> who both submitted patches for this problem.
+
+	* IPython/iplib.py (InteractiveShell.embed_mainloop): Patch for
+	global embedding to make sure that things don't overwrite user
+	globals accidentally. Thanks to Richard <rxe-AT-renre-europe.com>
+
+	* IPython/Gnuplot2.py (gp): Patch for Gnuplot.py 1.6
+	compatibility. Thanks to Hayden Callow
+	<h.callow-AT-elec.canterbury.ac.nz>
+
+2002-10-04  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Gnuplot2.py (PlotItem): Added 'index' option for
+	Gnuplot.File objects.
+	      
+2002-07-23  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (timing): Added timings() and timing() for
+	quick access to the most commonly needed data, the execution
+	times. Old timing() renamed to timings_out().
+
+2002-07-18  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Shell.py (IPShellEmbed.restore_system_completer): fixed
+	bug with nested instances disrupting the parent's tab completion.
+
+	* IPython/iplib.py (all_completions): Added Alex Schmolck's
+	all_completions code to begin the emacs integration.
+
+	* IPython/Gnuplot2.py (zip_items): Added optional 'titles'
+	argument to allow titling individual arrays when plotting.
+
+2002-07-15  Fernando Perez  <fperez@colorado.edu>
+
+	* setup.py (make_shortcut): changed to retrieve the value of
+	'Program Files' directory from the registry (this value changes in
+	non-english versions of Windows). Thanks to Thomas Fanslau
+	<tfanslau-AT-gmx.de> for the report.
+
+2002-07-10  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ultraTB.py (VerboseTB.debugger): enabled workaround for
+	a bug in pdb, which crashes if a line with only whitespace is
+	entered. Bug report submitted to sourceforge.
+
+2002-07-09  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ultraTB.py (VerboseTB.nullrepr): fixed rare crash when
+	reporting exceptions (it's a bug in inspect.py, I just set a
+	workaround).
+
+2002-07-08  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.__init__): fixed reference to
+	__IPYTHON__ in __builtins__ to show up in user_ns.
+
+2002-07-03  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/GnuplotInteractive.py (magic_gp_set_default): changed
+	name from @gp_set_instance to @gp_set_default.
+
+	* IPython/ipmaker.py (make_IPython): default editor value set to
+	'0' (a string), to match the rc file. Otherwise will crash when
+	.strip() is called on it.
+	
+
+2002-06-28  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.safe_execfile): fix importing
+	of files in current directory when a file is executed via
+	@run. Patch also by RA <ralf_ahlbrink-AT-web.de>.
+
+	* setup.py (manfiles): fix for rpm builds, submitted by RA
+	<ralf_ahlbrink-AT-web.de>. Now we have RPMs!
+
+	* IPython/ipmaker.py (make_IPython): fixed lookup of default
+	editor when set to '0'. Problem was, '0' evaluates to True (it's a
+	string!). A. Schmolck caught this one.
+
+2002-06-27  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ipmaker.py (make_IPython): fixed bug when running user
+	defined files at the cmd line. __name__ wasn't being set to
+	__main__.
+
+	* IPython/Gnuplot2.py (zip_items): improved it so it can plot also
+	regular lists and tuples besides Numeric arrays.
+
+	* IPython/Prompts.py (CachedOutput.__call__): Added output
+	supression for input ending with ';'. Similar to Mathematica and
+	Matlab. The _* vars and Out[] list are still updated, just like
+	Mathematica behaves.
+
+2002-06-25  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ConfigLoader.py (ConfigLoader.load): fixed checking of
+	.ini extensions for profiels under Windows.
+
+	* IPython/OInspect.py (Inspector.pinfo): improved alignment of
+	string form. Fix contributed by Alexander Schmolck
+	<a.schmolck-AT-gmx.net>
+
+	* IPython/GnuplotRuntime.py (gp_new): new function. Returns a
+	pre-configured Gnuplot instance.
+
+2002-06-21  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/numutils.py (exp_safe): new function, works around the
+	underflow problems in Numeric.
+	(log2): New fn. Safe log in base 2: returns exact integer answer
+	for exact integer powers of 2.
+
+	* IPython/Magic.py (get_py_filename): fixed it not expanding '~'
+	properly.
+
+2002-06-20  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (timing): new function like
+	Mathematica's. Similar to time_test, but returns more info.
+
+2002-06-18  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_save): modified @save and @r
+	according to Mike Heeter's suggestions.
+
+2002-06-16  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/GnuplotRuntime.py: Massive overhaul to the Gnuplot
+	system. GnuplotMagic is gone as a user-directory option. New files
+	make it easier to use all the gnuplot stuff both from external
+	programs as well as from IPython. Had to rewrite part of
+	hardcopy() b/c of a strange bug: often the ps files simply don't
+	get created, and require a repeat of the command (often several
+	times).
+
+	* IPython/ultraTB.py (AutoFormattedTB.__call__): changed to
+	resolve output channel at call time, so that if sys.stderr has
+	been redirected by user this gets honored.
+
+2002-06-13  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Shell.py (IPShell.__init__): Changed IPythonShell to
+	IPShell. Kept a copy with the old names to avoid breaking people's
+	embedded code.
+
+	* IPython/ipython: simplified it to the bare minimum after
+	Holger's suggestions. Added info about how to use it in
+	PYTHONSTARTUP.
+
+	* IPython/Shell.py (IPythonShell): changed the options passing
+	from a string with funky %s replacements to a straight list. Maybe
+	a bit more typing, but it follows sys.argv conventions, so there's
+	less special-casing to remember.
+
+2002-06-12  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_r): new magic auto-repeat
+	command. Thanks to a suggestion by Mike Heeter.
+	(Magic.magic_pfile): added behavior to look at filenames if given
+	arg is not a defined object.
+	(Magic.magic_save): New @save function to save code snippets. Also
+	a Mike Heeter idea.
+
+	* IPython/UserConfig/GnuplotMagic.py (plot): Improvements to
+	plot() and replot(). Much more convenient now, especially for
+	interactive use.
+
+	* IPython/Magic.py (Magic.magic_run): Added .py automatically to
+	filenames.
+
+2002-06-02  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Struct.py (Struct.__init__): modified to admit
+	initialization via another struct.
+
+	* IPython/genutils.py (SystemExec.__init__): New stateful
+	interface to xsys and bq. Useful for writing system scripts.
+
+2002-05-30  Fernando Perez  <fperez@colorado.edu>
+
+	* MANIFEST.in: Changed docfile selection to exclude all the lyx
+	documents. This will make the user download smaller (it's getting
+	too big).
+
+2002-05-29  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (_FakeModule.__init__): New class introduced to
+	fix problems with shelve and pickle. Seems to work, but I don't
+	know if corner cases break it. Thanks to Mike Heeter
+	<korora-AT-SDF.LONESTAR.ORG> for the bug reports and test cases.
+
+2002-05-24  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Macro.__init__): fixed magics embedded in
+	macros having broken.
+
+2002-05-21  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_logstart): fixed recently
+	introduced logging bug: all history before logging started was
+	being written one character per line! This came from the redesign
+	of the input history as a special list which slices to strings,
+	not to lists.
+
+2002-05-20  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Prompts.py (CachedOutput.__init__): made the color table
+	be an attribute of all classes in this module. The design of these
+	classes needs some serious overhauling.
+
+	* IPython/DPyGetOpt.py (DPyGetOpt.setPosixCompliance): fixed bug
+	which was ignoring '_' in option names.
+
+	* IPython/ultraTB.py (FormattedTB.__init__): Changed
+	'Verbose_novars' to 'Context' and made it the new default. It's a
+	bit more readable and also safer than verbose.
+
+	* IPython/PyColorize.py (Parser.__call__): Fixed coloring of
+	triple-quoted strings.
+
+	* IPython/OInspect.py (__all__): new module exposing the object
+	introspection facilities. Now the corresponding magics are dummy
+	wrappers around this. Having this module will make it much easier
+	to put these functions into our modified pdb.
+	This new object inspector system uses the new colorizing module,
+	so source code and other things are nicely syntax highlighted.
+
+2002-05-18  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ColorANSI.py: Split the coloring tools into a separate
+	module so I can use them in other code easier (they were part of
+	ultraTB).
+
+2002-05-17  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/UserConfig/GnuplotMagic.py (magic_gp_set_instance):
+	fixed it to set the global 'g' also to the called instance, as
+	long as 'g' was still a gnuplot instance (so it doesn't overwrite
+	user's 'g' variables).
+
+	* IPython/iplib.py (InteractiveShell.__init__): Added In/Out
+	global variables (aliases to _ih,_oh) so that users which expect
+	In[5] or Out[7] to work aren't unpleasantly surprised.
+	(InputList.__getslice__): new class to allow executing slices of
+	input history directly. Very simple class, complements the use of
+	macros.
+
+2002-05-16  Fernando Perez  <fperez@colorado.edu>
+
+	* setup.py (docdirbase): make doc directory be just doc/IPython
+	without version numbers, it will reduce clutter for users.
+
+	* IPython/Magic.py (Magic.magic_run): Add explicit local dict to
+	execfile call to prevent possible memory leak. See for details:
+	http://mail.python.org/pipermail/python-list/2002-February/088476.html
+
+2002-05-15  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_psource): made the object
+	introspection names be more standard: pdoc, pdef, pfile and
+	psource. They all print/page their output, and it makes
+	remembering them easier. Kept old names for compatibility as
+	aliases.
+
+2002-05-14  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/UserConfig/GnuplotMagic.py: I think I finally understood
+	what the mouse problem was. The trick is to use gnuplot with temp
+	files and NOT with pipes (for data communication), because having
+	both pipes and the mouse on is bad news.
+
+2002-05-13  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic._ofind): fixed namespace order search
+	bug. Information would be reported about builtins even when
+	user-defined functions overrode them.
+
+2002-05-11  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/__init__.py (__all__): removed FlexCompleter from
+	__all__ so that things don't fail in platforms without readline.
+
+2002-05-10  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/__init__.py (__all__): removed numutils from __all__ b/c
+	it requires Numeric, effectively making Numeric a dependency for
+	IPython.
+
+	* Released 0.2.13
+
+	* IPython/Magic.py (Magic.magic_prun): big overhaul to the
+	profiler interface. Now all the major options from the profiler
+	module are directly supported in IPython, both for single
+	expressions (@prun) and for full programs (@run -p).
+
+2002-05-09  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_doc): fixed to show docstrings of
+	magic properly formatted for screen.
+
+	* setup.py (make_shortcut): Changed things to put pdf version in
+	doc/ instead of doc/manual (had to change lyxport a bit).
+
+	* IPython/Magic.py (Profile.string_stats): made profile runs go
+	through pager (they are long and a pager allows searching, saving,
+	etc.)
+
+2002-05-08  Fernando Perez  <fperez@colorado.edu>
+
+	* Released 0.2.12
+
+2002-05-06  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_hist): small bug fixed (recently
+	introduced); 'hist n1 n2' was broken.
+	(Magic.magic_pdb): added optional on/off arguments to @pdb
+	(Magic.magic_run): added option -i to @run, which executes code in
+	the IPython namespace instead of a clean one. Also added @irun as
+	an alias to @run -i.
+
+	* IPython/UserConfig/GnuplotMagic.py (magic_gp_set_instance):
+	fixed (it didn't really do anything, the namespaces were wrong).
+
+	* IPython/Debugger.py (__init__): Added workaround for python 2.1
+
+	* IPython/__init__.py (__all__): Fixed package namespace, now
+	'import IPython' does give access to IPython.<all> as
+	expected. Also renamed __release__ to Release.
+
+	* IPython/Debugger.py (__license__): created new Pdb class which
+	functions like a drop-in for the normal pdb.Pdb but does NOT
+	import readline by default. This way it doesn't muck up IPython's
+	readline handling, and now tab-completion finally works in the
+	debugger -- sort of. It completes things globally visible, but the
+	completer doesn't track the stack as pdb walks it. That's a bit
+	tricky, and I'll have to implement it later.
+
+2002-05-05  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_oinfo): fixed formatting bug for
+	magic docstrings when printed via ? (explicit \'s were being
+	printed).
+
+	* IPython/ipmaker.py (make_IPython): fixed namespace
+	identification bug. Now variables loaded via logs or command-line
+	files are recognized in the interactive namespace by @who.
+
+	* IPython/iplib.py (InteractiveShell.safe_execfile): Fixed bug in
+	log replay system stemming from the string form of Structs.
+
+	* IPython/Magic.py (Macro.__init__): improved macros to properly
+	handle magic commands in them.
+	(Magic.magic_logstart): usernames are now expanded so 'logstart
+	~/mylog' now works.
+
+	* IPython/iplib.py (complete): fixed bug where paths starting with
+	'/' would be completed as magic names.
+
+2002-05-04  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_run): added options -p and -f to
+	allow running full programs under the profiler's control.
+
+	* IPython/ultraTB.py (FormattedTB.__init__): Added Verbose_novars
+	mode to report exceptions verbosely but without formatting
+	variables. This addresses the issue of ipython 'freezing' (it's
+	not frozen, but caught in an expensive formatting loop) when huge
+	variables are in the context of an exception.
+	(VerboseTB.text): Added '--->' markers at line where exception was
+	triggered. Much clearer to read, especially in NoColor modes.
+
+	* IPython/Magic.py (Magic.magic_run): bugfix: -n option had been
+	implemented in reverse when changing to the new parse_options().
+
+2002-05-03  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.parse_options): new function so that
+	magics can parse options easier.
+	(Magic.magic_prun): new function similar to profile.run(),
+	suggested by Chris Hart.
+	(Magic.magic_cd): fixed behavior so that it only changes if
+	directory actually is in history.
+
+	* IPython/usage.py (__doc__): added information about potential
+	slowness of Verbose exception mode when there are huge data
+	structures to be formatted (thanks to Archie Paulson).
+
+	* IPython/ipmaker.py (make_IPython): Changed default logging
+	(when simply called with -log) to use curr_dir/ipython.log in
+	rotate mode. Fixed crash which was occuring with -log before
+	(thanks to Jim Boyle).
+
+2002-05-01  Fernando Perez  <fperez@colorado.edu>
+
+	* Released 0.2.11 for these fixes (mainly the ultraTB one which
+	was nasty -- though somewhat of a corner case).
+
+	* IPython/ultraTB.py (AutoFormattedTB.text): renamed __text to
+	text (was a bug).
+
+2002-04-30  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/UserConfig/GnuplotMagic.py (magic_gp): Minor fix to add
+	a print after ^D or ^C from the user so that the In[] prompt
+	doesn't over-run the gnuplot one.
+
+2002-04-29  Fernando Perez  <fperez@colorado.edu>
+
+	* Released 0.2.10
+
+	* IPython/__release__.py (version): get date dynamically.
+
+	* Misc. documentation updates thanks to Arnd's comments. Also ran
+	a full spellcheck on the manual (hadn't been done in a while).
+
+2002-04-27  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_logstart): Fixed bug where
+	starting a log in mid-session would reset the input history list.
+
+2002-04-26  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.wait): Fixed bug where not
+	all files were being included in an update. Now anything in
+	UserConfig that matches [A-Za-z]*.py will go (this excludes
+	__init__.py)
+
+2002-04-25  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.__init__): Added __IPYTHON__
+	to __builtins__ so that any form of embedded or imported code can
+	test for being inside IPython.
+
+	* IPython/UserConfig/GnuplotMagic.py: (magic_gp_set_instance):
+	changed to GnuplotMagic because it's now an importable module,
+	this makes the name follow that of the standard Gnuplot module.
+	GnuplotMagic can now be loaded at any time in mid-session.
+
+2002-04-24  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/numutils.py: removed SIUnits. It doesn't properly set
+	the globals (IPython has its own namespace) and the
+	PhysicalQuantity stuff is much better anyway.
+
+	* IPython/UserConfig/example-gnuplot.py (g2): Added gnuplot
+	embedding example to standard user directory for
+	distribution. Also put it in the manual.
+
+	* IPython/numutils.py (gnuplot_exec): Changed to take a gnuplot
+	instance as first argument (so it doesn't rely on some obscure
+	hidden global).
+
+	* IPython/UserConfig/ipythonrc.py: put () back in accepted
+	delimiters. While it prevents ().TAB from working, it allows
+	completions in open (... expressions. This is by far a more common
+	case.
+
+2002-04-23  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Extensions/InterpreterPasteInput.py: new
+	syntax-processing module for pasting lines with >>> or ... at the
+	start.
+
+	* IPython/Extensions/PhysicalQ_Interactive.py
+	(PhysicalQuantityInteractive.__int__): fixed to work with either
+	Numeric or math.
+
+	* IPython/UserConfig/ipythonrc-numeric.py: reorganized the
+	provided profiles. Now we have:
+	-math -> math module as * and cmath with its own namespace.
+	-numeric -> Numeric as *, plus gnuplot & grace
+	-physics -> same as before
+
+	* IPython/Magic.py (Magic.magic_magic): Fixed bug where
+	user-defined magics wouldn't be found by @magic if they were
+	defined as class methods. Also cleaned up the namespace search
+	logic and the string building (to use %s instead of many repeated
+	string adds).
+
+	* IPython/UserConfig/example-magic.py (magic_foo): updated example
+	of user-defined magics to operate with class methods (cleaner, in
+	line with the gnuplot code).
+
+2002-04-22  Fernando Perez  <fperez@colorado.edu>
+
+	* setup.py: updated dependency list so that manual is updated when
+	all included files change.
+
+	* IPython/ipmaker.py (make_IPython): Fixed bug which was ignoring
+	the delimiter removal option (the fix is ugly right now).
+
+	* IPython/UserConfig/ipythonrc-physics.py: simplified not to load
+	all of the math profile (quicker loading, no conflict between
+	g-9.8 and g-gnuplot).
+
+	* IPython/CrashHandler.py (CrashHandler.__call__): changed default
+	name of post-mortem files to IPython_crash_report.txt.
+
+	* Cleanup/update of the docs. Added all the new readline info and
+	formatted all lists as 'real lists'.
+
+	* IPython/ipmaker.py (make_IPython): removed now-obsolete
+	tab-completion options, since the full readline parse_and_bind is
+	now accessible.
+
+	* IPython/iplib.py (InteractiveShell.init_readline): Changed
+	handling of readline options. Now users can specify any string to
+	be passed to parse_and_bind(), as well as the delimiters to be
+	removed.
+	(InteractiveShell.__init__): Added __name__ to the global
+	namespace so that things like Itpl which rely on its existence
+	don't crash.
+	(InteractiveShell._prefilter): Defined the default with a _ so
+	that prefilter() is easier to override, while the default one
+	remains available.
+
+2002-04-18  Fernando Perez  <fperez@colorado.edu>
+
+	* Added information about pdb in the docs.
+
+2002-04-17  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ipmaker.py (make_IPython): added rc_override option to
+	allow passing config options at creation time which may override
+	anything set in the config files or command line. This is
+	particularly useful for configuring embedded instances.
+
+2002-04-15  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Logger.py (Logger.log): Fixed a nasty bug which could
+	crash embedded instances because of the input cache falling out of
+	sync with the output counter.
+
+	* IPython/Shell.py (IPythonShellEmbed.__init__): added a debug
+	mode which calls pdb after an uncaught exception in IPython itself.
+
+2002-04-14  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.showtraceback): pdb mucks up
+	readline, fix it back after each call.
+
+	* IPython/ultraTB.py (AutoFormattedTB.__text): made text a private
+	method to force all access via __call__(), which guarantees that
+	traceback references are properly deleted.
+
+	* IPython/Prompts.py (CachedOutput._display): minor fixes to
+	improve printing when pprint is in use.
+
+2002-04-13  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Shell.py (IPythonShellEmbed.__call__): SystemExit
+	exceptions aren't caught anymore. If the user triggers one, he
+	should know why he's doing it and it should go all the way up,
+	just like any other exception. So now @abort will fully kill the
+	embedded interpreter and the embedding code (unless that happens
+	to catch SystemExit).
+
+	* IPython/ultraTB.py (VerboseTB.__init__): added a call_pdb flag
+	and a debugger() method to invoke the interactive pdb debugger
+	after printing exception information. Also added the corresponding
+	-pdb option and @pdb magic to control this feature, and updated
+	the docs. After a suggestion from Christopher Hart
+	(hart-AT-caltech.edu).
+
+2002-04-12  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Shell.py (IPythonShellEmbed.__init__): modified to use
+	the exception handlers defined by the user (not the CrashHandler)
+	so that user exceptions don't trigger an ipython bug report.
+
+	* IPython/ultraTB.py (ColorTB.__init__): made the color scheme
+	configurable (it should have always been so).
+
+2002-03-26  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Shell.py (IPythonShellEmbed.__call__): many changes here
+	and there to fix embedding namespace issues. This should all be
+	done in a more elegant way.
+
+2002-03-25  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (get_home_dir): Try to make it work under
+	win9x also.
+
+2002-03-20  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Shell.py (IPythonShellEmbed.__init__): leave
+	sys.displayhook untouched upon __init__.
+
+2002-03-19  Fernando Perez  <fperez@colorado.edu>
+
+	* Released 0.2.9 (for embedding bug, basically).
+
+	* IPython/Shell.py (IPythonShellEmbed.__call__): Trap SystemExit
+	exceptions so that enclosing shell's state can be restored.
+
+	* Changed magic_gnuplot.py to magic-gnuplot.py to standardize
+	naming conventions in the .ipython/ dir.
+
+	* IPython/iplib.py (InteractiveShell.init_readline): removed '-'
+	from delimiters list so filenames with - in them get expanded.
+
+	* IPython/Shell.py (IPythonShellEmbed.__call__): fixed bug with
+	sys.displayhook not being properly restored after an embedded call.
+
+ 2002-03-18  Fernando Perez  <fperez@colorado.edu>
+
+	* Released 0.2.8
+
+	* IPython/iplib.py (InteractiveShell.user_setup): fixed bug where
+	some files weren't being included in a -upgrade.
+	(InteractiveShell.init_readline): Added 'set show-all-if-ambiguous
+	on' so that the first tab completes.
+	(InteractiveShell.handle_magic): fixed bug with spaces around
+	quotes breaking many magic commands.
+
+	* setup.py: added note about ignoring the syntax error messages at
+	installation.
+
+	* IPython/UserConfig/magic_gnuplot.py (magic_gp): finished
+	streamlining the gnuplot interface, now there's only one magic @gp.
+
+2002-03-17  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/UserConfig/magic_gnuplot.py: new name for the
+	example-magic_pm.py file. Much enhanced system, now with a shell
+	for communicating directly with gnuplot, one command at a time.
+
+	* IPython/Magic.py (Magic.magic_run): added option -n to prevent
+	setting __name__=='__main__'.
+
+	* IPython/UserConfig/example-magic_pm.py (magic_pm): Added
+	mini-shell for accessing gnuplot from inside ipython. Should
+	extend it later for grace access too. Inspired by Arnd's
+	suggestion.
+
+	* IPython/iplib.py (InteractiveShell.handle_magic): fixed bug when
+	calling magic functions with () in their arguments. Thanks to Arnd
+	Baecker for pointing this to me.
+
+	* IPython/numutils.py (sum_flat): fixed bug. Would recurse
+	infinitely for integer or complex arrays (only worked with floats).
+
+2002-03-16  Fernando Perez  <fperez@colorado.edu>
+
+	* setup.py: Merged setup and setup_windows into a single script
+	which properly handles things for windows users.
+
+2002-03-15  Fernando Perez  <fperez@colorado.edu>
+
+	* Big change to the manual: now the magics are all automatically
+	documented. This information is generated from their docstrings
+	and put in a latex file included by the manual lyx file. This way
+	we get always up to date information for the magics. The manual
+	now also has proper version information, also auto-synced.
+
+	For this to work, an undocumented --magic_docstrings option was added.
+
+2002-03-13  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ultraTB.py (TermColors): fixed problem with dark colors
+	under CDE terminals. An explicit ;2 color reset is needed in the escapes.
+
+2002-03-12  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ultraTB.py (TermColors): changed color escapes again to
+	fix the (old, reintroduced) line-wrapping bug. Basically, if
+	\001..\002 aren't given in the color escapes, lines get wrapped
+	weirdly. But giving those screws up old xterms and emacs terms. So
+	I added some logic for emacs terms to be ok, but I can't identify old
+	xterms separately ($TERM=='xterm' for many terminals, like konsole).
+
+2002-03-10  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/usage.py (__doc__): Various documentation cleanups and
+	updates, both in usage docstrings and in the manual.
+
+	* IPython/Prompts.py (CachedOutput.set_colors): cleanups for
+	handling of caching. Set minimum acceptabe value for having a
+	cache at 20 values.
+
+	* IPython/iplib.py (InteractiveShell.user_setup): moved the
+	install_first_time function to a method, renamed it and added an
+	'upgrade' mode. Now people can update their config directory with
+	a simple command line switch (-upgrade, also new).
+
+	* IPython/Magic.py (Magic.magic_pfile): Made @pfile an alias to
+	@file (convenient for automagic users under Python >= 2.2). 
+	Removed @files (it seemed more like a plural than an abbrev. of
+	'file show').
+
+	* IPython/iplib.py (install_first_time): Fixed crash if there were
+	backup files ('~') in .ipython/ install directory.
+
+	* IPython/ipmaker.py (make_IPython): fixes for new prompt
+	system. Things look fine, but these changes are fairly
+	intrusive. Test them for a few days.
+
+	* IPython/Prompts.py (CachedOutput.__init__): Massive rewrite of
+	the prompts system. Now all in/out prompt strings are user
+	controllable. This is particularly useful for embedding, as one
+	can tag embedded instances with particular prompts. 
+
+	Also removed global use of sys.ps1/2, which now allows nested
+	embeddings without any problems. Added command-line options for
+	the prompt strings.
+
+2002-03-08  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/UserConfig/example-embed-short.py (ipshell): added
+	example file with the bare minimum code for embedding.
+
+	* IPython/Shell.py (IPythonShellEmbed.set_dummy_mode): added
+	functionality for the embeddable shell to be activated/deactivated
+	either globally or at each call.
+
+	* IPython/Prompts.py (Prompt1.auto_rewrite): Fixes the problem of
+	rewriting the prompt with '--->' for auto-inputs with proper
+	coloring. Now the previous UGLY hack in handle_auto() is gone, and
+	this is handled by the prompts class itself, as it should.
+
+2002-03-05  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/Magic.py (Magic.magic_logstart): Changed @log to
+	@logstart to avoid name clashes with the math log function.
+
+	* Big updates to X/Emacs section of the manual.
+
+	* Removed ipython_emacs. Milan explained to me how to pass
+	arguments to ipython through Emacs. Some day I'm going to end up
+	learning some lisp...
+
+2002-03-04  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ipython_emacs: Created script to be used as the
+	py-python-command Emacs variable so we can pass IPython
+	parameters. I can't figure out how to tell Emacs directly to pass
+	parameters to IPython, so a dummy shell script will do it.
+
+	Other enhancements made for things to work better under Emacs'
+	various types of terminals. Many thanks to Milan Zamazal
+	<pdm-AT-zamazal.org> for all the suggestions and pointers.
+
+2002-03-01  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ipmaker.py (make_IPython): added a --readline! option so
+	that loading of readline is now optional. This gives better
+	control to emacs users.
+
+	* IPython/ultraTB.py (__date__): Modified color escape sequences
+	and now things work fine under xterm and in Emacs' term buffers
+	(though not shell ones). Well,  in emacs you get colors, but all
+	seem to be 'light' colors (no difference between dark and light
+	ones). But the garbage chars are gone, and also in xterms. It
+	seems that now I'm using 'cleaner' ansi sequences.
+
+2002-02-21  Fernando Perez  <fperez@colorado.edu>
+
+	* Released 0.2.7 (mainly to publish the scoping fix).
+	
+	* IPython/Logger.py (Logger.logstate): added. A corresponding
+	@logstate magic was created.
+
+	* IPython/Magic.py: fixed nested scoping problem under Python
+	2.1.x (automagic wasn't working).
+
+2002-02-20  Fernando Perez  <fperez@colorado.edu>
+
+	* Released 0.2.6.
+
+	* IPython/OutputTrap.py (OutputTrap.__init__): added a 'quiet'
+	option so that logs can come out without any headers at all.
+
+	* IPython/UserConfig/ipythonrc-scipy.py: created a profile for
+	SciPy.
+
+	* IPython/iplib.py (InteractiveShell.embed_mainloop): Changed so
+	that embedded IPython calls don't require vars() to be explicitly
+	passed. Now they are extracted from the caller's frame (code
+	snatched from Eric Jones' weave). Added better documentation to
+	the section on embedding and the example file.
+
+	* IPython/genutils.py (page): Changed so that under emacs, it just
+	prints the string. You can then page up and down in the emacs
+	buffer itself. This is how the builtin help() works.
+
+	* IPython/Prompts.py (CachedOutput.__call__): Fixed issue with
+	macro scoping: macros need to be executed in the user's namespace
+	to work as if they had been typed by the user.
+
+	* IPython/Magic.py (Magic.magic_macro): Changed macros so they
+	execute automatically (no need to type 'exec...'). They then
+	behave like 'true macros'. The printing system was also modified
+	for this to work.
+
+2002-02-19  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (page_file): new function for paging files
+	in an OS-independent way. Also necessary for file viewing to work
+	well inside Emacs buffers.
+	(page): Added checks for being in an emacs buffer.
+	(page): fixed bug for Windows ($TERM isn't set in Windows). Fixed
+	same bug in iplib.
+
+2002-02-18  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.init_readline): modified use
+	of readline so that IPython can work inside an Emacs buffer.
+
+	* IPython/ultraTB.py (AutoFormattedTB.__call__): some fixes to
+	method signatures (they weren't really bugs, but it looks cleaner
+	and keeps PyChecker happy).
+
+	* IPython/ipmaker.py (make_IPython): added hooks Struct to __IP
+	for implementing various user-defined hooks. Currently only
+	display is done.
+
+	* IPython/Prompts.py (CachedOutput._display): changed display
+	functions so that they can be dynamically changed by users easily.
+
+	* IPython/Extensions/numeric_formats.py (num_display): added an
+	extension for printing NumPy arrays in flexible manners. It
+	doesn't do anything yet, but all the structure is in
+	place. Ultimately the plan is to implement output format control
+	like in Octave.
+
+	* IPython/Magic.py (Magic.lsmagic): changed so that bound magic
+	methods are found at run-time by all the automatic machinery.
+
+2002-02-17  Fernando Perez  <fperez@colorado.edu>
+
+	* setup_Windows.py (make_shortcut): documented. Cleaned up the
+	whole file a little.
+
+	* ToDo: closed this document. Now there's a new_design.lyx
+	document for all new ideas. Added making a pdf of it for the
+	end-user distro.
+
+	* IPython/Logger.py (Logger.switch_log): Created this to replace
+	logon() and logoff(). It also fixes a nasty crash reported by 
+	Philip Hisley <compsys-AT-starpower.net>. Many thanks to him.
+
+	* IPython/iplib.py (complete): got auto-completion to work with
+	automagic (I had wanted this for a long time).
+
+	* IPython/Magic.py (Magic.magic_files): Added @files as an alias
+	to @file, since file() is now a builtin and clashes with automagic
+	for @file.
+
+	* Made some new files: Prompts, CrashHandler, Magic, Logger. All
+	of this was previously in iplib, which had grown to more than 2000
+	lines, way too long. No new functionality, but it makes managing
+	the code a bit easier.
+
+	* IPython/iplib.py (IPythonCrashHandler.__call__): Added version
+	information to crash reports.
+
+2002-02-12  Fernando Perez  <fperez@colorado.edu>
+
+	* Released 0.2.5.
+
+2002-02-11  Fernando Perez  <fperez@colorado.edu>
+
+	* Wrote a relatively complete Windows installer. It puts
+	everything in place, creates Start Menu entries and fixes the
+	color issues. Nothing fancy, but it works.
+
+2002-02-10  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.safe_execfile): added an
+	os.path.expanduser() call so that we can type @run ~/myfile.py and
+	have thigs work as expected.
+
+	* IPython/genutils.py (page): fixed exception handling so things
+	work both in Unix and Windows correctly. Quitting a pager triggers
+	an IOError/broken pipe in Unix, and in windows not finding a pager
+	is also an IOError, so I had to actually look at the return value
+	of the exception, not just the exception itself. Should be ok now.
+
+	* IPython/ultraTB.py (ColorSchemeTable.set_active_scheme):
+	modified to allow case-insensitive color scheme changes.
+
+2002-02-09  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/genutils.py (native_line_ends): new function to leave
+	user config files with os-native line-endings.
+
+	* README and manual updates.
+
+	* IPython/genutils.py: fixed unicode bug: use types.StringTypes
+	instead of StringType to catch Unicode strings.
+
+	* IPython/genutils.py (filefind): fixed bug for paths with
+	embedded spaces (very common in Windows).
+
+	* IPython/ipmaker.py (make_IPython): added a '.ini' to the rc
+	files under Windows, so that they get automatically associated
+	with a text editor. Windows makes it a pain to handle
+	extension-less files.
+
+	* IPython/iplib.py (InteractiveShell.init_readline): Made the
+	warning about readline only occur for Posix. In Windows there's no
+	way to get readline, so why bother with the warning.
+
+	* IPython/Struct.py (Struct.__str__): fixed to use self.__dict__
+	for __str__ instead of dir(self), since dir() changed in 2.2.
+
+	* Ported to Windows! Tested on XP, I suspect it should work fine
+	on NT/2000, but I don't think it will work on 98 et al. That
+	series of Windows is such a piece of junk anyway that I won't try
+	porting it there. The XP port was straightforward, showed a few
+	bugs here and there (fixed all), in particular some string
+	handling stuff which required considering Unicode strings (which
+	Windows uses). This is good, but hasn't been too tested :) No
+	fancy installer yet, I'll put a note in the manual so people at
+	least make manually a shortcut.
+
+	* IPython/iplib.py (Magic.magic_colors): Unified the color options
+	into a single one, "colors". This now controls both prompt and
+	exception color schemes, and can be changed both at startup
+	(either via command-line switches or via ipythonrc files) and at
+	runtime, with @colors.
+	(Magic.magic_run): renamed @prun to @run and removed the old
+	@run. The two were too similar to warrant keeping both.
+
+2002-02-03  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (install_first_time): Added comment on how to
+	configure the color options for first-time users. Put a <return>
+	request at the end so that small-terminal users get a chance to
+	read the startup info.
+
+2002-01-23  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (CachedOutput.update): Changed output memory
+	variable names from _o,_oo,_ooo,_o<n> to simply _,__,___,_<n>. For
+	input history we still use _i. Did this b/c these variable are
+	very commonly used in interactive work, so the less we need to
+	type the better off we are.
+	(Magic.magic_prun): updated @prun to better handle the namespaces
+	the file will run in, including a fix for __name__ not being set
+	before.
+
+2002-01-20  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/ultraTB.py (VerboseTB.linereader): Fixed printing of
+	extra garbage for Python 2.2. Need to look more carefully into
+	this later.
+
+2002-01-19  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.showtraceback): fixed to
+	display SyntaxError exceptions properly formatted when they occur
+	(they can be triggered by imported code).
+
+2002-01-18  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.safe_execfile): now
+	SyntaxError exceptions are reported nicely formatted, instead of
+	spitting out only offset information as before.
+	(Magic.magic_prun): Added the @prun function for executing
+	programs with command line args inside IPython.
+
+2002-01-16  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (Magic.magic_hist): Changed @hist and @dhist
+	to *not* include the last item given in a range. This brings their
+	behavior in line with Python's slicing: 
+	  a[n1:n2] -> a[n1]...a[n2-1]
+	It may be a bit less convenient, but I prefer to stick to Python's
+	conventions *everywhere*, so users never have to wonder.
+	(Magic.magic_macro): Added @macro function to ease the creation of
+	macros.
+
+2002-01-05  Fernando Perez  <fperez@colorado.edu>
+
+	* Released 0.2.4.
+
+	* IPython/iplib.py (Magic.magic_pdef): 
+	(InteractiveShell.safe_execfile): report magic lines and error
+	lines without line numbers so one can easily copy/paste them for
+	re-execution.
+
+	* Updated manual with recent changes.
+
+	* IPython/iplib.py (Magic.magic_oinfo): added constructor
+	docstring printing when class? is called. Very handy for knowing
+	how to create class instances (as long as __init__ is well
+	documented, of course :)
+	(Magic.magic_doc): print both class and constructor docstrings.
+	(Magic.magic_pdef): give constructor info if passed a class and
+	__call__ info for callable object instances.
+
+2002-01-04  Fernando Perez  <fperez@colorado.edu>
+
+	* Made deep_reload() off by default. It doesn't always work
+	exactly as intended, so it's probably safer to have it off. It's
+	still available as dreload() anyway, so nothing is lost.
+
+2002-01-02  Fernando Perez  <fperez@colorado.edu>
+
+	* Released 0.2.3 (contacted R.Singh at CU about biopython course,
+	so I wanted an updated release).
+
+2001-12-27  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython/iplib.py (InteractiveShell.interact): Added the original
+	code from 'code.py' for this module in order to change the
+	handling of a KeyboardInterrupt. This was necessary b/c otherwise
+	the history cache would break when the user hit Ctrl-C, and
+	interact() offers no way to add any hooks to it.
+
+2001-12-23  Fernando Perez  <fperez@colorado.edu>
+
+	* setup.py: added check for 'MANIFEST' before trying to remove
+	it. Thanks to Sean Reifschneider.
+
+2001-12-22  Fernando Perez  <fperez@colorado.edu>
+
+	* Released 0.2.2.
+
+	* Finished (reasonably) writing the manual. Later will add the
+	python-standard navigation stylesheets, but for the time being
+	it's fairly complete. Distribution will include html and pdf
+	versions.
+
+	* Bugfix: '.' wasn't being added to sys.path. Thanks to Prabhu
+	(MayaVi author).
+
+2001-12-21  Fernando Perez  <fperez@colorado.edu>
+
+	* Released 0.2.1. Barring any nasty bugs, this is it as far as a
+	good public release, I think (with the manual and the distutils
+	installer). The manual can use some work, but that can go
+	slowly. Otherwise I think it's quite nice for end users. Next
+	summer, rewrite the guts of it...
+
+	* Changed format of ipythonrc files to use whitespace as the
+	separator instead of an explicit '='. Cleaner.
+
+2001-12-20  Fernando Perez  <fperez@colorado.edu>
+
+	* Started a manual in LyX. For now it's just a quick merge of the
+	various internal docstrings and READMEs. Later it may grow into a
+	nice, full-blown manual.
+
+	* Set up a distutils based installer. Installation should now be
+	trivially simple for end-users.
+
+2001-12-11  Fernando Perez  <fperez@colorado.edu>
+
+	* Released 0.2.0. First public release, announced it at
+	comp.lang.python. From now on, just bugfixes...
+
+	* Went through all the files, set copyright/license notices and
+	cleaned up things. Ready for release.
+
+2001-12-10  Fernando Perez  <fperez@colorado.edu>
+
+	* Changed the first-time installer not to use tarfiles. It's more
+	robust now and less unix-dependent. Also makes it easier for
+	people to later upgrade versions.
+
+	* Changed @exit to @abort to reflect the fact that it's pretty
+	brutal (a sys.exit()). The difference between @abort and Ctrl-D
+	becomes significant only when IPyhton is embedded: in that case,
+	C-D closes IPython only, but @abort kills the enclosing program
+	too (unless it had called IPython inside a try catching
+	SystemExit).
+
+	* Created Shell module which exposes the actuall IPython Shell
+	classes, currently the normal and the embeddable one. This at
+	least offers a stable interface we won't need to change when
+	(later) the internals are rewritten. That rewrite will be confined
+	to iplib and ipmaker, but the Shell interface should remain as is.
+
+	* Added embed module which offers an embeddable IPShell object,
+	useful to fire up IPython *inside* a running program. Great for
+	debugging or dynamical data analysis.
+
+2001-12-08  Fernando Perez  <fperez@colorado.edu>
+
+	* Fixed small bug preventing seeing info from methods of defined
+	objects (incorrect namespace in _ofind()).
+
+	* Documentation cleanup. Moved the main usage docstrings to a
+	separate file, usage.py (cleaner to maintain, and hopefully in the
+	future some perlpod-like way of producing interactive, man and
+	html docs out of it will be found).
+
+	* Added @profile to see your profile at any time.
+
+	* Added @p as an alias for 'print'. It's especially convenient if
+	using automagic ('p x' prints x).
+
+	* Small cleanups and fixes after a pychecker run.
+
+	* Changed the @cd command to handle @cd - and @cd -<n> for
+	visiting any directory in _dh.
+
+	* Introduced _dh, a history of visited directories. @dhist prints
+	it out with numbers.
+
+2001-12-07  Fernando Perez  <fperez@colorado.edu>
+
+	* Released 0.1.22
+
+	* Made initialization a bit more robust against invalid color
+	options in user input (exit, not traceback-crash).
+
+	* Changed the bug crash reporter to write the report only in the
+	user's .ipython directory. That way IPython won't litter people's
+	hard disks with crash files all over the place. Also print on
+	screen the necessary mail command.
+
+	* With the new ultraTB, implemented LightBG color scheme for light
+	background terminals. A lot of people like white backgrounds, so I
+	guess we should at least give them something readable.
+
+2001-12-06  Fernando Perez  <fperez@colorado.edu>
+
+	* Modified the structure of ultraTB. Now there's a proper class
+	for tables of color schemes which allow adding schemes easily and
+	switching the active scheme without creating a new instance every
+	time (which was ridiculous). The syntax for creating new schemes
+	is also cleaner. I think ultraTB is finally done, with a clean
+	class structure. Names are also much cleaner (now there's proper
+	color tables, no need for every variable to also have 'color' in
+	its name).
+
+	* Broke down genutils into separate files. Now genutils only
+	contains utility functions, and classes have been moved to their
+	own files (they had enough independent functionality to warrant
+	it): ConfigLoader, OutputTrap, Struct.
+
+2001-12-05  Fernando Perez  <fperez@colorado.edu>
+
+	* IPython turns 21! Released version 0.1.21, as a candidate for
+	public consumption. If all goes well, release in a few days.
+
+	* Fixed path bug (files in Extensions/ directory wouldn't be found
+	unless IPython/ was explicitly in sys.path).
+
+	* Extended the FlexCompleter class as MagicCompleter to allow
+	completion of @-starting lines.
+
+	* Created __release__.py file as a central repository for release
+	info that other files can read from.
+
+	* Fixed small bug in logging: when logging was turned on in
+	mid-session, old lines with special meanings (!@?) were being
+	logged without the prepended comment, which is necessary since
+	they are not truly valid python syntax. This should make session
+	restores produce less errors.
+
+	* The namespace cleanup forced me to make a FlexCompleter class
+	which is nothing but a ripoff of rlcompleter, but with selectable
+	namespace (rlcompleter only works in __main__.__dict__). I'll try
+	to submit a note to the authors to see if this change can be
+	incorporated in future rlcompleter releases (Dec.6: done)
+
+	* More fixes to namespace handling. It was a mess! Now all
+	explicit references to __main__.__dict__ are gone (except when
+	really needed) and everything is handled through the namespace
+	dicts in the IPython instance. We seem to be getting somewhere
+	with this, finally...
+
+	* Small documentation updates.
+
+	* Created the Extensions directory under IPython (with an
+	__init__.py). Put the PhysicalQ stuff there. This directory should
+	be used for all special-purpose extensions.
+
+	* File renaming:
+	  ipythonlib --> ipmaker
+	  ipplib     --> iplib
+	This makes a bit more sense in terms of what these files actually do.
+
+	* Moved all the classes and functions in ipythonlib to ipplib, so
+	now ipythonlib only has make_IPython(). This will ease up its
+	splitting in smaller functional chunks later.
+
+	* Cleaned up (done, I think) output of @whos. Better column
+	formatting, and now shows str(var) for as much as it can, which is
+	typically what one gets with a 'print var'.
+
+2001-12-04  Fernando Perez  <fperez@colorado.edu>
+
+	* Fixed namespace problems. Now builtin/IPyhton/user names get
+	properly reported in their namespace. Internal namespace handling
+	is finally getting decent (not perfect yet, but much better than
+	the ad-hoc mess we had).
+
+	* Removed -exit option. If people just want to run a python
+	script, that's what the normal interpreter is for. Less
+	unnecessary options, less chances for bugs.
+
+	* Added a crash handler which generates a complete post-mortem if
+	IPython crashes. This will help a lot in tracking bugs down the
+	road.
+
+	* Fixed nasty bug in auto-evaluation part of prefilter(). Names
+	which were boud to functions being reassigned would bypass the
+	logger, breaking the sync of _il with the prompt counter. This
+	would then crash IPython later when a new line was logged.
+
+2001-12-02  Fernando Perez  <fperez@colorado.edu>
+
+	* Made IPython a package. This means people don't have to clutter
+	their sys.path with yet another directory. Changed the INSTALL
+	file accordingly.
+
+	* Cleaned up the output of @who_ls, @who and @whos. @who_ls now
+	sorts its output (so @who shows it sorted) and @whos formats the
+	table according to the width of the first column. Nicer, easier to
+	read. Todo: write a generic table_format() which takes a list of
+	lists and prints it nicely formatted, with optional row/column
+	separators and proper padding and justification. 
+
+	* Released 0.1.20
+
+	* Fixed bug in @log which would reverse the inputcache list (a
+	copy operation was missing).
+
+	* Code cleanup. @config was changed to use page(). Better, since
+	its output is always quite long.
+
+	* Itpl is back as a dependency. I was having too many problems
+	getting the parametric aliases to work reliably, and it's just
+	easier to code weird string operations with it than playing %()s
+	games. It's only ~6k, so I don't think it's too big a deal.
+
+	* Found (and fixed) a very nasty bug with history. !lines weren't
+	getting cached, and the out of sync caches would crash
+	IPython. Fixed it by reorganizing the prefilter/handlers/logger
+	division of labor a bit better. Bug fixed, cleaner structure.
+
+2001-12-01  Fernando Perez  <fperez@colorado.edu>
+
+	* Released 0.1.19
+
+	* Added option -n to @hist to prevent line number printing. Much
+	easier to copy/paste code this way.
+
+	* Created global _il to hold the input list. Allows easy
+	re-execution of blocks of code by slicing it (inspired by Janko's
+	comment on 'macros').
+
+	* Small fixes and doc updates.
+
+	* Rewrote @history function (was @h). Renamed it to @hist, @h is
+	much too fragile with automagic. Handles properly multi-line
+	statements and takes parameters.
+
+2001-11-30  Fernando Perez  <fperez@colorado.edu>
+
+	* Version 0.1.18 released.
+
+	* Fixed nasty namespace bug in initial module imports.
+
+	* Added copyright/license notes to all code files (except
+	DPyGetOpt). For the time being, LGPL. That could change.
+
+	* Rewrote a much nicer README, updated INSTALL, cleaned up
+	ipythonrc-* samples.
+
+	* Overall code/documentation cleanup. Basically ready for
+	release. Only remaining thing: licence decision (LGPL?).
+
+	* Converted load_config to a class, ConfigLoader. Now recursion
+	control is better organized. Doesn't include the same file twice.
+
+2001-11-29  Fernando Perez  <fperez@colorado.edu>
+
+	* Got input history working. Changed output history variables from
+	_p to _o so that _i is for input and _o for output. Just cleaner
+	convention.
+
+	* Implemented parametric aliases. This pretty much allows the
+	alias system to offer full-blown shell convenience, I think.
+
+	* Version 0.1.17 released, 0.1.18 opened.
+
+	* dot_ipython/ipythonrc (alias): added documentation.
+	(xcolor): Fixed small bug (xcolors -> xcolor)
+
+	* Changed the alias system. Now alias is a magic command to define
+	aliases just like the shell. Rationale: the builtin magics should
+	be there for things deeply connected to IPython's
+	architecture. And this is a much lighter system for what I think
+	is the really important feature: allowing users to define quickly
+	magics that will do shell things for them, so they can customize
+	IPython easily to match their work habits. If someone is really
+	desperate to have another name for a builtin alias, they can
+	always use __IP.magic_newname = __IP.magic_oldname. Hackish but
+	works.
+
+2001-11-28  Fernando Perez  <fperez@colorado.edu>
+
+	* Changed @file so that it opens the source file at the proper
+	line. Since it uses less, if your EDITOR environment is
+	configured, typing v will immediately open your editor of choice
+	right at the line where the object is defined. Not as quick as
+	having a direct @edit command, but for all intents and purposes it
+	works. And I don't have to worry about writing @edit to deal with
+	all the editors, less does that.
+
+	* Version 0.1.16 released, 0.1.17 opened.
+
+	* Fixed some nasty bugs in the page/page_dumb combo that could
+	crash IPython.
+
+2001-11-27  Fernando Perez  <fperez@colorado.edu>
+
+	* Version 0.1.15 released, 0.1.16 opened.
+
+	* Finally got ? and ?? to work for undefined things: now it's
+	possible to type {}.get? and get information about the get method
+	of dicts, or os.path? even if only os is defined (so technically
+	os.path isn't). Works at any level. For example, after import os,
+	os?, os.path?, os.path.abspath? all work. This is great, took some
+	work in _ofind.
+
+	* Fixed more bugs with logging. The sanest way to do it was to add
+	to @log a 'mode' parameter. Killed two in one shot (this mode
+	option was a request of Janko's). I think it's finally clean
+	(famous last words).
+
+	* Added a page_dumb() pager which does a decent job of paging on
+	screen, if better things (like less) aren't available. One less
+	unix dependency (someday maybe somebody will port this to
+	windows).
+
+	* Fixed problem in magic_log: would lock of logging out if log
+	creation failed (because it would still think it had succeeded).
+
+	* Improved the page() function using curses to auto-detect screen
+	size. Now it can make a much better decision on whether to print
+	or page a string. Option screen_length was modified: a value 0
+	means auto-detect, and that's the default now.
+
+	* Version 0.1.14 released, 0.1.15 opened. I think this is ready to
+	go out. I'll test it for a few days, then talk to Janko about
+	licences and announce it.
+
+	* Fixed the length of the auto-generated ---> prompt which appears
+	for auto-parens and auto-quotes. Getting this right isn't trivial,
+	with all the color escapes, different prompt types and optional
+	separators. But it seems to be working in all the combinations.
+
+2001-11-26  Fernando Perez  <fperez@colorado.edu>
+
+	* Wrote a regexp filter to get option types from the option names
+	string. This eliminates the need to manually keep two duplicate
+	lists.
+
+	* Removed the unneeded check_option_names. Now options are handled
+	in a much saner manner and it's easy to visually check that things
+	are ok.
+
+	* Updated version numbers on all files I modified to carry a
+	notice so Janko and Nathan have clear version markers.
+
+	* Updated docstring for ultraTB with my changes. I should send
+	this to Nathan.
+
+	* Lots of small fixes. Ran everything through pychecker again.
+
+	* Made loading of deep_reload an cmd line option. If it's not too
+	kosher, now people can just disable it. With -nodeep_reload it's
+	still available as dreload(), it just won't overwrite reload().
+
+	* Moved many options to the no| form (-opt and -noopt
+	accepted). Cleaner.
+
+	* Changed magic_log so that if called with no parameters, it uses
+	'rotate' mode. That way auto-generated logs aren't automatically
+	over-written. For normal logs, now a backup is made if it exists
+	(only 1 level of backups). A new 'backup' mode was added to the
+	Logger class to support this. This was a request by Janko.
+
+	* Added @logoff/@logon to stop/restart an active log.
+
+	* Fixed a lot of bugs in log saving/replay. It was pretty
+	broken. Now special lines (!@,/) appear properly in the command
+	history after a log replay.
+
+	* Tried and failed to implement full session saving via pickle. My
+	idea was to pickle __main__.__dict__, but modules can't be
+	pickled. This would be a better alternative to replaying logs, but
+	seems quite tricky to get to work. Changed -session to be called
+	-logplay, which more accurately reflects what it does. And if we
+	ever get real session saving working, -session is now available.
+
+	* Implemented color schemes for prompts also. As for tracebacks,
+	currently only NoColor and Linux are supported. But now the
+	infrastructure is in place, based on a generic ColorScheme
+	class. So writing and activating new schemes both for the prompts
+	and the tracebacks should be straightforward.
+
+	* Version 0.1.13 released, 0.1.14 opened.
+
+	* Changed handling of options for output cache. Now counter is
+	hardwired starting at 1 and one specifies the maximum number of
+	entries *in the outcache* (not the max prompt counter). This is
+	much better, since many statements won't increase the cache
+	count. It also eliminated some confusing options, now there's only
+	one: cache_size.
+
+	* Added 'alias' magic function and magic_alias option in the
+	ipythonrc file. Now the user can easily define whatever names he
+	wants for the magic functions without having to play weird
+	namespace games. This gives IPython a real shell-like feel.
+
+	* Fixed doc/?/?? for magics. Now all work, in all forms (explicit
+	@ or not).
+
+	This was one of the last remaining 'visible' bugs (that I know
+	of). I think if I can clean up the session loading so it works
+	100% I'll release a 0.2.0 version on c.p.l (talk to Janko first
+	about licensing).	
+
+2001-11-25  Fernando Perez  <fperez@colorado.edu>
+
+	* Rewrote somewhat oinfo (?/??). Nicer, now uses page() and
+	there's a cleaner distinction between what ? and ?? show.
+
+	* Added screen_length option. Now the user can define his own
+	screen size for page() operations.
+
+	* Implemented magic shell-like functions with automatic code
+	generation. Now adding another function is just a matter of adding
+	an entry to a dict, and the function is dynamically generated at
+	run-time. Python has some really cool features!
+
+	* Renamed many options to cleanup conventions a little. Now all
+	are lowercase, and only underscores where needed. Also in the code
+	option name tables are clearer.
+
+	* Changed prompts a little. Now input is 'In [n]:' instead of
+	'In[n]:='. This allows it the numbers to be aligned with the
+	Out[n] numbers, and removes usage of ':=' which doesn't exist in
+	Python (it was a Mathematica thing). The '...' continuation prompt
+	was also changed a little to align better.
+
+	* Fixed bug when flushing output cache. Not all _p<n> variables
+	exist, so their deletion needs to be wrapped in a try:
+
+	* Figured out how to properly use inspect.formatargspec() (it
+	requires the args preceded by *). So I removed all the code from
+	_get_pdef in Magic, which was just replicating that.
+
+	* Added test to prefilter to allow redefining magic function names
+	as variables. This is ok, since the @ form is always available,
+	but whe should allow the user to define a variable called 'ls' if
+	he needs it.
+
+	* Moved the ToDo information from README into a separate ToDo.
+
+	* General code cleanup and small bugfixes. I think it's close to a
+	state where it can be released, obviously with a big 'beta'
+	warning on it.
+
+	* Got the magic function split to work. Now all magics are defined
+	in a separate class. It just organizes things a bit, and now
+	Xemacs behaves nicer (it was choking on InteractiveShell b/c it
+	was too long).
+
+	* Changed @clear to @reset to avoid potential confusions with
+	the shell command clear. Also renamed @cl to @clear, which does
+	exactly what people expect it to from their shell experience.
+
+	Added a check to the @reset command (since it's so
+	destructive, it's probably a good idea to ask for confirmation).
+	But now reset only works for full namespace resetting. Since the
+	del keyword is already there for deleting a few specific
+	variables, I don't see the point of having a redundant magic
+	function for the same task.
+
+2001-11-24  Fernando Perez  <fperez@colorado.edu>
+
+	* Updated the builtin docs (esp. the ? ones).
+
+	* Ran all the code through pychecker. Not terribly impressed with
+	it: lots of spurious warnings and didn't really find anything of
+	substance (just a few modules being imported and not used).
+
+	* Implemented the new ultraTB functionality into IPython. New
+	option: xcolors. This chooses color scheme. xmode now only selects
+	between Plain and Verbose. Better orthogonality.
+
+	* Large rewrite of ultraTB. Much cleaner now, with a separation of
+	mode and color scheme for the exception handlers. Now it's
+	possible to have the verbose traceback with no coloring.
+
+2001-11-23  Fernando Perez  <fperez@colorado.edu>
+
+	* Version 0.1.12 released, 0.1.13 opened.
+
+	* Removed option to set auto-quote and auto-paren escapes by
+	user. The chances of breaking valid syntax are just too high. If
+	someone *really* wants, they can always dig into the code.
+
+	* Made prompt separators configurable.
+
+2001-11-22  Fernando Perez  <fperez@colorado.edu>
+
+	* Small bugfixes in many places.
+
+	* Removed the MyCompleter class from ipplib. It seemed redundant
+	with the C-p,C-n history search functionality. Less code to
+	maintain.
+
+	* Moved all the original ipython.py code into ipythonlib.py. Right
+	now it's just one big dump into a function called make_IPython, so
+	no real modularity has been gained. But at least it makes the
+	wrapper script tiny, and since ipythonlib is a module, it gets
+	compiled and startup is much faster.
+
+	This is a reasobably 'deep' change, so we should test it for a
+	while without messing too much more with the code.
+
+2001-11-21  Fernando Perez  <fperez@colorado.edu>
+
+	* Version 0.1.11 released, 0.1.12 opened for further work.
+
+	* Removed dependency on Itpl. It was only needed in one place. It
+	would be nice if this became part of python, though. It makes life
+	*a lot* easier in some cases.
+
+	* Simplified the prefilter code a bit. Now all handlers are
+	expected to explicitly return a value (at least a blank string).
+
+	* Heavy edits in ipplib. Removed the help system altogether. Now
+	obj?/?? is used for inspecting objects, a magic @doc prints
+	docstrings, and full-blown Python help is accessed via the 'help'
+	keyword. This cleans up a lot of code (less to maintain) and does
+	the job. Since 'help' is now a standard Python component, might as
+	well use it and remove duplicate functionality.
+
+	Also removed the option to use ipplib as a standalone program. By
+	now it's too dependent on other parts of IPython to function alone.
+
+	* Fixed bug in genutils.pager. It would crash if the pager was
+	exited immediately after opening (broken pipe).
+
+	* Trimmed down the VerboseTB reporting a little. The header is
+	much shorter now and the repeated exception arguments at the end
+	have been removed. For interactive use the old header seemed a bit
+	excessive.
+
+	* Fixed small bug in output of @whos for variables with multi-word
+	types (only first word was displayed).
+
+2001-11-17  Fernando Perez  <fperez@colorado.edu>
+
+	* Version 0.1.10 released, 0.1.11 opened for further work.
+
+	* Modified dirs and friends. dirs now *returns* the stack (not
+	prints), so one can manipulate it as a variable. Convenient to
+	travel along many directories.
+
+	* Fixed bug in magic_pdef: would only work with functions with
+	arguments with default values.
+
+2001-11-14  Fernando Perez  <fperez@colorado.edu>
+
+	* Added the PhysicsInput stuff to dot_ipython so it ships as an
+	example with IPython. Various other minor fixes and cleanups.
+
+	* Version 0.1.9 released, 0.1.10 opened for further work.
+
+	* Added sys.path to the list of directories searched in the
+	execfile= option. It used to be the current directory and the
+	user's IPYTHONDIR only.
+
+2001-11-13  Fernando Perez  <fperez@colorado.edu>
+
+	* Reinstated the raw_input/prefilter separation that Janko had
+	initially. This gives a more convenient setup for extending the
+	pre-processor from the outside: raw_input always gets a string,
+	and prefilter has to process it. We can then redefine prefilter
+	from the outside and implement extensions for special
+	purposes.
+
+	Today I got one for inputting PhysicalQuantity objects
+	(from Scientific) without needing any function calls at
+	all. Extremely convenient, and it's all done as a user-level
+	extension (no IPython code was touched). Now instead of:
+		a = PhysicalQuantity(4.2,'m/s**2')
+	one can simply say
+		a = 4.2 m/s**2
+	or even
+		a = 4.2 m/s^2
+	
+	I use this, but it's also a proof of concept: IPython really is
+	fully user-extensible, even at the level of the parsing of the
+	command line. It's not trivial, but it's perfectly doable.
+
+	* Added 'add_flip' method to inclusion conflict resolver. Fixes
+	the problem of modules being loaded in the inverse order in which
+	they were defined in 
+
+	* Version 0.1.8 released, 0.1.9 opened for further work.
+
+	* Added magics pdef, source and file. They respectively show the
+	definition line ('prototype' in C), source code and full python
+	file for any callable object. The object inspector oinfo uses
+	these to show the same information.
+
+	* Version 0.1.7 released, 0.1.8 opened for further work.
+
+	* Separated all the magic functions into a class called Magic. The
+	InteractiveShell class was becoming too big for Xemacs to handle
+	(de-indenting a line would lock it up for 10 seconds while it
+	backtracked on the whole class!)
+
+	FIXME: didn't work. It can be done, but right now namespaces are
+	all messed up. Do it later (reverted it for now, so at least
+	everything works as before).
+
+	* Got the object introspection system (magic_oinfo) working! I
+	think this is pretty much ready for release to Janko, so he can
+	test it for a while and then announce it. Pretty much 100% of what
+	I wanted for the 'phase 1' release is ready. Happy, tired.
+
+2001-11-12  Fernando Perez  <fperez@colorado.edu>
+
+	* Version 0.1.6 released, 0.1.7 opened for further work.
+
+	* Fixed bug in printing: it used to test for truth before
+	printing, so 0 wouldn't print. Now checks for None.
+
+	* Fixed bug where auto-execs increase the prompt counter by 2 (b/c
+	they have to call len(str(sys.ps1)) ). But the fix is ugly, it
+	reaches by hand into the outputcache. Think of a better way to do
+	this later.
+
+	* Various small fixes thanks to Nathan's comments.
+
+	* Changed magic_pprint to magic_Pprint. This way it doesn't
+	collide with pprint() and the name is consistent with the command
+	line option.
+
+	* Changed prompt counter behavior to be fully like
+	Mathematica's. That is, even input that doesn't return a result
+	raises the prompt counter. The old behavior was kind of confusing
+	(getting the same prompt number several times if the operation
+	didn't return a result).
+
+	* Fixed Nathan's last name in a couple of places (Gray, not Graham).
+
+	* Fixed -Classic mode (wasn't working anymore).
+
+	* Added colored prompts using Nathan's new code. Colors are
+	currently hardwired, they can be user-configurable. For
+	developers, they can be chosen in file ipythonlib.py, at the
+	beginning of the CachedOutput class def.
+
+2001-11-11  Fernando Perez  <fperez@colorado.edu>
+
+	* Version 0.1.5 released, 0.1.6 opened for further work.
+
+	* Changed magic_env to *return* the environment as a dict (not to
+	print it). This way it prints, but it can also be processed.
+
+	* Added Verbose exception reporting to interactive
+	exceptions. Very nice, now even 1/0 at the prompt gives a verbose
+	traceback. Had to make some changes to the ultraTB file. This is
+	probably the last 'big' thing in my mental todo list.  This ties
+	in with the next entry:
+
+	* Changed -Xi and -Xf to a single -xmode option. Now all the user
+	has to specify is Plain, Color or Verbose for all exception
+	handling.
+
+	* Removed ShellServices option. All this can really be done via
+	the magic system. It's easier to extend, cleaner and has automatic
+	namespace protection and documentation.
+
+2001-11-09  Fernando Perez  <fperez@colorado.edu>
+
+	* Fixed bug in output cache flushing (missing parameter to
+	__init__). Other small bugs fixed (found using pychecker).
+
+	* Version 0.1.4 opened for bugfixing.
+
+2001-11-07  Fernando Perez  <fperez@colorado.edu>
+
+	* Version 0.1.3 released, mainly because of the raw_input bug.
+
+	* Fixed NASTY bug in raw_input: input line wasn't properly parsed
+	and when testing for whether things were callable, a call could
+	actually be made to certain functions. They would get called again
+	once 'really' executed, with a resulting double call. A disaster
+	in many cases (list.reverse() would never work!).
+
+	* Removed prefilter() function, moved its code to raw_input (which
+	after all was just a near-empty caller for prefilter). This saves
+	a function call on every prompt, and simplifies the class a tiny bit.
+
+	* Fix _ip to __ip name in magic example file.
+
+	* Changed 'tar -x -f' to 'tar xvf' in auto-installer. This should
+	work with non-gnu versions of tar.
+
+2001-11-06  Fernando Perez  <fperez@colorado.edu>
+
+	* Version 0.1.2. Just to keep track of the recent changes.
+
+	* Fixed nasty bug in output prompt routine. It used to check 'if
+	arg != None...'. Problem is, this fails if arg implements a
+	special comparison (__cmp__) which disallows comparing to
+	None. Found it when trying to use the PhysicalQuantity module from
+	ScientificPython.
+
+2001-11-05  Fernando Perez  <fperez@colorado.edu>
+
+	* Also added dirs. Now the pushd/popd/dirs family functions
+	basically like the shell, with the added convenience of going home
+	when called with no args.
+
+	* pushd/popd slightly modified to mimic shell behavior more
+	closely.
+
+	* Added env,pushd,popd from ShellServices as magic functions. I
+	think the cleanest will be to port all desired functions from
+	ShellServices as magics and remove ShellServices altogether. This
+	will provide a single, clean way of adding functionality
+	(shell-type or otherwise) to IP.
+
+2001-11-04  Fernando Perez  <fperez@colorado.edu>
+
+	* Added .ipython/ directory to sys.path. This way users can keep
+	customizations there and access them via import.
+
+2001-11-03  Fernando Perez  <fperez@colorado.edu>
+
+	* Opened version 0.1.1 for new changes.
+
+	* Changed version number to 0.1.0: first 'public' release, sent to
+	Nathan and Janko.
+
+	* Lots of small fixes and tweaks.
+
+	* Minor changes to whos format. Now strings are shown, snipped if
+	too long.
+
+	* Changed ShellServices to work on __main__ so they show up in @who
+
+	* Help also works with ? at the end of a line:
+		?sin and sin?
+	both produce the same effect. This is nice, as often I use the
+	tab-complete to find the name of a method, but I used to then have
+	to go to the beginning of the line to put a ? if I wanted more
+	info. Now I can just add the ? and hit return. Convenient.
+
+2001-11-02  Fernando Perez  <fperez@colorado.edu>
+
+	* Python version check (>=2.1) added.
+
+	* Added LazyPython documentation. At this point the docs are quite
+	a mess. A cleanup is in order.
+
+	* Auto-installer created. For some bizarre reason, the zipfiles
+	module isn't working on my system. So I made a tar version
+	(hopefully the command line options in various systems won't kill
+	me).
+
+	* Fixes to Struct in genutils. Now all dictionary-like methods are
+	protected (reasonably).
+
+	* Added pager function to genutils and changed ? to print usage
+	note through it (it was too long).
+
+	* Added the LazyPython functionality. Works great! I changed the
+	auto-quote escape to ';', it's on home row and next to '. But
+	both auto-quote and auto-paren (still /) escapes are command-line
+	parameters.
+	
+
+2001-11-01  Fernando Perez  <fperez@colorado.edu>
+
+	* Version changed to 0.0.7. Fairly large change: configuration now
+	is all stored in a directory, by default .ipython. There, all
+	config files have normal looking names (not .names)
+
+	* Version 0.0.6 Released first to Lucas and Archie as a test
+	run. Since it's the first 'semi-public' release, change version to
+	> 0.0.6 for any changes now.
+
+	* Stuff I had put in the ipplib.py changelog:
+	
+	Changes to InteractiveShell:
+	
+	- Made the usage message a parameter.
+	
+	- Require the name of the shell variable to be given. It's a bit
+	of a hack, but allows the name 'shell' not to be hardwire in the
+	magic (@) handler, which is problematic b/c it requires
+	polluting the global namespace with 'shell'. This in turn is
+	fragile: if a user redefines a variable called shell, things
+	break.
+
+	- magic @: all functions available through @ need to be defined
+	as magic_<name>, even though they can be called simply as
+	@<name>. This allows the special command @magic to gather
+	information automatically about all existing magic functions,
+	even if they are run-time user extensions, by parsing the shell
+	instance __dict__ looking for special magic_ names.
+
+	- mainloop: added *two* local namespace parameters. This allows
+	the class to differentiate between parameters which were there
+	before and after command line initialization was processed. This
+	way, later @who can show things loaded at startup by the
+	user. This trick was necessary to make session saving/reloading
+	really work: ideally after saving/exiting/reloading a session,
+	*everythin* should look the same, including the output of @who. I
+	was only able to make this work with this double namespace
+	trick.
+
+	- added a header to the logfile which allows (almost) full
+	session restoring.
+
+	- prepend lines beginning with @ or !, with a and log
+	them. Why?  !lines: may be useful to know what you did @lines:
+	they may affect session state. So when restoring a session, at
+	least inform the user of their presence. I couldn't quite get
+	them to properly re-execute, but at least the user is warned.
+
+	* Started ChangeLog.
diff --git a/doc/README.txt b/doc/README.txt
new file mode 100644
index 0000000..6a6745a
--- /dev/null
+++ b/doc/README.txt
@@ -0,0 +1,14 @@
+Current version information
+---------------------------
+
+Please open manual.pdf for a PDF version of IPython's user manual, or go to
+the manual/ directory for an HTML version.
+
+
+Bugs and future developments
+----------------------------
+
+The new_design.pdf document is a description of the goals for IPython's future
+development.  It includes a TODO/bugs section listing all currently known bugs
+in IPython.  Please report any bug you encounter if it is not already listed
+there.
diff --git a/doc/README_Windows.txt b/doc/README_Windows.txt
new file mode 100644
index 0000000..0f90694
--- /dev/null
+++ b/doc/README_Windows.txt
@@ -0,0 +1,39 @@
+Notes for Windows Users
+=======================
+
+These are just minimal notes.  The manual contains more detailed
+information.
+
+Requirements
+------------
+
+IPython runs under (as far as the Windows family is concerned):
+
+- Windows XP (I think WinNT/2000 are ok): works well.  It needs:
+
+  * Gary Bishop's readline from 
+    http://sourceforge.net/projects/uncpythontools.
+    
+  * This in turn requires Tomas Heller's ctypes from
+    http://starship.python.net/crew/theller/ctypes.
+
+- Windows 95/98/ME: I have no idea. It should work, but I can't test.
+
+- CygWin environments should work, they are basically Posix.
+
+It needs Python 2.2 or newer.
+
+
+Installation
+------------
+
+Double-click the supplied .exe installer file.  If all goes well, that's all
+you need to do. You should now have an IPython entry in your Start Menu.
+
+In case the automatic installer does not work for some reason, you can
+download the ipython-XXX.tar.gz file, which contains the full IPython source
+distribution (the popular WinZip can read .tar.gz files). After uncompressing
+the archive, you can install it at a command terminal just like any other
+Python module, by using python setup.py install'. After this completes, you
+can run the supplied win32_manual_post_install.py script which will add
+the relevant shortcuts to your startup menu.
diff --git a/doc/examples/example-embed-short.py b/doc/examples/example-embed-short.py
new file mode 100644
index 0000000..4b2e735
--- /dev/null
+++ b/doc/examples/example-embed-short.py
@@ -0,0 +1,51 @@
+"""Quick code snippets for embedding IPython into other programs.
+
+See example-embed.py for full details, this file has the bare minimum code for
+cut and paste use once you understand how to use the system."""
+
+#---------------------------------------------------------------------------
+# This code loads IPython but modifies a few things if it detects it's running
+# embedded in another IPython session (helps avoid confusion)
+
+try:
+    __IPYTHON__
+except NameError:
+    argv = ['']
+    banner = exit_msg = ''
+else:
+    # Command-line options for IPython (a list like sys.argv)
+    argv = ['-pi1','In <\\#>:','-pi2','   .\\D.:','-po','Out<\\#>:']
+    banner = '*** Nested interpreter ***'
+    exit_msg = '*** Back in main IPython ***'
+
+# First import the embeddable shell class
+from IPython.Shell import IPShellEmbed
+# Now create the IPython shell instance. Put ipshell() anywhere in your code
+# where you want it to open.
+ipshell = IPShellEmbed(argv,banner=banner,exit_msg=exit_msg)
+                            
+#---------------------------------------------------------------------------
+# This code will load an embeddable IPython shell always with no changes for
+# nested embededings.
+
+from IPython.Shell import IPShellEmbed
+ipshell = IPShellEmbed()
+# Now ipshell() will open IPython anywhere in the code.
+
+#---------------------------------------------------------------------------
+# This code loads an embeddable shell only if NOT running inside
+# IPython. Inside IPython, the embeddable shell variable ipshell is just a
+# dummy function.
+
+try:
+    __IPYTHON__
+except NameError:
+    from IPython.Shell import IPShellEmbed
+    ipshell = IPShellEmbed()
+    # Now ipshell() will open IPython anywhere in the code
+else:
+    # Define a dummy ipshell() so the same code doesn't crash inside an
+    # interactive IPython
+    def ipshell(): pass
+
+#******************* End of file <example-embed-short.py> ********************
diff --git a/doc/examples/example-embed.py b/doc/examples/example-embed.py
new file mode 100755
index 0000000..88d67f5
--- /dev/null
+++ b/doc/examples/example-embed.py
@@ -0,0 +1,127 @@
+#!/usr/bin/env python
+
+"""An example of how to embed an IPython shell into a running program.
+
+Please see the documentation in the IPython.Shell module for more details.
+
+The accompanying file example-embed-short.py has quick code fragments for
+embedding which you can cut and paste in your code once you understand how
+things work.
+
+The code in this file is deliberately extra-verbose, meant for learning."""
+
+# The basics to get you going:
+
+# IPython sets the __IPYTHON__ variable so you can know if you have nested
+# copies running.
+
+# Try running this code both at the command line and from inside IPython (with
+# %run example-embed.py)
+try:
+    __IPYTHON__
+except NameError:
+    nested = 0
+    args = ['']
+else:
+    print "Running nested copies of IPython."
+    print "The prompts for the nested copy have been modified"
+    nested = 1
+    # what the embedded instance will see as sys.argv:
+    args = ['-pi1','In <\\#>:','-pi2','   .\\D.:','-po','Out<\\#>:','-nosep']
+
+# First import the embeddable shell class
+from IPython.Shell import IPShellEmbed
+
+# Now create an instance of the embeddable shell. The first argument is a
+# string with options exactly as you would type them if you were starting
+# IPython at the system command line. Any parameters you want to define for
+# configuration can thus be specified here.
+ipshell = IPShellEmbed(args,
+                       banner = 'Dropping into IPython',
+                       exit_msg = 'Leaving Interpreter, back to program.')
+
+# Make a second instance, you can have as many as you want.
+if nested:
+    args[1] = 'In2<\\#>'
+else:
+    args = ['-pi1','In2<\\#>:','-pi2','   .\\D.:','-po','Out<\\#>:','-nosep']
+ipshell2 = IPShellEmbed(args,banner = 'Second IPython instance.')
+
+print '\nHello. This is printed from the main controller program.\n'
+
+# You can then call ipshell() anywhere you need it (with an optional
+# message):
+ipshell('***Called from top level. '
+        'Hit Ctrl-D to exit interpreter and continue program.')
+
+print '\nBack in caller program, moving along...\n'
+
+#---------------------------------------------------------------------------
+# More details:
+
+# IPShellEmbed instances don't print the standard system banner and
+# messages. The IPython banner (which actually may contain initialization
+# messages) is available as <instance>.IP.BANNER in case you want it.
+
+# IPShellEmbed instances print the following information everytime they
+# start:
+
+# - A global startup banner.
+
+# - A call-specific header string, which you can use to indicate where in the
+# execution flow the shell is starting.
+
+# They also print an exit message every time they exit.
+
+# Both the startup banner and the exit message default to None, and can be set
+# either at the instance constructor or at any other time with the
+# set_banner() and set_exit_msg() methods.
+
+# The shell instance can be also put in 'dummy' mode globally or on a per-call
+# basis. This gives you fine control for debugging without having to change
+# code all over the place.
+
+# The code below illustrates all this.
+
+
+# This is how the global banner and exit_msg can be reset at any point
+ipshell.set_banner('Entering interpreter - New Banner')
+ipshell.set_exit_msg('Leaving interpreter - New exit_msg')
+
+def foo(m):
+    s = 'spam'
+    ipshell('***In foo(). Try @whos, or print s or m:')
+    print 'foo says m = ',m
+
+def bar(n):
+    s = 'eggs'
+    ipshell('***In bar(). Try @whos, or print s or n:')
+    print 'bar says n = ',n
+    
+# Some calls to the above functions which will trigger IPython:
+print 'Main program calling foo("eggs")\n'
+foo('eggs')
+
+# The shell can be put in 'dummy' mode where calls to it silently return. This
+# allows you, for example, to globally turn off debugging for a program with a
+# single call.
+ipshell.set_dummy_mode(1)
+print '\nTrying to call IPython which is now "dummy":'
+ipshell()
+print 'Nothing happened...'
+# The global 'dummy' mode can still be overridden for a single call
+print '\nOverriding dummy mode manually:'
+ipshell(dummy=0)
+
+# Reactivate the IPython shell
+ipshell.set_dummy_mode(0)
+
+print 'You can even have multiple embedded instances:'
+ipshell2()
+
+print '\nMain program calling bar("spam")\n'
+bar('spam')
+
+print 'Main program finished. Bye!'
+
+#********************** End of file <example-embed.py> ***********************
diff --git a/doc/examples/example-gnuplot.py b/doc/examples/example-gnuplot.py
new file mode 100755
index 0000000..c585fd5
--- /dev/null
+++ b/doc/examples/example-gnuplot.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+"""
+Example code showing how to use Gnuplot and an embedded IPython shell.
+"""
+
+from Numeric import *
+from IPython.numutils import *
+from IPython.Shell import IPShellEmbed
+
+# Arguments to start IPython shell with. Load numeric profile.
+ipargs = ['-profile','numeric']
+ipshell = IPShellEmbed(ipargs)
+
+# Compute sin(x) over the 0..2pi range at 200 points
+x = frange(0,2*pi,npts=200)
+y = sin(x)
+
+# In the 'numeric' profile, IPython has an internal gnuplot instance:
+g = ipshell.IP.gnuplot
+
+# Change some defaults
+g('set style data lines')
+
+# Or also call a multi-line set of gnuplot commands on it:
+g("""
+set xrange [0:pi]     # Set the visible range to half the data only
+set title 'Half sine' # Global gnuplot labels
+set xlabel 'theta'
+set ylabel 'sin(theta)'
+""")
+
+# Now start an embedded ipython.
+ipshell('Starting the embedded IPyhton.\n'
+        'Try calling plot(x,y), or @gpc for direct access to Gnuplot"\n')
+
+#********************** End of file <example-gnuplot.py> *********************
diff --git a/doc/examples/example-magic.py b/doc/examples/example-magic.py
new file mode 100644
index 0000000..449061b
--- /dev/null
+++ b/doc/examples/example-magic.py
@@ -0,0 +1,36 @@
+"""Example of how to define a magic function for extending IPython.
+
+The name of the function *must* begin with magic_. IPython mangles it so
+that magic_foo() becomes available as %foo.
+
+The argument list must be *exactly* (self,parameter_s='').
+
+The single string parameter_s will have the user's input. It is the magic
+function's responsability to parse this string.
+
+That is, if the user types
+>>>%foo a b c
+
+The followinng internal call is generated:
+   self.magic_foo(parameter_s='a b c').
+
+To have any functions defined here available as magic functions in your
+IPython environment, import this file in your configuration file with an
+execfile = this_file.py statement. See the details at the end of the sample
+ipythonrc file.  """
+
+# fisrt define a function with the proper form:
+def magic_foo(self,parameter_s=''):
+    """My very own magic!. (Use docstrings, IPython reads them)."""
+    print 'Magic function. Passed parameter is between < >: <'+parameter_s+'>'
+    print 'The self object is:',self
+
+# Add the new magic function to the class dict:
+from IPython.iplib import InteractiveShell
+InteractiveShell.magic_foo = magic_foo
+
+# And remove the global name to keep global namespace clean.  Don't worry, the
+# copy bound to IPython stays, we're just removing the global name.
+del magic_foo
+
+#********************** End of file <example-magic.py> ***********************
diff --git a/doc/examples/magic_grepl.py b/doc/examples/magic_grepl.py
new file mode 100644
index 0000000..9e50113
--- /dev/null
+++ b/doc/examples/magic_grepl.py
@@ -0,0 +1,60 @@
+"""This function implements a simple grep-like function in pure python.
+
+You can enable it by copying it to your ~/.ipython directory and putting
+
+execfile = magic_grepl.py
+
+in your ipythonrc file.
+
+Code contributed by Gever Tulley <gever@helium.com>, minor changes applied.
+"""
+
+import glob
+import re
+import os
+
+def magic_grepl(self, parameter_s=''):
+    """Search for a pattern in a list of files.
+
+    It prints the names of the files containing the pattern. Similar to 'grep
+    -l' in Unix-like environments.
+
+    Usage: @grepl pattern [files]
+
+    - pattern:  any regular expression pattern which re.compile() will accept.
+    - files: list of files to scan.  It can contain standard unix wildcards.
+    """
+
+    # argument processing
+    params = parameter_s.split()
+    if len(params) > 1:
+        target = params[0]    # first one is the target
+        file_patterns = params[1:]    # all the rest are filenames or patterns
+
+        # build the regular expression
+        expr = re.compile(target)
+
+        for pattern in file_patterns:
+            flist = [f for f in glob.glob(pattern) if os.path.isfile(f)]
+            for filename in flist:
+                # open and read the whole file
+                f = open(filename,'r')
+                data = f.read()
+                f.close()
+
+                # see if pattern occurs in the file
+                if expr.search(data):
+                    print filename
+    else:
+        # no parameters given
+        print("Usage: @grepl pattern [files]");
+
+# Add the new magic function to the class dict:
+from IPython.iplib import InteractiveShell
+InteractiveShell.magic_grepl = magic_grepl
+
+# And remove the global name to keep global namespace clean.  Don't worry, the
+# copy bound to IPython stays, we're just removing the global name.
+del magic_grepl
+
+#********************** End of file <magic_grepl.py> ***********************
diff --git a/doc/ipnb_google_soc.lyx b/doc/ipnb_google_soc.lyx
new file mode 100644
index 0000000..f931c7c
--- /dev/null
+++ b/doc/ipnb_google_soc.lyx
@@ -0,0 +1,645 @@
+#LyX 1.3 created this file. For more info see http://www.lyx.org/
+\lyxformat 221
+\textclass article
+\begin_preamble
+\usepackage{hyperref}
+
+\usepackage{color}
+\definecolor{orange}{cmyk}{0,0.4,0.8,0.2}
+\definecolor{brown}{cmyk}{0,0.75,0.75,0.35}
+
+% Use and configure listings package for nicely formatted code
+\usepackage{listings}
+\lstset{
+  language=Python,
+  basicstyle=\small\ttfamily,
+  commentstyle=\ttfamily\color{blue},
+  stringstyle=\ttfamily\color{brown},
+  showstringspaces=false,
+  breaklines=true,
+  postbreak = \space\dots
+}
+\end_preamble
+\language english
+\inputencoding auto
+\fontscheme palatino
+\graphics default
+\paperfontsize 11
+\spacing single 
+\papersize Default
+\paperpackage a4
+\use_geometry 1
+\use_amsmath 0
+\use_natbib 0
+\use_numerical_citations 0
+\paperorientation portrait
+\leftmargin 1in
+\topmargin 0.9in
+\rightmargin 1in
+\bottommargin 0.9in
+\secnumdepth 3
+\tocdepth 3
+\paragraph_separation skip
+\defskip medskip
+\quotes_language english
+\quotes_times 2
+\papercolumns 1
+\papersides 1
+\paperpagestyle default
+
+\layout Title
+
+Interactive Notebooks for Python
+\newline 
+
+\size small 
+An IPython project for Google's Summer of Code 2005
+\layout Author
+
+Fernando P
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+'{e}
+\end_inset 
+
+rez
+\begin_inset Foot
+collapsed true
+
+\layout Standard
+
+
+\family typewriter 
+\size small 
+Fernando.Perez@colorado.edu
+\end_inset 
+
+
+\layout Abstract
+
+This project aims to develop a file format and interactive support for documents
+ which can combine Python code with rich text and embedded graphics.
+ The initial requirements only aim at being able to edit such documents
+ with a normal programming editor, with final rendering to PDF or HTML being
+ done by calling an external program.
+ The editing component would have to be integrated with IPython.
+ 
+\layout Abstract
+
+This document was written by the IPython developer; it is made available
+ to students looking for projects of interest and for inclusion in their
+ application.
+\layout Section
+
+Project overview
+\layout Standard
+
+Python's interactive interpreter is one of the language's most appealing
+ features for certain types of usage, yet the basic shell which ships with
+ the language is very limited.
+ Over the last few years, IPython
+\begin_inset Foot
+collapsed true
+
+\layout Standard
+
+
+\begin_inset LatexCommand \htmlurl{http://ipython.scipy.org}
+
+\end_inset 
+
+
+\end_inset 
+
+ has become the de facto standard interactive shell in the scientific computing
+ community, and it enjoys wide popularity with general audiences.
+ All the major Linux distributions (Fedora Core via Extras, SUSE, Debian)
+ and OS X (via fink) carry IPython, and Windows users report using it as
+ a viable system shell.
+\layout Standard
+
+However, IPython is currently a command-line only application, based on
+ the readline library and hence with single-line editing capabilities.
+ While this kind of usage is sufficient for many contexts, there are usage
+ cases where integration in a graphical user interface (GUI) is desirable.
+ 
+\layout Standard
+
+In particular, we wish to have an interface where users can execute Python
+ code, input regular text (neither code nor comments) and keep inline graphics,
+ which we will call 
+\emph on 
+Python notebooks
+\emph default 
+.
+ This kind of system is very popular in scientific computing; well known
+ implementations can be found in Mathematica
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+texttrademark
+\end_inset 
+
+\SpecialChar ~
+
+\begin_inset Foot
+collapsed true
+
+\layout Standard
+
+
+\begin_inset LatexCommand \htmlurl{http://www.wolfram.com/products/mathematica}
+
+\end_inset 
+
+
+\end_inset 
+
+ and Maple
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+texttrademark
+\end_inset 
+
+\SpecialChar ~
+
+\begin_inset Foot
+collapsed true
+
+\layout Standard
+
+
+\begin_inset LatexCommand \htmlurl{http://www.maplesoft.com}
+
+\end_inset 
+
+
+\end_inset 
+
+, among others.
+ However, these are proprietary (and quite expensive) systems aimed at an
+ audience of mathematicians, scientists and engineers.
+\layout Standard
+
+The full-blown implementation of a graphical shell supporting this kind
+ of work model is probably too ambitious for a summer project.
+ Simultaneous support for rich-text editing, embedded graphics and syntax-highli
+ghted code is extremely complex, and likely to require far more effort than
+ can be mustered by an individual developer for a short-term project.
+\layout Standard
+
+This project will thus aim to build the necessary base infrastructure to
+ be able to edit such documents from a plain text editor, and to render
+ them to suitable formats for printing or online distribution, such as HTML,
+ PDF or PostScript.
+ This model follows that for the production of LaTeX documents, which can
+ be edited with any text editor.
+\layout Standard
+
+Such documents would be extremely useful for many audiences beyond scientists:
+ one can use them to produce additionally documented code, to explore a
+ problem with Python and maintain all relevant information in the same place,
+ as a way to distribute enhanced Python-based educational materials, etc.
+\layout Standard
+
+Demand for such a system exists, as evidenced by repeated requests made
+ to me by IPython users over the last few years.
+ Unfortunately IPython is only a spare-time project for me, and I have not
+ had the time to devote to this, despite being convinced of its long term
+ value and wide appeal.
+\layout Standard
+
+If this project is successful, the infrastructure laid out by it will be
+ immediately useful for Python users wishing to maintain `literate' programs
+ which include rich formatting.
+ In addition, this will open the door for the future development of graphical
+ shells which can render such documents in real time: this is exactly the
+ development model successfully followed by the LyX
+\begin_inset Foot
+collapsed true
+
+\layout Standard
+
+
+\begin_inset LatexCommand \htmlurl{http://www.lyx.org}
+
+\end_inset 
+
+
+\end_inset 
+
+ document processing system.
+\layout Section
+
+Implementation effort
+\layout Subsection
+
+Specific goals
+\layout Standard
+
+This is a brief outline of the main points of this project.
+ The next section provides details on all of them.
+ The student(s) working on the project would need to:
+\layout Enumerate
+
+Make design decisions for the internal file structure to enable valid Python
+ notebooks.
+ 
+\layout Enumerate
+
+Implement the rendering library, capable of processing an input notebook
+ through reST or LaTeX and producing HTML or PDF output, as well as exporting
+ a `pure-code' Python file stripped of all markup calls.
+\layout Enumerate
+
+Study existing programming editor widgets to find the most suitable one
+ for extending with an IPython connector for interactive execution of the
+ notebooks.
+\layout Subsection
+
+Complexity level
+\layout Standard
+
+This project is relatively complicated.
+ While I will gladly assist the student with design and implementation issues,
+ it will require a fair amount of thinking in terms of overall library architect
+ure.
+ The actual implementation does not require any sophisticated concepts,
+ but rather a reasonably broad knowledge of a wide set of topics (markup,
+ interaction with external programs and libraries, namespace tricks to provide
+ runtime changes in the effect of the markup calls, etc.)
+\layout Standard
+
+While raw novices are welcome to try, I suspect that it may be a bit too
+ much for them.
+ Students wanting to apply should keep in mind, if the money is an important
+ consideration, that Google only gives the $4500 reward upon 
+\emph on 
+successful completion
+\emph default 
+ of the project.
+ So don't bite more than you can chew.
+ Obviously if this doesn't matter, anyone is welcome to participate, since
+ the project can be a very interesting learning experience, and it will
+ provide a genuinely useful tool for many.
+\layout Section
+
+Technical details
+\layout Subsection
+
+The files
+\layout Standard
+
+A basic requirement of this project will be that the Python notebooks shall
+ be valid Python source files, typically with a 
+\family typewriter 
+.py
+\family default 
+ extension.
+ A renderer program can be used to process the markup calls in them and
+ generate output.
+ If run at a regular command line, these files should execute like normal
+ Python files.
+ But when run via a special rendering script, the result should be a properly
+ formatted file.
+ Output formats could be PDF or HTML depending on user-supplied options.
+\layout Standard
+
+A reST markup mode should be implemented, as reST is already widely used
+ in the Python community and is a very simple format to write.
+ The following is a sketch of what such files could look like using reST
+ markup:
+\layout Standard
+
+
+\begin_inset ERT
+status Open
+
+\layout Standard
+
+\backslash 
+lstinputlisting{nbexample.py}
+\end_inset 
+
+
+\layout Standard
+
+Additionally, a LaTeX markup mode should also be implemented.
+ Here's a mockup example of what code using the LaTeX mode could look like.
+\layout Standard
+
+
+\begin_inset ERT
+status Open
+
+\layout Standard
+
+\backslash 
+lstinputlisting{nbexample_latex.py}
+\end_inset 
+
+
+\layout Standard
+
+At this point, it must be noted that the code above is simply a sketch of
+ these ideas, not a finalized design.
+ An important part of this project will be to think about what the best
+ API and structure for this problem should be.
+\layout Subsection
+
+From notebooks to PDF, HTML or Python
+\layout Standard
+
+Once a clean API for markup has been specified, converters will be written
+ to take a python source file which uses notebook constructs, and generate
+ final output in printable formats, such as HTML or PDF.
+ For example, if 
+\family typewriter 
+nbfile.py
+\family default 
+ is a python notebook, then
+\layout LyX-Code
+
+$ pynb --export=pdf nbfile.py
+\layout Standard
+
+should produce 
+\family typewriter 
+nbfile.pdf
+\family default 
+, while
+\layout LyX-Code
+
+$ pynb --export=html nbfile.py
+\layout Standard
+
+would produce an HTML version.
+ The actual rendering will be done by calling appropriate utilities, such
+ as the reST toolchain or LaTeX, depending on the markup used by the file.
+\layout Standard
+
+Additionally, while the notebooks will be valid Python files, if executed
+ on their own, all the markup calls will still return their results, which
+ are not really needed when the file is being treated as pure code.
+ For this reason, a module to execute these files turning the markup calls
+ into no-ops should be written.
+ Using Python 2.4's -m switch, one can then use something like
+\layout LyX-Code
+
+$ python -m notebook nbfile.py
+\layout Standard
+
+and the notebook file 
+\family typewriter 
+nbfile.py
+\family default 
+ will be executed without any overhead introduced by the markup (other than
+ making calls to functions which return immediately).
+ Finally, an exporter to clean code can be trivially implemented, so that:
+\layout LyX-Code
+
+$ pynb --export=python nbfile.py nbcode.py
+\layout Standard
+
+would export only the code in 
+\family typewriter 
+nbfile.py
+\family default 
+ to 
+\family typewriter 
+nbcode.py
+\family default 
+, removing the markup completely.
+ This can be used to generate final production versions of large modules
+ implemented as notebooks, if one wants to eliminate the markup overhead.
+\layout Subsection
+
+The editing environment
+\layout Standard
+
+The first and most important part of the project should be the definition
+ of a clean API and the implementation of the exporter modules as indicated
+ above.
+ Ultimately, such files can be developed using any text editor, since they
+ are nothing more than regular Python code.
+\layout Standard
+
+But once these goals are reached, further integration with an editor will
+ be done, without the need for a full-blown GUI shell.
+ In fact, already today the (X)Emacs editors can provide for interactive
+ usage of such files.
+ Using python-mode in (X)Emacs, one can pass highlighted regions of a file
+ for execution to an underlying python process, and the results are printed
+ in the python window.
+ With recent versions of python-mode, IPython can be used instead of the
+ plain python interpreter, so that IPython's extended interactive capabilities
+ become available within (X)Emacs (improved tracebacks, automatic debugger
+ integration, variable information, easy filesystem access to Python, etc).
+\layout Standard
+
+But even with IPython integration, the usage within (X)Emacs is not ideal
+ for a notebook environment, since the python process buffer is separate
+ from the python file.
+ Therefore, the next stage of the project will be to enable tighter integration
+ between the editing and execution environments.
+ The basic idea is to provide an easy way to mark regions of the file to
+ be executed interactively, and to have the output inserted automatically
+ into the file.
+ The following listing is a mockup of what the resulting file could look
+ like
+\layout Standard
+
+
+\begin_inset ERT
+status Open
+
+\layout Standard
+
+\backslash 
+lstinputlisting{nbexample_output.py}
+\end_inset 
+
+
+\layout Standard
+
+Basically, the editor will execute 
+\family typewriter 
+add(2,3)
+\family default 
+ and insert the string representation of the output into the file, so it
+ can be used for rendering later.
+ 
+\layout Section
+
+Available resources
+\layout Standard
+
+IPython currently has all the necessary infrastructure for code execution,
+ albeit in a rather messy code base.
+ Most I/O is already abstracted out, a necessary condition for embedding
+ in a GUI (since you are not writing to stdout/err but to the GUI's text
+ area).
+ 
+\layout Standard
+
+For interaction with an editor, it will be necessary to identify a good
+ programming editor with a Python-compatible license, which can be extended
+ to communicate with the underlying IPython engine.
+ IDLE, the Tk-based IDE which ships with Python, should obviously be considered.
+ The Scintilla editing component
+\begin_inset Foot
+collapsed true
+
+\layout Standard
+
+
+\begin_inset LatexCommand \htmlurl{http://www.scintilla.org}
+
+\end_inset 
+
+
+\end_inset 
+
+ may also be a viable candidate.
+ 
+\layout Standard
+
+It will also be interesting to look at the LyX editor
+\begin_inset Foot
+collapsed true
+
+\layout Standard
+
+
+\begin_inset LatexCommand \htmlurl{http://www.lyx.org}
+
+\end_inset 
+
+
+\end_inset 
+
+, which already offers a Python client
+\begin_inset Foot
+collapsed true
+
+\layout Standard
+
+
+\begin_inset LatexCommand \htmlurl{http://wiki.lyx.org/Tools/PyClient}
+
+\end_inset 
+
+
+\end_inset 
+
+.
+ Since LyX has very sophisticated LaTeX support, this is a very interesting
+ direction to consider for the future (though LyX makes a poor programming
+ editor).
+\layout Section
+
+Support offered to the students
+\layout Standard
+
+The IPython project already has an established Open Source infrastructure,
+ including CVS repositories, a bug tracker and mailing lists.
+ As the main author and sole maintainer of IPython, I will personally assist
+ the student(s) funded with architectural and design guidance, preferably
+ on the public development mailing list.
+ I expect them to start working by submitting patches until they show, by
+ the quality of their work, that they can be granted CVS write access.
+ I expect most actual implementation work to be done by the students, though
+ I will provide assistance if they need it with a specific technical issue.
+\layout Standard
+
+If more than one applicant is accepted to work on this project, there is
+ more than enough work to be done which can be coordinated between them.
+\layout Section
+
+Licensing and copyright
+\layout Standard
+
+IPython is licensed under BSD terms, and copyright of all sources rests
+ with the original authors of the core modules.
+ Over the years, all external contributions have been small enough patches
+ that they have been simply folded into the main source tree without additional
+ copyright attributions, though explicit credit has always been given to
+ all contributors.
+\layout Standard
+
+I expect the students participating in this project to contribute enough
+ standalone code that they can retain the copyright to it if they so desire,
+ as long as they accept all their work to be licensed under BSD terms.
+\layout Section
+
+Acknowledgements
+\layout Standard
+
+I'd like to thank John D.
+ Hunter, the author of matplotlib
+\begin_inset Foot
+collapsed true
+
+\layout Standard
+
+
+\begin_inset LatexCommand \htmlurl{http://matplotlib.sf.net}
+
+\end_inset 
+
+
+\end_inset 
+
+, for lengthy discussions which helped clarify much of this project.
+ In particular, the important decision of embedding the notebook markup
+ calls in true Python functions instead of specially-tagged strings or comments
+ was an idea I thank him for pushing hard enough to convince me of using.
+ 
+\layout Standard
+
+My conversations with Brian Granger, the author of PyXG
+\begin_inset Foot
+collapsed true
+
+\layout Standard
+
+
+\begin_inset LatexCommand \htmlurl{http://hammonds.scu.edu/~classes/pyxg.html}
+
+\end_inset 
+
+
+\end_inset 
+
+ and braid
+\begin_inset Foot
+collapsed true
+
+\layout Standard
+
+
+\begin_inset LatexCommand \htmlurl{http://hammonds.scu.edu/~classes/braid.html}
+
+\end_inset 
+
+
+\end_inset 
+
+, have also been very useful in clarifying details of the necessary underlying
+ infrastructure and future evolution of IPython for this kind of system.
+\layout Standard
+
+Thank you also to the IPython users who have, in the past, discussed this
+ topic with me either in private or on the IPython or Scipy lists.
+\the_end
diff --git a/doc/ipython.1 b/doc/ipython.1
new file mode 100644
index 0000000..ac873a3
--- /dev/null
+++ b/doc/ipython.1
@@ -0,0 +1,392 @@
+.\"                                      Hey, EMACS: -*- nroff -*-
+.\" First parameter, NAME, should be all caps
+.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
+.\" other parameters are allowed: see man(7), man(1)
+.TH IPYTHON 1 "November 30, 2004"
+.\" Please adjust this date whenever revising the manpage.
+.\"
+.\" Some roff macros, for reference:
+.\" .nh        disable hyphenation
+.\" .hy        enable hyphenation
+.\" .ad l      left justify
+.\" .ad b      justify to both left and right margins
+.\" .nf        disable filling
+.\" .fi        enable filling
+.\" .br        insert line break
+.\" .sp <n>    insert n+1 empty lines
+.\" for manpage-specific macros, see man(7) and groff_man(7)
+.\" .SH        section heading
+.\" .SS        secondary section heading
+.\"
+.\"
+.\" To preview this page as plain text: nroff -man ipython.1
+.\"
+.SH NAME
+ipython \- An Enhanced Interactive Python
+.SH SYNOPSIS
+.B ipython
+.RI [ options ] " files" ...
+.SH DESCRIPTION
+An interactive Python shell with automatic history (input and output),
+dynamic object introspection, easier configuration, command
+completion, access to the system shell, integration with numerical and
+scientific computing tools, and more.
+.SH SPECIAL THREADING OPTIONS
+The following special options are ONLY valid at the beginning of the command
+line, and not later.  This is because they control the initialization of
+ipython itself, before the normal option-handling mechanism is active.
+.TP
+.B \-gthread, \-qthread, \-wthread, \-pylab
+Only ONE of these can be given, and it can only be given as the first option
+passed to IPython (it will have no effect in any other position).  They
+provide threading support for the GTK, QT and WXWidgets toolkits, and for the
+matplotlib library.
+.br
+.sp 1
+With any of the first three options, IPython starts running a separate thread
+for the graphical toolkit's operation, so that you can open and control
+graphical elements from within an IPython command line, without blocking.  All
+three provide essentially the same functionality, respectively for GTK, QT and
+WXWidgets (via their Python interfaces).
+.br
+.sp 1
+If \-pylab is given, IPython loads special support for the matplotlib library
+(http://matplotlib.sourceforge.net), allowing interactive usage of any of its
+backends as defined in the user's .matplotlibrc file.  It automatically
+activates GTK, QT or WX threading for IPyhton if the choice of matplotlib
+backend requires it.  It also modifies the %run command to correctly execute
+(without blocking) any matplotlib-based script which calls show() at the end.
+.TP
+.B \-tk
+The \-g/q/wthread options, and \-pylab (if matplotlib is configured to use
+GTK, QT or WX), will normally block Tk graphical interfaces.  This means that
+when GTK, QT or WX threading is active, any attempt to open a Tk GUI will
+result in a dead window, and possibly cause the Python interpreter to crash.
+An extra option, \-tk, is available to address this issue.  It can ONLY be
+given as a SECOND option after any of the above (\-gthread, \-qthread,
+\-wthread or \-pylab).
+.br
+.sp 1
+If \-tk is given, IPython will try to coordinate Tk threading with GTK, QT or
+WX.  This is however potentially unreliable, and you will have to test on your
+platform and Python configuration to determine whether it works for you.
+Debian users have reported success, apparently due to the fact that Debian
+builds all of Tcl, Tk, Tkinter and Python with pthreads support.  Under other
+Linux environments (such as Fedora Core 2), this option has caused random
+crashes and lockups of the Python interpreter.  Under other operating systems
+(Mac OSX and Windows), you'll need to try it to find out, since currently no
+user reports are available.
+.br
+.sp 1
+There is unfortunately no way for IPython to determine at runtime whether \-tk
+will work reliably or not, so you will need to do some experiments before
+relying on it for regular work.
+.
+.SS A WARNING ABOUT SIGNALS AND THREADS
+When any of the thread systems (GTK, QT or WX) are active, either directly or
+via \-pylab with a threaded backend, it is impossible to interrupt
+long-running Python code via Ctrl\-C.  IPython can not pass the
+KeyboardInterrupt exception (or the underlying SIGINT) across threads, so any
+long-running process started from IPython will run to completion, or will have
+to be killed via an external (OS-based) mechanism.
+.br
+.sp 1
+To the best of my knowledge, this limitation is imposed by the Python
+interpreter itself, and it comes from the difficulty of writing portable
+signal/threaded code.  If any user is an expert on this topic and can suggest
+a better solution, I would love to hear about it.  In the IPython sources,
+look at the Shell.py module, and in particular at the runcode() method.
+.
+.SH REGULAR OPTIONS
+After the above threading options have been given, regular options can follow
+in any order.  All options can be abbreviated to their shortest non-ambiguous
+form and are case-sensitive.  One or two dashes can be used.  Some options
+have an alternate short form, indicated after a |.
+.br
+.sp 1
+Most options can also be set from your ipythonrc configuration file.
+See the provided examples for assistance.  Options given on the
+commandline override the values set in the ipythonrc file.
+.br
+.sp 1
+All options with a no| prepended can be specified in 'no' form
+(\-nooption instead of \-option) to turn the feature off.
+.TP
+.B \-h, \-\-help
+Show summary of options.
+.TP
+.B \-no|autocall
+Make IPython automatically call any callable object even if you didn't type
+explicit parentheses. For example, 'str 43' becomes 'str(43)' automatically.
+.TP
+.B \-no|autoindent
+Turn automatic indentation on/off.
+.TP
+.B \-no|automagic
+Make magic commands automatic (without needing their first character
+to be @).  Type @magic at the IPython prompt for more information.
+.TP
+.B \-no|autoparens
+Make IPython automatically call any callable object even if you didn't
+type explicit parentheses.  For example, 'str 43' becomes 'str(43)'
+automatically.
+.TP
+.B \-no|banner
+Print the intial information banner (default on).
+.TP
+.B \-c <command>
+Execute the given command string, and set sys.argv to ['c'].  This is similar
+to the \-c option in the normal Python interpreter.
+.TP
+.B \-cache_size|cs <n>
+Size of the output cache (maximum number of entries to hold in
+memory).  The default is 1000, you can change it permanently in your
+config file.  Setting it to 0 completely disables the caching system,
+and the minimum value accepted is 20 (if you provide a value less than
+20, it is reset to 0 and a warning is issued).  This limit is defined
+because otherwise you'll spend more time re-flushing a too small cache
+than working.
+.TP
+.B \-classic|cl
+Gives IPython a similar feel to the classic Python prompt.
+.TP
+.B \-colors <scheme>
+Color scheme for prompts and exception reporting.  Currently
+implemented: NoColor, Linux, and LightBG.
+.TP
+.B \-no|color_info
+IPython can display information about objects via a set of functions,
+and optionally can use colors for this, syntax highlighting source
+code and various other elements.  However, because this information is
+passed through a pager (like 'less') and many pagers get confused with
+color codes, this option is off by default.  You can test it and turn
+it on permanently in your ipythonrc file if it works for you.  As a
+reference, the 'less' pager supplied with Mandrake 8.2 works ok, but
+that in RedHat 7.2 doesn't.
+.br
+.sp 1
+Test it and turn it on permanently if it works with your system.  The
+magic function @color_info allows you to toggle this interactively for
+testing.
+.TP
+.B \-no|confirm_exit
+Set to confirm when you try to exit IPython with an EOF (Control-D in
+Unix, Control-Z/Enter in Windows). Note that using the magic functions
+@Exit or @Quit you can force a direct exit, bypassing any
+confirmation.
+.TP
+.B \-no|debug
+Show information about the loading process. Very useful to pin down
+problems with your configuration files or to get details about session
+restores.
+.TP
+.B \-no|deep_reload
+IPython can use the deep_reload module which reloads changes in
+modules recursively (it replaces the reload() function, so you don't
+need to change anything to use it). deep_reload() forces a full reload
+of modules whose code may have changed, which the default reload()
+function does not.
+.br
+.sp 1
+When deep_reload is off, IPython will use the normal reload(), but
+deep_reload will still be available as dreload(). This feature is off
+by default [which means that you have both normal reload() and
+dreload()].
+.TP
+.B \-editor <name>
+Which editor to use with the @edit command. By default, IPython will
+honor your EDITOR environment variable (if not set, vi is the Unix
+default and notepad the Windows one). Since this editor is invoked on
+the fly by IPython and is meant for editing small code snippets, you
+may want to use a small, lightweight editor here (in case your default
+EDITOR is something like Emacs).
+.TP
+.B \-ipythondir <name>
+The name of your IPython configuration directory IPYTHONDIR.  This can
+also be specified through the environment variable IPYTHONDIR.
+.TP
+.B \-log|l
+Generate a log file of all input. The file is named ipython.log in
+your current directory (which prevents logs from multiple IPython
+sessions from trampling each other). You can use this to later restore
+a session by loading your logfile as a file to be executed with option
+-logplay (see below).
+.TP
+.B \-logfile|lf
+Specifu the name of your logfile.
+.TP
+.B \-logplay|lp
+Replay a previous log. For restoring a session as close as possible to
+the state you left it in, use this option (don't just run the
+logfile). With \-logplay, IPython will try to reconstruct the previous
+working environment in full, not just execute the commands in the
+logfile.
+.br
+.sh 1
+When a session is restored, logging is automatically turned on again
+with the name of the logfile it was invoked with (it is read from the
+log header). So once you've turned logging on for a session, you can
+quit IPython and reload it as many times as you want and it will
+continue to log its history and restore from the beginning every time.
+.br
+.sp 1
+Caveats: there are limitations in this option. The history variables
+_i*,_* and _dh don't get restored properly. In the future we will try
+to implement full session saving by writing and retrieving a
+'snapshot' of the memory state of IPython. But our first attempts
+failed because of inherent limitations of Python's Pickle module, so
+this may have to wait.
+.TP
+.B \-no|messages
+Print messages which IPython collects about its startup process
+(default on).
+.TP
+.B \-no|pdb
+Automatically call the pdb debugger after every uncaught exception. If
+you are used to debugging using pdb, this puts you automatically
+inside of it after any call (either in IPython or in code called by
+it) which triggers an exception which goes uncaught.
+.TP
+.B \-no|pprint
+IPython can optionally use the pprint (pretty printer) module for
+displaying results. pprint tends to give a nicer display of nested
+data structures. If you like it, you can turn it on permanently in
+your config file (default off).
+.TP
+.B \-profile|p <name>
+Assume that your config file is ipythonrc-<name> (looks in current dir
+first, then in IPYTHONDIR). This is a quick way to keep and load
+multiple config files for different tasks, especially if you use the
+include option of config files. You can keep a basic
+IPYTHONDIR/ipythonrc file and then have other 'profiles' which include
+this one and load extra things for particular tasks. For example:
+.br
+.sp 1
+1) $HOME/.ipython/ipythonrc : load basic things you always want.
+.br
+2) $HOME/.ipython/ipythonrc-math : load (1) and basic math-related
+modules.
+.br
+3) $HOME/.ipython/ipythonrc-numeric : load (1) and Numeric and
+plotting modules.
+.br
+.sp 1
+Since it is possible to create an endless loop by having circular file
+inclusions, IPython will stop if it reaches 15 recursive inclusions.
+.TP
+.B \-prompt_in1|pi1 <string>
+Specify the string used for input prompts. Note that if you are using
+numbered prompts, the number is represented with a '\\#' in the
+string. Don't forget to quote strings with spaces embedded in
+them. Default: 'In [\\#]:'.
+.br
+.sp 1
+Most bash-like escapes can be used to customize IPython's prompts, as well as
+a few additional ones which are IPython-specific.  All valid prompt escapes
+are described in detail in the Customization section of the IPython HTML/PDF
+manual.
+.TP
+.B \-prompt_in2|pi2 <string>
+Similar to the previous option, but used for the continuation prompts. The
+special sequence '\\D' is similar to '\\#', but with all digits replaced dots
+(so you can have your continuation prompt aligned with your input
+prompt). Default: '   .\\D.:' (note three spaces at the start for alignment
+with 'In [\\#]').
+.TP
+.B \-prompt_out|po <string>
+String used for output prompts, also uses numbers like prompt_in1.
+Default: 'Out[\\#]:'.
+.TP
+.B \-quick
+Start in bare bones mode (no config file loaded).
+.TP
+.B \-rcfile <name>
+Name of your IPython resource configuration file.  normally IPython
+loads ipythonrc (from current directory) or IPYTHONDIR/ipythonrc.  If
+the loading of your config file fails, IPython starts with a bare
+bones configuration (no modules loaded at all).
+.TP
+.B \-no|readline
+Use the readline library, which is needed to support name completion
+and command history, among other things. It is enabled by default, but
+may cause problems for users of X/Emacs in Python comint or shell
+buffers.
+.br
+.sp 1
+Note that emacs 'eterm' buffers (opened with M-x term) support
+IPython's readline and syntax coloring fine, only 'emacs' (M-x shell
+and C-c !)  buffers do not.
+.TP
+.B \-screen_length|sl <n>
+Number of lines of your screen.  This is used to control printing of
+very long strings.  Strings longer than this number of lines will be
+sent through a pager instead of directly printed.
+.br
+.sp 1
+The default value for this is 0, which means IPython will auto-detect
+your screen size every time it needs to print certain potentially long
+strings (this doesn't change the behavior of the 'print' keyword, it's
+only triggered internally). If for some reason this isn't working well
+(it needs curses support), specify it yourself. Otherwise don't change
+the default.
+.TP
+.B \-separate_in|si <string>
+Separator before input prompts.  Default '\n'.
+.TP
+.B \-separate_out|so <string>
+Separator before output prompts.  Default: 0 (nothing).
+.TP
+.B \-separate_out2|so2 <string>
+Separator after output prompts.  Default: 0 (nothing).
+.TP
+.B \-nosep
+Shorthand for '\-separate_in 0 \-separate_out 0 \-separate_out2 0'.
+Simply removes all input/output separators.
+.TP
+.B \-upgrade
+Allows you to upgrade your IPYTHONDIR configuration when you install a
+new version of IPython.  Since new versions may include new command
+lines options or example files, this copies updated ipythonrc-type
+files.  However, it backs up (with a .old extension) all files which
+it overwrites so that you can merge back any custimizations you might
+have in your personal files.
+.TP
+.B \-Version
+Print version information and exit.
+.TP
+.B \-xmode <modename>
+Mode for exception reporting.  The valid modes are Plain, Context, and
+Verbose.
+.br
+.sp 1
+\- Plain: similar to python's normal traceback printing.
+.br
+.sp 1
+\- Context: prints 5 lines of context source code around each line in the
+traceback.
+.br
+.sp 1
+\- Verbose: similar to Context, but additionally prints the variables
+currently visible where the exception happened (shortening their strings if
+too long).  This can potentially be very slow, if you happen to have a huge
+data structure whose string representation is complex to compute.  Your
+computer may appear to freeze for a while with cpu usage at 100%.  If this
+occurs, you can cancel the traceback with Ctrl-C (maybe hitting it more than
+once).
+.
+.SH EMBEDDING
+It is possible to start an IPython instance inside your own Python
+programs.  In the documentation example files there are some
+illustrations on how to do this.
+.br
+.sp 1
+This feature allows you to evalutate dynamically the state of your
+code, operate with your variables, analyze them, etc.  Note however
+that any changes you make to values while in the shell do NOT
+propagate back to the running code, so it is safe to modify your
+values because you won't break your code in bizarre ways by doing so.
+.SH AUTHOR
+IPython was written by Fernando Perez <fperez@colorado.edu>, based on earlier
+code by Janko Hauser <jh@comunit.de> and Nathaniel Gray
+<n8gray@caltech.edu>.  This manual page was written by Jack Moffitt
+<jack@xiph.org>, for the Debian project (but may be used by others).
diff --git a/doc/ipython.el b/doc/ipython.el
new file mode 100644
index 0000000..36e7b35
--- /dev/null
+++ b/doc/ipython.el
@@ -0,0 +1,398 @@
+;;; ipython.el --- Adds support for IPython to python-mode.el
+
+;; Copyright (C) 2002, 2003, 2004, 2005 Alexander Schmolck
+;; Author:        Alexander Schmolck
+;; Keywords:      ipython python languages oop
+;; URL:           http://ipython.scipy.org
+;; Compatibility: Emacs21, XEmacs21
+;; FIXME: #$@! INPUT RING
+(defconst ipython-version "$Revision: 565 $"
+  "VC version number.")
+
+;;; Commentary 
+;; This library makes all the functionality python-mode has when running with
+;; the normal python-interpreter available for ipython, too. It also enables a
+;; persistent py-shell command history accross sessions (if you exit python
+;; with C-d in py-shell) and defines the command `ipython-to-doctest', which
+;; can be used to convert bits of a ipython session into something that can be
+;; used for doctests. To install, put this file somewhere in your emacs
+;; `load-path' [1] and add the following line to your ~/.emacs file (the first
+;; line only needed if the default (``"ipython"``) is wrong)::
+;;
+;;   (setq ipython-command "/SOME-PATH/ipython")
+;;   (require 'ipython)
+;;
+;; Ipython will be set as the default python shell, but only if the ipython
+;; executable is in the path. For ipython sessions autocompletion with <tab>
+;; is also enabled (experimental feature!). Please also note that all the
+;; terminal functions in py-shell are handled by emacs's comint, **not** by
+;; (i)python, so importing readline etc. will have 0 effect.
+;;
+;; To start an interactive ipython session run `py-shell' with ``M-x py-shell``
+;; (or the default keybinding ``C-c C-!``).
+;;
+;; NOTE: This mode is currently somewhat alpha and although I hope that it
+;; will work fine for most cases, doing certain things (like the
+;; autocompletion and a decent scheme to switch between python interpreters)
+;; properly will also require changes to ipython that will likely have to wait
+;; for a larger rewrite scheduled some time in the future.
+;; 
+;; Also note that you currently NEED THE CVS VERSION OF PYTHON.EL.
+;;
+;; Further note that I don't know whether this runs under windows or not and
+;; that if it doesn't I can't really help much, not being afflicted myself.
+;;
+;;
+;; Hints for effective usage
+;; -------------------------
+;;
+;; - IMO the best feature by far of the ipython/emacs combo is how much easier it
+;;   makes it to find and fix bugs thanks to the ``@pdb on``/ pdbtrack combo. Try
+;;   it: first in the ipython to shell do ``@pdb on`` then do something that will
+;;   raise an exception (FIXME nice example) -- and be amazed how easy it is to
+;;   inspect the live objects in each stack frames and to jump to the
+;;   corresponding sourcecode locations as you walk up and down the stack trace
+;;   (even without ``%pdb on`` you can always use ``C-c -`` (`py-up-exception')
+;;   to jump to the corresponding source code locations).
+;;
+;; - emacs gives you much more powerful commandline editing and output searching
+;;   capabilities than ipython-standalone -- isearch is your friend if you
+;;   quickly want to print 'DEBUG ...' to stdout out etc.
+;;
+;; - This is not really specific to ipython, but for more convenient history
+;;   access you might want to add something like the following to *the beggining*
+;;   of your ``.emacs`` (if you want behavior that's more similar to stand-alone
+;;   ipython, you can change ``meta p`` etc. for ``control p``)::
+;;
+;;         (require 'comint)
+;;         (define-key comint-mode-map [(meta p)] 
+;;           'comint-previous-matching-input-from-input)
+;;         (define-key comint-mode-map [(meta n)] 
+;;           'comint-next-matching-input-from-input)
+;;         (define-key comint-mode-map [(control meta n)]
+;;            'comint-next-input)
+;;         (define-key comint-mode-map [(control meta p)]
+;;            'comint-previous-input)
+;;
+;; - Be aware that if you customize py-python-command previously, this value
+;;   will override what ipython.el does (because loading the customization
+;;   variables comes later).
+;;
+;; Please send comments and feedback to the ipython-list
+;; (<ipython-user@scipy.net>) where I (a.s.) or someone else will try to
+;; answer them (it helps if you specify your emacs version, OS etc; 
+;; familiarity with <http://www.catb.org/~esr/faqs/smart-questions.html> might
+;; speed up things further).
+;;
+;; Footnotes:
+;;
+;;     [1] If you don't know what `load-path' is, C-h v load-path will tell
+;;     you; if required you can also add a new directory. So assuming that
+;;     ipython.el resides in ~/el/, put this in your emacs:
+;;
+;;
+;;           (add-to-list 'load-path "~/el")
+;;           (setq ipython-command "/some-path/ipython")
+;;           (require 'ipython)
+;;
+;;
+;;
+;;
+;; TODO:
+;;      - do autocompletion properly
+;;      - implement a proper switching between python interpreters
+;;
+;; BUGS:
+;;      - neither::
+;;
+;;         (py-shell "-c print 'FOOBAR'")
+;;       
+;;        nor::
+;;       
+;;         (let ((py-python-command-args (append py-python-command-args 
+;;                                              '("-c" "print 'FOOBAR'"))))
+;;           (py-shell))
+;;
+;;        seem to print anything as they should
+;;
+;;      - look into init priority issues with `py-python-command' (if it's set
+;;        via custom)
+
+
+;;; Code
+(require 'cl)
+(require 'shell)
+(require 'executable)
+(require 'ansi-color)
+
+(defcustom ipython-command "ipython"
+  "*Shell command used to start ipython."
+  :type 'string 
+  :group 'python)
+
+;; Users can set this to nil
+(defvar py-shell-initial-switch-buffers t
+  "If nil, don't switch to the *Python* buffer on the first call to
+  `py-shell'.")
+
+(defvar ipython-backup-of-py-python-command nil
+  "HACK")
+
+  
+(defvar ipython-de-input-prompt-regexp "\\(?:
+In \\[[0-9]+\\]: *.*
+----+> \\(.*
+\\)[\n]?\\)\\|\\(?:
+In \\[[0-9]+\\]: *\\(.*
+\\)\\)\\|^[ ]\\{3\\}[.]\\{3,\\}: *\\(.*
+\\)"
+  "A regular expression to match the IPython input prompt and the python
+command after it. The first match group is for a command that is rewritten,
+the second for a 'normal' command, and the third for a multiline command.")
+(defvar ipython-de-output-prompt-regexp "^Out\\[[0-9]+\\]: "
+  "A regular expression to match the output prompt of IPython.")
+
+
+(if (not (executable-find ipython-command))
+    (message (format "Can't find executable %s - ipython.el *NOT* activated!!!"
+                     ipython-command))
+    ;; XXX load python-mode, so that we can screw around with its variables
+    ;; this has the disadvantage that python-mode is loaded even if no
+    ;; python-file is ever edited etc. but it means that `py-shell' works
+    ;; without loading a python-file first. Obviously screwing around with
+    ;; python-mode's variables like this is a mess, but well.
+    (require 'python-mode)
+    ;; turn on ansi colors for ipython and activate completion
+    (defun ipython-shell-hook ()
+      ;; the following is to synchronize dir-changes
+      (make-local-variable 'shell-dirstack)
+      (setq shell-dirstack nil)
+      (make-local-variable 'shell-last-dir)
+      (setq shell-last-dir nil)
+      (make-local-variable 'shell-dirtrackp)
+      (setq shell-dirtrackp t)
+      (add-hook 'comint-input-filter-functions 'shell-directory-tracker nil t)
+
+      (ansi-color-for-comint-mode-on)
+      (define-key py-shell-map [tab] 'ipython-complete)
+      ;;XXX this is really just a cheap hack, it only completes symbols in the
+      ;;interactive session -- useful nonetheless.
+      (define-key py-mode-map [(meta tab)] 'ipython-complete))
+    (add-hook 'py-shell-hook 'ipython-shell-hook)
+    ;; Regular expression that describes tracebacks for IPython in context and
+    ;; verbose mode. 
+  
+    ;;Adapt python-mode settings for ipython.
+    ;; (this works for %xmode 'verbose' or 'context')
+
+    ;; XXX putative regexps for syntax errors; unfortunately the 
+    ;;     current python-mode traceback-line-re scheme is too primitive,
+    ;;     so it's either matching syntax errors, *or* everything else
+    ;;     (XXX: should ask Fernando for a change)
+    ;;"^   File \"\\(.*?\\)\", line \\([0-9]+\\).*\n.*\n.*\nSyntaxError:"
+    ;;^   File \"\\(.*?\\)\", line \\([0-9]+\\)"
+    (setq py-traceback-line-re
+          "\\(^[^\t ].+?\\.py\\).*\n   +[0-9]+[^\00]*?\n-+> \\([0-9]+\\) +")
+
+    (setq py-shell-input-prompt-1-regexp "^In \\[[0-9]+\\]: *"
+          py-shell-input-prompt-2-regexp "^   [.][.][.]+: *" )
+    ;; select a suitable color-scheme
+    (unless (member "-colors" py-python-command-args)
+      (setq py-python-command-args 
+            (nconc py-python-command-args 
+                   (list "-colors"
+                         (cond  
+                           ((eq frame-background-mode 'dark)
+                            "DarkBG")
+                           ((eq frame-background-mode 'light)
+                            "LightBG")
+                           (t ; default (backg-mode isn't always set by XEmacs)
+                            "LightBG"))))))
+    (unless (equal ipython-backup-of-py-python-command py-python-command)
+      (setq ipython-backup-of-py-python-command py-python-command))
+    (setq py-python-command ipython-command))
+
+
+;; MODIFY py-shell so that it loads the editing history
+(defadvice py-shell (around py-shell-with-history)
+  "Add persistent command-history support (in
+$PYTHONHISTORY (or \"~/.ipython/history\", if we use IPython)). Also, if
+`py-shell-initial-switch-buffers' is nil, it only switches to *Python* if that
+buffer already exists."
+  (if (comint-check-proc "*Python*")
+      ad-do-it
+    (setq comint-input-ring-file-name
+          (if (string-equal py-python-command ipython-command)
+              (concat (or (getenv "IPYTHONDIR") "~/.ipython") "/history")
+            (or (getenv "PYTHONHISTORY") "~/.python-history.py")))
+    (comint-read-input-ring t)
+    (let ((buf (current-buffer)))
+      ad-do-it
+      (unless py-shell-initial-switch-buffers
+        (switch-to-buffer-other-window buf)))))
+(ad-activate 'py-shell)
+;; (defadvice py-execute-region (before py-execute-buffer-ensure-process)
+;;   "HACK: test that ipython is already running before executing something.
+;;   Doing this properly seems not worth the bother (unless people actually
+;;   request it)."
+;; (unless (comint-check-proc "*Python*")
+;;     (error "Sorry you have to first do M-x py-shell to send something to ipython.")))
+;; (ad-activate 'py-execute-region)
+
+(defadvice py-execute-region (around py-execute-buffer-ensure-process)
+  "HACK: if `py-shell' is not active or ASYNC is explicitly desired, fall back
+  to python instead of ipython." 
+  (let ((py-python-command (if (and (comint-check-proc "*Python*") (not async))
+                               py-python-command
+                               ipython-backup-of-py-python-command)))
+    ad-do-it))
+(ad-activate 'py-execute-region)
+
+(defun ipython-to-doctest (start end)
+  "Transform a cut-and-pasted bit from an IPython session into something that
+looks like it came from a normal interactive python session, so that it can
+be used in doctests. Example:
+
+
+    In [1]: import sys
+    
+    In [2]: sys.stdout.write 'Hi!\n'
+    ------> sys.stdout.write ('Hi!\n')
+    Hi!
+    
+    In [3]: 3 + 4
+    Out[3]: 7
+    
+gets converted to:
+
+    >>> import sys
+    >>> sys.stdout.write ('Hi!\n')
+    Hi!
+    >>> 3 + 4
+    7
+
+"
+  (interactive "*r\n")
+  ;(message (format "###DEBUG s:%de:%d" start end))
+  (save-excursion
+    (save-match-data
+      ;; replace ``In [3]: bla`` with ``>>> bla`` and 
+      ;;         ``... :   bla`` with ``...    bla``
+      (goto-char start)
+      (while (re-search-forward ipython-de-input-prompt-regexp end t)
+        ;(message "finding 1")
+        (cond ((match-string 3)         ;continued
+               (replace-match "... \\3" t nil))
+              (t
+               (replace-match ">>> \\1\\2" t nil))))
+      ;; replace ``
+      (goto-char start)
+      (while (re-search-forward ipython-de-output-prompt-regexp end t)
+        (replace-match "" t nil)))))
+
+(defvar ipython-completion-command-string 
+  "print ';'.join(__IP.Completer.all_completions('%s')) #PYTHON-MODE SILENT\n"
+  "The string send to ipython to query for all possible completions")
+
+
+;; xemacs doesn't have `comint-preoutput-filter-functions' so we'll try the
+;; following wonderful hack to work around this case
+(if (featurep 'xemacs)
+    ;;xemacs
+    (defun ipython-complete ()
+      "Try to complete the python symbol before point. Only knows about the stuff
+in the current *Python* session."
+      (interactive)
+      (let* ((ugly-return nil)
+             (sep ";")
+             ;; XXX currently we go backwards to find the beginning of an
+             ;; expression part; a more powerful approach in the future might be
+             ;; to let ipython have the complete line, so that context can be used
+             ;; to do things like filename completion etc.
+             (beg (save-excursion (skip-chars-backward "a-z0-9A-Z_." (point-at-bol))
+                                  (point)))
+             (end (point))
+             (pattern (buffer-substring-no-properties beg end))
+             (completions nil)
+             (completion-table nil)
+             completion
+             (comint-output-filter-functions
+              (append comint-output-filter-functions 
+                      '(ansi-color-filter-apply
+                        (lambda (string) 
+                                        ;(message (format "DEBUG filtering: %s" string))
+                          (setq ugly-return (concat ugly-return string))
+                          (delete-region comint-last-output-start 
+                                         (process-mark (get-buffer-process (current-buffer)))))))))
+                                        ;(message (format "#DEBUG pattern: '%s'" pattern))
+        (process-send-string  (or (get-buffer-process (current-buffer))
+                                  (get-process py-which-bufname)) ;XXX hack for .py buffers
+                              (format ipython-completion-command-string pattern))
+        (accept-process-output (get-buffer-process (current-buffer)))
+                                        ;(message (format "DEBUG return: %s" ugly-return))
+        (setq completions 
+              (split-string (substring ugly-return 0 (position ?\n ugly-return)) sep))
+        (setq completion-table (loop for str in completions
+                                     collect (list str nil)))
+        (setq completion (try-completion pattern completion-table))
+        (cond ((eq completion t))
+              ((null completion)
+               (message "Can't find completion for \"%s\"" pattern)
+               (ding))
+              ((not (string= pattern completion))
+               (delete-region beg end)
+               (insert completion))
+              (t
+               (message "Making completion list...")
+               (with-output-to-temp-buffer "*Python Completions*"
+                 (display-completion-list (all-completions pattern completion-table)))
+               (message "Making completion list...%s" "done")))))
+  ;; emacs
+  (defun ipython-complete ()
+    "Try to complete the python symbol before point. Only knows about the stuff
+in the current *Python* session."
+    (interactive)
+    (let* ((ugly-return nil)
+           (sep ";")
+           ;; XXX currently we go backwards to find the beginning of an
+           ;; expression part; a more powerful approach in the future might be
+           ;; to let ipython have the complete line, so that context can be used
+           ;; to do things like filename completion etc.
+           (beg (save-excursion (skip-chars-backward "a-z0-9A-Z_." (point-at-bol))
+                                (point))) 
+           (end (point))
+           (pattern (buffer-substring-no-properties beg end))
+           (completions nil)
+           (completion-table nil)
+           completion
+         (comint-preoutput-filter-functions
+          (append comint-preoutput-filter-functions 
+                  '(ansi-color-filter-apply
+                    (lambda (string) 
+                      (setq ugly-return (concat ugly-return string))
+                      "")))))
+      (process-send-string  (or (get-buffer-process (current-buffer))
+                                (get-process py-which-bufname)) ;XXX hack for .py buffers
+                            (format ipython-completion-command-string pattern))
+      (accept-process-output (get-buffer-process (current-buffer)))
+      (setq completions 
+            (split-string (substring ugly-return 0 (position ?\n ugly-return)) sep))
+                                        ;(message (format "DEBUG completions: %S" completions))
+      (setq completion-table (loop for str in completions
+                                   collect (list str nil)))
+      (setq completion (try-completion pattern completion-table))
+      (cond ((eq completion t))
+            ((null completion)
+             (message "Can't find completion for \"%s\"" pattern)
+             (ding))
+            ((not (string= pattern completion))
+             (delete-region beg end)
+             (insert completion))
+            (t
+             (message "Making completion list...")
+             (with-output-to-temp-buffer "*IPython Completions*"
+               (display-completion-list (all-completions pattern completion-table)))
+             (message "Making completion list...%s" "done")))))
+)
+
+(provide 'ipython)
diff --git a/doc/manual_base.lyx b/doc/manual_base.lyx
new file mode 100644
index 0000000..5031150
--- /dev/null
+++ b/doc/manual_base.lyx
@@ -0,0 +1,8777 @@
+#LyX 1.3 created this file. For more info see http://www.lyx.org/
+\lyxformat 221
+\textclass article
+\begin_preamble
+\usepackage{ae,aecompl}
+\usepackage{hyperref}
+\usepackage{html}
+\end_preamble
+\language english
+\inputencoding latin1
+\fontscheme default
+\graphics default
+\paperfontsize default
+\spacing single 
+\papersize Default
+\paperpackage a4
+\use_geometry 1
+\use_amsmath 0
+\use_natbib 0
+\use_numerical_citations 0
+\paperorientation portrait
+\leftmargin 1.25in
+\topmargin 1in
+\rightmargin 1.25in
+\bottommargin 1in
+\secnumdepth 3
+\tocdepth 3
+\paragraph_separation skip
+\defskip medskip
+\quotes_language english
+\quotes_times 2
+\papercolumns 1
+\papersides 1
+\paperpagestyle fancy
+
+\layout Title
+
+IPython
+\newline 
+
+\size larger 
+An enhanced Interactive Python
+\size large 
+
+\newline 
+User Manual, v.
+ __version__
+\layout Author
+
+Fernando P�rez
+\layout Standard
+
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+latex{
+\end_inset 
+
+
+\begin_inset LatexCommand \tableofcontents{}
+
+\end_inset 
+
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+}
+\end_inset 
+
+
+\layout Standard
+
+
+\begin_inset ERT
+status Open
+
+\layout Standard
+
+\backslash 
+html{
+\backslash 
+bodytext{bgcolor=#ffffff}}
+\end_inset 
+
+
+\layout Section
+\pagebreak_top 
+Overview
+\layout Standard
+
+One of Python's most useful features is its interactive interpreter.
+ This system allows very fast testing of ideas without the overhead of creating
+ test files as is typical in most programming languages.
+ However, the interpreter supplied with the standard Python distribution
+ is somewhat limited for extended interactive use.
+\layout Standard
+
+IPython is a free software project (released under the BSD license) which
+ tries to:
+\layout Enumerate
+
+Provide an interactive shell superior to Python's default.
+ IPython has many features for object introspection, system shell access,
+ and its own special command system for adding functionality when working
+ interactively.
+ It tries to be a very efficient environment both for Python code development
+ and for exploration of problems using Python objects (in situations like
+ data analysis).
+\layout Enumerate
+
+Serve as an embeddable, ready to use interpreter for your own programs.
+ IPython can be started with a single call from inside another program,
+ providing access to the current namespace.
+ This can be very useful both for debugging purposes and for situations
+ where a blend of batch-processing and interactive exploration are needed.
+\layout Enumerate
+
+Offer a flexible framework which can be used as the base environment for
+ other systems with Python as the underlying language.
+ Specifically scientific environments like Mathematica, IDL and Matlab inspired
+ its design, but similar ideas can be useful in many fields.
+\layout Subsection
+
+Main features
+\layout Itemize
+
+Dynamic object introspection.
+ One can access docstrings, function definition prototypes, source code,
+ source files and other details of any object accessible to the interpreter
+ with a single keystroke (`
+\family typewriter 
+?
+\family default 
+').
+\layout Itemize
+
+Completion in the local namespace, by typing TAB at the prompt.
+ This works for keywords, methods, variables and files in the current directory.
+ This is supported via the readline library, and full access to configuring
+ readline's behavior is provided.
+\layout Itemize
+
+Numbered input/output prompts with command history (persistent across sessions
+ and tied to each profile), full searching in this history and caching of
+ all input and output.
+\layout Itemize
+
+User-extensible `magic' commands.
+ A set of commands prefixed with 
+\family typewriter 
+%
+\family default 
+ is available for controlling IPython itself and provides directory control,
+ namespace information and many aliases to common system shell commands.
+\layout Itemize
+
+Alias facility for defining your own system aliases.
+\layout Itemize
+
+Complete system shell access.
+ Lines starting with ! are passed directly to the system shell, and using
+ !! captures shell output into python variables for further use.
+\layout Itemize
+
+All calls to the system (via aliases or via !) have their standard output/error
+ automatically stored as strings, and also available as lists.
+\layout Itemize
+
+Background execution of Python commands in a separate thread.
+ IPython has an internal job manager called 
+\family typewriter 
+jobs
+\family default 
+, and a conveninence backgrounding magic function called 
+\family typewriter 
+%bg
+\family default 
+.
+\layout Itemize
+
+The ability to expand python variables when calling the system shell.
+ In a shell command, any python variable prefixed with 
+\family typewriter 
+$
+\family default 
+ is expanded.
+ A double 
+\family typewriter 
+$$
+\family default 
+ allows passing a literal 
+\family typewriter 
+$
+\family default 
+ to the shell (for access to shell and environment variables like 
+\family typewriter 
+$PATH
+\family default 
+).
+\layout Itemize
+
+Filesystem navigation, via a magic 
+\family typewriter 
+%cd
+\family default 
+ command, along with a persistent bookmark system (using 
+\family typewriter 
+%bookmark
+\family default 
+) for fast access to frequently visited directories.
+\layout Itemize
+
+Automatic indentation (optional) of code as you type (through the readline
+ library).
+\layout Itemize
+
+Macro system for quickly re-executing multiple lines of previous input with
+ a single name.
+\layout Itemize
+
+Session logging (you can then later use these logs as code in your programs).
+\layout Itemize
+
+Session restoring: logs can be replayed to restore a previous session to
+ the state where you left it.
+\layout Itemize
+
+Verbose and colored exception traceback printouts.
+ Easier to parse visually, and in verbose mode they produce a lot of useful
+ debugging information (basically a terminal version of the cgitb module).
+\layout Itemize
+
+Auto-parentheses: callable objects can be executed without parentheses:
+ 
+\family typewriter 
+`sin 3'
+\family default 
+ is automatically converted to 
+\family typewriter 
+`sin(3)
+\family default 
+'.
+\layout Itemize
+
+Auto-quoting: using `
+\family typewriter 
+,
+\family default 
+' or `
+\family typewriter 
+;
+\family default 
+' as the first character forces auto-quoting of the rest of the line: 
+\family typewriter 
+`,my_function a\SpecialChar ~
+b'
+\family default 
+ becomes automatically 
+\family typewriter 
+`my_function("a","b")'
+\family default 
+, while 
+\family typewriter 
+`;my_function a\SpecialChar ~
+b'
+\family default 
+ becomes 
+\family typewriter 
+`my_function("a b")'
+\family default 
+.
+\layout Itemize
+
+Extensible input syntax.
+ You can define filters that pre-process user input to simplify input in
+ special situations.
+ This allows for example pasting multi-line code fragments which start with
+ 
+\family typewriter 
+`>>>'
+\family default 
+ or 
+\family typewriter 
+`...'
+\family default 
+ such as those from other python sessions or the standard Python documentation.
+\layout Itemize
+
+Flexible configuration system.
+ It uses a configuration file which allows permanent setting of all command-line
+ options, module loading, code and file execution.
+ The system allows recursive file inclusion, so you can have a base file
+ with defaults and layers which load other customizations for particular
+ projects.
+\layout Itemize
+
+Embeddable.
+ You can call IPython as a python shell inside your own python programs.
+ This can be used both for debugging code or for providing interactive abilities
+ to your programs with knowledge about the local namespaces (very useful
+ in debugging and data analysis situations).
+\layout Itemize
+
+Easy debugger access.
+ You can set IPython to call up the Python debugger (pdb) every time there
+ is an uncaught exception.
+ This drops you inside the code which triggered the exception with all the
+ data live and it is possible to navigate the stack to rapidly isolate the
+ source of a bug.
+ The 
+\family typewriter 
+%run
+\family default 
+ magic command --with the 
+\family typewriter 
+-d
+\family default 
+ option-- can run any script under 
+\family typewriter 
+pdb
+\family default 
+'s control, automatically setting initial breakpoints for you.
+\layout Itemize
+
+Profiler support.
+ You can run single statements (similar to 
+\family typewriter 
+profile.run()
+\family default 
+) or complete programs under the profiler's control.
+ While this is possible with the standard 
+\family typewriter 
+profile
+\family default 
+ module, IPython wraps this functionality with magic commands (see 
+\family typewriter 
+`%prun'
+\family default 
+ and 
+\family typewriter 
+`%run -p
+\family default 
+') convenient for rapid interactive work.
+\layout Subsection
+
+Portability and Python requirements
+\layout Standard
+
+
+\series bold 
+Python requirements: 
+\series default 
+IPython works with Python version 2.2 or newer.
+ It has been tested with Python 2.4 and no problems have been reported.
+ Support for Python 2.1 hasn't been recently tested, since I don't have access
+ to it on any of my systems.
+ But I suspect there may be some problems with Python 2.1, because some of
+ the newer code may use 2.2 features.
+\layout Standard
+
+IPython is developed under 
+\series bold 
+Linux
+\series default 
+, but it should work in any reasonable Unix-type system (tested OK under
+ Solaris and the *BSD family, for which a port exists thanks to Dryice Liu).
+\layout Standard
+
+
+\series bold 
+Mac OS X
+\series default 
+: it works, apparently without any problems (thanks to Jim Boyle at Lawrence
+ Livermore for the information).
+ Thanks to Andrea Riciputi, Fink support is available.
+\layout Standard
+
+
+\series bold 
+CygWin
+\series default 
+: it works mostly OK, though some users have reported problems with prompt
+ coloring.
+ No satisfactory solution to this has been found so far, you may want to
+ disable colors permanently in the 
+\family typewriter 
+ipythonrc
+\family default 
+ configuration file if you experience problems.
+ If you have proper color support under cygwin, please post to the IPython
+ mailing list so this issue can be resolved for all users.
+\layout Standard
+
+
+\series bold 
+Windows
+\series default 
+: it works well under Windows XP/2k, and I suspect NT should behave similarly.
+ Section\SpecialChar ~
+
+\begin_inset LatexCommand \ref{sub:Under-Windows}
+
+\end_inset 
+
+ describes installation details for Windows, including some additional tools
+ needed on this platform.
+\layout Standard
+
+Windows 9x support is present, and has been reported to work fine (at least
+ on WinME).
+\layout Standard
+
+Please note, however, that I have very little access to and experience with
+ Windows development.
+ For this reason, Windows-specific bugs tend to linger far longer than I
+ would like, and often I just can't find a satisfactory solution.
+ If any Windows user wants to join in with development help, all hands are
+ always welcome.
+\layout Subsection
+
+Location
+\layout Standard
+
+IPython is generously hosted at 
+\begin_inset LatexCommand \htmlurl{http://ipython.scipy.org}
+
+\end_inset 
+
+ by the SciPy project.
+ This site offers downloads, CVS access, mailing lists and a bug tracking
+ system.
+ I am very grateful to Enthought (
+\begin_inset LatexCommand \htmlurl{http://www.enthought.com}
+
+\end_inset 
+
+) and all of the SciPy team for their contribution.
+\layout Section
+
+
+\begin_inset LatexCommand \label{sec:install}
+
+\end_inset 
+
+Installation
+\layout Subsection
+
+Instant instructions
+\layout Standard
+
+If you are of the impatient kind, under Linux/Unix simply untar/unzip the
+ download, then install with 
+\family typewriter 
+`python setup.py install'
+\family default 
+.
+ Under Windows, double-click on the provided 
+\family typewriter 
+.exe
+\family default 
+ binary installer.
+\layout Standard
+
+Then, take a look at Sections 
+\begin_inset LatexCommand \ref{sec:good_config}
+
+\end_inset 
+
+ for configuring things optimally and 
+\begin_inset LatexCommand \ref{sec:quick_tips}
+
+\end_inset 
+
+ for quick tips on efficient use of IPython.
+ You can later refer to the rest of the manual for all the gory details.
+\layout Standard
+
+See the notes in sec.
+ 
+\begin_inset LatexCommand \ref{sec:upgrade}
+
+\end_inset 
+
+ for upgrading IPython versions.
+\layout Subsection
+
+Detailed Unix instructions (Linux, Mac OS X, etc.)
+\layout Standard
+
+
+\begin_inset ERT
+status Open
+
+\layout Standard
+
+\backslash 
+html{ 
+\backslash 
+textbf{A warning to readers of the HTML version of this manual}: all options below are preceded with with TWO dashes and no intervening space between the dashes (e.g. Dash-Dash-home). The default HTML conversion tools mangle these into a single dash.}
+\end_inset 
+
+
+\layout Standard
+
+For RPM based systems, simply install the supplied package in the usual
+ manner.
+ If you download the tar archive, the process is:
+\layout Enumerate
+
+Unzip/untar the 
+\family typewriter 
+ipython-XXX.tar.gz
+\family default 
+ file wherever you want (
+\family typewriter 
+XXX
+\family default 
+ is the version number).
+ It will make a directory called 
+\family typewriter 
+ipython-XXX.
+ 
+\family default 
+Change into that directory where you will find the files 
+\family typewriter 
+README
+\family default 
+ and 
+\family typewriter 
+setup.py
+\family default 
+.
+
+\family typewriter 
+ O
+\family default 
+nce you've completed the installation, you can safely remove this directory.
+ 
+\layout Enumerate
+
+If you are installing over a previous installation of version 0.2.0 or earlier,
+ first remove your 
+\family typewriter 
+$HOME/.ipython
+\family default 
+ directory, since the configuration file format has changed somewhat (the
+ '=' were removed from all option specifications).
+ Or you can call ipython with the 
+\family typewriter 
+-upgrade
+\family default 
+ option and it will do this automatically for you.
+\layout Enumerate
+
+IPython uses distutils, so you can install it by simply typing at the system
+ prompt (don't type the 
+\family typewriter 
+$
+\family default 
+)
+\newline 
+
+\family typewriter 
+$ python setup.py install
+\family default 
+
+\newline 
+Note that this assumes you have root access to your machine.
+ If you don't have root access or don't want IPython to go in the default
+ python directories, you'll need to use the 
+\family typewriter 
+--home
+\family default 
+ option (or 
+\family typewriter 
+--prefix
+\family default 
+).
+ For example:
+\newline 
+
+\family typewriter 
+$ python setup.py install --home $HOME/local
+\family default 
+
+\newline 
+will install
+\begin_inset Foot
+collapsed true
+
+\layout Standard
+
+If you are reading these instructions in HTML format, please note that the
+ option is --home, with 
+\emph on 
+two
+\emph default 
+ dashes.
+ The automatic HTML conversion program seems to eat up one of the dashes,
+ unfortunately (it's ok in the PDF version).
+\end_inset 
+
+ IPython into 
+\family typewriter 
+$HOME/local 
+\family default 
+and its subdirectories (creating them if necessary).
+\newline 
+You can type
+\newline 
+
+\family typewriter 
+$ python setup.py --help
+\family default 
+
+\newline 
+for more details.
+\newline 
+Note that if you change the default location for 
+\family typewriter 
+--home
+\family default 
+ at installation, IPython may end up installed at a location which is not
+ part of your 
+\family typewriter 
+$PYTHONPATH
+\family default 
+ environment variable.
+ In this case, you'll need to configure this variable to include the actual
+ directory where the 
+\family typewriter 
+IPython/
+\family default 
+ directory ended (typically the value you give to 
+\family typewriter 
+--home
+\family default 
+ plus 
+\family typewriter 
+/lib/python
+\family default 
+).
+\layout Subsubsection
+
+Mac OSX information
+\layout Subsubsection*
+
+GUI problems
+\layout Standard
+
+The following instructions apply to an install of IPython under OSX from
+ unpacking the 
+\family typewriter 
+.tar.gz
+\family default 
+ distribution and installing it for the default Python interpreter shipped
+ by Apple.
+ If you are using a fink install, fink will take care of these details for
+ you, by installing IPython against fink's Python.
+\layout Standard
+
+IPython offers various forms of support for interacting with graphical applicati
+ons from the command line, from simple Tk apps (which are in principle always
+ supported by Python) to interactive control of WX, QT and GTK apps.
+ Under OSX, however, this requires that ipython is installed by calling
+ the special 
+\family typewriter 
+pythonw
+\family default 
+ script at installation time, which takes care of coordinating things with
+ Apple's graphical environment.
+\layout Standard
+
+So when installing under OSX, it is best to use the following command
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+html{ 
+\backslash 
+emph{[Again, in the HTML manual, the option is called -~-install=scripts, with TWO dashes and no intervening space between the dashes]}}
+\end_inset 
+
+:
+\family typewriter 
+
+\newline 
+\SpecialChar ~
+\SpecialChar ~
+$ sudo pythonw setup.py install --install-scripts=/usr/local/bin
+\family default 
+
+\newline 
+or
+\family typewriter 
+
+\newline 
+\SpecialChar ~
+\SpecialChar ~
+$ sudo pythonw setup.py install --install-scripts=/usr/bin
+\newline 
+
+\family default 
+depending on where you like to keep hand-installed executables.
+\layout Standard
+
+The resulting script will have an appropriate shebang line (the first line
+ in the script whic begins with 
+\family typewriter 
+#!...
+\family default 
+) such that the ipython interpreter can interact with the OS X GUI.
+ If the installed version does not work and has a shebang line that points
+ to, for example, just 
+\family typewriter 
+/usr/bin/python
+\family default 
+, then you might have a stale, cached version in your 
+\family typewriter 
+build/scripts-<python-version>
+\family default 
+ directory.
+ Delete that directory and rerun the 
+\family typewriter 
+setup.py
+\family default 
+.
+ 
+\layout Standard
+
+It is also a good idea to use the special flag 
+\family typewriter 
+--install-scripts
+\family default 
+ as indicated above, to ensure that the ipython scripts end up in a location
+ which is part of your 
+\family typewriter 
+$PATH
+\family default 
+.
+ Otherwise Apple's Python will put the scripts in an internal directory
+ not available by default at the command line (if you use 
+\family typewriter 
+/usr/local/bin
+\family default 
+, you need to make sure this is in your 
+\family typewriter 
+$PATH
+\family default 
+, which may not be true by default).
+\layout Subsubsection*
+
+Readline problems
+\layout Standard
+
+By default, the Python version shipped by Apple does 
+\emph on 
+not
+\emph default 
+ include the readline library, so central to IPython's behavior.
+ If you install IPython against Apple's Python, you will not have arrow
+ keys, tab completion, etc.
+ For Mac OSX 10.3 (Panther), you can find a prebuilt readline library here:
+\newline 
+
+\begin_inset LatexCommand \htmlurl{http://pythonmac.org/packages/readline-5.0-py2.3-macosx10.3.zip}
+
+\end_inset 
+
+ 
+\layout Standard
+
+At this point I don't know of such a released version for OSX 10.4 (Tiger),
+ or if the problem even occurs with Tiger at all (feedback welcome).
+\layout Standard
+
+Users installing against fink's Python or a properly hand-built one should
+ not have this problem.
+\layout Subsection
+
+
+\begin_inset LatexCommand \label{sub:Under-Windows}
+
+\end_inset 
+
+Windows instructions
+\layout Standard
+
+While you can use IPython under Windows with only a stock Python installation,
+ there is one extension, 
+\family typewriter 
+readline
+\family default 
+, which will make the whole experience a lot more pleasant.
+ It is almost a requirement, since IPython will complain in its absence
+ (though it will function).
+ 
+\layout Standard
+
+The
+\family typewriter 
+ readline
+\family default 
+ extension needs two other libraries to work, so in all you need:
+\layout Enumerate
+
+
+\family typewriter 
+PyWin32
+\family default 
+ from 
+\begin_inset LatexCommand \htmlurl{http://starship.python.net/crew/mhammond}
+
+\end_inset 
+
+.
+\layout Enumerate
+
+
+\family typewriter 
+CTypes
+\family default 
+ from 
+\begin_inset LatexCommand \htmlurl{http://starship.python.net/crew/theller/ctypes}
+
+\end_inset 
+
+ (you 
+\emph on 
+must
+\emph default 
+ use version 0.9.1 or newer).
+\layout Enumerate
+
+
+\family typewriter 
+Readline
+\family default 
+ for Windows from 
+\begin_inset LatexCommand \htmlurl{http://sourceforge.net/projects/uncpythontools}
+
+\end_inset 
+
+.
+\layout Standard
+
+
+\series bold 
+Warning about a broken readline-like library:
+\series default 
+ several users have reported problems stemming from using the pseudo-readline
+ library at 
+\begin_inset LatexCommand \htmlurl{http://newcenturycomputers.net/projects/readline.html}
+
+\end_inset 
+
+.
+ This is a broken library which, while called readline, only implements
+ an incomplete subset of the readline API.
+ Since it is still called readline, it fools IPython's detection mechanisms
+ and causes unpredictable crashes later.
+ If you wish to use IPython under Windows, you must NOT use this library,
+ which for all purposes is (at least as of version 1.6) terminally broken.
+\layout Subsubsection
+
+Gary Bishop's readline and color support for Windows
+\layout Standard
+
+Some of IPython's very useful features are:
+\layout Itemize
+
+Integrated readline support (Tab-based file, object and attribute completion,
+ input history across sessions, editable command line, etc.)
+\layout Itemize
+
+Coloring of prompts, code and tracebacks.
+\layout Standard
+
+These, by default, are only available under Unix-like operating systems.
+ However, thanks to Gary Bishop's work, Windows XP/2k users can also benefit
+ from them.
+ His readline library implements both GNU readline functionality and color
+ support, so that IPython under Windows XP/2k can be as friendly and powerful
+ as under Unix-like environments.
+\layout Standard
+
+You can find Gary's tools at 
+\begin_inset LatexCommand \htmlurl{http://sourceforge.net/projects/uncpythontools}
+
+\end_inset 
+
+; Gary's 
+\family typewriter 
+readline
+\family default 
+ requires in turn the 
+\family typewriter 
+ctypes
+\family default 
+ library by Thomas Heller, available at 
+\begin_inset LatexCommand \htmlurl{http://starship.python.net/crew/theller/ctypes}
+
+\end_inset 
+
+, and Mark Hammond's 
+\family typewriter 
+PyWin32
+\family default 
+ from 
+\begin_inset LatexCommand \htmlurl{http://starship.python.net/crew/mhammond}
+
+\end_inset 
+
+ (
+\family typewriter 
+PyWin32
+\family default 
+ is great for anything Windows-related anyway, so you might as well get
+ it).
+\layout Standard
+
+Under MS\SpecialChar ~
+Windows, IPython will complain if it can not find this 
+\family typewriter 
+readline
+\family default 
+ library at startup and any time the 
+\family typewriter 
+%colors
+\family default 
+ command is issued, so you can consider it to be a quasi-requirement.
+\layout Subsubsection
+
+Installation procedure
+\layout Standard
+
+Once you have the above installed, from the IPython download directory grab
+ the 
+\family typewriter 
+ipython-XXX.win32.exe
+\family default 
+ file, where 
+\family typewriter 
+XXX
+\family default 
+ represents the version number.
+ This is a regular windows executable installer, which you can simply double-cli
+ck to install.
+ It will add an entry for IPython to your Start Menu, as well as registering
+ IPython in the Windows list of applications, so you can later uninstall
+ it from the Control Panel.
+ 
+\layout Standard
+
+IPython tries to install the configuration information in a directory named
+ 
+\family typewriter 
+.ipython
+\family default 
+ (
+\family typewriter 
+_ipython
+\family default 
+ under Windows) located in your `home' directory.
+ IPython sets this directory by looking for a 
+\family typewriter 
+HOME
+\family default 
+ environment variable; if such a variable does not exist, it uses 
+\family typewriter 
+HOMEDRIVE
+\backslash 
+HOMEPATH 
+\family default 
+(these are always defined by Windows).
+ This typically gives something like 
+\family typewriter 
+C:
+\backslash 
+Documents and Settings
+\backslash 
+YourUserName
+\family default 
+, but your local details may vary.
+ In this directory you will find all the files that configure IPython's
+ defaults, and you can put there your profiles and extensions.
+ This directory is automatically added by IPython to 
+\family typewriter 
+sys.path
+\family default 
+, so anything you place there can be found by 
+\family typewriter 
+import
+\family default 
+ statements.
+\layout Paragraph
+
+Upgrading
+\layout Standard
+
+For an IPython upgrade, you should first uninstall the previous version.
+ This will ensure that all files and directories (such as the documentation)
+ which carry embedded version strings in their names are properly removed.
+\layout Paragraph
+
+Manual installation under Win32
+\layout Standard
+
+In case the automatic installer does not work for some reason, you can download
+ the 
+\family typewriter 
+ipython-XXX.tar.gz
+\family default 
+ file, which contains the full IPython source distribution (the popular
+ WinZip can read 
+\family typewriter 
+.tar.gz
+\family default 
+ files).
+ After uncompressing the archive, you can install it at a command terminal
+ just like any other Python module, by using 
+\family typewriter 
+`python setup.py install'
+\family default 
+.
+ 
+\layout Standard
+
+After the installation, run the supplied 
+\family typewriter 
+win32_manual_post_install.py 
+\family default 
+script, which creates the necessary Start Menu shortcuts for you.
+\layout Subsection
+
+
+\begin_inset LatexCommand \label{sec:upgrade}
+
+\end_inset 
+
+Upgrading from a previous version
+\layout Standard
+
+If you are upgrading from a previous version of IPython, after doing the
+ routine installation described above, you should call IPython with the
+ 
+\family typewriter 
+-upgrade
+\family default 
+ option the first time you run your new copy.
+ This will automatically update your configuration directory while preserving
+ copies of your old files.
+ You can then later merge back any personal customizations you may have
+ made into the new files.
+ It is a good idea to do this as there may be new options available in the
+ new configuration files which you will not have.
+\layout Standard
+
+Under Windows, if you don't know how to call python scripts with arguments
+ from a command line, simply delete the old config directory and IPython
+ will make a new one.
+ Win2k and WinXP users will find it in 
+\family typewriter 
+C:
+\backslash 
+Documents and Settings
+\backslash 
+YourUserName
+\backslash 
+.ipython
+\family default 
+, and Win 9x users under 
+\family typewriter 
+C:
+\backslash 
+Program Files
+\backslash 
+IPython
+\backslash 
+.ipython.
+\layout Section
+
+
+\begin_inset LatexCommand \label{sec:good_config}
+
+\end_inset 
+
+
+\begin_inset OptArg
+collapsed true
+
+\layout Standard
+
+Initial configuration
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+ldots
+\end_inset 
+
+
+\end_inset 
+
+Initial configuration of your environment
+\layout Standard
+
+This section will help you set various things in your environment for your
+ IPython sessions to be as efficient as possible.
+ All of IPython's configuration information, along with several example
+ files, is stored in a directory named by default 
+\family typewriter 
+$HOME/.ipython
+\family default 
+.
+ You can change this by defining the environment variable 
+\family typewriter 
+IPYTHONDIR
+\family default 
+, or at runtime with the command line option 
+\family typewriter 
+-ipythondir
+\family default 
+.
+\layout Standard
+
+If all goes well, the first time you run IPython it should automatically
+ create a user copy of the config directory for you, based on its builtin
+ defaults.
+ You can look at the files it creates to learn more about configuring the
+ system.
+ The main file you will modify to configure IPython's behavior is called
+ 
+\family typewriter 
+ipythonrc
+\family default 
+ (with a 
+\family typewriter 
+.ini
+\family default 
+ extension under Windows), included for reference in Sec.
+ 
+\begin_inset LatexCommand \ref{sec:ipytonrc-sample}
+
+\end_inset 
+
+.
+ This file is very commented and has many variables you can change to suit
+ your taste, you can find more details in Sec.
+ 
+\begin_inset LatexCommand \ref{sec:customization}
+
+\end_inset 
+
+.
+ Here we discuss the basic things you will want to make sure things are
+ working properly from the beginning.
+\layout Subsection
+
+
+\begin_inset LatexCommand \label{sec:help-access}
+
+\end_inset 
+
+Access to the Python help system
+\layout Standard
+
+This is true for Python in general (not just for IPython): you should have
+ an environment variable called 
+\family typewriter 
+PYTHONDOCS
+\family default 
+ pointing to the directory where your HTML Python documentation lives.
+ In my system it's 
+\family typewriter 
+/usr/share/doc/python-docs-2.3.4/html
+\family default 
+, check your local details or ask your systems administrator.
+ 
+\layout Standard
+
+This is the directory which holds the HTML version of the Python manuals.
+ Unfortunately it seems that different Linux distributions package these
+ files differently, so you may have to look around a bit.
+ Below I show the contents of this directory on my system for reference:
+\layout Standard
+
+
+\family typewriter 
+[html]> ls
+\newline 
+about.dat acks.html dist/ ext/ index.html lib/ modindex.html stdabout.dat tut/
+ about.html api/ doc/ icons/ inst/ mac/ ref/ style.css
+\layout Standard
+
+You should really make sure this variable is correctly set so that Python's
+ pydoc-based help system works.
+ It is a powerful and convenient system with full access to the Python manuals
+ and all modules accessible to you.
+\layout Standard
+
+Under Windows it seems that pydoc finds the documentation automatically,
+ so no extra setup appears necessary.
+\layout Subsection
+
+Editor
+\layout Standard
+
+The 
+\family typewriter 
+%edit
+\family default 
+ command (and its alias 
+\family typewriter 
+%ed
+\family default 
+) will invoke the editor set in your environment as 
+\family typewriter 
+EDITOR
+\family default 
+.
+ If this variable is not set, it will default to 
+\family typewriter 
+vi
+\family default 
+ under Linux/Unix and to 
+\family typewriter 
+notepad
+\family default 
+ under Windows.
+ You may want to set this variable properly and to a lightweight editor
+ which doesn't take too long to start (that is, something other than a new
+ instance of 
+\family typewriter 
+Emacs
+\family default 
+).
+ This way you can edit multi-line code quickly and with the power of a real
+ editor right inside IPython.
+ 
+\layout Standard
+
+If you are a dedicated 
+\family typewriter 
+Emacs
+\family default 
+ user, you should set up the 
+\family typewriter 
+Emacs
+\family default 
+ server so that new requests are handled by the original process.
+ This means that almost no time is spent in handling the request (assuming
+ an 
+\family typewriter 
+Emacs
+\family default 
+ process is already running).
+ For this to work, you need to set your 
+\family typewriter 
+EDITOR 
+\family default 
+environment variable to 
+\family typewriter 
+'emacsclient'
+\family default 
+.
+
+\family typewriter 
+ 
+\family default 
+The code below, supplied by Francois Pinard, can then be used in your 
+\family typewriter 
+.emacs
+\family default 
+ file to enable the server:
+\layout Standard
+
+
+\family typewriter 
+(defvar server-buffer-clients)
+\newline 
+(when (and (fboundp 'server-start) (string-equal (getenv "TERM") 'xterm))
+\newline 
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+hspace*{0mm}
+\end_inset 
+
+\SpecialChar ~
+\SpecialChar ~
+(server-start)
+\newline 
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+hspace*{0mm}
+\end_inset 
+
+\SpecialChar ~
+\SpecialChar ~
+(defun fp-kill-server-with-buffer-routine ()
+\newline 
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+hspace*{0mm}
+\end_inset 
+
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+(and server-buffer-clients (server-done)))
+\newline 
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+hspace*{0mm}
+\end_inset 
+
+\SpecialChar ~
+\SpecialChar ~
+(add-hook 'kill-buffer-hook 'fp-kill-server-with-buffer-routine))
+\layout Standard
+
+You can also set the value of this editor via the commmand-line option '-
+\family typewriter 
+editor'
+\family default 
+ or in your 
+\family typewriter 
+ipythonrc
+\family default 
+ file.
+ This is useful if you wish to use specifically for IPython an editor different
+ from your typical default (and for Windows users who tend to use fewer
+ environment variables).
+\layout Subsection
+
+Color 
+\layout Standard
+
+The default IPython configuration has most bells and whistles turned on
+ (they're pretty safe).
+ But there's one that 
+\emph on 
+may
+\emph default 
+ cause problems on some systems: the use of color on screen for displaying
+ information.
+ This is very useful, since IPython can show prompts and exception tracebacks
+ with various colors, display syntax-highlighted source code, and in general
+ make it easier to visually parse information.
+\layout Standard
+
+The following terminals seem to handle the color sequences fine:
+\layout Itemize
+
+Linux main text console, KDE Konsole, Gnome Terminal, E-term, rxvt, xterm.
+\layout Itemize
+
+CDE terminal (tested under Solaris).
+ This one boldfaces light colors.
+\layout Itemize
+
+(X)Emacs buffers.
+ See sec.
+\begin_inset LatexCommand \ref{sec:emacs}
+
+\end_inset 
+
+ for more details on using IPython with (X)Emacs.
+\layout Itemize
+
+A Windows (XP/2k) command prompt 
+\emph on 
+with Gary Bishop's support extensions
+\emph default 
+.
+ Gary's extensions are discussed in Sec.\SpecialChar ~
+
+\begin_inset LatexCommand \ref{sub:Under-Windows}
+
+\end_inset 
+
+.
+\layout Itemize
+
+A Windows (XP/2k) CygWin shell.
+ Although some users have reported problems; it is not clear whether there
+ is an issue for everyone or only under specific configurations.
+ If you have full color support under cygwin, please post to the IPython
+ mailing list so this issue can be resolved for all users.
+\layout Standard
+
+These have shown problems:
+\layout Itemize
+
+Windows command prompt in WinXP/2k logged into a Linux machine via telnet
+ or ssh.
+\layout Itemize
+
+Windows native command prompt in WinXP/2k, 
+\emph on 
+without 
+\emph default 
+Gary Bishop's extensions.
+ Once Gary's readline library is installed, the normal WinXP/2k command
+ prompt works perfectly.
+\layout Standard
+
+Currently the following color schemes are available:
+\layout Itemize
+
+
+\family typewriter 
+NoColor
+\family default 
+: uses no color escapes at all (all escapes are empty 
+\begin_inset Quotes eld
+\end_inset 
+
+ 
+\begin_inset Quotes eld
+\end_inset 
+
+ strings).
+ This 'scheme' is thus fully safe to use in any terminal.
+\layout Itemize
+
+
+\family typewriter 
+Linux
+\family default 
+: works well in Linux console type environments: dark background with light
+ fonts.
+ It uses bright colors for information, so it is difficult to read if you
+ have a light colored background.
+\layout Itemize
+
+
+\family typewriter 
+LightBG
+\family default 
+: the basic colors are similar to those in the 
+\family typewriter 
+Linux
+\family default 
+ scheme but darker.
+ It is easy to read in terminals with light backgrounds.
+\layout Standard
+
+IPython uses colors for two main groups of things: prompts and tracebacks
+ which are directly printed to the terminal, and the object introspection
+ system which passes large sets of data through a pager.
+\layout Subsubsection
+
+Input/Output prompts and exception tracebacks
+\layout Standard
+
+You can test whether the colored prompts and tracebacks work on your system
+ interactively by typing 
+\family typewriter 
+'%colors Linux'
+\family default 
+ at the prompt (use '
+\family typewriter 
+%colors LightBG'
+\family default 
+ if your terminal has a light background).
+ If the input prompt shows garbage like:
+\newline 
+
+\family typewriter 
+[0;32mIn [[1;32m1[0;32m]: [0;00m
+\family default 
+
+\newline 
+instead of (in color) something like:
+\newline 
+
+\family typewriter 
+In [1]:
+\family default 
+ 
+\newline 
+this means that your terminal doesn't properly handle color escape sequences.
+ You can go to a 'no color' mode by typing '
+\family typewriter 
+%colors NoColor
+\family default 
+'.
+ 
+\layout Standard
+
+You can try using a different terminal emulator program.
+ To permanently set your color preferences, edit the file
+\family typewriter 
+ $HOME/.ipython/ipythonrc 
+\family default 
+and set the 
+\family typewriter 
+colors
+\family default 
+ option to the desired value.
+\layout Subsubsection
+
+Object details (types, docstrings, source code, etc.)
+\layout Standard
+
+IPython has a set of special functions for studying the objects you are
+ working with, discussed in detail in Sec.
+ 
+\begin_inset LatexCommand \ref{sec:dyn-object-info}
+
+\end_inset 
+
+.
+ But this system relies on passing information which is longer than your
+ screen through a data pager, such as the common Unix 
+\family typewriter 
+less
+\family default 
+ and 
+\family typewriter 
+more
+\family default 
+ programs.
+ In order to be able to see this information in color, your pager needs
+ to be properly configured.
+ I strongly recommend using 
+\family typewriter 
+less
+\family default 
+ instead of 
+\family typewriter 
+more
+\family default 
+, as it seems that 
+\family typewriter 
+more
+\family default 
+ simply can not understand colored text correctly.
+\layout Standard
+
+In order to configure 
+\family typewriter 
+less
+\family default 
+ as your default pager, do the following:
+\layout Enumerate
+
+Set the environment 
+\family typewriter 
+PAGER
+\family default 
+ variable to 
+\family typewriter 
+less
+\family default 
+.
+\layout Enumerate
+
+Set the environment 
+\family typewriter 
+LESS
+\family default 
+ variable to 
+\family typewriter 
+-r
+\family default 
+ (plus any other options you always want to pass to 
+\family typewriter 
+less
+\family default 
+ by default).
+ This tells 
+\family typewriter 
+less
+\family default 
+ to properly interpret control sequences, which is how color information
+ is given to your terminal.
+\layout Standard
+
+For the 
+\family typewriter 
+csh
+\family default 
+ or 
+\family typewriter 
+tcsh
+\family default 
+ shells, add to your 
+\family typewriter 
+~/.cshrc
+\family default 
+ file the lines:
+\layout Standard
+
+
+\family typewriter 
+setenv PAGER less
+\newline 
+setenv LESS -r
+\layout Standard
+
+There is similar syntax for other Unix shells, look at your system documentation
+ for details.
+\layout Standard
+
+If you are on a system which lacks proper data pagers (such as Windows),
+ IPython will use a very limited builtin pager.
+\layout Subsection
+
+
+\begin_inset LatexCommand \label{sec:emacs}
+
+\end_inset 
+
+(X)Emacs configuration
+\layout Standard
+
+Thanks to the work of Alexander Schmolck and Prabhu Ramachandran, currently
+ (X)Emacs and IPython get along very well.
+ 
+\layout Standard
+
+
+\series bold 
+Important note:
+\series default 
+ You will need to use a recent enough version of 
+\family typewriter 
+python-mode.el
+\family default 
+, along with the file 
+\family typewriter 
+ipython.el
+\family default 
+.
+ You can check that the version you have of 
+\family typewriter 
+python-mode.el
+\family default 
+ is new enough by either looking at the revision number in the file itself,
+ or asking for it in (X)Emacs via 
+\family typewriter 
+M-x py-version
+\family default 
+.
+ Versions 4.68 and newer contain the necessary fixes for proper IPython support.
+\layout Standard
+
+The file 
+\family typewriter 
+ipython.el
+\family default 
+ is included with the IPython distribution, in the documentation directory
+ (where this manual resides in PDF and HTML formats).
+\layout Standard
+
+Once you put these files in your Emacs path, all you need in your 
+\family typewriter 
+.emacs
+\family default 
+ file is:
+\layout Standard
+
+
+\family typewriter 
+(require 'ipython)
+\layout Standard
+
+This should give you full support for executing code snippets via IPython,
+ opening IPython as your Python shell via 
+\family typewriter 
+C-c\SpecialChar ~
+!
+\family default 
+, etc.
+ 
+\layout Subsubsection*
+
+Notes
+\layout Itemize
+
+There is one caveat you should be aware of: you must start the IPython shell
+ 
+\emph on 
+before
+\emph default 
+ attempting to execute any code regions via 
+\family typewriter 
+C-c\SpecialChar ~
+|
+\family default 
+.
+ Simply type 
+\family typewriter 
+C-c\SpecialChar ~
+!
+\family default 
+ to start IPython before passing any code regions to the interpreter, and
+ you shouldn't experience any problems.
+\newline 
+This is due to a bug in Python itself, which has been fixed for Python 2.3,
+ but exists as of Python 2.2.2 (reported as SF bug [ 737947 ]).
+\layout Itemize
+
+The (X)Emacs support is maintained by Alexander Schmolck, so all comments/reques
+ts should be directed to him through the IPython mailing lists.
+ 
+\layout Itemize
+
+This code is still somewhat experimental so it's a bit rough around the
+ edges (although in practice, it works quite well).
+\layout Itemize
+
+Be aware that if you customize 
+\family typewriter 
+py-python-command
+\family default 
+ previously, this value will override what 
+\family typewriter 
+ipython.el
+\family default 
+ does (because loading the customization variables comes later).
+\layout Section
+
+
+\begin_inset LatexCommand \label{sec:quick_tips}
+
+\end_inset 
+
+Quick tips
+\layout Standard
+
+IPython can be used as an improved replacement for the Python prompt, and
+ for that you don't really need to read any more of this manual.
+ But in this section we'll try to summarize a few tips on how to make the
+ most effective use of it for everyday Python development, highlighting
+ things you might miss in the rest of the manual (which is getting long).
+ We'll give references to parts in the manual which provide more detail
+ when appropriate.
+\layout Standard
+
+The following article by Jeremy Jones provides an introductory tutorial
+ about IPython:
+\newline 
+
+\begin_inset LatexCommand \htmlurl{http://www.onlamp.com/pub/a/python/2005/01/27/ipython.html}
+
+\end_inset 
+
+
+\layout Itemize
+
+The TAB key.
+ TAB-completion, especially for attributes, is a convenient way to explore
+ the structure of any object you're dealing with.
+ Simply type 
+\family typewriter 
+object_name.<TAB>
+\family default 
+ and a list of the object's attributes will be printed (see sec.
+ 
+\begin_inset LatexCommand \ref{sec:readline}
+
+\end_inset 
+
+ for more).
+ Tab completion also works on file and directory names, which combined with
+ IPython's alias system allows you to do from within IPython many of the
+ things you normally would need the system shell for.
+ 
+\layout Itemize
+
+Explore your objects.
+ Typing 
+\family typewriter 
+object_name?
+\family default 
+ will print all sorts of details about any object, including docstrings,
+ function definition lines (for call arguments) and constructor details
+ for classes.
+ The magic commands 
+\family typewriter 
+%pdoc
+\family default 
+, 
+\family typewriter 
+%pdef
+\family default 
+, 
+\family typewriter 
+%psource
+\family default 
+ and 
+\family typewriter 
+%pfile
+\family default 
+ will respectively print the docstring, function definition line, full source
+ code and the complete file for any object (when they can be found).
+ If automagic is on (it is by default), you don't need to type the '
+\family typewriter 
+%
+\family default 
+' explicitly.
+ See sec.
+ 
+\begin_inset LatexCommand \ref{sec:dyn-object-info}
+
+\end_inset 
+
+ for more.
+\layout Itemize
+
+The 
+\family typewriter 
+%run
+\family default 
+ magic command allows you to run any python script and load all of its data
+ directly into the interactive namespace.
+ Since the file is re-read from disk each time, changes you make to it are
+ reflected immediately (in contrast to the behavior of 
+\family typewriter 
+import
+\family default 
+).
+ I rarely use 
+\family typewriter 
+import
+\family default 
+ for code I am testing, relying on 
+\family typewriter 
+%run
+\family default 
+ instead.
+ See sec.
+ 
+\begin_inset LatexCommand \ref{sec:magic}
+
+\end_inset 
+
+ for more on this and other magic commands, or type the name of any magic
+ command and ? to get details on it.
+ See also sec.
+ 
+\begin_inset LatexCommand \ref{sec:dreload}
+
+\end_inset 
+
+ for a recursive reload command.
+\newline 
+
+\family typewriter 
+%run
+\family default 
+ also has special flags for timing the execution of your scripts (
+\family typewriter 
+-t
+\family default 
+) and for executing them under the control of either Python's 
+\family typewriter 
+pdb 
+\family default 
+debugger (
+\family typewriter 
+-d
+\family default 
+) or profiler (
+\family typewriter 
+-p
+\family default 
+).
+ With all of these, 
+\family typewriter 
+%run
+\family default 
+ can be used as the main tool for efficient interactive development of code
+ which you write in your editor of choice.
+\layout Itemize
+
+Use the Python debugger, 
+\family typewriter 
+pdb
+\family default 
+
+\begin_inset Foot
+collapsed true
+
+\layout Standard
+
+Thanks to Christian Hart and Matthew Arnison for the suggestions leading
+ to IPython's improved debugger and profiler support.
+\end_inset 
+
+.
+ The 
+\family typewriter 
+%pdb
+\family default 
+ command allows you to toggle on and off the automatic invocation of the
+ pdb debugger at any uncaught exception.
+ The advantage of this is that pdb starts 
+\emph on 
+inside
+\emph default 
+ the function where the exception occurred, with all data still available.
+ You can print variables, see code, execute statements and even walk up
+ and down the call stack to track down the true source of the problem (which
+ often is many layers in the stack above where the exception gets triggered).
+\newline 
+Running programs with 
+\family typewriter 
+%run
+\family default 
+ and pdb active can be an efficient to develop and debug code, in many cases
+ eliminating the need for 
+\family typewriter 
+print
+\family default 
+ statements or external debugging tools.
+ I often simply put a 
+\family typewriter 
+1/0
+\family default 
+ in a place where I want to take a look so that pdb gets called, quickly
+ view whatever variables I need to or test various pieces of code and then
+ remove the 
+\family typewriter 
+1/0
+\family default 
+.
+\newline 
+Note also that `
+\family typewriter 
+%run -d
+\family default 
+' activates 
+\family typewriter 
+pdb
+\family default 
+ and automatically sets initial breakpoints for you to step through your
+ code, watch variables, etc.
+ See Sec.\SpecialChar ~
+
+\begin_inset LatexCommand \ref{sec:cache_output}
+
+\end_inset 
+
+ for details.
+\layout Itemize
+
+Use the output cache.
+ All output results are automatically stored in a global dictionary named
+ 
+\family typewriter 
+Out
+\family default 
+ and variables named 
+\family typewriter 
+_1
+\family default 
+, 
+\family typewriter 
+_2
+\family default 
+, etc.
+ alias them.
+ For example, the result of input line 4 is available either as 
+\family typewriter 
+Out[4]
+\family default 
+ or as 
+\family typewriter 
+_4
+\family default 
+.
+ Additionally, three variables named 
+\family typewriter 
+_
+\family default 
+, 
+\family typewriter 
+__
+\family default 
+ and 
+\family typewriter 
+___
+\family default 
+ are always kept updated with the for the last three results.
+ This allows you to recall any previous result and further use it for new
+ calculations.
+ See Sec.\SpecialChar ~
+
+\begin_inset LatexCommand \ref{sec:cache_output}
+
+\end_inset 
+
+ for more.
+\layout Itemize
+
+Put a '
+\family typewriter 
+;
+\family default 
+' at the end of a line to supress the printing of output.
+ This is useful when doing calculations which generate long output you are
+ not interested in seeing.
+ The 
+\family typewriter 
+_*
+\family default 
+ variables and the 
+\family typewriter 
+Out[]
+\family default 
+ list do get updated with the contents of the output, even if it is not
+ printed.
+ You can thus still access the generated results this way for further processing.
+\layout Itemize
+
+A similar system exists for caching input.
+ All input is stored in a global list called 
+\family typewriter 
+In
+\family default 
+ , so you can re-execute lines 22 through 28 plus line 34 by typing 
+\family typewriter 
+'exec In[22:29]+In[34]'
+\family default 
+ (using Python slicing notation).
+ If you need to execute the same set of lines often, you can assign them
+ to a macro with the 
+\family typewriter 
+%macro
+\family default 
+ 
+\family typewriter 
+function.
+ 
+\family default 
+See sec.
+ 
+\begin_inset LatexCommand \ref{sec:cache_input}
+
+\end_inset 
+
+ for more.
+\layout Itemize
+
+Use your input history.
+ The 
+\family typewriter 
+%hist
+\family default 
+ command can show you all previous input, without line numbers if desired
+ (option 
+\family typewriter 
+-n
+\family default 
+) so you can directly copy and paste code either back in IPython or in a
+ text editor.
+ You can also save all your history by turning on logging via 
+\family typewriter 
+%logstart
+\family default 
+; these logs can later be either reloaded as IPython sessions or used as
+ code for your programs.
+\layout Itemize
+
+Define your own macros with 
+\family typewriter 
+%macro
+\family default 
+.
+ This can be useful for automating sequences of expressions when working
+ interactively.
+\layout Itemize
+
+Define your own system aliases.
+ Even though IPython gives you access to your system shell via the 
+\family typewriter 
+!
+\family default 
+ prefix, it is convenient to have aliases to the system commands you use
+ most often.
+ This allows you to work seamlessly from inside IPython with the same commands
+ you are used to in your system shell.
+\newline 
+IPython comes with some pre-defined aliases and a complete system for changing
+ directories, both via a stack (see 
+\family typewriter 
+%pushd
+\family default 
+, 
+\family typewriter 
+%popd
+\family default 
+ and 
+\family typewriter 
+%ds
+\family default 
+) and via direct 
+\family typewriter 
+%cd
+\family default 
+.
+ The latter keeps a history of visited directories and allows you to go
+ to any previously visited one.
+\layout Itemize
+
+Use Python to manipulate the results of system commands.
+ The `
+\family typewriter 
+!!
+\family default 
+' special syntax, and the 
+\family typewriter 
+%sc
+\family default 
+ and 
+\family typewriter 
+%sx
+\family default 
+ magic commands allow you to capture system output into Python variables.
+\layout Itemize
+
+Expand python variables when calling the shell (either via 
+\family typewriter 
+`!'
+\family default 
+ and 
+\family typewriter 
+`!!'
+\family default 
+ or via aliases) by prepending a 
+\family typewriter 
+$
+\family default 
+ in front of them.
+ You can also expand complete python expressions.
+ See sec.\SpecialChar ~
+
+\begin_inset LatexCommand \ref{sub:System-shell-access}
+
+\end_inset 
+
+ for more.
+\layout Itemize
+
+Use profiles to maintain different configurations (modules to load, function
+ definitions, option settings) for particular tasks.
+ You can then have customized versions of IPython for specific purposes.
+ See sec.\SpecialChar ~
+
+\begin_inset LatexCommand \ref{sec:profiles}
+
+\end_inset 
+
+ for more.
+\layout Itemize
+
+Embed IPython in your programs.
+ A few lines of code are enough to load a complete IPython inside your own
+ programs, giving you the ability to work with your data interactively after
+ automatic processing has been completed.
+ See sec.\SpecialChar ~
+
+\begin_inset LatexCommand \ref{sec:embed}
+
+\end_inset 
+
+ for more.
+\layout Itemize
+
+Use the Python profiler.
+ When dealing with performance issues, the 
+\family typewriter 
+%run
+\family default 
+ command with a 
+\family typewriter 
+-p
+\family default 
+ option allows you to run complete programs under the control of the Python
+ profiler.
+ The 
+\family typewriter 
+%prun
+\family default 
+ command does a similar job for single Python expressions (like function
+ calls).
+\layout Itemize
+
+Use 
+\family typewriter 
+%edit
+\family default 
+ to have almost multiline editing.
+ While IPython doesn't support true multiline editing, this command allows
+ you to call an editor on the spot, and IPython will execute the code you
+ type in there as if it were typed interactively.
+\layout Standard
+
+If you have your own favorite tip on using IPython efficiently for a certain
+ task (especially things which can't be done in the normal Python interpreter),
+ don't hesitate to send it!
+\layout Section
+
+Command-line use
+\layout Standard
+
+You start IPython with the command:
+\layout Standard
+
+
+\family typewriter 
+$ ipython [options] files
+\layout Standard
+
+If invoked with no options, it executes all the files listed in sequence
+ and drops you into the interpreter while still acknowledging any options
+ you may have set in your ipythonrc file.
+ This behavior is different from standard Python, which when called as 
+\family typewriter 
+python -i
+\family default 
+ will only execute one file and ignore your configuration setup.
+\layout Standard
+
+Please note that some of the configuration options are not available at
+ the command line, simply because they are not practical here.
+ Look into your ipythonrc configuration file for details on those.
+ This file typically installed in the 
+\family typewriter 
+$HOME/.ipython
+\family default 
+ directory.
+ For Windows users, 
+\family typewriter 
+$HOME
+\family default 
+ resolves to 
+\family typewriter 
+C:
+\backslash 
+
+\backslash 
+Documents and Settings
+\backslash 
+
+\backslash 
+YourUserName
+\family default 
+ in most instances.
+ In the rest of this text, we will refer to this directory as 
+\family typewriter 
+IPYTHONDIR
+\family default 
+.
+\layout Subsection
+
+
+\begin_inset LatexCommand \label{sec:threading-opts}
+
+\end_inset 
+
+Special Threading Options
+\layout Standard
+
+The following special options are ONLY valid at the beginning of the command
+ line, and not later.
+ This is because they control the initial- ization of ipython itself, before
+ the normal option-handling mechanism is active.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-gthread,\SpecialChar ~
+-wthread,\SpecialChar ~
+-pylab:
+\family default 
+\series default 
+ Only 
+\emph on 
+one
+\emph default 
+ of these can be given, and it can only be given as the first option passed
+ to IPython (it will have no effect in any other position).
+ They provide threading support for the GTK and WXPython toolkits, and for
+ the matplotlib library.
+\layout List
+\labelwidthstring 00.00.0000
+
+\SpecialChar ~
+ If 
+\family typewriter 
+-gthread
+\family default 
+ is given, IPython starts running a separate thread for GTK operation, so
+ that pyGTK-based programs can open and control GUIs without blocking IPython.
+ 
+\layout List
+\labelwidthstring 00.00.0000
+
+\SpecialChar ~
+ Similarly, 
+\family typewriter 
+-wthread
+\family default 
+ instantiates IPython with threading support for the WXPython toolkit.
+ You can control WX application windows from within IPython.
+\layout List
+\labelwidthstring 00.00.0000
+
+\SpecialChar ~
+ If 
+\family typewriter 
+-pylab
+\family default 
+ is given, IPython loads special support for the mat- plotlib library (
+\begin_inset LatexCommand \htmlurl{http://matplotlib.sourceforge.net}
+
+\end_inset 
+
+), allowing interactive usage of any of its backends as defined in the user's
+ .matplotlibrc file.
+ It automatically activates GTK or WX threading for IPyhton if the choice
+ of matplotlib backend requires it.
+ It also modifies the 
+\family typewriter 
+%run
+\family default 
+ command to correctly execute (without blocking) any matplotlib-based script
+ which calls 
+\family typewriter 
+show()
+\family default 
+ at the end.
+ 
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-tk
+\family default 
+\series default 
+ The 
+\family typewriter 
+-g/wthread
+\family default 
+ options, and 
+\family typewriter 
+-pylab
+\family default 
+ (if matplotlib is configured to use WX or GTK), will normally block Tk
+ graphical interfaces.
+ This means that when either GTK or WX threading is active, any attempt
+ to open a Tk GUI will result in a dead window, and pos- sibly cause the
+ Python interpreter to crash.
+ An extra option, 
+\family typewriter 
+-tk
+\family default 
+, is available to address this issue.
+ It can 
+\emph on 
+only
+\emph default 
+ be given as a 
+\emph on 
+second
+\emph default 
+ option after any of the above (
+\family typewriter 
+-gthread
+\family default 
+, 
+\family typewriter 
+-wthread
+\family default 
+ or 
+\family typewriter 
+-pylab
+\family default 
+).
+\layout List
+\labelwidthstring 00.00.0000
+
+\SpecialChar ~
+ If 
+\family typewriter 
+-tk
+\family default 
+ is given, IPython will try to coordinate Tk threading with WX or GTK.
+ This is however potentially unreliable, and you will have to test on your
+ platform and Python configuration to determine whether it works for you.
+ Debian users have reported success, apparently due to the fact that Debian
+ builds all of Tcl, Tk, Tkinter and Python with pthreads support.
+ Under other Linux environments (such as Fedora Core 2), this option has
+ caused random crashes and lockups of the Python interpreter.
+ Under other operating systems (Mac OSX and Windows), you'll need to try
+ it to find out, since currently no user reports are available.
+\layout List
+\labelwidthstring 00.00.0000
+
+\SpecialChar ~
+ There is unfortunately no way for IPython to determine at run time whether
+ 
+\family typewriter 
+-tk
+\family default 
+ will work reliably or not, so you will need to do some experiments before
+ relying on it for regular work.
+ 
+\layout Subsection
+
+
+\begin_inset LatexCommand \label{sec:cmd-line-opts}
+
+\end_inset 
+
+Regular Options
+\layout Standard
+
+After the above threading options have been given, regular options can follow
+ in any order.
+ All options can be abbreviated to their shortest non-ambiguous form and
+ are case-sensitive.
+ One or two dashes can be used.
+ Some options have an alternate short form, indicated after a 
+\family typewriter 
+|
+\family default 
+.
+\layout Standard
+
+Most options can also be set from your ipythonrc configuration file.
+ See the provided example for more details on what the options do.
+ Options given at the command line override the values set in the ipythonrc
+ file.
+\layout Standard
+
+All options with a 
+\family typewriter 
+no|
+\family default 
+ prepended can be specified in 'no' form (
+\family typewriter 
+-nooption
+\family default 
+ instead of 
+\family typewriter 
+-option
+\family default 
+) to turn the feature off.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-help
+\family default 
+\series default 
+: print a help message and exit.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-pylab:
+\family default 
+\series default 
+ this can 
+\emph on 
+only
+\emph default 
+ be given as the 
+\emph on 
+first
+\emph default 
+ option passed to IPython (it will have no effect in any other position).
+ It adds special support for the matplotlib library (
+\begin_inset LatexCommand \htmlurl[http://matplotlib.sourceforge.net]{http://matplotlib.sourceforge.net}
+
+\end_inset 
+
+), allowing interactive usage of any of its backends as defined in the user's
+ 
+\family typewriter 
+.matplotlibrc
+\family default 
+ file.
+ It automatically activates GTK or WX threading for IPyhton if the choice
+ of matplotlib backend requires it.
+ It also modifies the 
+\family typewriter 
+%run
+\family default 
+ command to correctly execute (without blocking) any matplotlib-based script
+ which calls 
+\family typewriter 
+show()
+\family default 
+ at the end.
+ See Sec.\SpecialChar ~
+
+\begin_inset LatexCommand \ref{sec:matplotlib-support}
+
+\end_inset 
+
+ for more details.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-no|automagic
+\series default 
+:
+\family default 
+ make magic commands automatic (without needing their first character to
+ be 
+\family typewriter 
+%
+\family default 
+).
+ Type 
+\family typewriter 
+%magic
+\family default 
+ at the IPython prompt for more information.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-no|banner
+\series default 
+:
+\family default 
+ Print the initial information banner (default on).
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-c\SpecialChar ~
+<command>:
+\family default 
+\series default 
+ execute the given command string, and set sys.argv to 
+\family typewriter 
+['c']
+\family default 
+.
+ This is similar to the 
+\family typewriter 
+-c
+\family default 
+ option in the normal Python interpreter.
+ 
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-cache_size|cs\SpecialChar ~
+<n>
+\series default 
+:
+\family default 
+ size of the output cache (maximum number of entries to hold in memory).
+ The default is 1000, you can change it permanently in your config file.
+ Setting it to 0 completely disables the caching system, and the minimum
+ value accepted is 20 (if you provide a value less than 20, it is reset
+ to 0 and a warning is issued) This limit is defined because otherwise you'll
+ spend more time re-flushing a too small cache than working.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-classic|cl
+\series default 
+:
+\family default 
+ Gives IPython a similar feel to the classic Python prompt.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-colors\SpecialChar ~
+<scheme>:
+\family default 
+\series default 
+ Color scheme for prompts and exception reporting.
+ Currently implemented: NoColor, Linux and LightBG.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-no|color_info:
+\family default 
+\series default 
+ IPython can display information about objects via a set of functions, and
+ optionally can use colors for this, syntax highlighting source code and
+ various other elements.
+ However, because this information is passed through a pager (like 'less')
+ and many pagers get confused with color codes, this option is off by default.
+ You can test it and turn it on permanently in your ipythonrc file if it
+ works for you.
+ As a reference, the 'less' pager supplied with Mandrake 8.2 works ok, but
+ that in RedHat 7.2 doesn't.
+\layout List
+\labelwidthstring 00.00.0000
+
+\SpecialChar ~
+ Test it and turn it on permanently if it works with your system.
+ The magic function 
+\family typewriter 
+%color_info
+\family default 
+ allows you to toggle this interactively for testing.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-no|debug
+\family default 
+\series default 
+: Show information about the loading process.
+ Very useful to pin down problems with your configuration files or to get
+ details about session restores.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-no|deep_reload
+\series default 
+:
+\family default 
+ IPython can use the 
+\family typewriter 
+deep_reload
+\family default 
+ module which reloads changes in modules recursively (it replaces the 
+\family typewriter 
+reload()
+\family default 
+ function, so you don't need to change anything to use it).
+ 
+\family typewriter 
+deep_reload()
+\family default 
+ forces a full reload of modules whose code may have changed, which the
+ default 
+\family typewriter 
+reload()
+\family default 
+ function does not.
+\layout List
+\labelwidthstring 00.00.0000
+
+\SpecialChar ~
+ When deep_reload is off, IPython will use the normal 
+\family typewriter 
+reload()
+\family default 
+, but deep_reload will still be available as 
+\family typewriter 
+dreload()
+\family default 
+.
+ This feature is off by default [which means that you have both normal 
+\family typewriter 
+reload()
+\family default 
+ and 
+\family typewriter 
+dreload()
+\family default 
+].
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-editor\SpecialChar ~
+<name>
+\family default 
+\series default 
+: Which editor to use with the 
+\family typewriter 
+%edit
+\family default 
+ command.
+ By default, IPython will honor your 
+\family typewriter 
+EDITOR
+\family default 
+ environment variable (if not set, vi is the Unix default and notepad the
+ Windows one).
+ Since this editor is invoked on the fly by IPython and is meant for editing
+ small code snippets, you may want to use a small, lightweight editor here
+ (in case your default 
+\family typewriter 
+EDITOR
+\family default 
+ is something like Emacs).
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-ipythondir\SpecialChar ~
+<name>
+\series default 
+:
+\family default 
+ name of your IPython configuration directory 
+\family typewriter 
+IPYTHONDIR
+\family default 
+.
+ This can also be specified through the environment variable 
+\family typewriter 
+IPYTHONDIR
+\family default 
+.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-log|l
+\family default 
+\series default 
+: generate a log file of all input.
+ Defaults to 
+\family typewriter 
+$IPYTHONDIR/log
+\family default 
+.
+ You can use this to later restore a session by loading your logfile as
+ a file to be executed with option 
+\family typewriter 
+-logplay
+\family default 
+ (see below).
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-logfile|lf\SpecialChar ~
+<name>
+\series default 
+: 
+\family default 
+specify the name of your logfile.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-logplay|lp\SpecialChar ~
+<name>
+\series default 
+:
+\family default 
+ you can replay a previous log.
+ For restoring a session as close as possible to the state you left it in,
+ use this option (don't just run the logfile).
+ With 
+\family typewriter 
+-logplay
+\family default 
+, IPython will try to reconstruct the previous working environment in full,
+ not just execute the commands in the logfile.
+\layout List
+\labelwidthstring 00.00.0000
+
+\SpecialChar ~
+ When a session is restored, logging is automatically turned on again with
+ the name of the logfile it was invoked with (it is read from the log header).
+ So once you've turned logging on for a session, you can quit IPython and
+ reload it as many times as you want and it will continue to log its history
+ and restore from the beginning every time.
+\layout List
+\labelwidthstring 00.00.0000
+
+\SpecialChar ~
+ Caveats: there are limitations in this option.
+ The history variables 
+\family typewriter 
+_i*
+\family default 
+,
+\family typewriter 
+_*
+\family default 
+ and 
+\family typewriter 
+_dh
+\family default 
+ don't get restored properly.
+ In the future we will try to implement full session saving by writing and
+ retrieving a 'snapshot' of the memory state of IPython.
+ But our first attempts failed because of inherent limitations of Python's
+ Pickle module, so this may have to wait.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-no|messages
+\series default 
+:
+\family default 
+ Print messages which IPython collects about its startup process (default
+ on).
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-no|pdb
+\family default 
+\series default 
+: Automatically call the pdb debugger after every uncaught exception.
+ If you are used to debugging using pdb, this puts you automatically inside
+ of it after any call (either in IPython or in code called by it) which
+ triggers an exception which goes uncaught.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-no|pprint
+\series default 
+:
+\family default 
+ ipython can optionally use the pprint (pretty printer) module for displaying
+ results.
+ pprint tends to give a nicer display of nested data structures.
+ If you like it, you can turn it on permanently in your config file (default
+ off).
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-profile|p <name>
+\series default 
+:
+\family default 
+ assume that your config file is 
+\family typewriter 
+ipythonrc-<name>
+\family default 
+ (looks in current dir first, then in 
+\family typewriter 
+IPYTHONDIR
+\family default 
+).
+ This is a quick way to keep and load multiple config files for different
+ tasks, especially if you use the include option of config files.
+ You can keep a basic 
+\family typewriter 
+IPYTHONDIR/ipythonrc
+\family default 
+ file and then have other 'profiles' which include this one and load extra
+ things for particular tasks.
+ For example:
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\SpecialChar ~
+ 
+\family default 
+1.
+
+\family typewriter 
+ $HOME/.ipython/ipythonrc
+\family default 
+ : load basic things you always want.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\SpecialChar ~
+ 
+\family default 
+2.
+
+\family typewriter 
+ $HOME/.ipython/ipythonrc-math
+\family default 
+ : load (1) and basic math-related modules.
+ 
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\SpecialChar ~
+ 
+\family default 
+3.
+
+\family typewriter 
+ $HOME/.ipython/ipythonrc-numeric
+\family default 
+ : load (1) and Numeric and plotting modules.
+\layout List
+\labelwidthstring 00.00.0000
+
+\SpecialChar ~
+ Since it is possible to create an endless loop by having circular file
+ inclusions, IPython will stop if it reaches 15 recursive inclusions.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-prompt_in1|pi1\SpecialChar ~
+<string>:
+\family default 
+\series default 
+ Specify the string used for input prompts.
+ Note that if you are using numbered prompts, the number is represented
+ with a '
+\backslash 
+#' in the string.
+ Don't forget to quote strings with spaces embedded in them.
+ Default: '
+\family typewriter 
+In\SpecialChar ~
+[
+\backslash 
+#]:
+\family default 
+'.
+ Sec.\SpecialChar ~
+
+\begin_inset LatexCommand \ref{sec:prompts}
+
+\end_inset 
+
+ discusses in detail all the available escapes to customize your prompts.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-prompt_in2|pi2\SpecialChar ~
+<string>:
+\family default 
+\series default 
+ Similar to the previous option, but used for the continuation prompts.
+ The special sequence '
+\family typewriter 
+
+\backslash 
+D
+\family default 
+' is similar to '
+\family typewriter 
+
+\backslash 
+#
+\family default 
+', but with all digits replaced dots (so you can have your continuation
+ prompt aligned with your input prompt).
+ Default: '
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+.
+\backslash 
+D.:
+\family default 
+' (note three spaces at the start for alignment with '
+\family typewriter 
+In\SpecialChar ~
+[
+\backslash 
+#]
+\family default 
+').
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-prompt_out|po\SpecialChar ~
+<string>:
+\family default 
+\series default 
+ String used for output prompts, also uses numbers like 
+\family typewriter 
+prompt_in1
+\family default 
+.
+ Default: '
+\family typewriter 
+Out[
+\backslash 
+#]:
+\family default 
+'
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-quick
+\family default 
+\series default 
+: start in bare bones mode (no config file loaded).
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-rcfile\SpecialChar ~
+<name>
+\series default 
+:
+\family default 
+ name of your IPython resource configuration file.
+ Normally IPython loads ipythonrc (from current directory) or
+\family typewriter 
+ IPYTHONDIR/ipythonrc
+\family default 
+.
+\layout List
+\labelwidthstring 00.00.0000
+
+\SpecialChar ~
+ If the loading of your config file fails, IPython starts with a bare bones
+ configuration (no modules loaded at all).
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-no|readline
+\family default 
+\series default 
+: use the readline library, which is needed to support name completion and
+ command history, among other things.
+ It is enabled by default, but may cause problems for users of X/Emacs in
+ Python comint or shell buffers.
+\layout List
+\labelwidthstring 00.00.0000
+
+\SpecialChar ~
+ Note that X/Emacs 'eterm' buffers (opened with 
+\family typewriter 
+M-x\SpecialChar ~
+term
+\family default 
+) support IPython's readline and syntax coloring fine, only 'emacs' (
+\family typewriter 
+M-x\SpecialChar ~
+shell
+\family default 
+ and 
+\family typewriter 
+C-c\SpecialChar ~
+!
+\family default 
+) buffers do not.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-screen_length|sl\SpecialChar ~
+<n>
+\series default 
+:
+\family default 
+ number of lines of your screen.
+ This is used to control printing of very long strings.
+ Strings longer than this number of lines will be sent through a pager instead
+ of directly printed.
+\layout List
+\labelwidthstring 00.00.0000
+
+\SpecialChar ~
+ The default value for this is 0, which means IPython will auto-detect your
+ screen size every time it needs to print certain potentially long strings
+ (this doesn't change the behavior of the 'print' keyword, it's only triggered
+ internally).
+ If for some reason this isn't working well (it needs curses support), specify
+ it yourself.
+ Otherwise don't change the default.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-separate_in|si\SpecialChar ~
+<string>
+\series default 
+:
+\family default 
+ separator before input prompts.
+ Default: '
+\family typewriter 
+
+\backslash 
+n
+\family default 
+'
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-separate_out|so\SpecialChar ~
+<string>
+\family default 
+\series default 
+: separator before output prompts.
+ Default: nothing.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-separate_out2|so2\SpecialChar ~
+<string>
+\series default 
+:
+\family default 
+ separator after output prompts.
+ Default: nothing.
+\layout List
+\labelwidthstring 00.00.0000
+
+\SpecialChar ~
+ For these three options, use the value 0 to specify no separator.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-nosep
+\series default 
+: 
+\family default 
+shorthand for 
+\family typewriter 
+'-SeparateIn 0 -SeparateOut 0 -SeparateOut2 0'
+\family default 
+.
+ Simply removes all input/output separators.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-upgrade
+\family default 
+\series default 
+: allows you to upgrade your 
+\family typewriter 
+IPYTHONDIR
+\family default 
+ configuration when you install a new version of IPython.
+ Since new versions may include new command line options or example files,
+ this copies updated ipythonrc-type files.
+ However, it backs up (with a 
+\family typewriter 
+.old
+\family default 
+ extension) all files which it overwrites so that you can merge back any
+ customizations you might have in your personal files.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-Version
+\series default 
+:
+\family default 
+ print version information and exit.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+-xmode <modename>
+\series default 
+:
+\family default 
+ Mode for exception reporting.
+\layout List
+\labelwidthstring 00.00.0000
+
+\SpecialChar ~
+ Valid modes: Plain, Context and Verbose.
+\layout List
+\labelwidthstring 00.00.0000
+
+\SpecialChar ~
+ Plain: similar to python's normal traceback printing.
+\layout List
+\labelwidthstring 00.00.0000
+
+\SpecialChar ~
+ Context: prints 5 lines of context source code around each line in the
+ traceback.
+\layout List
+\labelwidthstring 00.00.0000
+
+\SpecialChar ~
+ Verbose: similar to Context, but additionally prints the variables currently
+ visible where the exception happened (shortening their strings if too long).
+ This can potentially be very slow, if you happen to have a huge data structure
+ whose string representation is complex to compute.
+ Your computer may appear to freeze for a while with cpu usage at 100%.
+ If this occurs, you can cancel the traceback with Ctrl-C (maybe hitting
+ it more than once).
+\layout Section
+
+Interactive use
+\layout Standard
+
+
+\series bold 
+Warning
+\series default 
+: IPython relies on the existence of a global variable called 
+\family typewriter 
+__IP
+\family default 
+ which controls the shell itself.
+ If you redefine 
+\family typewriter 
+__IP
+\family default 
+ to anything, bizarre behavior will quickly occur.
+\layout Standard
+
+Other than the above warning, IPython is meant to work as a drop-in replacement
+ for the standard interactive interpreter.
+ As such, any code which is valid python should execute normally under IPython
+ (cases where this is not true should be reported as bugs).
+ It does, however, offer many features which are not available at a standard
+ python prompt.
+ What follows is a list of these.
+\layout Subsection
+
+Caution for Windows users
+\layout Standard
+
+Windows, unfortunately, uses the `
+\family typewriter 
+
+\backslash 
+
+\family default 
+' character as a path separator.
+ This is a terrible choice, because `
+\family typewriter 
+
+\backslash 
+
+\family default 
+' also represents the escape character in most modern programming languages,
+ including Python.
+ For this reason, issuing many of the commands discussed below (especially
+ magics which affect the filesystem) with `
+\family typewriter 
+
+\backslash 
+
+\family default 
+' in them will cause strange errors.
+\layout Standard
+
+A partial solution is to use instead the `
+\family typewriter 
+/
+\family default 
+' character as a path separator, which Windows recognizes in 
+\emph on 
+most
+\emph default 
+ situations.
+ However, in Windows commands `
+\family typewriter 
+/
+\family default 
+' flags options, so you can not use it for the root directory.
+ This means that paths beginning at the root must be typed in a contrived
+ manner like:
+\newline 
+
+\family typewriter 
+%copy 
+\backslash 
+opt/foo/bar.txt 
+\backslash 
+tmp
+\layout Standard
+
+There is no sensible thing IPython can do to truly work around this flaw
+ in Windows
+\begin_inset Foot
+collapsed true
+
+\layout Standard
+
+If anyone comes up with a 
+\emph on 
+clean
+\emph default 
+ solution which works consistently and does not negatively impact other
+ platforms at all, I'll gladly accept a patch.
+\end_inset 
+
+.
+\layout Subsection
+
+
+\begin_inset LatexCommand \label{sec:magic}
+
+\end_inset 
+
+Magic command system
+\layout Standard
+
+IPython will treat any line whose first character is a 
+\family typewriter 
+%
+\family default 
+ as a special call to a 'magic' function.
+ These allow you to control the behavior of IPython itself, plus a lot of
+ system-type features.
+ They are all prefixed with a 
+\family typewriter 
+%
+\family default 
+ character, but parameters are given without parentheses or quotes.
+\layout Standard
+
+Example: typing 
+\family typewriter 
+'%cd mydir'
+\family default 
+ (without the quotes) changes you working directory to 
+\family typewriter 
+'mydir'
+\family default 
+, if it exists.
+\layout Standard
+
+If you have 'automagic' enabled (in your 
+\family typewriter 
+ipythonrc
+\family default 
+ file, via the command line option 
+\family typewriter 
+-automagic 
+\family default 
+or with the 
+\family typewriter 
+%automagic
+\family default 
+ function), you don't need to type in the 
+\family typewriter 
+%
+\family default 
+ explicitly.
+ IPython will scan its internal list of magic functions and call one if
+ it exists.
+ With automagic on you can then just type '
+\family typewriter 
+cd mydir
+\family default 
+' to go to directory '
+\family typewriter 
+mydir
+\family default 
+'.
+ The automagic system has the lowest possible precedence in name searches,
+ so defining an identifier with the same name as an existing magic function
+ will shadow it for automagic use.
+ You can still access the shadowed magic function by explicitly using the
+ 
+\family typewriter 
+%
+\family default 
+ character at the beginning of the line.
+\layout Standard
+
+An example (with automagic on) should clarify all this:
+\layout LyX-Code
+
+In [1]: cd ipython # %cd is called by automagic
+\layout LyX-Code
+
+/home/fperez/ipython
+\layout LyX-Code
+
+In [2]: cd=1 # now cd is just a variable
+\layout LyX-Code
+
+In [3]: cd ..
+ # and doesn't work as a function anymore
+\layout LyX-Code
+
+------------------------------------------------------------
+\layout LyX-Code
+
+    File "<console>", line 1
+\layout LyX-Code
+
+      cd ..
+\layout LyX-Code
+
+          ^
+\layout LyX-Code
+
+SyntaxError: invalid syntax
+\layout LyX-Code
+
+\layout LyX-Code
+
+In [4]: %cd ..
+ # but %cd always works
+\layout LyX-Code
+
+/home/fperez
+\layout LyX-Code
+
+In [5]: del cd # if you remove the cd variable
+\layout LyX-Code
+
+In [6]: cd ipython # automagic can work again
+\layout LyX-Code
+
+/home/fperez/ipython
+\layout Standard
+
+You can define your own magic functions to extend the system.
+ The following is a snippet of code which shows how to do it.
+ It is provided as file 
+\family typewriter 
+example-magic.py
+\family default 
+ in the examples directory:
+\layout Standard
+
+
+\begin_inset Include \verbatiminput{examples/example-magic.py}
+preview false
+
+\end_inset 
+
+
+\layout Standard
+
+You can also define your own aliased names for magic functions.
+ In your 
+\family typewriter 
+ipythonrc
+\family default 
+ file, placing a line like:
+\layout Standard
+
+
+\family typewriter 
+execute __IP.magic_cl = __IP.magic_clear
+\layout Standard
+
+will define 
+\family typewriter 
+%cl
+\family default 
+ as a new name for 
+\family typewriter 
+%clear
+\family default 
+.
+\layout Standard
+
+Type 
+\family typewriter 
+%magic
+\family default 
+ for more information, including a list of all available magic functions
+ at any time and their docstrings.
+ You can also type 
+\family typewriter 
+%magic_function_name?
+\family default 
+ (see sec.
+ 
+\begin_inset LatexCommand \ref{sec:dyn-object-info}
+
+\end_inset 
+
+ for information on the 
+\family typewriter 
+'?'
+\family default 
+ system) to get information about any particular magic function you are
+ interested in.
+\layout Subsubsection
+
+Magic commands
+\layout Standard
+
+The rest of this section is automatically generated for each release from
+ the docstrings in the IPython code.
+ Therefore the formatting is somewhat minimal, but this method has the advantage
+ of having information always in sync with the code.
+\layout Standard
+
+A list of all the magic commands available in IPython's 
+\emph on 
+default
+\emph default 
+ installation follows.
+ This is similar to what you'll see by simply typing 
+\family typewriter 
+%magic
+\family default 
+ at the prompt, but that will also give you information about magic commands
+ you may have added as part of your personal customizations.
+\layout Standard
+
+
+\begin_inset Include \input{magic.tex}
+preview false
+
+\end_inset 
+
+
+\layout Subsection
+
+Access to the standard Python help
+\layout Standard
+
+As of Python 2.1, a help system is available with access to object docstrings
+ and the Python manuals.
+ Simply type 
+\family typewriter 
+'help'
+\family default 
+ (no quotes) to access it.
+ You can also type 
+\family typewriter 
+help(object)
+\family default 
+ to obtain information about a given object, and 
+\family typewriter 
+help('keyword')
+\family default 
+ for information on a keyword.
+ As noted in sec.
+ 
+\begin_inset LatexCommand \ref{sec:help-access}
+
+\end_inset 
+
+, you need to properly configure your environment variable 
+\family typewriter 
+PYTHONDOCS
+\family default 
+ for this feature to work correctly.
+\layout Subsection
+
+
+\begin_inset LatexCommand \label{sec:dyn-object-info}
+
+\end_inset 
+
+Dynamic object information
+\layout Standard
+
+Typing 
+\family typewriter 
+?word
+\family default 
+ or 
+\family typewriter 
+word?
+\family default 
+ prints detailed information about an object.
+ If certain strings in the object are too long (docstrings, code, etc.) they
+ get snipped in the center for brevity.
+ This system gives access variable types and values, full source code for
+ any object (if available), function prototypes and other useful information.
+\layout Standard
+
+Typing 
+\family typewriter 
+??word
+\family default 
+ or 
+\family typewriter 
+word??
+\family default 
+ gives access to the full information without snipping long strings.
+ Long strings are sent to the screen through the 
+\family typewriter 
+less
+\family default 
+ pager if longer than the screen and printed otherwise.
+ On systems lacking the 
+\family typewriter 
+less
+\family default 
+ command, IPython uses a very basic internal pager.
+\layout Standard
+
+The following magic functions are particularly useful for gathering information
+ about your working environment.
+ You can get more details by typing 
+\family typewriter 
+%magic
+\family default 
+ or querying them individually (use 
+\family typewriter 
+%function_name?
+\family default 
+ with or without the 
+\family typewriter 
+%
+\family default 
+), this is just a summary:
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+%pdoc\SpecialChar ~
+<object>
+\family default 
+\series default 
+: Print (or run through a pager if too long) the docstring for an object.
+ If the given object is a class, it will print both the class and the constructo
+r docstrings.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+%pdef\SpecialChar ~
+<object>
+\family default 
+\series default 
+: Print the definition header for any callable object.
+ If the object is a class, print the constructor information.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+%psource\SpecialChar ~
+<object>
+\family default 
+\series default 
+: Print (or run through a pager if too long) the source code for an object.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+%pfile\SpecialChar ~
+<object>
+\family default 
+\series default 
+: Show the entire source file where an object was defined via a pager, opening
+ it at the line where the object definition begins.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+%who/%whos
+\family default 
+\series default 
+: These functions give information about identifiers you have defined interactiv
+ely (not things you loaded or defined in your configuration files).
+ 
+\family typewriter 
+%who
+\family default 
+ just prints a list of identifiers and 
+\family typewriter 
+%whos
+\family default 
+ prints a table with some basic details about each identifier.
+\layout Standard
+
+Note that the dynamic object information functions (
+\family typewriter 
+?/??, %pdoc, %pfile, %pdef, %psource
+\family default 
+) give you access to documentation even on things which are not really defined
+ as separate identifiers.
+ Try for example typing 
+\family typewriter 
+{}.get?
+\family default 
+ or after doing 
+\family typewriter 
+import os
+\family default 
+, type 
+\family typewriter 
+os.path.abspath??
+\family default 
+.
+\layout Subsection
+
+
+\begin_inset LatexCommand \label{sec:readline}
+
+\end_inset 
+
+Readline-based features
+\layout Standard
+
+These features require the GNU readline library, so they won't work if your
+ Python installation lacks readline support.
+ We will first describe the default behavior IPython uses, and then how
+ to change it to suit your preferences.
+\layout Subsubsection
+
+Command line completion
+\layout Standard
+
+At any time, hitting TAB will complete any available python commands or
+ variable names, and show you a list of the possible completions if there's
+ no unambiguous one.
+ It will also complete filenames in the current directory if no python names
+ match what you've typed so far.
+\layout Subsubsection
+
+Search command history
+\layout Standard
+
+IPython provides two ways for searching through previous input and thus
+ reduce the need for repetitive typing:
+\layout Enumerate
+
+Start typing, and then use 
+\family typewriter 
+Ctrl-p
+\family default 
+ (previous,up) and 
+\family typewriter 
+Ctrl-n
+\family default 
+ (next,down) to search through only the history items that match what you've
+ typed so far.
+ If you use 
+\family typewriter 
+Ctrl-p/Ctrl-n
+\family default 
+ at a blank prompt, they just behave like normal arrow keys.
+\layout Enumerate
+
+Hit 
+\family typewriter 
+Ctrl-r
+\family default 
+: opens a search prompt.
+ Begin typing and the system searches your history for lines that contain
+ what you've typed so far, completing as much as it can.
+\layout Subsubsection
+
+Persistent command history across sessions
+\layout Standard
+
+IPython will save your input history when it leaves and reload it next time
+ you restart it.
+ By default, the history file is named 
+\family typewriter 
+$IPYTHONDIR/history
+\family default 
+, but if you've loaded a named profile, '
+\family typewriter 
+-PROFILE_NAME
+\family default 
+' is appended to the name.
+ This allows you to keep separate histories related to various tasks: commands
+ related to numerical work will not be clobbered by a system shell history,
+ for example.
+\layout Subsubsection
+
+Autoindent
+\layout Standard
+
+IPython can recognize lines ending in ':' and indent the next line, while
+ also un-indenting automatically after 'raise' or 'return'.
+ 
+\layout Standard
+
+This feature uses the readline library, so it will honor your 
+\family typewriter 
+~/.inputrc
+\family default 
+ configuration (or whatever file your 
+\family typewriter 
+INPUTRC
+\family default 
+ variable points to).
+ Adding the following lines to your 
+\family typewriter 
+.inputrc
+\family default 
+ file can make indenting/unindenting more convenient (
+\family typewriter 
+M-i
+\family default 
+ indents, 
+\family typewriter 
+M-u
+\family default 
+ unindents):
+\layout Standard
+
+
+\family typewriter 
+$if Python
+\newline 
+"
+\backslash 
+M-i": "\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+" 
+\newline 
+"
+\backslash 
+M-u": "
+\backslash 
+d
+\backslash 
+d
+\backslash 
+d
+\backslash 
+d" 
+\newline 
+$endif
+\layout Standard
+
+Note that there are 4 spaces between the quote marks after 
+\family typewriter 
+"M-i"
+\family default 
+ above.
+\layout Standard
+
+
+\series bold 
+Warning:
+\series default 
+ this feature is ON by default, but it can cause problems with the pasting
+ of multi-line indented code (the pasted code gets re-indented on each line).
+ A magic function 
+\family typewriter 
+%autoindent
+\family default 
+ allows you to toggle it on/off at runtime.
+ You can also disable it permanently on in your 
+\family typewriter 
+ipythonrc
+\family default 
+ file (set 
+\family typewriter 
+autoindent 0
+\family default 
+).
+\layout Subsubsection
+
+Customizing readline behavior
+\layout Standard
+
+All these features are based on the GNU readline library, which has an extremely
+ customizable interface.
+ Normally, readline is configured via a file which defines the behavior
+ of the library; the details of the syntax for this can be found in the
+ readline documentation available with your system or on the Internet.
+ IPython doesn't read this file (if it exists) directly, but it does support
+ passing to readline valid options via a simple interface.
+ In brief, you can customize readline by setting the following options in
+ your 
+\family typewriter 
+ipythonrc
+\family default 
+ configuration file (note that these options can 
+\emph on 
+not
+\emph default 
+ be specified at the command line):
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+readline_parse_and_bind:
+\family default 
+\series default 
+ this option can appear as many times as you want, each time defining a
+ string to be executed via a 
+\family typewriter 
+readline.parse_and_bind()
+\family default 
+ command.
+ The syntax for valid commands of this kind can be found by reading the
+ documentation for the GNU readline library, as these commands are of the
+ kind which readline accepts in its configuration file.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+readline_remove_delims:
+\family default 
+\series default 
+ a string of characters to be removed from the default word-delimiters list
+ used by readline, so that completions may be performed on strings which
+ contain them.
+ Do not change the default value unless you know what you're doing.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+readline_omit__names
+\family default 
+\series default 
+: when tab-completion is enabled, hitting 
+\family typewriter 
+<tab>
+\family default 
+ after a '
+\family typewriter 
+.
+\family default 
+' in a name will complete all attributes of an object, including all the
+ special methods whose names include double underscores (like 
+\family typewriter 
+__getitem__
+\family default 
+ or 
+\family typewriter 
+__class__
+\family default 
+).
+ If you'd rather not see these names by default, you can set this option
+ to 1.
+ Note that even when this option is set, you can still see those names by
+ explicitly typing a 
+\family typewriter 
+_
+\family default 
+ after the period and hitting 
+\family typewriter 
+<tab>
+\family default 
+: '
+\family typewriter 
+name._<tab>
+\family default 
+' will always complete attribute names starting with '
+\family typewriter 
+_
+\family default 
+'.
+\layout List
+\labelwidthstring 00.00.0000
+
+\SpecialChar ~
+ This option is off by default so that new users see all attributes of any
+ objects they are dealing with.
+\layout Standard
+
+You will find the default values along with a corresponding detailed explanation
+ in your 
+\family typewriter 
+ipythonrc
+\family default 
+ file.
+\layout Subsection
+
+Session logging and restoring
+\layout Standard
+
+You can log all input from a session either by starting IPython with the
+ command line switches 
+\family typewriter 
+-log
+\family default 
+ or 
+\family typewriter 
+-logfile 
+\family default 
+(see sec.
+ 
+\begin_inset LatexCommand \ref{sec:cmd-line-opts}
+
+\end_inset 
+
+)or by activating the logging at any moment with the magic function 
+\family typewriter 
+%logstart
+\family default 
+.
+ 
+\layout Standard
+
+Log files can later be reloaded with the 
+\family typewriter 
+-logplay
+\family default 
+ option and IPython will attempt to 'replay' the log by executing all the
+ lines in it, thus restoring the state of a previous session.
+ This feature is not quite perfect, but can still be useful in many cases.
+\layout Standard
+
+The log files can also be used as a way to have a permanent record of any
+ code you wrote while experimenting.
+ Log files are regular text files which you can later open in your favorite
+ text editor to extract code or to 'clean them up' before using them to
+ replay a session.
+\layout Standard
+
+The 
+\family typewriter 
+%logstart
+\family default 
+ function for activating logging in mid-session is used as follows:
+\layout Standard
+
+
+\family typewriter 
+%logstart [log_name [log_mode]]
+\layout Standard
+
+If no name is given, it defaults to a file named 
+\family typewriter 
+'log'
+\family default 
+ in your IPYTHONDIR directory, in 
+\family typewriter 
+'rotate'
+\family default 
+ mode (see below).
+\layout Standard
+
+'
+\family typewriter 
+%logstart name
+\family default 
+' saves to file 
+\family typewriter 
+'name'
+\family default 
+ in 
+\family typewriter 
+'backup'
+\family default 
+ mode.
+ It saves your history up to that point and then continues logging.
+\layout Standard
+
+
+\family typewriter 
+%logstart
+\family default 
+ takes a second optional parameter: logging mode.
+ This can be one of (note that the modes are given unquoted):
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+over
+\family default 
+: overwrite existing 
+\family typewriter 
+log_name
+\family default 
+.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+backup
+\family default 
+: rename (if exists) to 
+\family typewriter 
+log_name~
+\family default 
+ and start 
+\family typewriter 
+log_name
+\family default 
+.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+append
+\family default 
+: well, that says it.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+rotate
+\family default 
+: create rotating logs 
+\family typewriter 
+log_name
+\family default 
+.
+\family typewriter 
+1~
+\family default 
+, 
+\family typewriter 
+log_name.2~
+\family default 
+, etc.
+\layout Standard
+
+The 
+\family typewriter 
+%logoff
+\family default 
+ and 
+\family typewriter 
+%logon
+\family default 
+ functions allow you to temporarily stop and resume logging to a file which
+ had previously been started with 
+\family typewriter 
+%logstart
+\family default 
+.
+ They will fail (with an explanation) if you try to use them before logging
+ has been started.
+\layout Subsection
+
+
+\begin_inset LatexCommand \label{sub:System-shell-access}
+
+\end_inset 
+
+System shell access
+\layout Standard
+
+Any input line beginning with a 
+\family typewriter 
+!
+\family default 
+ character is passed verbatim (minus the 
+\family typewriter 
+!
+\family default 
+, of course) to the underlying operating system.
+ For example, typing 
+\family typewriter 
+!ls
+\family default 
+ will run 
+\family typewriter 
+'ls'
+\family default 
+ in the current directory.
+\layout Subsubsection
+
+Manual capture of command output
+\layout Standard
+
+If the input line begins with 
+\emph on 
+two
+\emph default 
+ exclamation marks, 
+\family typewriter 
+!!
+\family default 
+, the command is executed but its output is captured and returned as a python
+ list, split on newlines.
+ Any output sent by the subprocess to standard error is printed separately,
+ so that the resulting list only captures standard output.
+ The 
+\family typewriter 
+!!
+\family default 
+ syntax is a shorthand for the 
+\family typewriter 
+%sx
+\family default 
+ magic command.
+\layout Standard
+
+Finally, the 
+\family typewriter 
+%sc
+\family default 
+ magic (short for `shell capture') is similar to 
+\family typewriter 
+%sx
+\family default 
+, but allowing more fine-grained control of the capture details, and storing
+ the result directly into a named variable.
+\layout Standard
+
+See Sec.\SpecialChar ~
+
+\begin_inset LatexCommand \ref{sec:magic}
+
+\end_inset 
+
+ for details on the magics 
+\family typewriter 
+%sc
+\family default 
+ and 
+\family typewriter 
+%sx
+\family default 
+, or use IPython's own help (
+\family typewriter 
+sc?
+\family default 
+ and 
+\family typewriter 
+sx?
+\family default 
+) for further details.
+\layout Standard
+
+IPython also allows you to expand the value of python variables when making
+ system calls.
+ Any python variable or expression which you prepend with 
+\family typewriter 
+$
+\family default 
+ will get expanded before the system call is made.
+ 
+\layout Standard
+
+
+\family typewriter 
+In [1]: pyvar='Hello world'
+\newline 
+In [2]: !echo "A python variable: $pyvar" 
+\newline 
+A python variable: Hello world
+\layout Standard
+
+If you want the shell to actually see a literal 
+\family typewriter 
+$
+\family default 
+, you need to type it twice:
+\layout Standard
+
+
+\family typewriter 
+In [3]: !echo "A system variable: $$HOME" 
+\newline 
+A system variable: /home/fperez
+\layout Standard
+
+You can pass arbitrary expressions, though you'll need to delimit them with
+ 
+\family typewriter 
+{}
+\family default 
+ if there is ambiguity as to the extent of the expression:
+\layout Standard
+
+
+\family typewriter 
+In [5]: x=10
+\newline 
+In [6]: y=20
+\newline 
+In [13]: !echo $x+y 
+\newline 
+10+y 
+\newline 
+In [7]: !echo ${x+y} 
+\newline 
+30 
+\layout Standard
+
+Even object attributes can be expanded:
+\layout Standard
+
+
+\family typewriter 
+In [12]: !echo $sys.argv 
+\newline 
+[/home/fperez/usr/bin/ipython] 
+\layout Subsection
+
+System command aliases
+\layout Standard
+
+The 
+\family typewriter 
+%alias
+\family default 
+ magic function and the 
+\family typewriter 
+alias
+\family default 
+ option in the 
+\family typewriter 
+ipythonrc
+\family default 
+ configuration file allow you to define magic functions which are in fact
+ system shell commands.
+ These aliases can have parameters.
+ 
+\layout Standard
+
+'
+\family typewriter 
+%alias alias_name cmd
+\family default 
+' defines '
+\family typewriter 
+alias_name
+\family default 
+' as an alias for '
+\family typewriter 
+cmd
+\family default 
+' 
+\layout Standard
+
+Then, typing '
+\family typewriter 
+%alias_name params
+\family default 
+' will execute the system command '
+\family typewriter 
+cmd params
+\family default 
+' (from your underlying operating system).
+ 
+\layout Standard
+
+You can also define aliases with parameters using 
+\family typewriter 
+%s
+\family default 
+ specifiers (one per parameter).
+ The following example defines the 
+\family typewriter 
+%parts
+\family default 
+ function as an alias to the command '
+\family typewriter 
+echo first %s second %s
+\family default 
+' where each 
+\family typewriter 
+%s
+\family default 
+ will be replaced by a positional parameter to the call to 
+\family typewriter 
+%parts:
+\layout Standard
+
+
+\family typewriter 
+In [1]: alias parts echo first %s second %s
+\newline 
+In [2]: %parts A B
+\newline 
+first A second B 
+\newline 
+In [3]: %parts A 
+\newline 
+Incorrect number of arguments: 2 expected.
+ 
+\newline 
+parts is an alias to: 'echo first %s second %s' 
+\layout Standard
+
+If called with no parameters, 
+\family typewriter 
+%alias
+\family default 
+ prints the table of currently defined aliases.
+\layout Standard
+
+The 
+\family typewriter 
+%rehash/rehashx
+\family default 
+ magics allow you to load your entire 
+\family typewriter 
+$PATH
+\family default 
+ as ipython aliases.
+ See their respective docstrings (or sec.\SpecialChar ~
+
+\begin_inset LatexCommand \ref{sec:magic}
+
+\end_inset 
+
+ for further details).
+\layout Subsection
+
+
+\begin_inset LatexCommand \label{sec:dreload}
+
+\end_inset 
+
+Recursive reload
+\layout Standard
+
+The 
+\family typewriter 
+%dreload
+\family default 
+ command does a recursive reload of a module: changes made to the module
+ since you imported will actually be available without having to exit.
+\layout Subsection
+
+Verbose and colored exception traceback printouts
+\layout Standard
+
+IPython provides the option to see very detailed exception tracebacks, which
+ can be especially useful when debugging large programs.
+ You can run any Python file with the 
+\family typewriter 
+%run
+\family default 
+ function to benefit from these detailed tracebacks.
+ Furthermore, both normal and verbose tracebacks can be colored (if your
+ terminal supports it) which makes them much easier to parse visually.
+\layout Standard
+
+See the magic 
+\family typewriter 
+xmode
+\family default 
+ and 
+\family typewriter 
+colors
+\family default 
+ functions for details (just type 
+\family typewriter 
+%magic
+\family default 
+).
+\layout Standard
+
+These features are basically a terminal version of Ka-Ping Yee's 
+\family typewriter 
+cgitb
+\family default 
+ module, now part of the standard Python library.
+\layout Subsection
+
+
+\begin_inset LatexCommand \label{sec:cache_input}
+
+\end_inset 
+
+Input caching system
+\layout Standard
+
+IPython offers numbered prompts (In/Out) with input and output caching.
+ All input is saved and can be retrieved as variables (besides the usual
+ arrow key recall).
+\layout Standard
+
+The following GLOBAL variables always exist (so don't overwrite them!):
+ 
+\family typewriter 
+_i
+\family default 
+: stores previous input.
+ 
+\family typewriter 
+_ii
+\family default 
+: next previous.
+ 
+\family typewriter 
+_iii
+\family default 
+: next-next previous.
+ 
+\family typewriter 
+_ih
+\family default 
+ : a list of all input 
+\family typewriter 
+_ih[n]
+\family default 
+ is the input from line 
+\family typewriter 
+n
+\family default 
+ and this list is aliased to the global variable 
+\family typewriter 
+In
+\family default 
+.
+ If you overwrite 
+\family typewriter 
+In
+\family default 
+ with a variable of your own, you can remake the assignment to the internal
+ list with a simple 
+\family typewriter 
+'In=_ih'
+\family default 
+.
+\layout Standard
+
+Additionally, global variables named 
+\family typewriter 
+_i<n>
+\family default 
+ are dynamically created (
+\family typewriter 
+<n>
+\family default 
+ being the prompt counter), such that 
+\newline 
+
+\family typewriter 
+_i<n> == _ih[<n>] == In[<n>].
+\layout Standard
+
+For example, what you typed at prompt 14 is available as 
+\family typewriter 
+_i14,
+\family default 
+ 
+\family typewriter 
+_ih[14]
+\family default 
+ and 
+\family typewriter 
+In[14]
+\family default 
+.
+\layout Standard
+
+This allows you to easily cut and paste multi line interactive prompts by
+ printing them out: they print like a clean string, without prompt characters.
+ You can also manipulate them like regular variables (they are strings),
+ modify or exec them (typing 
+\family typewriter 
+'exec _i9'
+\family default 
+ will re-execute the contents of input prompt 9, '
+\family typewriter 
+exec In[9:14]+In[18]
+\family default 
+' will re-execute lines 9 through 13 and line 18).
+\layout Standard
+
+You can also re-execute multiple lines of input easily by using the magic
+ 
+\family typewriter 
+%macro
+\family default 
+ function (which automates the process and allows re-execution without having
+ to type '
+\family typewriter 
+exec
+\family default 
+' every time).
+ The macro system also allows you to re-execute previous lines which include
+ magic function calls (which require special processing).
+ Type 
+\family typewriter 
+%macro?
+\family default 
+ or see sec.
+ 
+\begin_inset LatexCommand \ref{sec:magic}
+
+\end_inset 
+
+ for more details on the macro system.
+\layout Standard
+
+A history function 
+\family typewriter 
+%hist
+\family default 
+ allows you to see any part of your input history by printing a range of
+ the 
+\family typewriter 
+_i
+\family default 
+ variables.
+\layout Subsection
+
+
+\begin_inset LatexCommand \label{sec:cache_output}
+
+\end_inset 
+
+Output caching system
+\layout Standard
+
+For output that is returned from actions, a system similar to the input
+ cache exists but using 
+\family typewriter 
+_
+\family default 
+ instead of 
+\family typewriter 
+_i
+\family default 
+.
+ Only actions that produce a result (NOT assignments, for example) are cached.
+ If you are familiar with Mathematica, IPython's 
+\family typewriter 
+_
+\family default 
+ variables behave exactly like Mathematica's 
+\family typewriter 
+%
+\family default 
+ variables.
+\layout Standard
+
+The following GLOBAL variables always exist (so don't overwrite them!):
+ 
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+_
+\family default 
+\series default 
+ (a 
+\emph on 
+single
+\emph default 
+ underscore) : stores previous output, like Python's default interpreter.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+__
+\family default 
+\series default 
+ (two underscores): next previous.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+___
+\family default 
+\series default 
+ (three underscores): next-next previous.
+\layout Standard
+
+Additionally, global variables named 
+\family typewriter 
+_<n> 
+\family default 
+are dynamically created (
+\family typewriter 
+<n>
+\family default 
+ being the prompt counter), such that the result of output 
+\family typewriter 
+<n>
+\family default 
+ is always available as 
+\family typewriter 
+_<n>
+\family default 
+ (don't use the angle brackets, just the number, e.g.
+ 
+\family typewriter 
+_21
+\family default 
+).
+\layout Standard
+
+These global variables are all stored in a global dictionary (not a list,
+ since it only has entries for lines which returned a result) available
+ under the names 
+\family typewriter 
+_oh
+\family default 
+ and 
+\family typewriter 
+Out
+\family default 
+ (similar to 
+\family typewriter 
+_ih
+\family default 
+ and 
+\family typewriter 
+In
+\family default 
+).
+ So the output from line 12 can be obtained as 
+\family typewriter 
+_12
+\family default 
+, 
+\family typewriter 
+Out[12]
+\family default 
+ or 
+\family typewriter 
+_oh[12]
+\family default 
+.
+ If you accidentally overwrite the 
+\family typewriter 
+Out
+\family default 
+ variable you can recover it by typing 
+\family typewriter 
+'Out=_oh
+\family default 
+' at the prompt.
+\layout Standard
+
+This system obviously can potentially put heavy memory demands on your system,
+ since it prevents Python's garbage collector from removing any previously
+ computed results.
+ You can control how many results are kept in memory with the option (at
+ the command line or in your 
+\family typewriter 
+ipythonrc
+\family default 
+ file) 
+\family typewriter 
+cache_size
+\family default 
+.
+ If you set it to 0, the whole system is completely disabled and the prompts
+ revert to the classic 
+\family typewriter 
+'>>>'
+\family default 
+ of normal Python.
+\layout Subsection
+
+Directory history
+\layout Standard
+
+Your history of visited directories is kept in the global list 
+\family typewriter 
+_dh
+\family default 
+, and the magic 
+\family typewriter 
+%cd
+\family default 
+ command can be used to go to any entry in that list.
+ The 
+\family typewriter 
+%dhist
+\family default 
+ command allows you to view this history.
+\layout Subsection
+
+Automatic parentheses and quotes
+\layout Standard
+
+These features were adapted from Nathan Gray's LazyPython.
+ They are meant to allow less typing for common situations.
+\layout Subsubsection
+
+Automatic parentheses
+\layout Standard
+
+Callable objects (i.e.
+ functions, methods, etc) can be invoked like this (notice the commas between
+ the arguments):
+\layout Standard
+
+
+\family typewriter 
+>>> callable_ob arg1, arg2, arg3 
+\layout Standard
+
+and the input will be translated to this: 
+\layout Standard
+
+
+\family typewriter 
+--> callable_ob(arg1, arg2, arg3) 
+\layout Standard
+
+You can force automatic parentheses by using '/' as the first character
+ of a line.
+ For example:
+\layout Standard
+
+
+\family typewriter 
+>>> /globals # becomes 'globals()' 
+\layout Standard
+
+Note that the '/' MUST be the first character on the line! This won't work:
+ 
+\layout Standard
+
+
+\family typewriter 
+>>> print /globals # syntax error
+\layout Standard
+
+In most cases the automatic algorithm should work, so you should rarely
+ need to explicitly invoke /.
+ One notable exception is if you are trying to call a function with a list
+ of tuples as arguments (the parenthesis will confuse IPython): 
+\layout Standard
+
+
+\family typewriter 
+In [1]: zip (1,2,3),(4,5,6) # won't work 
+\layout Standard
+
+but this will work: 
+\layout Standard
+
+
+\family typewriter 
+In [2]: /zip (1,2,3),(4,5,6)
+\newline 
+------> zip ((1,2,3),(4,5,6)) 
+\newline 
+Out[2]= [(1, 4), (2, 5), (3, 6)] 
+\layout Standard
+
+IPython tells you that it has altered your command line by displaying the
+ new command line preceded by 
+\family typewriter 
+-->
+\family default 
+.
+ e.g.: 
+\layout Standard
+
+
+\family typewriter 
+In [18]: callable list
+\newline 
+-------> callable (list)
+\layout Subsubsection
+
+Automatic quoting 
+\layout Standard
+
+You can force automatic quoting of a function's arguments by using 
+\family typewriter 
+`,'
+\family default 
+ or 
+\family typewriter 
+`;'
+\family default 
+ as the first character of a line.
+ For example: 
+\layout Standard
+
+
+\family typewriter 
+>>> ,my_function /home/me # becomes my_function("/home/me") 
+\layout Standard
+
+If you use 
+\family typewriter 
+`;'
+\family default 
+ instead, the whole argument is quoted as a single string (while 
+\family typewriter 
+`,'
+\family default 
+ splits on whitespace):
+\layout Standard
+
+
+\family typewriter 
+>>> ,my_function a b c # becomes my_function("a","b","c")
+\layout Standard
+
+
+\family typewriter 
+>>> ;my_function a b c # becomes my_function("a b c")
+\layout Standard
+
+Note that the `
+\family typewriter 
+,
+\family default 
+' or `
+\family typewriter 
+;
+\family default 
+' MUST be the first character on the line! This won't work: 
+\layout Standard
+
+
+\family typewriter 
+>>> x = ,my_function /home/me # syntax error
+\layout Section
+
+
+\begin_inset LatexCommand \label{sec:customization}
+
+\end_inset 
+
+Customization
+\layout Standard
+
+As we've already mentioned, IPython reads a configuration file which can
+ be specified at the command line (
+\family typewriter 
+-rcfile
+\family default 
+) or which by default is assumed to be called 
+\family typewriter 
+ipythonrc
+\family default 
+.
+ Such a file is looked for in the current directory where IPython is started
+ and then in your 
+\family typewriter 
+IPYTHONDIR
+\family default 
+, which allows you to have local configuration files for specific projects.
+ In this section we will call these types of configuration files simply
+ rcfiles (short for resource configuration file).
+\layout Standard
+
+The syntax of an rcfile is one of key-value pairs separated by whitespace,
+ one per line.
+ Lines beginning with a 
+\family typewriter 
+#
+\family default 
+ are ignored as comments, but comments can 
+\series bold 
+not
+\series default 
+ be put on lines with data (the parser is fairly primitive).
+ Note that these are not python files, and this is deliberate, because it
+ allows us to do some things which would be quite tricky to implement if
+ they were normal python files.
+\layout Standard
+
+First, an rcfile can contain permanent default values for almost all command
+ line options (except things like 
+\family typewriter 
+-help
+\family default 
+ or 
+\family typewriter 
+-Version
+\family default 
+).
+ Sec\SpecialChar ~
+
+\begin_inset LatexCommand \ref{sec:cmd-line-opts}
+
+\end_inset 
+
+ contains a description of all command-line options.
+ However, values you explicitly specify at the command line override the
+ values defined in the rcfile.
+\layout Standard
+
+Besides command line option values, the rcfile can specify values for certain
+ extra special options which are not available at the command line.
+ These options are briefly described below.
+ 
+\layout Standard
+
+Each of these options may appear as many times as you need it in the file.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+include\SpecialChar ~
+<file1>\SpecialChar ~
+<file2>\SpecialChar ~
+...
+\family default 
+\series default 
+: you can name 
+\emph on 
+other 
+\emph default 
+rcfiles you want to recursively load up to 15 levels (don't use the 
+\family typewriter 
+<>
+\family default 
+ brackets in your names!).
+ This feature allows you to define a 'base' rcfile with general options
+ and special-purpose files which can be loaded only when needed with particular
+ configuration options.
+ To make this more convenient, IPython accepts the 
+\family typewriter 
+-profile <name>
+\family default 
+ option (abbreviates to 
+\family typewriter 
+-p <name
+\family default 
+>)
+\family typewriter 
+ which
+\family default 
+ tells it to look for an rcfile named 
+\family typewriter 
+ipythonrc-<name>
+\family default 
+.
+ 
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+import_mod\SpecialChar ~
+<mod1>\SpecialChar ~
+<mod2>\SpecialChar ~
+...
+\family default 
+\series default 
+: import modules with '
+\family typewriter 
+import
+\family default 
+ 
+\family typewriter 
+<mod1>,<mod2>,...
+\family default 
+' 
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+import_some\SpecialChar ~
+<mod>\SpecialChar ~
+<f1>\SpecialChar ~
+<f2>\SpecialChar ~
+...
+\family default 
+\series default 
+: import functions with '
+\family typewriter 
+from <mod> import
+\family default 
+ 
+\family typewriter 
+<f1>,<f2>,...
+\family default 
+' 
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+import_all\SpecialChar ~
+<mod1>\SpecialChar ~
+<mod2>\SpecialChar ~
+...
+\family default 
+\series default 
+: for each module listed import functions with '
+\family typewriter 
+from <mod> import *
+\family default 
+' 
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+execute\SpecialChar ~
+<python\SpecialChar ~
+code>
+\family default 
+\series default 
+: give any single-line python code to be executed.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+execfile\SpecialChar ~
+<filename>
+\family default 
+\series default 
+: execute the python file given with an '
+\family typewriter 
+execfile(filename)
+\family default 
+' command.
+ Username expansion is performed on the given names.
+ So if you need any amount of extra fancy customization that won't fit in
+ any of the above 'canned' options, you can just put it in a separate python
+ file and execute it.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\family typewriter 
+\series bold 
+alias\SpecialChar ~
+<alias_def>
+\family default 
+\series default 
+: this is equivalent to calling '
+\family typewriter 
+%alias\SpecialChar ~
+<alias_def>
+\family default 
+' at the IPython command line.
+ This way, from within IPython you can do common system tasks without having
+ to exit it or use the 
+\family typewriter 
+!
+\family default 
+ escape.
+ IPython isn't meant to be a shell replacement, but it is often very useful
+ to be able to do things with files while testing code.
+ This gives you the flexibility to have within IPython any aliases you may
+ be used to under your normal system shell.
+\layout Subsection
+
+
+\begin_inset LatexCommand \label{sec:ipytonrc-sample}
+
+\end_inset 
+
+Sample 
+\family typewriter 
+ipythonrc
+\family default 
+ file
+\layout Standard
+
+The default rcfile, called 
+\family typewriter 
+ipythonrc
+\family default 
+ and supplied in your 
+\family typewriter 
+IPYTHONDIR 
+\family default 
+directory contains lots of comments on all of these options.
+ We reproduce it here for reference:
+\layout Standard
+
+
+\begin_inset Include \verbatiminput{../IPython/UserConfig/ipythonrc}
+preview false
+
+\end_inset 
+
+
+\layout Subsection
+
+
+\begin_inset LatexCommand \label{sec:prompts}
+
+\end_inset 
+
+Fine-tuning your prompt
+\layout Standard
+
+IPython's prompts can be customized using a syntax similar to that of the
+ 
+\family typewriter 
+bash
+\family default 
+ shell.
+ Many of 
+\family typewriter 
+bash
+\family default 
+'s escapes are supported, as well as a few additional ones.
+ We list them below:
+\layout Description
+
+
+\backslash 
+# the prompt/history count number
+\layout Description
+
+
+\backslash 
+D the prompt/history count, with the actual digits replaced by dots.
+ Used mainly in continuation prompts (prompt_in2)
+\layout Description
+
+
+\backslash 
+w the current working directory
+\layout Description
+
+
+\backslash 
+W the basename of current working directory
+\layout Description
+
+
+\backslash 
+X
+\emph on 
+n
+\emph default 
+ where 
+\begin_inset Formula $n=0\ldots5.$
+\end_inset 
+
+ The current working directory, with 
+\family typewriter 
+$HOME
+\family default 
+ replaced by 
+\family typewriter 
+~
+\family default 
+, and filtered out to contain only 
+\begin_inset Formula $n$
+\end_inset 
+
+ path elements
+\layout Description
+
+
+\backslash 
+Y
+\emph on 
+n
+\emph default 
+ Similar to 
+\backslash 
+X
+\emph on 
+n
+\emph default 
+, but with the 
+\begin_inset Formula $n+1$
+\end_inset 
+
+ element included if it is 
+\family typewriter 
+~
+\family default 
+ (this is similar to the behavior of the %c
+\emph on 
+n
+\emph default 
+ escapes in 
+\family typewriter 
+tcsh
+\family default 
+)
+\layout Description
+
+
+\backslash 
+u the username of the current user
+\layout Description
+
+
+\backslash 
+$ if the effective UID is 0, a #, otherwise a $
+\layout Description
+
+
+\backslash 
+h the hostname up to the first `.'
+\layout Description
+
+
+\backslash 
+H the hostname
+\layout Description
+
+
+\backslash 
+n a newline
+\layout Description
+
+
+\backslash 
+r a carriage return
+\layout Description
+
+
+\backslash 
+v IPython version string
+\layout Standard
+
+In addition to these, ANSI color escapes can be insterted into the prompts,
+ as 
+\family typewriter 
+
+\backslash 
+C_
+\emph on 
+ColorName
+\family default 
+\emph default 
+.
+ The list of valid color names is: Black, Blue, Brown, Cyan, DarkGray, Green,
+ LightBlue, LightCyan, LightGray, LightGreen, LightPurple, LightRed, NoColor,
+ Normal, Purple, Red, White, Yellow.
+\layout Standard
+
+Finally, IPython supports the evaluation of arbitrary expressions in your
+ prompt string.
+ The prompt strings are evaluated through the syntax of PEP 215, but basically
+ you can use 
+\family typewriter 
+$x.y
+\family default 
+ to expand the value of 
+\family typewriter 
+x.y
+\family default 
+, and for more complicated expressions you can use braces: 
+\family typewriter 
+${foo()+x}
+\family default 
+ will call function 
+\family typewriter 
+foo
+\family default 
+ and add to it the value of 
+\family typewriter 
+x
+\family default 
+, before putting the result into your prompt.
+ For example, using 
+\newline 
+
+\family typewriter 
+prompt_in1 '${commands.getoutput("uptime")}
+\backslash 
+nIn [
+\backslash 
+#]: '
+\newline 
+
+\family default 
+will print the result of the uptime command on each prompt (assuming the
+ 
+\family typewriter 
+commands
+\family default 
+ module has been imported in your 
+\family typewriter 
+ipythonrc
+\family default 
+ file).
+\layout Subsubsection
+
+Prompt examples
+\layout Standard
+
+The following options in an ipythonrc file will give you IPython's default
+ prompts:
+\layout Standard
+
+
+\family typewriter 
+prompt_in1 'In [
+\backslash 
+#]:'
+\newline 
+prompt_in2 '\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+.
+\backslash 
+D.:'
+\newline 
+prompt_out 'Out[
+\backslash 
+#]:'
+\layout Standard
+
+which look like this:
+\layout Standard
+
+
+\family typewriter 
+In [1]: 1+2
+\newline 
+Out[1]: 3
+\layout Standard
+
+
+\family typewriter 
+In [2]: for i in (1,2,3):
+\newline 
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+hspace*{0mm}
+\end_inset 
+
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+...: \SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+print i,
+\newline 
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+hspace*{0mm}
+\end_inset 
+
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+...:
+\newline 
+1 2 3
+\layout Standard
+
+These will give you a very colorful prompt with path information:
+\layout Standard
+
+
+\family typewriter 
+#prompt_in1 '
+\backslash 
+C_Red
+\backslash 
+u
+\backslash 
+C_Blue[
+\backslash 
+C_Cyan
+\backslash 
+Y1
+\backslash 
+C_Blue]
+\backslash 
+C_LightGreen
+\backslash 
+#>'
+\newline 
+prompt_in2 ' ..
+\backslash 
+D>'
+\newline 
+prompt_out '<
+\backslash 
+#>' 
+\layout Standard
+
+which look like this:
+\layout Standard
+
+
+\family typewriter 
+\color red
+fperez
+\color blue
+[
+\color cyan
+~/ipython
+\color blue
+]
+\color green
+1>
+\color default
+ 1+2
+\newline 
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+hspace*{0mm}
+\end_inset 
+
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+
+\color red
+<1>
+\color default
+ 3
+\newline 
+
+\color red
+fperez
+\color blue
+[
+\color cyan
+~/ipython
+\color blue
+]
+\color green
+2>
+\color default
+ for i in (1,2,3):
+\newline 
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+hspace*{0mm}
+\end_inset 
+
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+
+\color green
+...>
+\color default
+ \SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+print i,
+\newline 
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+hspace*{0mm}
+\end_inset 
+
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+
+\color green
+...>
+\color default
+
+\newline 
+1 2 3
+\layout Standard
+
+The following shows the usage of dynamic expression evaluation:
+\layout Subsection
+
+
+\begin_inset LatexCommand \label{sec:profiles}
+
+\end_inset 
+
+IPython profiles
+\layout Standard
+
+As we already mentioned, IPython supports the 
+\family typewriter 
+-profile
+\family default 
+ command-line option (see sec.
+ 
+\begin_inset LatexCommand \ref{sec:cmd-line-opts}
+
+\end_inset 
+
+).
+ A profile is nothing more than a particular configuration file like your
+ basic 
+\family typewriter 
+ipythonrc
+\family default 
+ one, but with particular customizations for a specific purpose.
+ When you start IPython with '
+\family typewriter 
+ipython -profile <name>
+\family default 
+', it assumes that in your 
+\family typewriter 
+IPYTHONDIR
+\family default 
+ there is a file called 
+\family typewriter 
+ipythonrc-<name>
+\family default 
+, and loads it instead of the normal 
+\family typewriter 
+ipythonrc
+\family default 
+.
+\layout Standard
+
+This system allows you to maintain multiple configurations which load modules,
+ set options, define functions, etc.
+ suitable for different tasks and activate them in a very simple manner.
+ In order to avoid having to repeat all of your basic options (common things
+ that don't change such as your color preferences, for example), any profile
+ can include another configuration file.
+ The most common way to use profiles is then to have each one include your
+ basic 
+\family typewriter 
+ipythonrc
+\family default 
+ file as a starting point, and then add further customizations.
+\layout Standard
+
+In sections 
+\begin_inset LatexCommand \ref{sec:syntax-extensions}
+
+\end_inset 
+
+ and 
+\begin_inset LatexCommand \ref{sec:Gnuplot}
+
+\end_inset 
+
+ we discuss some particular profiles which come as part of the standard
+ IPython distribution.
+ You may also look in your 
+\family typewriter 
+IPYTHONDIR
+\family default 
+ directory, any file whose name begins with 
+\family typewriter 
+ipythonrc-
+\family default 
+ is a profile.
+ You can use those as examples for further customizations to suit your own
+ needs.
+\layout Section
+
+
+\begin_inset OptArg
+collapsed false
+
+\layout Standard
+
+IPython as default...
+\end_inset 
+
+IPython as your default Python environment
+\layout Standard
+
+Python honors the environment variable 
+\family typewriter 
+PYTHONSTARTUP 
+\family default 
+and will execute at startup the file referenced by this variable.
+ If you put at the end of this file the following two lines of code:
+\layout Standard
+
+
+\family typewriter 
+import IPython
+\newline 
+IPython.Shell.IPShell().mainloop(sys_exit=1)
+\layout Standard
+
+then IPython will be your working environment anytime you start Python.
+ The 
+\family typewriter 
+sys_exit=1
+\family default 
+ is needed to have IPython issue a call to 
+\family typewriter 
+sys.exit()
+\family default 
+ when it finishes, otherwise you'll be back at the normal Python '
+\family typewriter 
+>>>
+\family default 
+' prompt
+\begin_inset Foot
+collapsed true
+
+\layout Standard
+
+Based on an idea by Holger Krekel.
+\end_inset 
+
+.
+\layout Standard
+
+This is probably useful to developers who manage multiple Python versions
+ and don't want to have correspondingly multiple IPython versions.
+ Note that in this mode, there is no way to pass IPython any command-line
+ options, as those are trapped first by Python itself.
+\layout Section
+
+
+\begin_inset LatexCommand \label{sec:embed}
+
+\end_inset 
+
+Embedding IPython
+\layout Standard
+
+It is possible to start an IPython instance 
+\emph on 
+inside
+\emph default 
+ your own Python programs.
+ This allows you to evaluate dynamically the state of your code, operate
+ with your variables, analyze them, etc.
+ Note however that any changes you make to values while in the shell do
+ 
+\emph on 
+not
+\emph default 
+ propagate back to the running code, so it is safe to modify your values
+ because you won't break your code in bizarre ways by doing so.
+\layout Standard
+
+This feature allows you to easily have a fully functional python environment
+ for doing object introspection anywhere in your code with a simple function
+ call.
+ In some cases a simple print statement is enough, but if you need to do
+ more detailed analysis of a code fragment this feature can be very valuable.
+\layout Standard
+
+It can also be useful in scientific computing situations where it is common
+ to need to do some automatic, computationally intensive part and then stop
+ to look at data, plots, etc
+\begin_inset Foot
+collapsed true
+
+\layout Standard
+
+This functionality was inspired by IDL's combination of the 
+\family typewriter 
+stop
+\family default 
+ keyword and the 
+\family typewriter 
+.continue
+\family default 
+ executive command, which I have found very useful in the past, and by a
+ posting on comp.lang.python by cmkl <cmkleffner-AT-gmx.de> on Dec.
+ 06/01 concerning similar uses of pyrepl.
+\end_inset 
+
+.
+ Opening an IPython instance will give you full access to your data and
+ functions, and you can resume program execution once you are done with
+ the interactive part (perhaps to stop again later, as many times as needed).
+\layout Standard
+
+The following code snippet is the bare minimum you need to include in your
+ Python programs for this to work (detailed examples follow later):
+\layout LyX-Code
+
+from IPython.Shell import IPShellEmbed
+\layout LyX-Code
+
+ipshell = IPShellEmbed()
+\layout LyX-Code
+
+ipshell() # this call anywhere in your program will start IPython
+\layout Standard
+
+You can run embedded instances even in code which is itself being run at
+ the IPython interactive prompt with '
+\family typewriter 
+%run\SpecialChar ~
+<filename>
+\family default 
+'.
+ Since it's easy to get lost as to where you are (in your top-level IPython
+ or in your embedded one), it's a good idea in such cases to set the in/out
+ prompts to something different for the embedded instances.
+ The code examples below illustrate this.
+\layout Standard
+
+You can also have multiple IPython instances in your program and open them
+ separately, for example with different options for data presentation.
+ If you close and open the same instance multiple times, its prompt counters
+ simply continue from each execution to the next.
+\layout Standard
+
+Please look at the docstrings in the 
+\family typewriter 
+Shell.py
+\family default 
+ module for more details on the use of this system.
+\layout Standard
+
+The following sample file illustrating how to use the embedding functionality
+ is provided in the examples directory as 
+\family typewriter 
+example-embed.py
+\family default 
+.
+ It should be fairly self-explanatory:
+\layout Standard
+
+
+\begin_inset Include \verbatiminput{examples/example-embed.py}
+preview false
+
+\end_inset 
+
+
+\layout Standard
+
+Once you understand how the system functions, you can use the following
+ code fragments in your programs which are ready for cut and paste:
+\layout Standard
+
+
+\begin_inset Include \verbatiminput{examples/example-embed-short.py}
+preview false
+
+\end_inset 
+
+
+\layout Section
+
+
+\begin_inset LatexCommand \label{sec:using-pdb}
+
+\end_inset 
+
+Using the Python debugger (
+\family typewriter 
+pdb
+\family default 
+)
+\layout Subsection
+
+Running entire programs via 
+\family typewriter 
+pdb
+\layout Standard
+
+
+\family typewriter 
+pdb
+\family default 
+, the Python debugger, is a powerful interactive debugger which allows you
+ to step through code, set breakpoints, watch variables, etc.
+ IPython makes it very easy to start any script under the control of 
+\family typewriter 
+pdb
+\family default 
+, regardless of whether you have wrapped it into a 
+\family typewriter 
+`main()'
+\family default 
+ function or not.
+ For this, simply type 
+\family typewriter 
+`%run -d myscript'
+\family default 
+ at an IPython prompt.
+ See the 
+\family typewriter 
+%run
+\family default 
+ command's documentation (via 
+\family typewriter 
+`%run?'
+\family default 
+ or in Sec.\SpecialChar ~
+
+\begin_inset LatexCommand \ref{sec:magic}
+
+\end_inset 
+
+) for more details, including how to control where 
+\family typewriter 
+pdb
+\family default 
+ will stop execution first.
+\layout Standard
+
+For more information on the use of the 
+\family typewriter 
+pdb
+\family default 
+ debugger, read the included 
+\family typewriter 
+pdb.doc
+\family default 
+ file (part of the standard Python distribution).
+ On a stock Linux system it is located at 
+\family typewriter 
+/usr/lib/python2.3/pdb.doc
+\family default 
+, but the easiest way to read it is by using the 
+\family typewriter 
+help()
+\family default 
+ function of the 
+\family typewriter 
+pdb
+\family default 
+ module as follows (in an IPython prompt):
+\layout Standard
+
+
+\family typewriter 
+In [1]: import pdb
+\newline 
+In [2]: pdb.help()
+\layout Standard
+
+This will load the 
+\family typewriter 
+pdb.doc
+\family default 
+ document in a file viewer for you automatically.
+\layout Subsection
+
+Automatic invocation of 
+\family typewriter 
+pdb
+\family default 
+ on exceptions
+\layout Standard
+
+IPython, if started with the 
+\family typewriter 
+-pdb
+\family default 
+ option (or if the option is set in your rc file) can call the Python 
+\family typewriter 
+pdb
+\family default 
+ debugger every time your code triggers an uncaught exception
+\begin_inset Foot
+collapsed true
+
+\layout Standard
+
+Many thanks to Christopher Hart for the request which prompted adding this
+ feature to IPython.
+\end_inset 
+
+.
+ This feature can also be toggled at any time with the 
+\family typewriter 
+%pdb
+\family default 
+ magic command.
+ This can be extremely useful in order to find the origin of subtle bugs,
+ because 
+\family typewriter 
+pdb
+\family default 
+ opens up at the point in your code which triggered the exception, and while
+ your program is at this point `dead', all the data is still available and
+ you can walk up and down the stack frame and understand the origin of the
+ problem.
+\layout Standard
+
+Furthermore, you can use these debugging facilities both with the embedded
+ IPython mode and without IPython at all.
+ For an embedded shell (see sec.
+ 
+\begin_inset LatexCommand \ref{sec:embed}
+
+\end_inset 
+
+), simply call the constructor with 
+\family typewriter 
+`-pdb'
+\family default 
+ in the argument string and automatically 
+\family typewriter 
+pdb
+\family default 
+ will be called if an uncaught exception is triggered by your code.
+ 
+\layout Standard
+
+For stand-alone use of the feature in your programs which do not use IPython
+ at all, put the following lines toward the top of your `main' routine:
+\layout Standard
+\align left 
+
+\family typewriter 
+import sys,IPython.ultraTB 
+\newline 
+sys.excepthook = IPython.ultraTB.FormattedTB(mode=`Verbose', color_scheme=`Linux',
+ call_pdb=1)
+\layout Standard
+
+The 
+\family typewriter 
+mode
+\family default 
+ keyword can be either 
+\family typewriter 
+`Verbose'
+\family default 
+ or 
+\family typewriter 
+`Plain'
+\family default 
+, giving either very detailed or normal tracebacks respectively.
+ The 
+\family typewriter 
+color_scheme
+\family default 
+ keyword can be one of 
+\family typewriter 
+`NoColor'
+\family default 
+, 
+\family typewriter 
+`Linux'
+\family default 
+ (default) or 
+\family typewriter 
+`LightBG'
+\family default 
+.
+ These are the same options which can be set in IPython with 
+\family typewriter 
+-colors
+\family default 
+ and 
+\family typewriter 
+-xmode
+\family default 
+.
+\layout Standard
+
+This will give any of your programs detailed, colored tracebacks with automatic
+ invocation of 
+\family typewriter 
+pdb
+\family default 
+.
+\layout Section
+
+
+\begin_inset LatexCommand \label{sec:syntax-extensions}
+
+\end_inset 
+
+Extensions for syntax processing
+\layout Standard
+
+This isn't for the faint of heart, because the potential for breaking things
+ is quite high.
+ But it can be a very powerful and useful feature.
+ In a nutshell, you can redefine the way IPython processes the user input
+ line to accept new, special extensions to the syntax without needing to
+ change any of IPython's own code.
+\layout Standard
+
+In the 
+\family typewriter 
+IPython/Extensions
+\family default 
+ directory you will find some examples supplied, which we will briefly describe
+ now.
+ These can be used `as is' (and both provide very useful functionality),
+ or you can use them as a starting point for writing your own extensions.
+\layout Subsection
+
+Pasting of code starting with 
+\family typewriter 
+`>>> 
+\family default 
+' or 
+\family typewriter 
+`...
+ 
+\family default 
+'
+\layout Standard
+
+In the python tutorial it is common to find code examples which have been
+ taken from real python sessions.
+ The problem with those is that all the lines begin with either 
+\family typewriter 
+`>>> 
+\family default 
+' or 
+\family typewriter 
+`...
+ 
+\family default 
+', which makes it impossible to paste them all at once.
+ One must instead do a line by line manual copying, carefully removing the
+ leading extraneous characters.
+\layout Standard
+
+This extension identifies those starting characters and removes them from
+ the input automatically, so that one can paste multi-line examples directly
+ into IPython, saving a lot of time.
+ Please look at the file 
+\family typewriter 
+InterpreterPasteInput.py
+\family default 
+ in the 
+\family typewriter 
+IPython/Extensions
+\family default 
+ directory for details on how this is done.
+\layout Standard
+
+IPython comes with a special profile enabling this feature, called 
+\family typewriter 
+tutorial
+\family default 
+\emph on 
+.
+
+\emph default 
+ Simply start IPython via 
+\family typewriter 
+`ipython\SpecialChar ~
+-p\SpecialChar ~
+tutorial'
+\family default 
+ and the feature will be available.
+ In a normal IPython session you can activate the feature by importing the
+ corresponding module with:
+\newline 
+
+\family typewriter 
+In [1]: import IPython.Extensions.InterpreterPasteInput
+\layout Standard
+
+The following is a 'screenshot' of how things work when this extension is
+ on, copying an example from the standard tutorial:
+\layout Standard
+
+
+\family typewriter 
+IPython profile: tutorial
+\newline 
+\SpecialChar ~
+
+\newline 
+*** Pasting of code with ">>>" or "..." has been enabled.
+\newline 
+\SpecialChar ~
+
+\newline 
+In [1]: >>> def fib2(n): # return Fibonacci series up to n
+\newline 
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+hspace*{0mm}
+\end_inset 
+
+\SpecialChar ~
+\SpecialChar ~
+ ...: ...\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+ """Return a list containing the Fibonacci series up to n."""
+\newline 
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+hspace*{0mm}
+\end_inset 
+
+\SpecialChar ~
+\SpecialChar ~
+ ...: ...\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+ result = []
+\newline 
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+hspace*{0mm}
+\end_inset 
+
+\SpecialChar ~
+\SpecialChar ~
+ ...: ...\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+ a, b = 0, 1
+\newline 
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+hspace*{0mm}
+\end_inset 
+
+\SpecialChar ~
+\SpecialChar ~
+ ...: ...\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+ while b < n:
+\newline 
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+hspace*{0mm}
+\end_inset 
+
+\SpecialChar ~
+\SpecialChar ~
+ ...: ...\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+ result.append(b)\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+ # see below
+\newline 
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+hspace*{0mm}
+\end_inset 
+
+\SpecialChar ~
+\SpecialChar ~
+ ...: ...\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+ a, b = b, a+b
+\newline 
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+hspace*{0mm}
+\end_inset 
+
+\SpecialChar ~
+\SpecialChar ~
+ ...: ...\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+ return result
+\newline 
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+hspace*{0mm}
+\end_inset 
+
+\SpecialChar ~
+\SpecialChar ~
+ ...:
+\newline 
+\SpecialChar ~
+
+\newline 
+In [2]: fib2(10)
+\newline 
+Out[2]: [1, 1, 2, 3, 5, 8]
+\layout Standard
+
+Note that as currently written, this extension does 
+\emph on 
+not 
+\emph default 
+recognize IPython's prompts for pasting.
+ Those are more complicated, since the user can change them very easily,
+ they involve numbers and can vary in length.
+ One could however extract all the relevant information from the IPython
+ instance and build an appropriate regular expression.
+ This is left as an exercise for the reader.
+\layout Subsection
+
+Input of physical quantities with units
+\layout Standard
+
+The module 
+\family typewriter 
+PhysicalQInput
+\family default 
+ allows a simplified form of input for physical quantities with units.
+ This file is meant to be used in conjunction with the 
+\family typewriter 
+PhysicalQInteractive
+\family default 
+ module (in the same directory) and 
+\family typewriter 
+Physics.PhysicalQuantities
+\family default 
+ from Konrad Hinsen's ScientificPython (
+\begin_inset LatexCommand \htmlurl{http://starship.python.net/crew/hinsen/scientific.html}
+
+\end_inset 
+
+).
+\layout Standard
+
+The 
+\family typewriter 
+Physics.PhysicalQuantities
+\family default 
+ module defines 
+\family typewriter 
+PhysicalQuantity
+\family default 
+ objects, but these must be declared as instances of a class.
+ For example, to define 
+\family typewriter 
+v
+\family default 
+ as a velocity of 3\SpecialChar ~
+m/s, normally you would write:
+\family typewriter 
+
+\newline 
+In [1]: v = PhysicalQuantity(3,'m/s')
+\layout Standard
+
+Using the 
+\family typewriter 
+PhysicalQ_Input
+\family default 
+ extension this can be input instead as:
+\family typewriter 
+
+\newline 
+In [1]: v = 3 m/s
+\family default 
+
+\newline 
+which is much more convenient for interactive use (even though it is blatantly
+ invalid Python syntax).
+\layout Standard
+
+The 
+\family typewriter 
+physics
+\family default 
+ profile supplied with IPython (enabled via 
+\family typewriter 
+'ipython -p physics'
+\family default 
+) uses these extensions, which you can also activate with:
+\layout Standard
+
+
+\family typewriter 
+from math import * # math MUST be imported BEFORE PhysicalQInteractive
+\newline 
+from IPython.Extensions.PhysicalQInteractive import *
+\newline 
+import IPython.Extensions.PhysicalQInput
+\layout Section
+
+IPython as a system shell
+\layout Standard
+
+IPython ships with a special profile called 
+\family typewriter 
+pysh
+\family default 
+, which you can activate at the command line as 
+\family typewriter 
+`ipython -p pysh'
+\family default 
+.
+ This loads 
+\family typewriter 
+InterpreterExec
+\family default 
+, along with some additional facilities and a prompt customized for filesystem
+ navigation.
+\layout Standard
+
+Note that this does 
+\emph on 
+not
+\emph default 
+ make IPython a full-fledged system shell.
+ In particular, it has no job control, so if you type Ctrl-Z (under Unix),
+ you'll suspend pysh itself, not the process you just started.
+ 
+\layout Standard
+
+What the shell profile allows you to do is to use the convenient and powerful
+ syntax of Python to do quick scripting at the command line.
+ Below we describe some of its features.
+\layout Subsection
+
+Aliases
+\layout Standard
+
+All of your 
+\family typewriter 
+$PATH
+\family default 
+ has been loaded as IPython aliases, so you should be able to type any normal
+ system command and have it executed.
+ See 
+\family typewriter 
+%alias?
+\family default 
+ and 
+\family typewriter 
+%unalias?
+\family default 
+ for details on the alias facilities.
+ See also 
+\family typewriter 
+%rehash?
+\family default 
+ and 
+\family typewriter 
+%rehashx? 
+\family default 
+for details on the mechanism used to load 
+\family typewriter 
+$PATH
+\family default 
+.
+\layout Subsection
+
+Special syntax
+\layout Standard
+
+Any lines which begin with 
+\family typewriter 
+`~'
+\family default 
+, 
+\family typewriter 
+`/'
+\family default 
+ and 
+\family typewriter 
+`.'
+\family default 
+ will be executed as shell commands instead of as Python code.
+ The special escapes below are also recognized.
+ 
+\family typewriter 
+!cmd
+\family default 
+ is valid in single or multi-line input, all others are only valid in single-lin
+e input:
+\layout Description
+
+
+\family typewriter 
+!cmd
+\family default 
+ pass `cmd' directly to the shell 
+\layout Description
+
+
+\family typewriter 
+!!cmd
+\family default 
+ execute `cmd' and return output as a list (split on `
+\backslash 
+n') 
+\layout Description
+
+
+\family typewriter 
+$var=cmd
+\family default 
+ capture output of cmd into var, as a string 
+\layout Description
+
+
+\family typewriter 
+$$var=cmd
+\family default 
+ capture output of cmd into var, as a list (split on `
+\backslash 
+n')
+\layout Standard
+
+The 
+\family typewriter 
+$
+\family default 
+/
+\family typewriter 
+$$
+\family default 
+ syntaxes make Python variables from system output, which you can later
+ use for further scripting.
+ The converse is also possible: when executing an alias or calling to the
+ system via 
+\family typewriter 
+!
+\family default 
+/
+\family typewriter 
+!!
+\family default 
+, you can expand any python variable or expression by prepending it with
+ 
+\family typewriter 
+$
+\family default 
+.
+ Full details of the allowed syntax can be found in Python's PEP 215.
+\layout Standard
+
+A few brief examples will illustrate these (note that the indentation below
+ may be incorrectly displayed):
+\layout Standard
+
+
+\family typewriter 
+fperez[~/test]|3> !ls *s.py 
+\newline 
+scopes.py strings.py
+\layout Standard
+
+ls is an internal alias, so there's no need to use 
+\family typewriter 
+!
+\family default 
+: 
+\layout Standard
+
+
+\family typewriter 
+fperez[~/test]|4> ls *s.py 
+\newline 
+scopes.py* strings.py
+\layout Standard
+
+!!ls will return the output into a Python variable: 
+\layout Standard
+
+
+\family typewriter 
+fperez[~/test]|5> !!ls *s.py 
+\newline 
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+hspace*{0mm}
+\end_inset 
+
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+<5> ['scopes.py', 'strings.py'] 
+\newline 
+fperez[~/test]|6> print _5 
+\newline 
+['scopes.py', 'strings.py']
+\layout Standard
+
+
+\family typewriter 
+$
+\family default 
+ and 
+\family typewriter 
+$$
+\family default 
+ allow direct capture to named variables: 
+\layout Standard
+
+
+\family typewriter 
+fperez[~/test]|7> $astr = ls *s.py 
+\newline 
+fperez[~/test]|8> astr 
+\newline 
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+hspace*{0mm}
+\end_inset 
+
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+<8> 'scopes.py
+\backslash 
+nstrings.py'
+\layout Standard
+
+
+\family typewriter 
+fperez[~/test]|9> $$alist = ls *s.py 
+\newline 
+fperez[~/test]|10> alist 
+\newline 
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+hspace*{0mm}
+\end_inset 
+
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+<10> ['scopes.py', 'strings.py']
+\layout Standard
+
+alist is now a normal python list you can loop over.
+ Using 
+\family typewriter 
+$
+\family default 
+ will expand back the python values when alias calls are made:
+\layout Standard
+
+
+\family typewriter 
+fperez[~/test]|11> for f in alist: 
+\newline 
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+hspace*{0mm}
+\end_inset 
+
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+|..> \SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+print 'file',f, 
+\newline 
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+hspace*{0mm}
+\end_inset 
+
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+|..> \SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+wc -l $f 
+\newline 
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+hspace*{0mm}
+\end_inset 
+
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+|..> 
+\newline 
+file scopes.py 13 scopes.py 
+\newline 
+file strings.py 4 strings.py
+\layout Standard
+
+Note that you may need to protect your variables with braces if you want
+ to append strings to their names.
+ To copy all files in alist to 
+\family typewriter 
+.bak
+\family default 
+ extensions, you must use: 
+\layout Standard
+
+
+\family typewriter 
+fperez[~/test]|12> for f in alist: 
+\newline 
+
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+hspace*{0mm}
+\end_inset 
+
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+|..> \SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+cp $f ${f}.bak
+\layout Standard
+
+If you try using 
+\family typewriter 
+$f.bak
+\family default 
+, you'll get an AttributeError exception saying that your string object
+ doesn't have a 
+\family typewriter 
+.bak
+\family default 
+ attribute.
+ This is because the 
+\family typewriter 
+$
+\family default 
+ expansion mechanism allows you to expand full Python expressions: 
+\layout Standard
+
+
+\family typewriter 
+fperez[~/test]|13> echo "sys.platform is: $sys.platform" 
+\newline 
+sys.platform is: linux2
+\layout Standard
+
+IPython's input history handling is still active, which allows you to rerun
+ a single block of multi-line input by simply using exec: 
+\newline 
+
+\family typewriter 
+fperez[~/test]|14> $$alist = ls *.eps 
+\newline 
+fperez[~/test]|15> exec _i11 
+\newline 
+file image2.eps 921 image2.eps 
+\newline 
+file image.eps 921 image.eps
+\layout Standard
+
+While these are new special-case syntaxes, they are designed to allow very
+ efficient use of the shell with minimal typing.
+ At an interactive shell prompt, conciseness of expression wins over readability.
+\layout Subsection
+
+Useful functions and modules
+\layout Standard
+
+The os, sys and shutil modules from the Python standard library are automaticall
+y loaded.
+ Some additional functions, useful for shell usage, are listed below.
+ You can request more help about them with `
+\family typewriter 
+?
+\family default 
+'.
+\layout Description
+
+
+\family typewriter 
+shell
+\family default 
+ - execute a command in the underlying system shell 
+\layout Description
+
+
+\family typewriter 
+system
+\family default 
+ - like 
+\family typewriter 
+shell()
+\family default 
+, but return the exit status of the command
+\layout Description
+
+
+\family typewriter 
+sout
+\family default 
+ - capture the output of a command as a string
+\layout Description
+
+
+\family typewriter 
+lout
+\family default 
+ - capture the output of a command as a list (split on `
+\backslash 
+n')
+\layout Description
+
+
+\family typewriter 
+getoutputerror
+\family default 
+ - capture (output,error) of a shell commandss
+\layout Standard
+
+
+\family typewriter 
+sout
+\family default 
+/
+\family typewriter 
+lout
+\family default 
+ are the functional equivalents of 
+\family typewriter 
+$
+\family default 
+/
+\family typewriter 
+$$
+\family default 
+.
+ They are provided to allow you to capture system output in the middle of
+ true python code, function definitions, etc (where 
+\family typewriter 
+$
+\family default 
+ and 
+\family typewriter 
+$$
+\family default 
+ are invalid).
+\layout Subsection
+
+Directory management
+\layout Standard
+
+Since each command passed by pysh to the underlying system is executed in
+ a subshell which exits immediately, you can NOT use !cd to navigate the
+ filesystem.
+\layout Standard
+
+Pysh provides its own builtin 
+\family typewriter 
+`%cd
+\family default 
+' magic command to move in the filesystem (the 
+\family typewriter 
+%
+\family default 
+ is not required with automagic on).
+ It also maintains a list of visited directories (use 
+\family typewriter 
+%dhist
+\family default 
+ to see it) and allows direct switching to any of them.
+ Type 
+\family typewriter 
+`cd?
+\family default 
+' for more details.
+\layout Standard
+
+
+\family typewriter 
+%pushd
+\family default 
+, 
+\family typewriter 
+%popd
+\family default 
+ and 
+\family typewriter 
+%dirs
+\family default 
+ are provided for directory stack handling.
+\layout Subsection
+
+Prompt customization
+\layout Standard
+
+The supplied 
+\family typewriter 
+ipythonrc-pysh
+\family default 
+ profile comes with an example of a very colored and detailed prompt, mainly
+ to serve as an illustration.
+ The valid escape sequences, besides color names, are:
+\layout Description
+
+
+\backslash 
+# - Prompt number.
+\layout Description
+
+
+\backslash 
+D - Dots, as many as there are digits in 
+\backslash 
+# (so they align).
+\layout Description
+
+
+\backslash 
+w - Current working directory (cwd).
+\layout Description
+
+
+\backslash 
+W - Basename of current working directory.
+\layout Description
+
+
+\backslash 
+X
+\emph on 
+N
+\emph default 
+ - Where 
+\emph on 
+N
+\emph default 
+=0..5.
+ N terms of the cwd, with $HOME written as ~.
+\layout Description
+
+
+\backslash 
+Y
+\emph on 
+N
+\emph default 
+ - Where 
+\emph on 
+N
+\emph default 
+=0..5.
+ Like X
+\emph on 
+N
+\emph default 
+, but if ~ is term 
+\emph on 
+N
+\emph default 
++1 it's also shown.
+\layout Description
+
+
+\backslash 
+u - Username.
+\layout Description
+
+
+\backslash 
+H - Full hostname.
+\layout Description
+
+
+\backslash 
+h - Hostname up to first '.'
+\layout Description
+
+
+\backslash 
+$ - Root symbol ($ or #).
+ 
+\layout Description
+
+
+\backslash 
+t - Current time, in H:M:S format.
+\layout Description
+
+
+\backslash 
+v - IPython release version.
+ 
+\layout Description
+
+
+\backslash 
+n - Newline.
+ 
+\layout Description
+
+
+\backslash 
+r - Carriage return.
+ 
+\layout Description
+
+
+\backslash 
+
+\backslash 
+ - An explicitly escaped '
+\backslash 
+'.
+\layout Standard
+
+You can configure your prompt colors using any ANSI color escape.
+ Each color escape sets the color for any subsequent text, until another
+ escape comes in and changes things.
+ The valid color escapes are:
+\layout Description
+
+
+\backslash 
+C_Black
+\layout Description
+
+
+\backslash 
+C_Blue
+\layout Description
+
+
+\backslash 
+C_Brown
+\layout Description
+
+
+\backslash 
+C_Cyan
+\layout Description
+
+
+\backslash 
+C_DarkGray
+\layout Description
+
+
+\backslash 
+C_Green
+\layout Description
+
+
+\backslash 
+C_LightBlue
+\layout Description
+
+
+\backslash 
+C_LightCyan
+\layout Description
+
+
+\backslash 
+C_LightGray
+\layout Description
+
+
+\backslash 
+C_LightGreen
+\layout Description
+
+
+\backslash 
+C_LightPurple
+\layout Description
+
+
+\backslash 
+C_LightRed
+\layout Description
+
+
+\backslash 
+C_Purple
+\layout Description
+
+
+\backslash 
+C_Red
+\layout Description
+
+
+\backslash 
+C_White
+\layout Description
+
+
+\backslash 
+C_Yellow
+\layout Description
+
+
+\backslash 
+C_Normal Stop coloring, defaults to your terminal settings.
+\layout Section
+
+
+\begin_inset LatexCommand \label{sec:Threading-support}
+
+\end_inset 
+
+Threading support
+\layout Standard
+
+
+\series bold 
+WARNING: 
+\series default 
+The threading support is still somewhat experimental, and it has only seen
+ reasonable testing under Linux.
+ Threaded code is particularly tricky to debug, and it tends to show extremely
+ platform-dependent behavior.
+ Since I only have access to Linux machines, I will have to rely on user's
+ experiences and assistance for this area of IPython to improve under other
+ platforms.
+\layout Standard
+
+IPython, via the 
+\family typewriter 
+-gthread
+\family default 
+ and 
+\family typewriter 
+-wthread
+\family default 
+ options (described in Sec.\SpecialChar ~
+
+\begin_inset LatexCommand \ref{sec:threading-opts}
+
+\end_inset 
+
+), can run in multithreaded mode to support pyGTK and WXPython applications
+ respectively.
+ Both of these GUI toolkits need to control the python main loop of execution,
+ so under a normal Python interpreter, starting a pyGTK (or WXPython) applicatio
+n will immediately freeze the shell.
+ 
+\layout Standard
+
+IPython, with one of these options (you can only use one at a time), separates
+ the graphical loop and IPython's code execution run into different threads.
+ This allows you to test interactively (with 
+\family typewriter 
+%run
+\family default 
+, for example) your GUI code without blocking.
+\layout Subsection
+
+Tk issues
+\layout Standard
+
+As indicated in Sec.\SpecialChar ~
+
+\begin_inset LatexCommand \ref{sec:threading-opts}
+
+\end_inset 
+
+, a special 
+\family typewriter 
+-tk
+\family default 
+ option is provided to try and allow Tk graphical applications to coexist
+ interactively with WX or GTK ones.
+ Whether this works at all, however, is very platform and configuration
+ dependent.
+ Please experiment with simple test cases before committing to using this
+ combination of Tk and WX/GTK threading in a production environment.
+\layout Subsection
+
+Signals and Threads
+\layout Standard
+
+When any of the thread systems (WX or GTK) are active, either directly or
+ via 
+\family typewriter 
+-pylab
+\family default 
+ with a threaded backend, it is impossible to interrupt long-running Python
+ code via 
+\family typewriter 
+Ctrl-C
+\family default 
+.
+ IPython can not pass the KeyboardInterrupt exception (or the underlying
+ 
+\family typewriter 
+SIGINT
+\family default 
+) across threads, so any long-running process started from IPython will
+ run to completion, or will have to be killed via an external (OS-based)
+ mechanism.
+\layout Standard
+
+To the best of my knowledge, this limitation is imposed by the Python interprete
+r itself, and it comes from the difficulty of writing portable signal/threaded
+ code.
+ If any user is an expert on this topic and can suggest a better solution,
+ I would love to hear about it.
+ In the IPython sources, look at the 
+\family typewriter 
+Shell.py
+\family default 
+ module, and in particular at the 
+\family typewriter 
+runcode()
+\family default 
+ method.
+ 
+\layout Subsection
+
+I/O pitfalls
+\layout Standard
+
+Be mindful that the Python interpreter switches between threads every 
+\begin_inset Formula $N$
+\end_inset 
+
+ bytecodes, where the default value as of Python\SpecialChar ~
+2.3 is 
+\begin_inset Formula $N=100.$
+\end_inset 
+
+ This value can be read by using the 
+\family typewriter 
+sys.getcheckinterval()
+\family default 
+ function, and it can be reset via 
+\family typewriter 
+sys.setcheckinterval(
+\emph on 
+N
+\emph default 
+)
+\family default 
+.
+ This switching of threads can cause subtly confusing effects if one of
+ your threads is doing file I/O.
+ In text mode, most systems only flush file buffers when they encounter
+ a 
+\family typewriter 
+`
+\backslash 
+n'
+\family default 
+.
+ An instruction as simple as
+\family typewriter 
+
+\newline 
+\SpecialChar ~
+\SpecialChar ~
+print >> filehandle, 
+\begin_inset Quotes eld
+\end_inset 
+
+hello world
+\begin_inset Quotes erd
+\end_inset 
+
+
+\family default 
+
+\newline 
+actually consists of several bytecodes, so it is possible that the newline
+ does not reach your file before the next thread switch.
+ Similarly, if you are writing to a file in binary mode, the file won't
+ be flushed until the buffer fills, and your other thread may see apparently
+ truncated files.
+ 
+\layout Standard
+
+For this reason, if you are using IPython's thread support and have (for
+ example) a GUI application which will read data generated by files written
+ to from the IPython thread, the safest approach is to open all of your
+ files in unbuffered mode (the third argument to the 
+\family typewriter 
+file/open
+\family default 
+ function is the buffering value):
+\newline 
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+filehandle = open(filename,mode,0)
+\layout Standard
+
+This is obviously a brute force way of avoiding race conditions with the
+ file buffering.
+ If you want to do it cleanly, and you have a resource which is being shared
+ by the interactive IPython loop and your GUI thread, you should really
+ handle it with thread locking and syncrhonization properties.
+ The Python documentation discusses these.
+\layout Section
+
+
+\begin_inset LatexCommand \label{sec:matplotlib-support}
+
+\end_inset 
+
+Plotting with 
+\family typewriter 
+matplotlib
+\family default 
+ 
+\layout Standard
+
+The matplotlib library (
+\begin_inset LatexCommand \htmlurl[http://matplotlib.sourceforge.net]{http://matplotlib.sourceforge.net}
+
+\end_inset 
+
+) provides high quality 2D plotting for Python.
+ Matplotlib can produce plots on screen using a variety of GUI toolkits,
+ including Tk, GTK and WXPython.
+ It also provides a number of commands useful for scientific computing,
+ all with a syntax compatible with that of the popular Matlab program.
+\layout Standard
+
+IPython accepts the special option 
+\family typewriter 
+-pylab
+\family default 
+ (Sec.\SpecialChar ~
+
+\begin_inset LatexCommand \ref{sec:cmd-line-opts}
+
+\end_inset 
+
+).
+ This configures it to support matplotlib, honoring the settings in the
+ 
+\family typewriter 
+.matplotlibrc
+\family default 
+ file.
+ IPython will detect the user's choice of matplotlib GUI backend, and automatica
+lly select the proper threading model to prevent blocking.
+ It also sets matplotlib in interactive mode and modifies 
+\family typewriter 
+%run
+\family default 
+ slightly, so that any matplotlib-based script can be executed using 
+\family typewriter 
+%run
+\family default 
+ and the final 
+\family typewriter 
+show()
+\family default 
+ command does not block the interactive shell.
+\layout Standard
+
+The 
+\family typewriter 
+-pylab
+\family default 
+ option must be given first in order for IPython to configure its threading
+ mode.
+ However, you can still issue other options afterwards.
+ This allows you to have a matplotlib-based environment customized with
+ additional modules using the standard IPython profile mechanism (Sec.\SpecialChar ~
+
+\begin_inset LatexCommand \ref{sec:profiles}
+
+\end_inset 
+
+): ``
+\family typewriter 
+ipython -pylab -p myprofile
+\family default 
+'' will load the profile defined in 
+\family typewriter 
+ipythonrc-myprofile
+\family default 
+ after configuring matplotlib.
+\layout Section
+
+
+\begin_inset LatexCommand \label{sec:Gnuplot}
+
+\end_inset 
+
+Plotting with 
+\family typewriter 
+Gnuplot
+\layout Standard
+
+Through the magic extension system described in sec.
+ 
+\begin_inset LatexCommand \ref{sec:magic}
+
+\end_inset 
+
+, IPython incorporates a mechanism for conveniently interfacing with the
+ Gnuplot system (
+\begin_inset LatexCommand \htmlurl{http://www.gnuplot.info}
+
+\end_inset 
+
+).
+ Gnuplot is a very complete 2D and 3D plotting package available for many
+ operating systems and commonly included in modern Linux distributions.
+ 
+\layout Standard
+
+Besides having Gnuplot installed, this functionality requires the 
+\family typewriter 
+Gnuplot.py
+\family default 
+ module for interfacing python with Gnuplot.
+ It can be downloaded from: 
+\begin_inset LatexCommand \htmlurl{http://gnuplot-py.sourceforge.net}
+
+\end_inset 
+
+.
+\layout Subsection
+
+Proper Gnuplot configuration
+\layout Standard
+
+As of version 4.0, Gnuplot has excellent mouse and interactive keyboard support.
+ However, as of 
+\family typewriter 
+Gnuplot.py
+\family default 
+ version 1.7, a new option was added to communicate between Python and Gnuplot
+ via FIFOs (pipes).
+ This mechanism, while fast, also breaks the mouse system.
+ You must therefore set the variable 
+\family typewriter 
+prefer_fifo_data
+\family default 
+ to 
+\family typewriter 
+0
+\family default 
+ in file 
+\family typewriter 
+gp_unix.py
+\family default 
+ if you wish to keep the interactive mouse and keyboard features working
+ properly (
+\family typewriter 
+prefer_inline_data
+\family default 
+ also must be 
+\family typewriter 
+0
+\family default 
+, but this is the default so unless you've changed it manually you should
+ be fine).
+\layout Standard
+
+'Out of the box', Gnuplot is configured with a rather poor set of size,
+ color and linewidth choices which make the graphs fairly hard to read on
+ modern high-resolution displays (although they work fine on old 640x480
+ ones).
+ Below is a section of my 
+\family typewriter 
+.Xdefaults
+\family default 
+ file which I use for having a more convenient Gnuplot setup.
+ Remember to load it by running 
+\family typewriter 
+`xrdb .Xdefaults`
+\family default 
+:
+\layout Standard
+
+
+\family typewriter 
+!******************************************************************
+\newline 
+! gnuplot options
+\newline 
+! modify this for a convenient window size
+\newline 
+gnuplot*geometry: 780x580
+\layout Standard
+
+
+\family typewriter 
+! on-screen font (not for PostScript)
+\newline 
+gnuplot*font: -misc-fixed-bold-r-normal--15-120-100-100-c-90-iso8859-1
+\layout Standard
+
+
+\family typewriter 
+! color options
+\newline 
+gnuplot*background: black
+\newline 
+gnuplot*textColor: white
+\newline 
+gnuplot*borderColor: white
+\newline 
+gnuplot*axisColor: white
+\newline 
+gnuplot*line1Color: red
+\newline 
+gnuplot*line2Color: green
+\newline 
+gnuplot*line3Color: blue
+\newline 
+gnuplot*line4Color: magenta
+\newline 
+gnuplot*line5Color: cyan
+\newline 
+gnuplot*line6Color: sienna
+\newline 
+gnuplot*line7Color: orange
+\newline 
+gnuplot*line8Color: coral
+\layout Standard
+
+
+\family typewriter 
+! multiplicative factor for point styles
+\newline 
+gnuplot*pointsize: 2
+\layout Standard
+
+
+\family typewriter 
+! line width options (in pixels)
+\newline 
+gnuplot*borderWidth: 2
+\newline 
+gnuplot*axisWidth: 2
+\newline 
+gnuplot*line1Width: 2
+\newline 
+gnuplot*line2Width: 2
+\newline 
+gnuplot*line3Width: 2
+\newline 
+gnuplot*line4Width: 2
+\newline 
+gnuplot*line5Width: 2
+\newline 
+gnuplot*line6Width: 2
+\newline 
+gnuplot*line7Width: 2
+\newline 
+gnuplot*line8Width: 2
+\layout Subsection
+
+The 
+\family typewriter 
+IPython.GnuplotRuntime
+\family default 
+ module
+\layout Standard
+
+IPython includes a module called 
+\family typewriter 
+Gnuplot2.py
+\family default 
+ which extends and improves the default 
+\family typewriter 
+Gnuplot
+\family default 
+.
+\family typewriter 
+py
+\family default 
+ (which it still relies upon).
+ For example, the new 
+\family typewriter 
+plot
+\family default 
+ function adds several improvements to the original making it more convenient
+ for interactive use, and 
+\family typewriter 
+hardcopy
+\family default 
+ fixes a bug in the original which under some circumstances blocks the creation
+ of PostScript output.
+\layout Standard
+
+For scripting use, 
+\family typewriter 
+GnuplotRuntime.py
+\family default 
+ is provided, which wraps 
+\family typewriter 
+Gnuplot2.py
+\family default 
+ and creates a series of global aliases.
+ These make it easy to control Gnuplot plotting jobs through the Python
+ language.
+\layout Standard
+
+Below is some example code which illustrates how to configure Gnuplot inside
+ your own programs but have it available for further interactive use through
+ an embedded IPython instance.
+ Simply run this file at a system prompt.
+ This file is provided as 
+\family typewriter 
+example-gnuplot.py
+\family default 
+ in the examples directory:
+\layout Standard
+
+
+\begin_inset Include \verbatiminput{examples/example-gnuplot.py}
+preview false
+
+\end_inset 
+
+
+\layout Subsection
+
+The 
+\family typewriter 
+numeric
+\family default 
+ profile: a scientific computing environment
+\layout Standard
+
+The 
+\family typewriter 
+numeric
+\family default 
+ IPython profile, which you can activate with 
+\family typewriter 
+`ipython -p numeric
+\family default 
+' will automatically load the IPython Gnuplot extensions (plus Numeric and
+ other useful things for numerical computing), contained in the 
+\family typewriter 
+IPython.GnuplotInteractive
+\family default 
+ module.
+ This will create the globals 
+\family typewriter 
+Gnuplot 
+\family default 
+(an alias to the improved Gnuplot2 module), 
+\family typewriter 
+gp
+\family default 
+ (a Gnuplot active instance), the new magic commands 
+\family typewriter 
+%gpc
+\family default 
+ and 
+\family typewriter 
+%gp_set_instance
+\family default 
+ and several other convenient globals.
+ Type 
+\family typewriter 
+gphelp()
+\family default 
+ for further details.
+\layout Standard
+
+This should turn IPython into a convenient environment for numerical computing,
+ with all the functions in the NumPy library and the Gnuplot facilities
+ for plotting.
+ Further improvements can be obtained by loading the SciPy libraries for
+ scientific computing, available at 
+\begin_inset LatexCommand \htmlurl{http://scipy.org}
+
+\end_inset 
+
+.
+\layout Standard
+
+If you are in the middle of a working session with numerical objects and
+ need to plot them but you didn't start the 
+\family typewriter 
+numeric
+\family default 
+ profile, you can load these extensions at any time by typing
+\newline 
+
+\family typewriter 
+from IPython.GnuplotInteractive import *
+\newline 
+
+\family default 
+at the IPython prompt.
+ This will allow you to keep your objects intact and start using Gnuplot
+ to view them.
+\layout Section
+
+Reporting bugs
+\layout Subsection*
+
+Automatic crash reports
+\layout Standard
+
+Ideally, IPython itself shouldn't crash.
+ It will catch exceptions produced by you, but bugs in its internals will
+ still crash it.
+\layout Standard
+
+In such a situation, IPython will leave a file named 
+\family typewriter 
+IPython_crash_report.txt
+\family default 
+ in your IPYTHONDIR directory (that way if crashes happen several times
+ it won't litter many directories, the post-mortem file is always located
+ in the same place and new occurrences just overwrite the previous one).
+ If you can mail this file to the developers (see sec.
+ 
+\begin_inset LatexCommand \ref{sec:credits}
+
+\end_inset 
+
+ for names and addresses), it will help us 
+\emph on 
+a lot
+\emph default 
+ in understanding the cause of the problem and fixing it sooner.
+\layout Subsection*
+
+The bug tracker
+\layout Standard
+
+IPython also has an online bug-tracker, located at 
+\begin_inset LatexCommand \htmlurl{http://www.scipy.net/roundup/ipython}
+
+\end_inset 
+
+.
+ In addition to mailing the developers, it would be a good idea to file
+ a bug report here.
+ This will ensure that the issue is properly followed to conclusion.
+\layout Standard
+
+You can also use this bug tracker to file feature requests.
+\layout Section
+
+Brief history
+\layout Subsection
+
+Origins
+\layout Standard
+
+The current IPython system grew out of the following three projects:
+\layout List
+\labelwidthstring 00.00.0000
+
+ipython by Fernando P�rez.
+ I was working on adding Mathematica-type prompts and a flexible configuration
+ system (something better than 
+\family typewriter 
+$PYTHONSTARTUP
+\family default 
+) to the standard Python interactive interpreter.
+\layout List
+\labelwidthstring 00.00.0000
+
+IPP by Janko Hauser.
+ Very well organized, great usability.
+ Had an old help system.
+ IPP was used as the `container' code into which I added the functionality
+ from ipython and LazyPython.
+\layout List
+\labelwidthstring 00.00.0000
+
+LazyPython by Nathan Gray.
+ Simple but 
+\emph on 
+very
+\emph default 
+ powerful.
+ The quick syntax (auto parens, auto quotes) and verbose/colored tracebacks
+ were all taken from here.
+\layout Standard
+
+When I found out (see sec.
+ 
+\begin_inset LatexCommand \ref{figgins}
+
+\end_inset 
+
+) about IPP and LazyPython I tried to join all three into a unified system.
+ I thought this could provide a very nice working environment, both for
+ regular programming and scientific computing: shell-like features, IDL/Matlab
+ numerics, Mathematica-type prompt history and great object introspection
+ and help facilities.
+ I think it worked reasonably well, though it was a lot more work than I
+ had initially planned.
+\layout Subsection
+
+Current status
+\layout Standard
+
+The above listed features work, and quite well for the most part.
+ But until a major internal restructuring is done (see below), only bug
+ fixing will be done, no other features will be added (unless very minor
+ and well localized in the cleaner parts of the code).
+\layout Standard
+
+IPython consists of some 12000 lines of pure python code, of which roughly
+ 50% are fairly clean.
+ The other 50% are fragile, messy code which needs a massive restructuring
+ before any further major work is done.
+ Even the messy code is fairly well documented though, and most of the problems
+ in the (non-existent) class design are well pointed to by a PyChecker run.
+ So the rewriting work isn't that bad, it will just be time-consuming.
+\layout Subsection
+
+Future
+\layout Standard
+
+See the separate 
+\family typewriter 
+new_design
+\family default 
+ document for details.
+ Ultimately, I would like to see IPython become part of the standard Python
+ distribution as a `big brother with batteries' to the standard Python interacti
+ve interpreter.
+ But that will never happen with the current state of the code, so all contribut
+ions are welcome.
+\layout Section
+
+License
+\layout Standard
+
+IPython is released under the terms of the BSD license, whose general form
+ can be found at: 
+\begin_inset LatexCommand \htmlurl{http://www.opensource.org/licenses/bsd-license.php}
+
+\end_inset 
+
+.
+ The full text of the IPython license is reproduced below:
+\layout Quote
+
+
+\family typewriter 
+\size small 
+IPython is released under a BSD-type license.
+\layout Quote
+
+
+\family typewriter 
+\size small 
+Copyright (c) 2001, 2002, 2003, 2004 Fernando Perez <fperez@colorado.edu>.
+\layout Quote
+
+
+\family typewriter 
+\size small 
+Copyright (c) 2001 Janko Hauser <jhauser@zscout.de> and 
+\newline 
+Nathaniel Gray <n8gray@caltech.edu>.
+\layout Quote
+
+
+\family typewriter 
+\size small 
+All rights reserved.
+\layout Quote
+
+
+\family typewriter 
+\size small 
+Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+\layout Quote
+
+
+\family typewriter 
+\size small 
+a.
+ Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+\layout Quote
+
+
+\family typewriter 
+\size small 
+b.
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+\layout Quote
+
+
+\family typewriter 
+\size small 
+c.
+ Neither the name of the copyright holders nor the names of any contributors
+ to this software may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+\layout Quote
+
+
+\family typewriter 
+\size small 
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+\layout Standard
+
+Individual authors are the holders of the copyright for their code and are
+ listed in each file.
+\layout Standard
+
+Some files (
+\family typewriter 
+DPyGetOpt.py
+\family default 
+, for example) may be licensed under different conditions.
+ Ultimately each file indicates clearly the conditions under which its author/au
+thors have decided to publish the code.
+\layout Standard
+
+Versions of IPython up to and including 0.6.3 were released under the GNU
+ Lesser General Public License (LGPL), available at 
+\begin_inset LatexCommand \htmlurl{http://www.gnu.org/copyleft/lesser.html}
+
+\end_inset 
+
+.
+\layout Section
+
+
+\begin_inset LatexCommand \label{sec:credits}
+
+\end_inset 
+
+Credits
+\layout Standard
+
+IPython is mainly developed by Fernando P�rez 
+\family typewriter 
+<fperez@colorado.edu>
+\family default 
+, but the project was born from mixing in Fernando's code with the IPP project
+ by Janko Hauser 
+\family typewriter 
+<jhauser-AT-zscout.de>
+\family default 
+ and LazyPython by Nathan Gray 
+\family typewriter 
+<n8gray-AT-caltech.edu>
+\family default 
+.
+ For all IPython-related requests, please contact Fernando.
+ User or development help should be requested via the IPython mailing lists:
+\layout Description
+
+User\SpecialChar ~
+list: 
+\begin_inset LatexCommand \htmlurl{http://scipy.net/mailman/listinfo/ipython-user}
+
+\end_inset 
+
+
+\layout Description
+
+Developer's\SpecialChar ~
+list: 
+\begin_inset LatexCommand \htmlurl{http://scipy.net/mailman/listinfo/ipython-dev}
+
+\end_inset 
+
+
+\layout Standard
+
+The IPython project is also very grateful to
+\begin_inset Foot
+collapsed true
+
+\layout Standard
+
+I've mangled email addresses to reduce spam, since the IPython manuals can
+ be accessed online.
+\end_inset 
+
+:
+\layout Standard
+
+Bill Bumgarner 
+\family typewriter 
+<bbum-AT-friday.com>
+\family default 
+: for providing the DPyGetOpt module which gives very powerful and convenient
+ handling of command-line options (light years ahead of what Python 2.1.1's
+ getopt module does).
+\layout Standard
+
+Ka-Ping Yee 
+\family typewriter 
+<ping-AT-lfw.org>
+\family default 
+: for providing the Itpl module for convenient and powerful string interpolation
+ with a much nicer syntax than formatting through the '%' operator.
+\layout Standard
+
+Arnd B�cker 
+\family typewriter 
+<baecker-AT-physik.tu-dresden.de>
+\family default 
+: for his many very useful suggestions and comments, and lots of help with
+ testing and documentation checking.
+ Many of IPython's newer features are a result of discussions with him (bugs
+ are still my fault, not his).
+\layout Standard
+
+Obviously Guido van\SpecialChar ~
+Rossum and the whole Python development team, that goes
+ without saying.
+\layout Standard
+
+IPython's website is generously hosted at 
+\begin_inset LatexCommand \htmlurl{http://ipython.scipy.org}
+
+\end_inset 
+
+ by Enthought (
+\begin_inset LatexCommand \htmlurl{http://www.enthought.com}
+
+\end_inset 
+
+).
+ I am very grateful to them and all of the SciPy team for their contribution.
+\layout Standard
+
+
+\begin_inset LatexCommand \label{figgins}
+
+\end_inset 
+
+Fernando would also like to thank Stephen Figgins 
+\family typewriter 
+<fig-AT-monitor.net>
+\family default 
+, an O'Reilly Python editor.
+ His Oct/11/2001 article about IPP and LazyPython, was what got this project
+ started.
+ You can read it at: 
+\begin_inset LatexCommand \htmlurl{http://www.onlamp.com/pub/a/python/2001/10/11/pythonnews.html}
+
+\end_inset 
+
+.
+\layout Standard
+
+And last but not least, all the kind IPython users who have emailed new
+ code, bug reports, fixes, comments and ideas.
+ A brief list follows, please let me know if I have ommitted your name by
+ accident: 
+\layout List
+\labelwidthstring 00.00.0000
+
+Jack\SpecialChar ~
+Moffit 
+\family typewriter 
+<jack-AT-xiph.org>
+\family default 
+ Bug fixes, including the infamous color problem.
+ This bug alone caused many lost hours and frustration, many thanks to him
+ for the fix.
+ I've always been a fan of Ogg & friends, now I have one more reason to
+ like these folks.
+\newline 
+Jack is also contributing with Debian packaging and many other things.
+\layout List
+\labelwidthstring 00.00.0000
+
+Alexander\SpecialChar ~
+Schmolck 
+\family typewriter 
+<a.schmolck-AT-gmx.net> 
+\family default 
+Emacs work, bug reports, bug fixes, ideas, lots more.
+ The ipython.el mode for (X)Emacs is Alex's code, providing full support
+ for IPython under (X)Emacs.
+\layout List
+\labelwidthstring 00.00.0000
+
+Andrea\SpecialChar ~
+Riciputi 
+\family typewriter 
+<andrea.riciputi-AT-libero.it>
+\family default 
+ Mac OSX information, Fink package management.
+\layout List
+\labelwidthstring 00.00.0000
+
+Gary\SpecialChar ~
+Bishop 
+\family typewriter 
+<gb-AT-cs.unc.edu>
+\family default 
+ Bug reports, and patches to work around the exception handling idiosyncracies
+ of WxPython.
+ Readline and color support for Windows.
+\layout List
+\labelwidthstring 00.00.0000
+
+Jeffrey\SpecialChar ~
+Collins 
+\family typewriter 
+<Jeff.Collins-AT-vexcel.com>
+\family default 
+ Bug reports.
+ Much improved readline support, including fixes for Python 2.3.
+\layout List
+\labelwidthstring 00.00.0000
+
+Dryice\SpecialChar ~
+Liu 
+\family typewriter 
+<dryice-AT-liu.com.cn>
+\family default 
+ FreeBSD port.
+\layout List
+\labelwidthstring 00.00.0000
+
+Mike\SpecialChar ~
+Heeter 
+\family typewriter 
+<korora-AT-SDF.LONESTAR.ORG>
+\layout List
+\labelwidthstring 00.00.0000
+
+Christopher\SpecialChar ~
+Hart 
+\family typewriter 
+<hart-AT-caltech.edu>
+\family default 
+ PDB integration.
+\layout List
+\labelwidthstring 00.00.0000
+
+Milan\SpecialChar ~
+Zamazal 
+\family typewriter 
+<pdm-AT-zamazal.org>
+\family default 
+ Emacs info.
+\layout List
+\labelwidthstring 00.00.0000
+
+Philip\SpecialChar ~
+Hisley 
+\family typewriter 
+<compsys-AT-starpower.net>
+\layout List
+\labelwidthstring 00.00.0000
+
+Holger\SpecialChar ~
+Krekel 
+\family typewriter 
+<pyth-AT-devel.trillke.net>
+\family default 
+ Tab completion, lots more.
+\layout List
+\labelwidthstring 00.00.0000
+
+Robin\SpecialChar ~
+Siebler 
+\family typewriter 
+<robinsiebler-AT-starband.net>
+\layout List
+\labelwidthstring 00.00.0000
+
+Ralf\SpecialChar ~
+Ahlbrink
+\family typewriter 
+ <ralf_ahlbrink-AT-web.de>
+\layout List
+\labelwidthstring 00.00.0000
+
+Thorsten\SpecialChar ~
+Kampe 
+\family typewriter 
+<thorsten-AT-thorstenkampe.de>
+\layout List
+\labelwidthstring 00.00.0000
+
+Fredrik\SpecialChar ~
+Kant 
+\family typewriter 
+<fredrik.kant-AT-front.com>
+\family default 
+ Windows setup.
+\layout List
+\labelwidthstring 00.00.0000
+
+Syver\SpecialChar ~
+Enstad 
+\family typewriter 
+<syver-en-AT-online.no>
+\family default 
+ Windows setup.
+\layout List
+\labelwidthstring 00.00.0000
+
+Richard 
+\family typewriter 
+<rxe-AT-renre-europe.com>
+\family default 
+ Global embedding.
+\layout List
+\labelwidthstring 00.00.0000
+
+Hayden\SpecialChar ~
+Callow 
+\family typewriter 
+<h.callow-AT-elec.canterbury.ac.nz>
+\family default 
+ Gnuplot.py 1.6 compatibility.
+\layout List
+\labelwidthstring 00.00.0000
+
+Leonardo\SpecialChar ~
+Santagada 
+\family typewriter 
+<retype-AT-terra.com.br>
+\family default 
+ Fixes for Windows installation.
+\layout List
+\labelwidthstring 00.00.0000
+
+Christopher\SpecialChar ~
+Armstrong 
+\family typewriter 
+<radix-AT-twistedmatrix.com>
+\family default 
+ Bugfixes.
+\layout List
+\labelwidthstring 00.00.0000
+
+Francois\SpecialChar ~
+Pinard 
+\family typewriter 
+<pinard-AT-iro.umontreal.ca>
+\family default 
+ Code and documentation fixes.
+\layout List
+\labelwidthstring 00.00.0000
+
+Cory\SpecialChar ~
+Dodt 
+\family typewriter 
+<cdodt-AT-fcoe.k12.ca.us>
+\family default 
+ Bug reports and Windows ideas.
+ Patches for Windows installer.
+\layout List
+\labelwidthstring 00.00.0000
+
+Olivier\SpecialChar ~
+Aubert 
+\family typewriter 
+<oaubert-AT-bat710.univ-lyon1.fr>
+\family default 
+ New magics.
+\layout List
+\labelwidthstring 00.00.0000
+
+King\SpecialChar ~
+C.\SpecialChar ~
+Shu 
+\family typewriter 
+<kingshu-AT-myrealbox.com>
+\family default 
+ Autoindent patch.
+\layout List
+\labelwidthstring 00.00.0000
+
+Chris\SpecialChar ~
+Drexler 
+\family typewriter 
+<chris-AT-ac-drexler.de>
+\family default 
+ Readline packages for Win32/CygWin.
+\layout List
+\labelwidthstring 00.00.0000
+
+Gustavo\SpecialChar ~
+C�rdova\SpecialChar ~
+Avila 
+\family typewriter 
+<gcordova-AT-sismex.com>
+\family default 
+ EvalDict code for nice, lightweight string interpolation.
+\layout List
+\labelwidthstring 00.00.0000
+
+Kasper\SpecialChar ~
+Souren 
+\family typewriter 
+<Kasper.Souren-AT-ircam.fr>
+\family default 
+ Bug reports, ideas.
+\layout List
+\labelwidthstring 00.00.0000
+
+Gever\SpecialChar ~
+Tulley 
+\family typewriter 
+<gever-AT-helium.com>
+\family default 
+ Code contributions.
+\layout List
+\labelwidthstring 00.00.0000
+
+Ralf\SpecialChar ~
+Schmitt 
+\family typewriter 
+<ralf-AT-brainbot.com>
+\family default 
+ Bug reports & fixes.
+\layout List
+\labelwidthstring 00.00.0000
+
+Oliver\SpecialChar ~
+Sander 
+\family typewriter 
+<osander-AT-gmx.de>
+\family default 
+ Bug reports.
+\layout List
+\labelwidthstring 00.00.0000
+
+Rod\SpecialChar ~
+Holland 
+\family typewriter 
+<rhh-AT-structurelabs.com>
+\family default 
+ Bug reports and fixes to logging module.
+\layout List
+\labelwidthstring 00.00.0000
+
+Daniel\SpecialChar ~
+'Dang'\SpecialChar ~
+Griffith 
+\family typewriter 
+<pythondev-dang-AT-lazytwinacres.net>
+\family default 
+ Fixes, enhancement suggestions for system shell use.
+\layout List
+\labelwidthstring 00.00.0000
+
+Viktor\SpecialChar ~
+Ransmayr 
+\family typewriter 
+<viktor.ransmayr-AT-t-online.de>
+\family default 
+ Tests and reports on Windows installation issues.
+ Contributed a true Windows binary installer.
+\layout List
+\labelwidthstring 00.00.0000
+
+Mike\SpecialChar ~
+Salib 
+\family typewriter 
+<msalib-AT-mit.edu>
+\family default 
+ Help fixing a subtle bug related to traceback printing.
+\layout List
+\labelwidthstring 00.00.0000
+
+W.J.\SpecialChar ~
+van\SpecialChar ~
+der\SpecialChar ~
+Laan 
+\family typewriter 
+<gnufnork-AT-hetdigitalegat.nl>
+\family default 
+ Bash-like prompt specials.
+\layout List
+\labelwidthstring 00.00.0000
+
+Ville\SpecialChar ~
+Vainio 
+\family typewriter 
+<vivainio-AT-kolumbus.fi>
+\family default 
+ Bugfixes and suggestions.
+ Excellent patches for many new features.
+\layout List
+\labelwidthstring 00.00.0000
+
+Antoon\SpecialChar ~
+Pardon 
+\family typewriter 
+<Antoon.Pardon-AT-rece.vub.ac.be>
+\family default 
+ Critical fix for the multithreaded IPython.
+\layout List
+\labelwidthstring 00.00.0000
+
+John\SpecialChar ~
+Hunter 
+\family typewriter 
+<jdhunter-AT-nitace.bsd.uchicago.edu>
+\family default 
+ Matplotlib author, helped with all the development of support for matplotlib
+ in IPyhton, including making necessary changes to matplotlib itself.
+\layout List
+\labelwidthstring 00.00.0000
+
+Matthew\SpecialChar ~
+Arnison 
+\family typewriter 
+<maffew-AT-cat.org.au>
+\family default 
+ Bug reports, `
+\family typewriter 
+%run -d
+\family default 
+' idea.
+\layout List
+\labelwidthstring 00.00.0000
+
+Prabhu\SpecialChar ~
+Ramachandran 
+\family typewriter 
+<prabhu_r-AT-users.sourceforge.net>
+\family default 
+ Help with (X)Emacs support, threading patches, ideas...
+\layout List
+\labelwidthstring 00.00.0000
+
+Norbert\SpecialChar ~
+Tretkowski 
+\family typewriter 
+<tretkowski-AT-inittab.de>
+\family default 
+ help with Debian packaging and distribution.
+\layout List
+\labelwidthstring 00.00.0000
+
+Robert\SpecialChar ~
+Kern 
+\family typewriter 
+<rkern-AT-ucsd.edu>
+\family default 
+ help with OSX issues, much help in general with various Python topics,
+ especially related to scientific computing.
+\layout List
+\labelwidthstring 00.00.0000
+
+George\SpecialChar ~
+Sakkis <
+\family typewriter 
+gsakkis-AT-eden.rutgers.edu>
+\family default 
+ New matcher for tab-completing named arguments of user-defined functions.
+\the_end
diff --git a/doc/nbexample.py b/doc/nbexample.py
new file mode 100644
index 0000000..7bc2727
--- /dev/null
+++ b/doc/nbexample.py
@@ -0,0 +1,11 @@
+from notebook.markup import rest
+
+rest.title('This is a Python Notebook')
+rest.heading(1,'A first-level heading')
+rest.text("""\
+Some plain text, without any special formatting.
+
+Below, we define a simple function to add two numbers.""")
+
+def add(x,y):
+    return x+y
diff --git a/doc/nbexample_latex.py b/doc/nbexample_latex.py
new file mode 100644
index 0000000..673cb4b
--- /dev/null
+++ b/doc/nbexample_latex.py
@@ -0,0 +1,25 @@
+from notebook.markup import latex
+
+latex.document_class('article')
+latex.title('This is a Python Notebook')
+
+latex.section('A section title',label='sec:intro')
+
+latex.text(r"""Below, we define a simple function
+\begin{equation}
+f: (x,y) \rightarrow x+y^2
+\end{equation}""")
+
+def f(x,y):
+    return x+y**2
+
+# since the .text method passes directly to latex, all markup could be input
+# in that way if so desired
+latex.text(r"""
+\section{Another section}
+
+More text...
+
+And now a picture showing our important results...""")
+
+latex.include_graphic('foo.png')
diff --git a/doc/nbexample_output.py b/doc/nbexample_output.py
new file mode 100644
index 0000000..8dfe099
--- /dev/null
+++ b/doc/nbexample_output.py
@@ -0,0 +1,20 @@
+from notebook.markup import rest
+
+rest.title('This is a Python Notebook')
+rest.text("""\
+Some plain text, without any special formatting.
+
+Below, we define a simple function to add two numbers.""")
+
+def add(x,y):
+    return x+y
+
+rest.text("Let's use it with x=2,y=3:")
+# This simply means that all code until the next markup call is to be executed
+# as a single call.  The editing screen should mark the whole group of lines
+# with a single In[NN] tag (like IPython does, but with multi-line capabilities)
+rest.input()
+add(2,3)
+# This output would appear on-screen (in the editing window) simply marked
+# with an Out[NN] tag
+rest.output("5")
diff --git a/doc/new_design.lyx b/doc/new_design.lyx
new file mode 100644
index 0000000..cb4a3a3
--- /dev/null
+++ b/doc/new_design.lyx
@@ -0,0 +1,1345 @@
+#LyX 1.3 created this file. For more info see http://www.lyx.org/
+\lyxformat 221
+\textclass article
+\begin_preamble
+\usepackage{ae,aecompl}
+\usepackage{hyperref}
+\usepackage{html}
+\end_preamble
+\language english
+\inputencoding auto
+\fontscheme default
+\graphics default
+\paperfontsize default
+\spacing single 
+\papersize Default
+\paperpackage a4
+\use_geometry 1
+\use_amsmath 0
+\use_natbib 0
+\use_numerical_citations 0
+\paperorientation portrait
+\leftmargin 1.25in
+\topmargin 1in
+\rightmargin 1.25in
+\bottommargin 1in
+\secnumdepth 3
+\tocdepth 3
+\paragraph_separation skip
+\defskip medskip
+\quotes_language english
+\quotes_times 2
+\papercolumns 1
+\papersides 1
+\paperpagestyle default
+
+\layout Title
+
+IPython
+\newline 
+
+\size larger 
+New design notes
+\layout Author
+
+Fernando P�rez
+\layout Section
+
+Introduction
+\layout Standard
+
+This is a draft document with notes and ideas for the IPython rewrite.
+ The section order and structure of this document roughly reflects in which
+ order things should be done and what the dependencies are.
+ This document is mainly a draft for developers, a pdf version is provided
+ with the standard distribution in case regular users are interested and
+ wish to contribute ideas.
+\layout Standard
+
+A tentative plan for the future:
+\layout Itemize
+
+0.6.x series: in practice, enough people are using IPython for real work that
+ I think it warrants a higher number.
+ This series will continue to evolve with bugfixes and incremental improvements.
+\layout Itemize
+
+0.7.x series: (maybe) If resources allow, there may be a branch for 'unstable'
+ development, where the architectural rewrite may take place.
+\layout Standard
+
+However, I am starting to doubt it is feasible to keep two separate branches.
+ I am leaning more towards a 
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash 
+LyX
+\end_inset 
+
+-like approach, where the main branch slowly transforms and evolves.
+ Having CVS support now makes this a reasonable alternative, as I don't
+ have to make pre-releases as often.
+ The active branch can remain the mainline of development, and users interested
+ in the bleeding-edge stuff can always grab the CVS code.
+\layout Standard
+
+Ideally, IPython should have a clean class setup that would allow further
+ extensions for special-purpose systems.
+ I view IPython as a base system that provides a great interactive environment
+ with full access to the Python language, and which could be used in many
+ different contexts.
+ The basic hooks are there: the magic extension syntax and the flexible
+ system of recursive configuration files and profiles.
+ But with a code as messy as the current one, nobody is going to touch it.
+\layout Section
+
+Immediate TODO and bug list
+\layout Standard
+
+Things that should be done for the current series, before starting major
+ changes.
+\layout Itemize
+
+Fix any bugs reported at the online bug tracker.
+\layout Itemize
+
+
+\series bold 
+Redesign the output traps.
+
+\series default 
+ They cause problems when users try to execute code which relies on sys.stdout
+ being the 'true' sys.stdout.
+ They also prevent scripts which use raw_input() to work as command-line
+ arguments.
+\newline 
+The best solution is probably to print the banner first, and then just execute
+ all the user code straight with no output traps at all.
+ Whatever comes out comes out.
+ This makes the ipython code actually simpler, and eliminates the problem
+ altogether.
+\newline 
+These things need to be ripped out, they cause no end of problems.
+ For example, if user code requires acces to stdin during startup, the process
+ just hangs indefinitely.
+ For now I've just disabled them, and I'll live with the ugly error messages.
+\layout Itemize
+
+The prompt specials dictionary should be turned into a class which does
+ proper namespace management, since the prompt specials need to be evaluated
+ in a certain namespace.
+ Currently it's just globals, which need to be managed manually by code
+ below.
+ 
+\layout Itemize
+
+Fix coloring of prompts: the pysh color strings don't have any effect on
+ prompt numbers, b/c these are controlled by the global scheme.
+ Make the prompts fully user-definable, colors and all.
+ This is what I said to a user:
+\newline 
+As far as the green 
+\backslash 
+#, this is a minor bug of the coloring code due to the vagaries of history.
+ While the color strings allow you to control the coloring of most elements,
+ there are a few which are still controlled by the old ipython internal
+ coloring code, which only accepts a global 'color scheme' choice.
+ So basically the input/output numbers are hardwired to the choice in the
+ color scheme, and there are only 'Linux', 'LightBG' and 'NoColor' schemes
+ to choose from.
+ 
+\layout Itemize
+
+Clean up FakeModule issues.
+ Currently, unittesting with embedded ipython breaks because a FakeModule
+ instance overwrites __main__.
+ Maybe ipython should revert back to using __main__ directly as the user
+ namespace? Handling a separate namespace is proving 
+\emph on 
+very
+\emph default 
+ tricky in all corner cases.
+\layout Itemize
+
+Make the output cache depth independent of the input one.
+ This way one can have say only the last 10 results stored and still have
+ a long input history/cache.
+\layout Itemize
+
+Fix the fact that importing a shell for embedding screws up the command-line
+ history.
+ This can be done by not importing the history file when the shell is already
+ inside ipython.
+\layout Itemize
+
+Lay out the class structure so that embedding into a gtk/wx/qt app is trivial,
+ much like the multithreaded gui shells now provide command-line coexistence
+ with the gui toolkits.
+ See 
+\begin_inset LatexCommand \url{http://www.livejournal.com/users/glyf/32396.html}
+
+\end_inset 
+
+
+\layout Itemize
+
+Get Holger's completer in, once he adds filename completion.
+\layout Standard
+
+Lower priority stuff:
+\layout Itemize
+
+Add @showopt/@setopt (decide name) for viewing/setting all options.
+ The existing option-setting magics should become aliases for setopt calls.
+\layout Itemize
+
+It would be nice to be able to continue with python stuff after an @ command.
+ For instance "@run something; test_stuff()" in order to test stuff even
+ faster.
+ Suggestion by Kasper Souren <Kasper.Souren@ircam.fr>
+\layout Itemize
+
+Run a 'first time wizard' which configures a few things for the user, such
+ as color_info, editor and the like.
+\layout Itemize
+
+Logging: @logstart and -log should start logfiles in ~.ipython, but with
+ unique names in case of collisions.
+ This would prevent ipython.log files all over while also allowing multiple
+ sessions.
+ Also the -log option should take an optional filename, instead of having
+ a separate -logfile option.
+\newline 
+In general the logging system needs a serious cleanup.
+ Many functions now in Magic should be moved to Logger, and the magic @s
+ should be very simple wrappers to the Logger methods.
+\layout Section
+
+Lighten the code
+\layout Standard
+
+If we decide to base future versions of IPython on Python 2.3, which has
+ the new Optik module (called optparse), it should be possible to drop DPyGetOpt.
+ We should also remove the need for Itpl.
+ Another area for trimming is the Gnuplot stuff: much of that could be merged
+ into the mainline project.
+\layout Standard
+
+Double check whether we really need FlexCompleter.
+ This was written as an enhanced rlcompleter, but my patches went in for
+ python 2.2 (or 2.3, can't remember).
+\layout Standard
+
+With these changes we could shed a fair bit of code from the main trunk.
+\layout Section
+
+Unit testing
+\layout Standard
+
+All new code should use a testing framework.
+ Python seems to have very good testing facilities, I just need to learn
+ how to use them.
+ I should also check out QMTest at 
+\begin_inset LatexCommand \htmlurl{http://www.codesourcery.com/qm/qmtest}
+
+\end_inset 
+
+, it sounds interesting (it's Python-based too).
+\layout Section
+
+Configuration system
+\layout Standard
+
+Move away from the current ipythonrc format to using standard python files
+ for configuration.
+ This will require users to be slightly more careful in their syntax, but
+ reduces code in IPython, is more in line with Python's normal form (using
+ the $PYTHONSTARTUP file) and allows much more flexibility.
+ I also think it's more 'pythonic', in using a single language for everything.
+\layout Standard
+
+Options can be set up with a function call which takes keywords and updates
+ the options Struct.
+\layout Standard
+
+In order to maintain the recursive inclusion system, write an 'include'
+ function which is basically a wrapper around safe_execfile().
+ Also for alias definitions an alias() function will do.
+ All functionality which we want to have at startup time for the users can
+ be wrapped in a small module so that config files look like:
+\layout Standard
+
+
+\family typewriter 
+from IPython.Startup import *
+\newline 
+...
+\newline 
+set_options(automagic=1,colors='NoColor',...)
+\newline 
+...
+\newline 
+include('mysetup.py')
+\newline 
+...
+\newline 
+alias('ls ls --color -l')
+\newline 
+...
+ etc.
+\layout Standard
+
+Also, put 
+\series bold 
+all
+\series default 
+ aliases in here, out of the core code.
+\layout Standard
+
+The new system should allow for more seamless upgrading, so that:
+\layout Itemize
+
+It automatically recognizes when the config files need updating and does
+ the upgrade.
+\layout Itemize
+
+It simply adds the new options to the user's config file without overwriting
+ it.
+ The current system is annoying since users need to manually re-sync their
+ configuration after every update.
+\layout Itemize
+
+It detects obsolete options and informs the user to remove them from his
+ config file.
+\layout Standard
+
+Here's a copy of Arnd Baecker suggestions on the matter:
+\layout Standard
+
+1.) upgrade: it might be nice to have an "auto" upgrade procedure: i.e.
+ imagine that IPython is installed system-wide and gets upgraded, how does
+ a user know, that an upgrade of the stuff in ~/.ipython is necessary ? So
+ maybe one has to a keep a version number in ~/.ipython and if there is a
+ mismatch with the started ipython, then invoke the upgrade procedure.
+\layout Standard
+
+2.) upgrade: I find that replacing the old files in ~/.ipython (after copying
+ them to .old not optimal (for example, after every update, I have to change
+ my color settings (and some others) in ~/.ipython/ipthonrc).
+ So somehow keeping the old files and merging the new features would be
+ nice.
+ (but how to distinguish changes from version to version with changes made
+ by the user ?) For, example, I would have to change in GnuplotMagic.py gnuplot_m
+ouse to 1 after every upgrade ...
+\layout Standard
+
+This is surely a minor point - also things will change during the "BIG"
+ rewrite, but maybe this is a point to keep in mind for this ?
+\layout Standard
+
+3.) upgrade: old, sometimes obsolete files stay in the ~/.ipython subdirectory.
+ (hmm, maybe one could move all these into some subdirectory, but which
+ name for that (via version-number ?) ?)
+\layout Subsection
+
+Command line options
+\layout Standard
+
+It would be great to design the command-line processing system so that it
+ can be dynamically modified in some easy way.
+ This would allow systems based on IPython to include their own command-line
+ processing to either extend or fully replace IPython's.
+ Probably moving to the new optparse library (also known as optik) will
+ make this a lot easier.
+\layout Section
+
+OS-dependent code
+\layout Standard
+
+Options which are OS-dependent (such as colors and aliases) should be loaded
+ via include files.
+ That is, the general file will have:
+\layout Standard
+
+
+\family typewriter 
+if os.name == 'posix':
+\newline 
+include('ipythonrc-posix.py')
+\newline 
+elif os.name == 'nt':
+\newline 
+include('ipythonrc-nt.py')...
+\layout Standard
+
+In the 
+\family typewriter 
+-posix
+\family default 
+, 
+\family typewriter 
+-nt
+\family default 
+, etc.
+ files we'll set all os-specific options.
+\layout Section
+
+Merging with other shell systems
+\layout Standard
+
+This is listed before the big design issues, as it is something which should
+ be kept in mind when that design is made.
+\layout Standard
+
+The following shell systems are out there and I think the whole design of
+ IPython should try to be modular enough to make it possible to integrate
+ its features into these.
+ In all cases IPython should exist as a stand-alone, terminal based program.
+ But it would be great if users of these other shells (some of them which
+ have very nice features of their own, especially the graphical ones) could
+ keep their environment but gain IPython's features.
+\layout List
+\labelwidthstring 00.00.0000
+
+IDLE This is the standard, distributed as part of Python.
+ 
+\layout List
+\labelwidthstring 00.00.0000
+
+pyrepl 
+\begin_inset LatexCommand \htmlurl{http://starship.python.net/crew/mwh/hacks/pyrepl.html}
+
+\end_inset 
+
+.
+ This is a text (curses-based) shell-like replacement which doesn't have
+ some of IPython's features, but has a crucially useful (and hard to implement)
+ one: full multi-line editing.
+ This turns the interactive interpreter into a true code testing and development
+ environment.
+ 
+\layout List
+\labelwidthstring 00.00.0000
+
+PyCrust 
+\begin_inset LatexCommand \htmlurl{http://sourceforge.net/projects/pycrust}
+
+\end_inset 
+
+.
+ Very nice, wxWindows based system.
+\layout List
+\labelwidthstring 00.00.0000
+
+PythonWin 
+\begin_inset LatexCommand \htmlurl{http://starship.python.net/crew/mhammond}
+
+\end_inset 
+
+.
+ Similar to PyCrust in some respects, a very good and free Python development
+ environment for Windows systems.
+\layout Section
+
+Class design
+\layout Standard
+
+This is the big one.
+ Currently classes use each other in a very messy way, poking inside one
+ another for data and methods.
+ ipmaker() adds tons of stuff to the main __IP instance by hand, and the
+ mix-ins used (Logger, Magic, etc) mean the final __IP instance has a million
+ things in it.
+ All that needs to be cleanly broken down with well defined interfaces amongst
+ the different classes, and probably no mix-ins.
+\layout Standard
+
+The best approach is probably to have all the sub-systems which are currently
+ mixins be fully independent classes which talk back only to the main instance
+ (and 
+\series bold 
+not
+\series default 
+ to each other).
+ In the main instance there should be an object whose job is to handle communica
+tion with the sub-systems.
+\layout Standard
+
+I should probably learn a little UML and diagram this whole thing before
+ I start coding.
+\layout Subsection
+
+Magic
+\layout Standard
+
+Now all methods which will become publicly available are called Magic.magic_name,
+ the magic_ should go away.
+ Then, Magic instead of being a mix-in should simply be an attribute of
+ __IP:
+\layout Standard
+
+__IP.Magic = Magic()
+\layout Standard
+
+This will then give all the magic functions as __IP.Magic.name(), which is
+ much cleaner.
+ This will also force a better separation so that Magic doesn't poke inside
+ __IP so much.
+ In the constructor, Magic should get whatever information it needs to know
+ about __IP (even if it means a pointer to __IP itself, but at least we'll
+ know where it is.
+ Right now since it's a mix-in, there's no way to know which variables belong
+ to whom).
+\layout Standard
+
+Build a class MagicFunction so that adding new functions is a matter of:
+\layout Standard
+
+
+\family typewriter 
+my_magic = MagicFunction(category = 'System utilities')
+\newline 
+my_magic.__call__ = ...
+\layout Standard
+
+Features:
+\layout Itemize
+
+The class constructor should automatically register the functions and keep
+ a table with category sections for easy sorting/viewing.
+\layout Itemize
+
+The object interface must allow automatic building of a GUI for them.
+ This requires registering the options the command takes, the number of
+ arguments, etc, in a formal way.
+ The advantage of this approach is that it allows not only to add GUIs to
+ the magics, but also for a much more intelligent building of docstrings,
+ and better parsing of options and arguments.
+\layout Standard
+
+Also think through better an alias system for magics.
+ Since the magic system is like a command shell inside ipython, the relation
+ between these aliases and system aliases should be cleanly thought out.
+\layout Subsection
+
+Color schemes
+\layout Standard
+
+These should be loaded from some kind of resource file so they are easier
+ to modify by the user.
+\layout Section
+
+Hooks
+\layout Standard
+
+IPython should have a modular system where functions can register themselves
+ for certain tasks.
+ Currently changing functionality requires overriding certain specific methods,
+ there should be a clean API for this to be done.
+\layout Subsection
+
+whos hook
+\layout Standard
+
+This was a very nice suggestion from Alexander Schmolck <a.schmolck@gmx.net>:
+\layout Standard
+
+2.
+ I think it would also be very helpful if there where some sort of hook
+ for ``whos`` that let one customize display formaters depending on the
+ object type.
+\layout Standard
+
+For example I'd rather have a whos that formats an array like:
+\layout Standard
+
+
+\family typewriter 
+Variable Type Data/Length
+\newline 
+------------------------------ 
+\newline 
+a array size: 4x3 type: 'Float'
+\layout Standard
+
+than
+\layout Standard
+
+
+\family typewriter 
+Variable Type Data/Length 
+\newline 
+------------------------------
+\newline 
+a array [[ 0.
+ 1.
+ 2.
+ 3<...> 8.
+ 9.
+ 10.
+ 11.]]
+\layout Section
+
+Parallel support
+\layout Standard
+
+For integration with graphical shells and other systems, it will be best
+ if ipython is split into a kernel/client model, much like Mathematica works.
+ This simultaneously opens the door for support of interactive parallel
+ computing.
+ Currenlty %bg provides a threads-based proof of concept, and Brian Granger's
+ XGrid project is a much more realistic such system.
+ The new design should integrates ideas as core elements.
+ Some notes from Brian on this topic:
+\layout Standard
+
+1.
+ How should the remote python server/kernel be designed? Multithreaded?
+ Blocking? Connected/disconnected modes? Load balancing?
+\layout Standard
+
+2.
+ What APi/protocol should the server/kernel expose to clients?
+\layout Standard
+
+3.
+ How should the client classes (which the user uses to interact with the
+ cluster) be designed?
+\layout Standard
+
+4.
+ What API should the client classes expose?
+\layout Standard
+
+5.
+ How should the client API be wrapped in a few simple magic functions?
+\layout Standard
+
+6.
+ How should security be handled?
+\layout Standard
+
+7.
+ How to work around the issues of the GIL and threads?
+\layout Standard
+
+I think the most important things to work out are the client API (#4) the
+ server/kernel API/protocol (#2) and the magic function API (#5).
+ We should let these determine the design and architecture of the components.
+\layout Standard
+
+One other thing.
+ What is your impression of twisted? I have been looking at it and it looks
+ like a _very_ powerful set of tools for this type of stuff.
+ I am wondering if it might make sense to think about using twisted for
+ this project.
+\layout Section
+
+Manuals
+\layout Standard
+
+The documentation should be generated from docstrings for the command line
+ args and all the magic commands.
+ Look into one of the simple text markup systems to see if we can get latex
+ (for reLyXing later) out of this.
+ Part of the build command would then be to make an update of the docs based
+ on this, thus giving more complete manual (and guaranteed to be in sync
+ with the code docstrings).
+\layout Standard
+
+[PARTLY DONE] At least now all magics are auto-documented, works farily
+ well.
+ Limited Latex formatting yet.
+\layout Subsection
+
+Integration with pydoc-help
+\layout Standard
+
+It should be possible to have access to the manual via the pydoc help system
+ somehow.
+ This might require subclassing the pydoc help, or figuring out how to add
+ the IPython docs in the right form so that help() finds them.
+\layout Standard
+
+Some comments from Arnd and my reply on this topic:
+\layout Standard
+
+> ((Generally I would like to have the nice documentation > more easily
+ accessable from within ipython ...
+ > Many people just don't read documentation, even if it is > as good as
+ the one of IPython ))
+\layout Standard
+
+That's an excellent point.
+ I've added a note to this effect in new_design.
+ Basically I'd like help() to naturally access the IPython docs.
+ Since they are already there in html for the user, it's probably a matter
+ of playing a bit with pydoc to tell it where to find them.
+ It would definitely make for a much cleaner system.
+ Right now the information on IPython is:
+\layout Standard
+
+-ipython --help at the command line: info on command line switches 
+\layout Standard
+
+-? at the ipython prompt: overview of IPython 
+\layout Standard
+
+-magic at the ipython prompt: overview of the magic system 
+\layout Standard
+
+-external docs (html/pdf)
+\layout Standard
+
+All that should be better integrated seamlessly in the help() system, so
+ that you can simply say:
+\layout Standard
+
+help ipython -> full documentation access 
+\layout Standard
+
+help magic -> magic overview 
+\layout Standard
+
+help profile -> help on current profile 
+\layout Standard
+
+help -> normal python help access.
+\layout Section
+
+Graphical object browsers
+\layout Standard
+
+I'd like a system for graphically browsing through objects.
+ 
+\family typewriter 
+@obrowse
+\family default 
+ should open a widged with all the things which 
+\family typewriter 
+@who
+\family default 
+ lists, but cliking on each object would open a dedicated object viewer
+ (also accessible as 
+\family typewriter 
+@oview <object>
+\family default 
+).
+ This object viewer could show a summary of what 
+\family typewriter 
+<object>?
+\family default 
+ currently shows, but also colorize source code and show it via an html
+ browser, show all attributes and methods of a given object (themselves
+ openable in their own viewers, since in Python everything is an object),
+ links to the parent classes, etc.
+\layout Standard
+
+The object viewer widget should be extensible, so that one can add methods
+ to view certain types of objects in a special way (for example, plotting
+ Numeric arrays via grace or gnuplot).
+ This would be very useful when using IPython as part of an interactive
+ complex system for working with certain types of data.
+\layout Standard
+
+I should look at what PyCrust has to offer along these lines, at least as
+ a starting point.
+\layout Section
+
+Miscellaneous small things
+\layout Itemize
+
+Collect whatever variables matter from the environment in some globals for
+ __IP, so we're not testing for them constantly (like $HOME, $TERM, etc.)
+\layout Section
+
+Session restoring
+\layout Standard
+
+I've convinced myself that session restore by log replay is too fragile
+ and tricky to ever work reliably.
+ Plus it can be dog slow.
+ I'd rather have a way of saving/restoring the *current* memory state of
+ IPython.
+ I tried with pickle but failed (can't pickle modules).
+ This seems the right way to do it to me, but it will have to wait until
+ someone tells me of a robust way of dumping/reloading *all* of the user
+ namespace in a file.
+\layout Standard
+
+Probably the best approach will be to pickle as much as possible and record
+ what can not be pickled for manual reload (such as modules).
+ This is not trivial to get to work reliably, so it's best left for after
+ the code restructuring.
+\layout Standard
+
+The following issues exist (old notes, see above paragraph for my current
+ take on the issue):
+\layout Itemize
+
+magic lines aren't properly re-executed when a log file is reloaded (and
+ some of them, like clear or run, may change the environment).
+ So session restore isn't 100% perfect.
+\layout Itemize
+
+auto-quote/parens lines aren't replayed either.
+ All this could be done, but it needs some work.
+ Basically it requires re-running the log through IPython itself, not through
+ python.
+\layout Itemize
+
+_p variables aren't restored with a session.
+ Fix: same as above.
+\layout Section
+
+Tips system
+\layout Standard
+
+It would be nice to have a tip() function which gives tips to users in some
+ situations, but keeps track of already-given tips so they aren't given
+ every time.
+ This could be done by pickling a dict of given tips to IPYTHONDIR.
+\layout Section
+
+TAB completer
+\layout Standard
+
+Some suggestions from Arnd Baecker:
+\layout Standard
+
+a) For file related commands (ls, cat, ...) it would be nice to be able to
+ TAB complete the files in the current directory.
+ (once you started typing something which is uniquely a file, this leads
+ to this effect, apart from going through the list of possible completions
+ ...).
+ (I know that this point is in your documentation.)
+\layout Standard
+
+More general, this might lead to something like command specific completion
+ ? 
+\layout Standard
+
+Here's John Hunter's suggestion:
+\layout Standard
+
+The *right way to do it* would be to make intelligent or customizable choices
+ about which namespace to add to the completion list depending on the string
+ match up to the prompt, eg programmed completions.
+ In the simplest implementation, one would only complete on files and directorie
+s if the line preceding the tab press matched 'cd ' or 'run ' (eg you don't
+ want callable showing up in 'cd ca<TAB>')
+\layout Standard
+
+In a more advanced scenario, you might imaging that functions supplied the
+ TAB namespace, and the user could configure a dictionary that mapped regular
+ expressions to namespace providing functions (with sensible defaults).
+ Something like
+\layout Standard
+
+completed = {
+\newline 
+'^cd
+\backslash 
+s+(.*)' : complete_files_and_dirs,
+\newline 
+'^run
+\backslash 
+s+(.*)' : complete_files_and_dirs,
+\newline 
+'^run
+\backslash 
+s+(-.*)' : complete_run_options,
+\newline 
+}
+\layout Standard
+
+I don't know if this is feasible, but I really like programmed completions,
+ which I use extensively in tcsh.
+ My feeling is that something like this is eminently doable in ipython.
+\layout Standard
+
+/JDH
+\layout Standard
+
+For something like this to work cleanly, the magic command system needs
+ also a clean options framework, so all valid options for a given magic
+ can be extracted programatically.
+\layout Section
+
+Debugger
+\layout Standard
+
+Current system uses a minimally tweaked pdb.
+ Fine-tune it a bit, to provide at least:
+\layout Itemize
+
+Tab-completion in each stack frame.
+ See email to Chris Hart for details.
+\layout Itemize
+
+Object information via ? at least.
+ Break up magic_oinfo a bit so that pdb can call it without loading all
+ of IPython.
+ If possible, also have the other magics for object study: doc, source,
+ pdef and pfile.
+\layout Itemize
+
+Shell access via !
+\layout Itemize
+
+Syntax highlighting in listings.
+ Use py2html code, implement color schemes.
+\layout Section
+
+A Python-based system shell - pysh?
+\layout Standard
+
+Note: as of IPython 0.6.1, most of this functionality has actually been implemente
+d.
+\layout Standard
+
+This section is meant as a working draft for discussions on the possibility
+ of having a python-based system shell.
+ It is the result of my own thinking about these issues as much of discussions
+ on the ipython lists.
+ I apologize in advance for not giving individual credit to the various
+ contributions, but right now I don't have the time to track down each message
+ from the archives.
+ So please consider this as the result of a collective effort by the ipython
+ user community.
+\layout Standard
+
+While IPyhton is (and will remain) a python shell first, it does offer a
+ fair amount of system access functionality:
+\layout Standard
+
+- ! and !! for direct system access,
+\layout Standard
+
+- magic commands which wrap various system commands,
+\layout Standard
+
+- @sc and @sx, for shell output capture into python variables,
+\layout Standard
+
+- @alias, for aliasing system commands.
+\layout Standard
+
+This has prompted many users, over time, to ask for a way of extending ipython
+ to the point where it could be used as a full-time replacement over typical
+ user shells like bash, csh or tcsh.
+ While my interest in ipython is such that I'll concentrate my personal
+ efforts on other fronts (debugging, architecture, improvements for scientific
+ use, gui access), I will be happy to do anything which could make such
+ a development possible.
+ It would be the responsibility of someone else to maintain the code, but
+ I would do all necessary architectural changes to ipython for such an extension
+ to be feasible.
+\layout Standard
+
+I'll try to outline here what I see as the key issues which need to be taken
+ into account.
+ This document should be considered an evolving draft.
+ Feel free to submit comments/improvements, even in the form of patches.
+\layout Standard
+
+In what follows, I'll represent the hypothetical python-based shell ('pysh'
+ for now) prompt with '>>'.
+\layout Subsection
+
+Basic design principles
+\layout Standard
+
+I think the basic design guideline should be the following: a hypothetical
+ python system shell should behave, as much as possible, like a normal shell
+ that users are familiar with (bash, tcsh, etc).
+ This means:
+\layout Standard
+
+1.
+ System commands can be issued directly at the prompt with no special syntax:
+\layout Standard
+
+>> ls
+\layout Standard
+
+>> xemacs
+\layout Standard
+
+should just work like a user expects.
+\layout Standard
+
+2.
+ The facilities of the python language should always be available, like
+ they are in ipython:
+\layout Standard
+
+>> 3+4 
+\newline 
+7
+\layout Standard
+
+3.
+ It should be possible to easily capture shell output into a variable.
+ bash and friends use backquotes, I think using a command (@sc) like ipython
+ currently does is an acceptable compromise.
+\layout Standard
+
+4.
+ It should also be possible to expand python variables/commands in the middle
+ of system commands.
+ I thihk this will make it necessary to use $var for name expansions:
+\layout Standard
+
+>> var='hello' # var is a Python variable 
+\newline 
+>> print var hello # This is the result of a Python print command 
+\newline 
+>> echo $var hello # This calls the echo command, expanding 'var'.
+\layout Standard
+
+5.
+ The above capabilities should remain possible for multi-line commands.
+ One of the most annoying things I find about tcsh, is that I never quite
+ remember the syntactic details of looping.
+ I often want to do something at the shell which involves a simple loop,
+ but I can never remember how to do it in tcsh.
+ This often means I just write a quick throwaway python script to do it
+ (Perl is great for this kind of quick things, but I've forgotten most its
+ syntax as well).
+\layout Standard
+
+It should be possible to write code like:
+\layout Standard
+
+>> for ext in ['.jpg','.gif']: 
+\newline 
+..
+ ls file$ext
+\layout Standard
+
+And have it work as 'ls file.jpg;ls file.gif'.
+\layout Subsection
+
+Smaller details 
+\layout Standard
+
+If the above are considered as valid guiding principles for how such a python
+ system shell should behave, then some smaller considerations and comments
+ to keep in mind are listed below.
+\layout Standard
+
+- it's ok for shell builtins (in this case this includes the python language)
+ to override system commands on the path.
+ See tcsh's 'time' vs '/usr/bin/time'.
+ This settles the 'print' issue and related.
+\layout Standard
+
+- pysh should take
+\layout Standard
+
+foo args
+\layout Standard
+
+as a command if (foo args is NOT valid python) and (foo is in $PATH).
+\layout Standard
+
+If the user types
+\layout Standard
+
+>> ./foo args
+\layout Standard
+
+it should be considered a system command always.
+\layout Standard
+
+- _, __ and ___ should automatically remember the previous 3 outputs captured
+ from stdout.
+ In parallel, there should be _e, __e and ___e for stderr.
+ Whether capture is done as a single string or in list mode should be a
+ user preference.
+ If users have numbered prompts, ipython's full In/Out cache system should
+ be available.
+\layout Standard
+
+But regardless of how variables are captured, the printout should be like
+ that of a plain shell (without quotes or braces to indicate strings/lists).
+ The everyday 'feel' of pysh should be more that of bash/tcsh than that
+ of ipython.
+\layout Standard
+
+- filename completion first.
+ Tab completion could work like in ipython, but with the order of priorities
+ reversed: first files, then python names.
+\layout Standard
+
+- configuration via standard python files.
+ Instead of 'setenv' you'd simply write into the os.environ[] dictionary.
+ This assumes that IPython itself has been fixed to be configured via normal
+ python files, instead of the current clunky ipythonrc format.
+\layout Standard
+
+- IPython can already configure the prompt in fairly generic ways.
+ It should be able to generate almost any kind of prompt which bash/tcsh
+ can (within reason).
+\layout Standard
+
+- Keep the Magics system.
+ They provide a lightweight syntax for configuring and modifying the state
+ of the user's session itself.
+ Plus, they are an extensible system so why not give the users one more
+ tool which is fairly flexible by nature? Finally, having the @magic optional
+ syntax allows a user to always be able to access the shell's control system,
+ regardless of name collisions with defined variables or system commands.
+\layout Standard
+
+But we need to move all magic functionality into a protected namespace,
+ instead of the current messy name-mangling tricks (which don't scale well).
+ 
+\layout Section
+
+Future improvements
+\layout Itemize
+
+When from <mod> import * is used, first check the existing namespace and
+ at least issue a warning on screen if names are overwritten.
+\layout Itemize
+
+Auto indent? Done, for users with readline support.
+\layout Subsection
+
+Better completion a la zsh
+\layout Standard
+
+This was suggested by Arnd:
+\layout Standard
+
+> >\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+ More general, this might lead to something like
+\layout Standard
+
+> >\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+ command specific completion ?
+\layout Standard
+
+>
+\layout Standard
+
+> I'm not sure what you mean here.
+\layout Standard
+
+\SpecialChar ~
+
+\layout Standard
+
+Sorry, that was not understandable, indeed ...
+\layout Standard
+
+I thought of something like
+\layout Standard
+
+\SpecialChar ~
+- cd and then use TAB to go through the list of directories
+\layout Standard
+
+\SpecialChar ~
+- ls and then TAB to consider all files and directories
+\layout Standard
+
+\SpecialChar ~
+- cat and TAB: only files (no directories ...)
+\layout Standard
+
+\SpecialChar ~
+
+\layout Standard
+
+For zsh things like this are established by defining in .zshrc
+\layout Standard
+
+\SpecialChar ~
+
+\layout Standard
+
+compctl -g '*.dvi' xdvi
+\layout Standard
+
+compctl -g '*.dvi' dvips
+\layout Standard
+
+compctl -g '*.tex' latex
+\layout Standard
+
+compctl -g '*.tex' tex
+\layout Standard
+
+...
+\layout Section
+
+Outline of steps
+\layout Standard
+
+Here's a rough outline of the order in which to start implementing the various
+ parts of the redesign.
+ The first 'test of success' should be a clean pychecker run (not the mess
+ we get right now).
+\layout Itemize
+
+Make Logger and Magic not be mixins but attributes of the main class.
+ 
+\begin_deeper 
+\layout Itemize
+
+Magic should have a pointer back to the main instance (even if this creates
+ a recursive structure) so it can control it with minimal message-passing
+ machinery.
+ 
+\layout Itemize
+
+Logger can be a standalone object, simply with a nice, clean interface.
+\layout Itemize
+
+Logger currently handles part of the prompt caching, but other parts of
+ that are in the prompts class itself.
+ Clean up.
+\end_deeper 
+\layout Itemize
+
+Change to python-based config system.
+\layout Itemize
+
+Move make_IPython() into the main shell class, as part of the constructor.
+ Do this 
+\emph on 
+after 
+\emph default 
+the config system has been changed, debugging will be a lot easier then.
+\layout Itemize
+
+Merge the embeddable class and the normal one into one.
+ After all, the standard ipython script 
+\emph on 
+is
+\emph default 
+ a python program with IPython embedded in it.
+ There's no need for two separate classes (
+\emph on 
+maybe
+\emph default 
+ keep the old one around for the sake of backwards compatibility).
+\layout Section
+
+Ville Vainio's suggestions
+\layout Standard
+
+Some notes sent in by Ville Vainio 
+\family typewriter 
+<vivainio@kolumbus.fi>
+\family default 
+ on Tue, 29 Jun 2004.
+ Keep here for reference, some of it replicates things already said above.
+\layout Standard
+
+Current ipython seems to "special case" lots of stuff - aliases, magics
+ etc.
+ It would seem to yield itself to a simpler and more extensible architecture,
+ consisting of multple dictionaries, where just the order of search is determine
+d by profile/prefix.
+ All the functionality would just be "pushed" to ipython core, i.e.
+ the objects that represent the functionality are instantiated on "plugins"
+ and they are registered with ipython core.
+ i.e.
+\layout Standard
+
+def magic_f(options, args): pass
+\layout Standard
+
+m = MyMagic(magic_f) m.arghandler = stockhandlers.OptParseArgHandler m.options
+ = ....
+ # optparse options, for easy passing to magic_f and help display
+\layout Standard
+
+# note that arghandler takes a peek at the instance, sees options, and proceeds
+ # accordingly.
+ Various arg handlers can ask for arbitrary options.
+ # some handler might optionally glob the filenames, search data folders
+ for filenames etc.
+\layout Standard
+
+ipythonregistry.register(category = "magic", name = "mymagic", obj = m)
+\layout Standard
+
+I bet most of the current functionality could easily be added to such a
+ registry by just instantiating e.g.
+ "Magic" class and registering all the functions with some sensible default
+ args.
+ Supporting legacy stuff in general would be easy - just implement new handlers
+ (arg and otherwise) for new stuff, and have the old handlers around forever
+ / as long as is deemed appropriate.
+ The 'python' namespace (locals() + globals()) should be special, of course.
+\layout Standard
+
+It should be easy to have arbitrary number of "categories" (like 'magic',
+ 'shellcommand','projectspecific_myproject', 'projectspecific_otherproject').
+ It would only influence the order in which the completions are suggested,
+ and in case of name collision which one is selected.
+ Also, I think all completions should be shown, even the ones in "later"
+ categories in the case of a match in an "earlier" category.
+\layout Standard
+
+The "functionality object" might also have a callable object 'expandarg',
+ and ipython would run it (with the arg index) when tab completion is attempted
+ after typing the function name.
+ It would return the possible completions for that particular command...
+ or None to "revert to default file completions".
+ Such functionality could be useful in making ipython an "operating console"
+ of a sort.
+ I'm talking about:
+\layout Standard
+
+>> lscat reactor # list commands in category - reactor is "project specific"
+ category
+\layout Standard
+
+r_operate
+\layout Standard
+
+>> r_operate <tab> start shutdown notify_meltdown evacuate
+\layout Standard
+
+>> r_operate shutdown <tab>
+\layout Standard
+
+1 2 5 6 # note that 3 and 4 are already shut down
+\layout Standard
+
+>> r_operate shutdown 2
+\layout Standard
+
+Shutting down..
+ ok.
+\layout Standard
+
+>> r_operate start <tab>
+\layout Standard
+
+2 3 4 # 2 was shut down, can be started now
+\layout Standard
+
+>> r_operate start 2
+\layout Standard
+
+Starting....
+ ok.
+\layout Standard
+
+I'm talking about having a super-configurable man-machine language here!
+ Like cmd.Cmd on steroids, as a free addition to ipython!
+\the_end
diff --git a/doc/pycolor.1 b/doc/pycolor.1
new file mode 100644
index 0000000..34cf5d5
--- /dev/null
+++ b/doc/pycolor.1
@@ -0,0 +1,33 @@
+.\"                                      Hey, EMACS: -*- nroff -*-
+.\" First parameter, NAME, should be all caps
+.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
+.\" other parameters are allowed: see man(7), man(1)
+.TH PYCOLOR 1 "March 21, 2003"
+.\" Please adjust this date whenever revising the manpage.
+.\"
+.\" Some roff macros, for reference:
+.\" .nh        disable hyphenation
+.\" .hy        enable hyphenation
+.\" .ad l      left justify
+.\" .ad b      justify to both left and right margins
+.\" .nf        disable filling
+.\" .fi        enable filling
+.\" .br        insert line break
+.\" .sp <n>    insert n+1 empty lines
+.\" for manpage-specific macros, see man(7)
+.SH NAME
+pycolor \- Colorize a python file using ANSI and print to stdout.
+.SH SYNOPSIS
+.B pycolor
+.RI [ options ] " file"
+.SH DESCRIPTION
+Prints a colorized version of the input file to standard out.
+.SH OPTIONS
+.TP
+.B \-s <scheme>
+Give the color scheme to use.  Currently only Linux (default),
+LightBG, and NOColor are implemented.
+.SH AUTHOR
+pycolor was written by Fernando Perez <fperez@colorado.edu>.
+This manual page was written by Jack Moffitt <jack@xiph.org>,
+for the Debian project (but may be used by others).
diff --git a/doc/pycon.ico b/doc/pycon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..a54682d91c85164fe9c910f5831935bd7fd6983c
GIT binary patch
literal 766
zc$|fjt!~3G6orrLNl`P<qR|BoM!L*skFrN73n_?F(6NnXC{mbF`379Hfl7Ua!aYJk
zrR-j(ag(Uqj(zNW$3IDA1By$M%pv-o0C(I!uoLzpTj9o!<rDm(+*jmz+ewj#8|NG+
zjjw2$wv!@}H2*2edRhR-=bqNgFHO)<cyU=f^IXbfY>CpAr*F0bs3vL|Wi5dXJbl$1
z=(=N+&{lS6IW{ImU1@V>%i;-P+!|vnPw3VYkug<l^_f%B9N54_enw#J1FFLJw1Fmc
z-viBA_&?xw^S(*@>^|I|Jen^%4w(G*p2yk^1Z4YDvu}1MhR<aNtS^IK%PZ?gl4CpY
rDf2DSd}UN{1XZY96?kH&?713@k6f@<Ikqbov1dac?zh+0$h&_4nYGO+

literal 0
Hc$@<O00001

diff --git a/doc/update_magic.sh b/doc/update_magic.sh
new file mode 100755
index 0000000..71098a8
--- /dev/null
+++ b/doc/update_magic.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+ipython --magic_docstrings > magic.tex
\ No newline at end of file
diff --git a/doc/update_version.sh b/doc/update_version.sh
new file mode 100755
index 0000000..4e09ef0
--- /dev/null
+++ b/doc/update_version.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+ver=`ipython -V`
+sed "s/__version__/${ver}/" manual_base.lyx > manual.lyx
diff --git a/scripts/ipython b/scripts/ipython
new file mode 100755
index 0000000..a7a78a4
--- /dev/null
+++ b/scripts/ipython
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""IPython -- An enhanced Interactive Python
+
+This is just the startup wrapper script, kept deliberately to a minimum.
+
+The shell's mainloop() takes an optional argument, sys_exit (default=0). If
+set to 1, it calls sys.exit() at exit time. You can use the following code in
+your PYTHONSTARTUP file:
+
+import IPython
+IPython.Shell.IPShell().mainloop(sys_exit=1)
+
+[or simply IPython.Shell.IPShell().mainloop(1) ]
+
+and IPython will be your working environment when you start python. The final
+sys.exit() call will make python exit transparently when IPython finishes, so
+you don't have an extra prompt to get out of.
+
+This is probably useful to developers who manage multiple Python versions and
+don't want to have correspondingly multiple IPython versions. Note that in
+this mode, there is no way to pass IPython any command-line options, as those
+are trapped first by Python itself.
+"""
+
+import IPython
+
+IPython.Shell.start().mainloop()
diff --git a/scripts/ipython_win_post_install.py b/scripts/ipython_win_post_install.py
new file mode 100755
index 0000000..efe573d
--- /dev/null
+++ b/scripts/ipython_win_post_install.py
@@ -0,0 +1,78 @@
+#!python
+"""Windows-specific part of the installation"""
+
+import os, sys
+
+def create_shortcut_safe(target,description,link_file,*args,**kw):
+    """make a shortcut if it doesn't exist, and register its creation"""
+    
+    if not os.path.isfile(link_file):
+        create_shortcut(target, description, link_file,*args,**kw)
+        file_created(link_file)
+
+def install():
+    """Routine to be run by the win32 installer with the -install switch."""
+
+    from IPython.Release import version
+
+    # Get some system constants
+    prefix = sys.prefix
+    python = prefix + r'\python.exe'
+    # Lookup path to common startmenu ...
+    ip_dir = get_special_folder_path('CSIDL_COMMON_PROGRAMS') + r'\IPython'
+    
+    # Some usability warnings at installation time.  I don't want them at the
+    # top-level, so they don't appear if the user is uninstalling.
+    try:
+        import ctypes
+    except ImportError:
+        print ('To take full advantage of IPython, you need ctypes from:\n'
+               'http://sourceforge.net/projects/ctypes')
+
+    try:
+        import win32con
+    except ImportError:
+        print ('To take full advantage of IPython, you need pywin32 from:\n'
+               'http://starship.python.net/crew/mhammond/win32/Downloads.html')
+
+    try:
+        import readline
+    except ImportError:
+        print ('To take full advantage of IPython, you need readline from:\n'
+               'http://sourceforge.net/projects/uncpythontools')
+
+    # Create IPython entry ...
+    if not os.path.isdir(ip_dir):
+        os.mkdir(ip_dir)
+        directory_created(ip_dir)
+
+    # Create program shortcuts ...
+    f = ip_dir + r'\IPython.lnk'
+    a = prefix + r'\scripts\ipython'
+    create_shortcut_safe(python,'IPython',f,a)
+
+    f = ip_dir + r'\pysh.lnk'
+    a = prefix + r'\scripts\ipython -p pysh'
+    create_shortcut_safe(python,'pysh',f,a)
+
+    # Create documentation shortcuts ...    
+    t = prefix + r'\share\doc\ipython-%s\manual.pdf' % version
+    f = ip_dir + r'\Manual in PDF.lnk'
+    create_shortcut_safe(t,r'IPython Manual - PDF-Format',f)
+
+    t = prefix + r'\share\doc\ipython-%s\manual\manual.html' % version
+    f = ip_dir + r'\Manual in HTML.lnk'
+    create_shortcut_safe(t,'IPython Manual - HTML-Format',f)
+
+def remove():
+    """Routine to be run by the win32 installer with the -remove switch."""
+    pass
+
+# main()
+if len(sys.argv) > 1:
+    if sys.argv[1] == '-install':
+        install()
+    elif sys.argv[1] == '-remove':
+        remove()
+    else:
+        print "Script was called with option %s" % sys.argv[1]
diff --git a/scripts/pycolor b/scripts/pycolor
new file mode 100755
index 0000000..9006717
--- /dev/null
+++ b/scripts/pycolor
@@ -0,0 +1,6 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""Simple wrapper around PyColorize, which colorizes python sources."""
+
+import IPython.PyColorize
+IPython.PyColorize.main()
diff --git a/setup.py b/setup.py
new file mode 100755
index 0000000..d11fee8
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,146 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""Setup script for IPython.
+
+Under Posix environments it works like a typical setup.py script. 
+Under Windows, the command sdist is not supported, since IPython 
+requires utilities, which are not available under Windows."""
+
+#*****************************************************************************
+#       Copyright (C) 2001-2005 Fernando Perez <fperez@colorado.edu>
+#
+#  Distributed under the terms of the BSD License.  The full license is in
+#  the file COPYING, distributed as part of this software.
+#*****************************************************************************
+
+import sys, os
+from glob import glob
+from setupext import install_data_ext
+isfile = os.path.isfile
+
+# BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
+# update it when the contents of directories change.
+if os.path.exists('MANIFEST'): os.remove('MANIFEST')
+
+if os.name == 'posix':
+    os_name = 'posix'
+elif os.name in ['nt','dos']:
+    os_name = 'windows'
+else:
+    print 'Unsupported operating system:',os.name
+    sys.exit(1)
+
+# Under Windows, 'sdist' is not supported, since it requires lyxport (and
+# hence lyx,perl,latex,pdflatex,latex2html,sh,...)
+if os_name == 'windows' and sys.argv[1] == 'sdist':
+    print 'The sdist command is not available under Windows.  Exiting.'
+    sys.exit(1)
+
+from distutils.core import setup
+
+# update the manuals when building a source dist
+if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
+    from IPython.genutils import target_update
+    # list of things to be updated. Each entry is a triplet of args for
+    # target_update()
+    to_update = [('doc/magic.tex',
+                  ['IPython/Magic.py'],
+                  "cd doc && ./update_magic.sh" ),
+                 
+                 ('doc/manual.lyx',
+                  ['IPython/Release.py','doc/manual_base.lyx'],
+                  "cd doc && ./update_version.sh" ),
+                 
+                 ('doc/manual/manual.html',
+                  ['doc/manual.lyx',
+                   'doc/magic.tex',
+                   'doc/examples/example-gnuplot.py',
+                   'doc/examples/example-magic.py',
+                   'doc/examples/example-embed.py',
+                   'doc/examples/example-embed-short.py',
+                   'IPython/UserConfig/ipythonrc',
+                   ],
+                  "cd doc && "
+                  "lyxport -tt --leave --pdf "
+                  "--html -o '-noinfo -split +1 -local_icons' manual.lyx"),
+                 
+                 ('doc/new_design.pdf',
+                  ['doc/new_design.lyx'],
+                  "cd doc && lyxport -tt --pdf new_design.lyx"),
+
+                 ('doc/ipython.1.gz',
+                  ['doc/ipython.1'],
+                  "cd doc && gzip -9c ipython.1 > ipython.1.gz"),
+
+                 ('doc/pycolor.1.gz',
+                  ['doc/pycolor.1'],
+                  "cd doc && gzip -9c pycolor.1 > pycolor.1.gz"),
+                 ]
+    for target in to_update:
+        target_update(*target)
+
+# Release.py contains version, authors, license, url, keywords, etc.
+execfile(os.path.join('IPython','Release.py'))
+
+# A little utility we'll need below, since glob() does NOT allow you to do
+# exclusion on multiple endings!
+def file_doesnt_endwith(test,endings):
+    """Return true if test is a file and its name does NOT end with any
+    of the strings listed in endings."""
+    if not isfile(test):
+        return False
+    for e in endings:
+        if test.endswith(e):
+            return False
+    return True
+
+# I can't find how to make distutils create a nested dir. structure, so
+# in the meantime do it manually. Butt ugly.
+docdirbase  = 'share/doc/ipython-%s' % version
+manpagebase = 'share/man/man1'
+
+# We only need to exclude from this things NOT already excluded in the
+# MANIFEST.in file.
+exclude     = ('.sh','.1.gz')
+docfiles    = filter(lambda f:file_doesnt_endwith(f,exclude),glob('doc/*'))
+
+examfiles   = filter(isfile, glob('doc/examples/*.py'))
+manfiles    = filter(isfile, glob('doc/manual/*.html')) + \
+              filter(isfile, glob('doc/manual/*.css')) + \
+              filter(isfile, glob('doc/manual/*.png'))
+manpages    = filter(isfile, glob('doc/*.1.gz'))
+cfgfiles    = filter(isfile, glob('IPython/UserConfig/*'))
+scriptfiles = filter(isfile, ['scripts/ipython','scripts/pycolor'])
+
+# Script to be run by the windows binary installer after the default setup
+# routine, to add shortcuts and similar windows-only things.  Windows
+# post-install scripts MUST reside in the scripts/ dir, otherwise distutils
+# doesn't find them.
+if 'bdist_wininst' in sys.argv:
+    if len(sys.argv) > 2 and ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
+        print >> sys.stderr,"ERROR: bdist_wininst must be run alone. Exiting."
+        sys.exit(1)
+    scriptfiles.append('scripts/ipython_win_post_install.py')
+
+# Call the setup() routine which does most of the work
+setup(name             = name,
+      version          = version,
+      description      = description,
+      long_description = long_description,
+      author           = authors['Fernando'][0],
+      author_email     = authors['Fernando'][1],
+      url              = url,
+      license          = license,
+      platforms        = platforms,
+      keywords         = keywords,
+      packages         = ['IPython', 'IPython.Extensions'],
+      scripts          = scriptfiles,
+      cmdclass         = {'install_data': install_data_ext},
+      data_files       = [('data', docdirbase, docfiles),
+                          ('data', os.path.join(docdirbase, 'examples'),
+                           examfiles),
+                          ('data', os.path.join(docdirbase, 'manual'),
+                           manfiles),
+                          ('data', manpagebase, manpages),
+                          ('lib', 'IPython/UserConfig', cfgfiles)]
+      )
diff --git a/setupext/__init__.py b/setupext/__init__.py
new file mode 100644
index 0000000..5f93fe1
--- /dev/null
+++ b/setupext/__init__.py
@@ -0,0 +1,3 @@
+# load extended setup modules for distuils
+
+from install_data_ext import install_data_ext
diff --git a/setupext/install_data_ext.py b/setupext/install_data_ext.py
new file mode 100644
index 0000000..f2ce894
--- /dev/null
+++ b/setupext/install_data_ext.py
@@ -0,0 +1,80 @@
+# install_data_ext.py
+#
+# Subclass of normal distutils install_data command to allow more
+# configurable installation of data files.
+
+import os
+from distutils.command.install_data import install_data
+from distutils.util import change_root, convert_path
+
+class install_data_ext(install_data):
+
+    def initialize_options(self):
+        self.install_base = None
+        self.install_platbase = None
+        self.install_purelib = None
+        self.install_headers = None
+        self.install_lib = None
+        self.install_scripts = None
+        self.install_data = None
+
+        self.outfiles = []
+        self.root = None
+        self.force = 0
+        self.data_files = self.distribution.data_files
+        self.warn_dir = 1
+        
+
+    def finalize_options(self):
+        self.set_undefined_options('install',
+                                   ('root', 'root'),
+                                   ('force', 'force'),
+                                   ('install_base', 'install_base'),
+                                   ('install_platbase',
+                                    'install_platbase'),
+                                   ('install_purelib',
+                                    'install_purelib'),
+                                   ('install_headers',
+                                    'install_headers'),
+                                   ('install_lib', 'install_lib'),
+                                   ('install_scripts',
+                                    'install_scripts'),
+                                   ('install_data', 'install_data'))
+                                   
+
+    def run(self):
+        """
+        This is where the meat is.  Basically the data_files list must
+        now be a list of tuples of 3 entries.  The first
+        entry is one of 'base', 'platbase', etc, which indicates which
+        base to install from.  The second entry is the path to install
+        too.  The third entry is a list of files to install.
+        """
+        for lof in self.data_files:
+            if lof[0]:
+                base = getattr(self, 'install_' + lof[0])
+            else:
+                base = getattr(self, 'install_base')
+            dir = convert_path(lof[1])
+            if not os.path.isabs(dir):
+                dir = os.path.join(base, dir)
+            elif self.root:
+                dir = change_root(self.root, dir)
+            self.mkpath(dir)
+
+            files = lof[2]
+            if len(files) == 0:
+                # If there are no files listed, the user must be
+                # trying to create an empty directory, so add the the
+                # directory to the list of output files.
+                self.outfiles.append(dir)
+            else:
+                # Copy files, adding them to the list of output files.
+                for f in files:
+                    f = convert_path(f)
+                    (out, _) = self.copy_file(f, dir)
+                    #print "DEBUG: ", out  # dbg
+                    self.outfiles.append(out)
+                    
+
+        return self.outfiles
diff --git a/tools/bkp.py b/tools/bkp.py
new file mode 100755
index 0000000..4fd2fb4
--- /dev/null
+++ b/tools/bkp.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+"""Backup directories using rsync. Quick and dirty.
+
+backup.py config_file final_actions
+"""
+
+#----------------------------------------------------------------------------
+# configure in this section
+
+# all dirs relative to current dir.
+
+# output directory for backups
+outdir = ''
+
+# list directories to backup as a dict with 1 or 0 values for
+# recursive (or not) descent:
+to_backup = {}
+
+# list exclude patterns here (space-separated):
+# if the pattern ends with a / then it will only match a directory, not a
+# file, link or device.
+# see man rsync for more details on the exclude patterns
+exc_pats = '#*#  *~  *.pyc *.pyo *.o '
+
+# global options for rsync
+rsync_opts='-v -t -a --delete --delete-excluded'
+
+#----------------------------------------------------------------------------
+# real code begins
+import os,string,re,sys
+from IPython.genutils import *
+from IPython.Itpl import itpl
+
+# config file can redefine final actions
+def final():
+    pass
+
+# load config from cmd line config file or default bkprc.py
+try:
+    execfile(sys.argv[1])
+except:
+    try:
+        execfile('bkprc.py')
+    except IOError:
+        print 'You need to provide a config file: bkp.py rcfile'
+        sys.exit()
+
+# make output dir if needed
+outdir = os.path.expanduser(outdir)
+try:
+    os.makedirs(outdir)
+except OSError:  # raised if dir already exists -> no need to make it
+    pass
+
+# build rsync command and call:
+exclude = re.sub(r'([^\s].*?)(\s|$)',r'--exclude "\1"\2',exc_pats)
+rsync = itpl('rsync $rsync_opts $exclude')
+
+# the same can also be done with lists (keep it for reference):
+#exclude = string.join(['--exclude "'+p+'"' for p in qw(exc_pats)])
+
+# rsync takes -r as a flag, not 0/1 so translate:
+rec_flag = {0:'',1:'-r'}
+
+# loop over user specified directories calling rsync
+for bakdir,rec in to_backup.items():
+    bakdir = os.path.expanduser(bakdir)
+    xsys(itpl('$rsync $rec_flag[rec] $bakdir $outdir'),
+         debug=0,verbose=1,header='\n### ')
+
+# final actions?
+final()
diff --git a/tools/bkprc.py b/tools/bkprc.py
new file mode 100644
index 0000000..6903150
--- /dev/null
+++ b/tools/bkprc.py
@@ -0,0 +1,22 @@
+# config file for a quick'n dirty backup script that uses rsync
+
+# output directory for backups
+outdir = '~/tmp'
+
+# list directories to backup as a dict with 1 or 0 values for
+# recursive (or not) descent:
+to_backup = {'~/ipython/ipython':1}
+
+# exclude patterns. anything ending in / is considered a directory
+exc_pats = '#*#  *~ *.o *.pyc *.pyo MANIFEST *.pdf *.flc build/ dist/ ' \
+' doc/manual/ doc/manual.lyx ChangeLog.* magic.tex *.1.gz '
+
+# final actions after doing the backup
+def final():
+    dbg = 0
+    version = bq('ipython -V')
+    out_tgz = outdir+'/ipython-'+version+'.tgz'
+    xsys(itpl('cd $outdir; pwd;tar -czf $out_tgz ipython'),debug=dbg,verbose=1)
+    #xsys(itpl('cp $out_tgz /mnt/card/fperez/ipython'),debug=dbg,verbose=1)
+    xsys(itpl('mv $out_tgz ~/ipython/backup'),debug=dbg,verbose=1)
+    xsys(itpl('rm -rf ${outdir}/ipython'),debug=dbg,verbose=1)
diff --git a/tools/release b/tools/release
new file mode 100755
index 0000000..4ca7455
--- /dev/null
+++ b/tools/release
@@ -0,0 +1,99 @@
+#!/bin/sh
+# IPython release script
+
+PYVER=`python -V 2>&1 | awk '{print $2}' | awk -F '.' '{print $1$2}' `
+version=`ipython -Version`
+ipdir=~/ipython/ipython
+
+echo
+echo "Releasing IPython version $version"
+echo "=================================="
+
+echo "Marking ChangeLog with release information and making NEWS file..."
+
+# Stamp changelog and save a copy of the status at each version, in case later
+# we want the NEWS file to start from a point before the very last release (if
+# very small interim releases have no significant changes).
+
+cd $ipdir/doc
+cp ChangeLog ChangeLog.old
+cp ChangeLog ChangeLog.$version
+daystamp=`date +%Y-%m-%d`
+echo $daystamp " ***" Released version $version > ChangeLog
+echo >> ChangeLog
+cat ChangeLog.old >> ChangeLog
+rm ChangeLog.old
+
+# Build NEWS file
+echo "Changes between the last two releases (major or minor)" > NEWS
+echo "Note that this is an auto-generated diff of the ChangeLogs" >> NEWS
+echo >> NEWS
+diff ChangeLog.previous ChangeLog | grep -v '^0a' | sed 's/^> //g' >> NEWS
+cp ChangeLog ChangeLog.previous
+
+# Clean up build/dist directories
+rm -rf $ipdir/build/*
+rm -rf $ipdir/dist/*
+
+# Perform local backup
+cd $ipdir/tools
+./bkp.py
+
+# Build source and binary distros
+cd $ipdir
+./setup.py sdist --formats=gztar
+#./setup.py bdist_rpm --release=py$PYVER
+python2.3 ./setup.py bdist_rpm --release=py23 --python=/usr/bin/python2.3
+
+# A 2.4-specific RPM, where we must use the --python option to ensure that
+# the resulting RPM is really built with 2.4 (so things go to
+# lib/python2.4/...)
+python2.4 ./setup.py bdist_rpm --release=py24 --python=/usr/bin/python2.4
+
+# Call the windows build separately, so that the extra Windows scripts don't
+# get pulled into Unix builds (setup.py has code which checks for
+# bdist_wininst)
+#./setup.py bdist_wininst --install-script=ipython_win_post_install.py
+
+# For now, make the win32 installer with a hand-built 2.3.5 python, which is
+# the only one that fixes a crash in the post-install phase.
+$HOME/tmp/local/bin/python2.3 setup.py bdist_wininst \
+  --install-script=ipython_win_post_install.py
+
+
+# Register with the Python Package Index (PyPI)
+echo "Registering with PyPI..."
+cd $ipdir
+./setup.py register
+
+# Upload all files
+cd $ipdir/dist
+echo "Uploading distribution files..."
+scp * fperez@scipy.org:www/dist/
+
+echo "Uploading backup files..."
+cd ~/ipython/backup
+scp `ls -1tr | tail -1` fperez@scipy.org:www/backup/
+
+echo "Updating webpage..."
+cd $ipdir/doc
+www=~/ipython/homepage
+cp ChangeLog NEWS $www
+rm -rf $www/doc/*
+cp -r manual.pdf manual/ $www/doc
+cd $www
+./update
+
+# Alert package maintainers
+echo "Alerting package maintainers..."
+maintainers='fperez@colorado.edu ariciputi@users.sourceforge.net jack@xiph.org tretkowski@inittab.de dryice@hotpop.com'
+#maintainers='fperez@colorado.edu'
+
+for email in $maintainers
+    do
+	echo "Emailing $email..."
+	mail -s "[Package maintainer notice] A new IPython is out. Version: $version" \
+    $email < NEWS
+    done
+
+echo "Done!"
diff --git a/tools/testrel b/tools/testrel
new file mode 100755
index 0000000..458f819
--- /dev/null
+++ b/tools/testrel
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# release test
+PYVER=`python -V 2>&1 | awk '{print $2}' | awk -F '.' '{print $1$2}' `
+
+# clean up build/dist directories
+rm -rf ~/ipython/ipython/build/*
+rm -rf ~/ipython/ipython/dist/*
+
+# build source distros
+cd ~/ipython/ipython
+
+./setup.py sdist --formats=gztar
+
+#./setup.py bdist_rpm --release=py$PYVER
+python2.3 ./setup.py bdist_rpm --release=py23 --python=/usr/bin/python2.3
+python2.4 ./setup.py bdist_rpm --release=py24 --python=/usr/bin/python2.4
+
+# Call the windows build separately, so that the extra Windows scripts don't
+# get pulled into Unix builds (setup.py has code which checks for
+# bdist_wininst)
+#./setup.py bdist_wininst --install-script=ipython_win_post_install.py
+
+# For now, make the win32 installer with a hand-built 2.3.5 python, which is
+# the only one that fixes a crash in the post-install phase.
+$HOME/tmp/local/bin/python2.3 setup.py bdist_wininst \
+  --install-script=ipython_win_post_install.py
diff --git a/win32_manual_post_install.py b/win32_manual_post_install.py
new file mode 100644
index 0000000..40addde
--- /dev/null
+++ b/win32_manual_post_install.py
@@ -0,0 +1,130 @@
+#!python
+"""Windows-specific part of the installation"""
+
+import os, sys
+
+try:
+    import shutil,pythoncom
+    from win32com.shell import shell
+    import _winreg as wreg
+except ImportError:
+    print """
+You seem to be missing the PythonWin extensions necessary for automatic
+installation.  You can get them (free) from
+http://starship.python.net/crew/mhammond/
+
+Please see the manual for details if you want to finish the installation by
+hand, or get PythonWin and repeat the procedure.
+
+Press <Enter> to exit this installer."""
+    raw_input()
+    sys.exit()
+
+
+def make_shortcut(fname,target,args='',start_in='',comment='',icon=None):
+    """Make a Windows shortcut (.lnk) file.
+
+    make_shortcut(fname,target,args='',start_in='',comment='',icon=None)
+
+    Arguments:
+        fname - name of the final shortcut file (include the .lnk)
+        target - what the shortcut will point to
+        args - additional arguments to pass to the target program
+        start_in - directory where the target command will be called
+        comment - for the popup tooltips
+        icon - optional icon file. This must be a tuple of the type 
+        (icon_file,index), where index is the index of the icon you want
+        in the file. For single .ico files, index=0, but for icon libraries
+        contained in a single file it can be >0.
+    """
+
+    shortcut = pythoncom.CoCreateInstance(
+        shell.CLSID_ShellLink, None,
+        pythoncom.CLSCTX_INPROC_SERVER, shell.IID_IShellLink
+    )
+    shortcut.SetPath(target)
+    shortcut.SetArguments(args)
+    shortcut.SetWorkingDirectory(start_in)
+    shortcut.SetDescription(comment)
+    if icon:
+        shortcut.SetIconLocation(*icon)
+    shortcut.QueryInterface(pythoncom.IID_IPersistFile).Save(fname,0)
+
+
+def run(wait=0):
+    # Find where the Start Menu and My Documents are on the filesystem
+    key = wreg.OpenKey(wreg.HKEY_CURRENT_USER,
+                       r'Software\Microsoft\Windows\CurrentVersion'
+                       r'\Explorer\Shell Folders')
+
+    programs_dir = wreg.QueryValueEx(key,'Programs')[0]
+    my_documents_dir = wreg.QueryValueEx(key,'Personal')[0]
+    key.Close()
+
+    # Find where the 'program files' directory is
+    key = wreg.OpenKey(wreg.HKEY_LOCAL_MACHINE,
+                       r'SOFTWARE\Microsoft\Windows\CurrentVersion')
+
+    program_files_dir = wreg.QueryValueEx(key,'ProgramFilesDir')[0]
+    key.Close()
+
+
+    # File and directory names
+    ip_dir = program_files_dir + '\\IPython'
+    ip_prog_dir = programs_dir + '\\IPython'
+    doc_dir = ip_dir+'\\doc'
+    ip_filename = ip_dir+'\\IPython_shell.py'
+    pycon_icon = doc_dir+'\\pycon.ico'
+
+    if not os.path.isdir(ip_dir):
+        os.mkdir(ip_dir)
+
+    # Copy startup script and documentation
+    shutil.copy(sys.prefix+'\\Scripts\\ipython',ip_filename)
+    if os.path.isdir(doc_dir):
+        shutil.rmtree(doc_dir)
+    shutil.copytree('doc',doc_dir)
+
+    # make shortcuts for IPython, html and pdf docs.
+    print 'Making entries for IPython in Start Menu...',
+
+    # Create shortcuts in Programs\IPython:
+    if not os.path.isdir(ip_prog_dir):
+        os.mkdir(ip_prog_dir)
+    os.chdir(ip_prog_dir)
+
+    man_pdf = doc_dir + '\\manual.pdf'
+    man_htm = doc_dir + '\\manual\\manual.html'
+
+    make_shortcut('IPython.lnk',sys.executable, '"%s"' % ip_filename,
+                  my_documents_dir,
+                  'IPython - Enhanced python command line interpreter',
+                  (pycon_icon,0))
+    make_shortcut('pysh.lnk',sys.executable, '"%s" -p pysh' % ip_filename,
+                  my_documents_dir,
+                  'pysh - a system shell with Python syntax (IPython based)',
+                  (pycon_icon,0))
+    make_shortcut('Manual in HTML format.lnk',man_htm,'','',
+                  'IPython Manual - HTML format')
+    make_shortcut('Manual in PDF format.lnk',man_pdf,'','',
+                  'IPython Manual - PDF format')
+
+    print """Done.
+
+I created the directory %s. There you will find the
+IPython startup script and manuals.
+
+An IPython menu was also created in your Start Menu, with entries for
+IPython itself and the manual in HTML and PDF formats.
+
+For reading PDF documents you need the freely available Adobe Acrobat
+Reader. If you don't have it, you can download it from:
+http://www.adobe.com/products/acrobat/readstep2.html
+""" % ip_dir
+
+    if wait:
+        print "Finished with IPython installation. Press Enter to exit this installer.",
+        raw_input()
+
+if __name__ == '__main__':
+    run()