##// END OF EJS Templates
Merging upstream change from module-reorg branch....
Brian Granger -
r2156:ed44a843 merge
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,229 +1,229 b''
1 1 # -*- coding: utf-8 -*-
2 2 """sys.excepthook for IPython itself, leaves a detailed report on disk.
3 3
4 4
5 5 Authors
6 6 -------
7 7 - Fernando Perez <Fernando.Perez@berkeley.edu>
8 8 """
9 9
10 10 #*****************************************************************************
11 11 # Copyright (C) 2008-2009 The IPython Development Team
12 12 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
13 13 #
14 14 # Distributed under the terms of the BSD License. The full license is in
15 15 # the file COPYING, distributed as part of this software.
16 16 #*****************************************************************************
17 17
18 18 #****************************************************************************
19 19 # Required modules
20 20
21 21 # From the standard library
22 22 import os
23 23 import sys
24 24 from pprint import pformat
25 25
26 26 # Our own
27 27 from IPython.core import release
28 28 from IPython.core import ultratb
29 29 from IPython.external.Itpl import itpl
30 30
31 31 from IPython.utils.genutils import *
32 32
33 33 #****************************************************************************
34 34 class CrashHandler:
35 35 """Customizable crash handlers for IPython-based systems.
36 36
37 37 Instances of this class provide a __call__ method which can be used as a
38 38 sys.excepthook, i.e., the __call__ signature is:
39 39
40 40 def __call__(self,etype, evalue, etb)
41 41
42 42 """
43 43
44 44 def __init__(self,IP,app_name,contact_name,contact_email,
45 45 bug_tracker,crash_report_fname,
46 46 show_crash_traceback=True):
47 47 """New crash handler.
48 48
49 49 Inputs:
50 50
51 51 - IP: a running IPython instance, which will be queried at crash time
52 52 for internal information.
53 53
54 54 - app_name: a string containing the name of your application.
55 55
56 56 - contact_name: a string with the name of the person to contact.
57 57
58 58 - contact_email: a string with the email address of the contact.
59 59
60 60 - bug_tracker: a string with the URL for your project's bug tracker.
61 61
62 62 - crash_report_fname: a string with the filename for the crash report
63 63 to be saved in. These reports are left in the ipython user directory
64 64 as determined by the running IPython instance.
65 65
66 66 Optional inputs:
67 67
68 68 - show_crash_traceback(True): if false, don't print the crash
69 69 traceback on stderr, only generate the on-disk report
70 70
71 71
72 72 Non-argument instance attributes:
73 73
74 74 These instances contain some non-argument attributes which allow for
75 75 further customization of the crash handler's behavior. Please see the
76 76 source for further details.
77 77 """
78 78
79 79 # apply args into instance
80 80 self.IP = IP # IPython instance
81 81 self.app_name = app_name
82 82 self.contact_name = contact_name
83 83 self.contact_email = contact_email
84 84 self.bug_tracker = bug_tracker
85 85 self.crash_report_fname = crash_report_fname
86 86 self.show_crash_traceback = show_crash_traceback
87 87
88 88 # Hardcoded defaults, which can be overridden either by subclasses or
89 89 # at runtime for the instance.
90 90
91 91 # Template for the user message. Subclasses which completely override
92 92 # this, or user apps, can modify it to suit their tastes. It gets
93 93 # expanded using itpl, so calls of the kind $self.foo are valid.
94 94 self.user_message_template = """
95 95 Oops, $self.app_name crashed. We do our best to make it stable, but...
96 96
97 97 A crash report was automatically generated with the following information:
98 98 - A verbatim copy of the crash traceback.
99 99 - A copy of your input history during this session.
100 100 - Data on your current $self.app_name configuration.
101 101
102 102 It was left in the file named:
103 103 \t'$self.crash_report_fname'
104 104 If you can email this file to the developers, the information in it will help
105 105 them in understanding and correcting the problem.
106 106
107 107 You can mail it to: $self.contact_name at $self.contact_email
108 108 with the subject '$self.app_name Crash Report'.
109 109
110 110 If you want to do it now, the following command will work (under Unix):
111 111 mail -s '$self.app_name Crash Report' $self.contact_email < $self.crash_report_fname
112 112
113 113 To ensure accurate tracking of this issue, please file a report about it at:
114 114 $self.bug_tracker
115 115 """
116 116
117 117 def __call__(self,etype, evalue, etb):
118 118 """Handle an exception, call for compatible with sys.excepthook"""
119 119
120 120 # Report tracebacks shouldn't use color in general (safer for users)
121 121 color_scheme = 'NoColor'
122 122
123 123 # Use this ONLY for developer debugging (keep commented out for release)
124 124 #color_scheme = 'Linux' # dbg
125 125
126 126 try:
127 127 rptdir = self.IP.rc.ipythondir
128 128 except:
129 129 rptdir = os.getcwd()
130 130 if not os.path.isdir(rptdir):
131 131 rptdir = os.getcwd()
132 132 report_name = os.path.join(rptdir,self.crash_report_fname)
133 133 # write the report filename into the instance dict so it can get
134 134 # properly expanded out in the user message template
135 135 self.crash_report_fname = report_name
136 136 TBhandler = ultratb.VerboseTB(color_scheme=color_scheme,
137 137 long_header=1)
138 138 traceback = TBhandler.text(etype,evalue,etb,context=31)
139 139
140 140 # print traceback to screen
141 141 if self.show_crash_traceback:
142 142 print >> sys.stderr, traceback
143 143
144 144 # and generate a complete report on disk
145 145 try:
146 146 report = open(report_name,'w')
147 147 except:
148 148 print >> sys.stderr, 'Could not create crash report on disk.'
149 149 return
150 150
151 151 # Inform user on stderr of what happened
152 152 msg = itpl('\n'+'*'*70+'\n'+self.user_message_template)
153 153 print >> sys.stderr, msg
154 154
155 155 # Construct report on disk
156 156 report.write(self.make_report(traceback))
157 157 report.close()
158 158 raw_input("Press enter to exit:")
159 159
160 160 def make_report(self,traceback):
161 161 """Return a string containing a crash report."""
162 162
163 163 sec_sep = '\n\n'+'*'*75+'\n\n'
164 164
165 165 report = []
166 166 rpt_add = report.append
167 167
168 168 rpt_add('*'*75+'\n\n'+'IPython post-mortem report\n\n')
169 169 rpt_add('IPython version: %s \n\n' % release.version)
170 170 rpt_add('BZR revision : %s \n\n' % release.revision)
171 171 rpt_add('Platform info : os.name -> %s, sys.platform -> %s' %
172 172 (os.name,sys.platform) )
173 173 rpt_add(sec_sep+'Current user configuration structure:\n\n')
174 174 rpt_add(pformat(self.IP.rc.dict()))
175 175 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
176 176 try:
177 177 rpt_add(sec_sep+"History of session input:")
178 178 for line in self.IP.user_ns['_ih']:
179 179 rpt_add(line)
180 180 rpt_add('\n*** Last line of input (may not be in above history):\n')
181 181 rpt_add(self.IP._last_input_line+'\n')
182 182 except:
183 183 pass
184 184
185 185 return ''.join(report)
186 186
187 187 class IPythonCrashHandler(CrashHandler):
188 188 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
189 189
190 190 def __init__(self,IP):
191 191
192 192 # Set here which of the IPython authors should be listed as contact
193 AUTHOR_CONTACT = 'Ville'
193 AUTHOR_CONTACT = 'Fernando'
194 194
195 195 # Set argument defaults
196 196 app_name = 'IPython'
197 197 bug_tracker = 'https://bugs.launchpad.net/ipython/+filebug'
198 198 contact_name,contact_email = release.authors[AUTHOR_CONTACT][:2]
199 199 crash_report_fname = 'IPython_crash_report.txt'
200 200 # Call parent constructor
201 201 CrashHandler.__init__(self,IP,app_name,contact_name,contact_email,
202 202 bug_tracker,crash_report_fname)
203 203
204 204 def make_report(self,traceback):
205 205 """Return a string containing a crash report."""
206 206
207 207 sec_sep = '\n\n'+'*'*75+'\n\n'
208 208
209 209 report = []
210 210 rpt_add = report.append
211 211
212 212 rpt_add('*'*75+'\n\n'+'IPython post-mortem report\n\n')
213 213 rpt_add('IPython version: %s \n\n' % release.version)
214 214 rpt_add('BZR revision : %s \n\n' % release.revision)
215 215 rpt_add('Platform info : os.name -> %s, sys.platform -> %s' %
216 216 (os.name,sys.platform) )
217 217 rpt_add(sec_sep+'Current user configuration structure:\n\n')
218 218 rpt_add(pformat(self.IP.rc.dict()))
219 219 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
220 220 try:
221 221 rpt_add(sec_sep+"History of session input:")
222 222 for line in self.IP.user_ns['_ih']:
223 223 rpt_add(line)
224 224 rpt_add('\n*** Last line of input (may not be in above history):\n')
225 225 rpt_add(self.IP._last_input_line+'\n')
226 226 except:
227 227 pass
228 228
229 229 return ''.join(report)
@@ -1,247 +1,266 b''
1 1 """hooks for IPython.
2 2
3 3 In Python, it is possible to overwrite any method of any object if you really
4 4 want to. But IPython exposes a few 'hooks', methods which are _designed_ to
5 5 be overwritten by users for customization purposes. This module defines the
6 6 default versions of all such hooks, which get used by IPython if not
7 7 overridden by the user.
8 8
9 9 hooks are simple functions, but they should be declared with 'self' as their
10 10 first argument, because when activated they are registered into IPython as
11 11 instance methods. The self argument will be the IPython running instance
12 12 itself, so hooks have full access to the entire IPython object.
13 13
14 14 If you wish to define a new hook and activate it, you need to put the
15 15 necessary code into a python file which can be either imported or execfile()'d
16 16 from within your ipythonrc configuration.
17 17
18 18 For example, suppose that you have a module called 'myiphooks' in your
19 19 PYTHONPATH, which contains the following definition:
20 20
21 21 import os
22 22 from IPython.core import ipapi
23 23 ip = ipapi.get()
24 24
25 25 def calljed(self,filename, linenum):
26 26 "My editor hook calls the jed editor directly."
27 27 print "Calling my own editor, jed ..."
28 28 if os.system('jed +%d %s' % (linenum,filename)) != 0:
29 29 raise ipapi.TryNext()
30 30
31 31 ip.set_hook('editor', calljed)
32 32
33 33 You can then enable the functionality by doing 'import myiphooks'
34 34 somewhere in your configuration files or ipython command line.
35 35 """
36 36
37 37 #*****************************************************************************
38 38 # Copyright (C) 2005 Fernando Perez. <fperez@colorado.edu>
39 39 #
40 40 # Distributed under the terms of the BSD License. The full license is in
41 41 # the file COPYING, distributed as part of this software.
42 42 #*****************************************************************************
43 43
44 44 from IPython.core import ipapi
45 45
46 46 import os,bisect
47 import sys
47 48 from IPython.utils.genutils import Term,shell
48 49 from pprint import PrettyPrinter
49 50
50 51 # List here all the default hooks. For now it's just the editor functions
51 52 # but over time we'll move here all the public API for user-accessible things.
52 53 # vds: >>
53 54 __all__ = ['editor', 'fix_error_editor', 'synchronize_with_editor', 'result_display',
54 55 'input_prefilter', 'shutdown_hook', 'late_startup_hook',
55 56 'generate_prompt', 'generate_output_prompt','shell_hook',
56 'show_in_pager','pre_prompt_hook', 'pre_runcode_hook']
57 'show_in_pager','pre_prompt_hook', 'pre_runcode_hook',
58 'clipboard_get']
57 59 # vds: <<
58 60
59 61 pformat = PrettyPrinter().pformat
60 62
61 63 def editor(self,filename, linenum=None):
62 64 """Open the default editor at the given filename and linenumber.
63 65
64 66 This is IPython's default editor hook, you can use it as an example to
65 67 write your own modified one. To set your own editor function as the
66 68 new editor hook, call ip.set_hook('editor',yourfunc)."""
67 69
68 70 # IPython configures a default editor at startup by reading $EDITOR from
69 71 # the environment, and falling back on vi (unix) or notepad (win32).
70 72 editor = self.rc.editor
71 73
72 74 # marker for at which line to open the file (for existing objects)
73 75 if linenum is None or editor=='notepad':
74 76 linemark = ''
75 77 else:
76 78 linemark = '+%d' % int(linenum)
77 79
78 80 # Enclose in quotes if necessary and legal
79 81 if ' ' in editor and os.path.isfile(editor) and editor[0] != '"':
80 82 editor = '"%s"' % editor
81 83
82 84 # Call the actual editor
83 85 if os.system('%s %s %s' % (editor,linemark,filename)) != 0:
84 86 raise ipapi.TryNext()
85 87
86 88 import tempfile
87 89 def fix_error_editor(self,filename,linenum,column,msg):
88 90 """Open the editor at the given filename, linenumber, column and
89 91 show an error message. This is used for correcting syntax errors.
90 92 The current implementation only has special support for the VIM editor,
91 93 and falls back on the 'editor' hook if VIM is not used.
92 94
93 95 Call ip.set_hook('fix_error_editor',youfunc) to use your own function,
94 96 """
95 97 def vim_quickfix_file():
96 98 t = tempfile.NamedTemporaryFile()
97 99 t.write('%s:%d:%d:%s\n' % (filename,linenum,column,msg))
98 100 t.flush()
99 101 return t
100 102 if os.path.basename(self.rc.editor) != 'vim':
101 103 self.hooks.editor(filename,linenum)
102 104 return
103 105 t = vim_quickfix_file()
104 106 try:
105 107 if os.system('vim --cmd "set errorformat=%f:%l:%c:%m" -q ' + t.name):
106 108 raise ipapi.TryNext()
107 109 finally:
108 110 t.close()
109 111
110 112 # vds: >>
111 113 def synchronize_with_editor(self, filename, linenum, column):
112 114 pass
113 115 # vds: <<
114 116
115 117 class CommandChainDispatcher:
116 118 """ Dispatch calls to a chain of commands until some func can handle it
117 119
118 120 Usage: instantiate, execute "add" to add commands (with optional
119 121 priority), execute normally via f() calling mechanism.
120 122
121 123 """
122 124 def __init__(self,commands=None):
123 125 if commands is None:
124 126 self.chain = []
125 127 else:
126 128 self.chain = commands
127 129
128 130
129 131 def __call__(self,*args, **kw):
130 132 """ Command chain is called just like normal func.
131 133
132 134 This will call all funcs in chain with the same args as were given to this
133 135 function, and return the result of first func that didn't raise
134 136 TryNext """
135 137
136 138 for prio,cmd in self.chain:
137 139 #print "prio",prio,"cmd",cmd #dbg
138 140 try:
139 141 ret = cmd(*args, **kw)
140 142 return ret
141 143 except ipapi.TryNext, exc:
142 144 if exc.args or exc.kwargs:
143 145 args = exc.args
144 146 kw = exc.kwargs
145 147 # if no function will accept it, raise TryNext up to the caller
146 148 raise ipapi.TryNext
147 149
148 150 def __str__(self):
149 151 return str(self.chain)
150 152
151 153 def add(self, func, priority=0):
152 154 """ Add a func to the cmd chain with given priority """
153 155 bisect.insort(self.chain,(priority,func))
154 156
155 157 def __iter__(self):
156 158 """ Return all objects in chain.
157 159
158 160 Handy if the objects are not callable.
159 161 """
160 162 return iter(self.chain)
161 163
162 164 def result_display(self,arg):
163 165 """ Default display hook.
164 166
165 167 Called for displaying the result to the user.
166 168 """
167 169
168 170 if self.rc.pprint:
169 171 out = pformat(arg)
170 172 if '\n' in out:
171 173 # So that multi-line strings line up with the left column of
172 174 # the screen, instead of having the output prompt mess up
173 175 # their first line.
174 176 Term.cout.write('\n')
175 177 print >>Term.cout, out
176 178 else:
177 179 # By default, the interactive prompt uses repr() to display results,
178 180 # so we should honor this. Users who'd rather use a different
179 181 # mechanism can easily override this hook.
180 182 print >>Term.cout, repr(arg)
181 183 # the default display hook doesn't manipulate the value to put in history
182 184 return None
183 185
184 186 def input_prefilter(self,line):
185 187 """ Default input prefilter
186 188
187 189 This returns the line as unchanged, so that the interpreter
188 190 knows that nothing was done and proceeds with "classic" prefiltering
189 191 (%magics, !shell commands etc.).
190 192
191 193 Note that leading whitespace is not passed to this hook. Prefilter
192 194 can't alter indentation.
193 195
194 196 """
195 197 #print "attempt to rewrite",line #dbg
196 198 return line
197 199
198 200 def shutdown_hook(self):
199 201 """ default shutdown hook
200 202
201 203 Typically, shotdown hooks should raise TryNext so all shutdown ops are done
202 204 """
203 205
204 206 #print "default shutdown hook ok" # dbg
205 207 return
206 208
207 209 def late_startup_hook(self):
208 210 """ Executed after ipython has been constructed and configured
209 211
210 212 """
211 213 #print "default startup hook ok" # dbg
212 214
213 215 def generate_prompt(self, is_continuation):
214 216 """ calculate and return a string with the prompt to display """
215 217 ip = self.api
216 218 if is_continuation:
217 219 return str(ip.IP.outputcache.prompt2)
218 220 return str(ip.IP.outputcache.prompt1)
219 221
220 222 def generate_output_prompt(self):
221 223 ip = self.api
222 224 return str(ip.IP.outputcache.prompt_out)
223 225
224 226 def shell_hook(self,cmd):
225 227 """ Run system/shell command a'la os.system() """
226 228
227 229 shell(cmd, header=self.rc.system_header, verbose=self.rc.system_verbose)
228 230
229 231 def show_in_pager(self,s):
230 232 """ Run a string through pager """
231 233 # raising TryNext here will use the default paging functionality
232 234 raise ipapi.TryNext
233 235
234 236 def pre_prompt_hook(self):
235 237 """ Run before displaying the next prompt
236 238
237 239 Use this e.g. to display output from asynchronous operations (in order
238 240 to not mess up text entry)
239 241 """
240 242
241 243 return None
242 244
243 245 def pre_runcode_hook(self):
244 246 """ Executed before running the (prefiltered) code in IPython """
245 247 return None
246 248
247
249 def clipboard_get(self):
250 """ Get text from the clipboard.
251 """
252 from IPython.lib.clipboard import (
253 osx_clipboard_get, tkinter_clipboard_get,
254 win32_clipboard_get
255 )
256 if sys.platform == 'win32':
257 chain = [win32_clipboard_get, tkinter_clipboard_get]
258 elif sys.platform == 'darwin':
259 chain = [osx_clipboard_get, tkinter_clipboard_get]
260 else:
261 chain = [tkinter_clipboard_get]
262 dispatcher = CommandChainDispatcher()
263 for func in chain:
264 dispatcher.add(func)
265 text = dispatcher()
266 return text
@@ -1,2865 +1,2865 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 IPython -- An enhanced Interactive Python
4 4
5 5 Requires Python 2.4 or newer.
6 6
7 7 This file contains all the classes and helper functions specific to IPython.
8 8 """
9 9
10 10 #*****************************************************************************
11 11 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
12 12 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
13 13 #
14 14 # Distributed under the terms of the BSD License. The full license is in
15 15 # the file COPYING, distributed as part of this software.
16 16 #
17 17 # Note: this code originally subclassed code.InteractiveConsole from the
18 18 # Python standard library. Over time, all of that class has been copied
19 19 # verbatim here for modifications which could not be accomplished by
20 20 # subclassing. At this point, there are no dependencies at all on the code
21 21 # module anymore (it is not even imported). The Python License (sec. 2)
22 22 # allows for this, but it's always nice to acknowledge credit where credit is
23 23 # due.
24 24 #*****************************************************************************
25 25
26 26 #****************************************************************************
27 27 # Modules and globals
28 28
29 29 # Python standard modules
30 30 import __main__
31 31 import __builtin__
32 32 import StringIO
33 33 import bdb
34 34 import codeop
35 35 import exceptions
36 36 import glob
37 37 import keyword
38 38 import new
39 39 import os
40 40 import re
41 41 import shutil
42 42 import string
43 43 import sys
44 44 import tempfile
45 45
46 46 # IPython's own modules
47 47 #import IPython
48 48 from IPython.core import ultratb
49 49 from IPython.utils import PyColorize
50 50 from IPython.core import debugger, oinspect
51 51 from IPython.extensions import pickleshare
52 52 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
53 53 from IPython.external.Itpl import ItplNS
54 54 from IPython.core.logger import Logger
55 55 from IPython.core.magic import Magic
56 56 from IPython.core.prompts import CachedOutput
57 57 from IPython.utils.ipstruct import Struct
58 58 from IPython.lib.backgroundjobs import BackgroundJobManager
59 59 from IPython.utils.genutils import *
60 60 from IPython.utils.strdispatch import StrDispatch
61 61 from IPython.core import ipapi
62 62 import IPython.core.history
63 63 import IPython.core.prefilter as prefilter
64 64 from IPython.core import shadowns
65 65 # Globals
66 66
67 67 # store the builtin raw_input globally, and use this always, in case user code
68 68 # overwrites it (like wx.py.PyShell does)
69 69 raw_input_original = raw_input
70 70
71 71 # compiled regexps for autoindent management
72 72 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
73 73
74 74
75 75 #****************************************************************************
76 76 # Some utility function definitions
77 77
78 78 ini_spaces_re = re.compile(r'^(\s+)')
79 79
80 80 def num_ini_spaces(strng):
81 81 """Return the number of initial spaces in a string"""
82 82
83 83 ini_spaces = ini_spaces_re.match(strng)
84 84 if ini_spaces:
85 85 return ini_spaces.end()
86 86 else:
87 87 return 0
88 88
89 89 def softspace(file, newvalue):
90 90 """Copied from code.py, to remove the dependency"""
91 91
92 92 oldvalue = 0
93 93 try:
94 94 oldvalue = file.softspace
95 95 except AttributeError:
96 96 pass
97 97 try:
98 98 file.softspace = newvalue
99 99 except (AttributeError, TypeError):
100 100 # "attribute-less object" or "read-only attributes"
101 101 pass
102 102 return oldvalue
103 103
104 104
105 105 def user_setup(ipythondir,rc_suffix,mode='install',interactive=True):
106 106 """Install or upgrade the user configuration directory.
107 107
108 108 Can be called when running for the first time or to upgrade the user's
109 109 .ipython/ directory.
110 110
111 111 Parameters
112 112 ----------
113 113 ipythondir : path
114 114 The directory to be used for installation/upgrade. In 'install' mode,
115 115 if this path already exists, the function exits immediately.
116 116
117 117 rc_suffix : str
118 118 Extension for the config files. On *nix platforms it is typically the
119 119 empty string, while Windows normally uses '.ini'.
120 120
121 121 mode : str, optional
122 122 Valid modes are 'install' and 'upgrade'.
123 123
124 124 interactive : bool, optional
125 125 If False, do not wait for user input on any errors. Normally after
126 126 printing its status information, this function waits for the user to
127 127 hit Return before proceeding. This is because the default use case is
128 128 when first installing the IPython configuration, so we want the user to
129 129 acknowledge the initial message, which contains some useful
130 130 information.
131 131 """
132 132
133 133 # For automatic use, deactivate all i/o
134 134 if interactive:
135 135 def wait():
136 136 try:
137 137 raw_input("Please press <RETURN> to start IPython.")
138 138 except EOFError:
139 139 print >> Term.cout
140 140 print '*'*70
141 141
142 142 def printf(s):
143 143 print s
144 144 else:
145 145 wait = lambda : None
146 146 printf = lambda s : None
147 147
148 148 # Install mode should be re-entrant: if the install dir already exists,
149 149 # bail out cleanly.
150 150 # XXX. This is too hasty to return. We need to check to make sure that
151 151 # all the expected config files and directories are actually there. We
152 152 # currently have a failure mode if someone deletes a needed config file
153 153 # but still has the ipythondir.
154 154 if mode == 'install' and os.path.isdir(ipythondir):
155 155 return
156 156
157 157 cwd = os.getcwd() # remember where we started
158 158 glb = glob.glob
159 159
160 160 printf('*'*70)
161 161 if mode == 'install':
162 162 printf(
163 163 """Welcome to IPython. I will try to create a personal configuration directory
164 164 where you can customize many aspects of IPython's functionality in:\n""")
165 165 else:
166 166 printf('I am going to upgrade your configuration in:')
167 167
168 168 printf(ipythondir)
169 169
170 170 rcdirend = os.path.join('IPython','config','userconfig')
171 171 cfg = lambda d: os.path.join(d,rcdirend)
172 172 try:
173 173 rcdir = filter(os.path.isdir,map(cfg,sys.path))[0]
174 174 printf("Initializing from configuration: %s" % rcdir)
175 175 except IndexError:
176 176 warning = """
177 177 Installation error. IPython's directory was not found.
178 178
179 179 Check the following:
180 180
181 181 The ipython/IPython directory should be in a directory belonging to your
182 182 PYTHONPATH environment variable (that is, it should be in a directory
183 183 belonging to sys.path). You can copy it explicitly there or just link to it.
184 184
185 185 IPython will create a minimal default configuration for you.
186 186
187 187 """
188 188 warn(warning)
189 189 wait()
190 190
191 191 if sys.platform =='win32':
192 192 inif = 'ipythonrc.ini'
193 193 else:
194 194 inif = 'ipythonrc'
195 195 minimal_setup = {'ipy_user_conf.py' : 'import ipy_defaults',
196 196 inif : '# intentionally left blank' }
197 197 os.makedirs(ipythondir, mode = 0777)
198 198 for f, cont in minimal_setup.items():
199 199 # In 2.5, this can be more cleanly done using 'with'
200 200 fobj = file(ipythondir + '/' + f,'w')
201 201 fobj.write(cont)
202 202 fobj.close()
203 203
204 204 return
205 205
206 206 if mode == 'install':
207 207 try:
208 208 shutil.copytree(rcdir,ipythondir)
209 209 os.chdir(ipythondir)
210 210 rc_files = glb("ipythonrc*")
211 211 for rc_file in rc_files:
212 212 os.rename(rc_file,rc_file+rc_suffix)
213 213 except:
214 214 warning = """
215 215
216 216 There was a problem with the installation:
217 217 %s
218 218 Try to correct it or contact the developers if you think it's a bug.
219 219 IPython will proceed with builtin defaults.""" % sys.exc_info()[1]
220 220 warn(warning)
221 221 wait()
222 222 return
223 223
224 224 elif mode == 'upgrade':
225 225 try:
226 226 os.chdir(ipythondir)
227 227 except:
228 228 printf("""
229 229 Can not upgrade: changing to directory %s failed. Details:
230 230 %s
231 231 """ % (ipythondir,sys.exc_info()[1]) )
232 232 wait()
233 233 return
234 234 else:
235 235 sources = glb(os.path.join(rcdir,'[A-Za-z]*'))
236 236 for new_full_path in sources:
237 237 new_filename = os.path.basename(new_full_path)
238 238 if new_filename.startswith('ipythonrc'):
239 239 new_filename = new_filename + rc_suffix
240 240 # The config directory should only contain files, skip any
241 241 # directories which may be there (like CVS)
242 242 if os.path.isdir(new_full_path):
243 243 continue
244 244 if os.path.exists(new_filename):
245 245 old_file = new_filename+'.old'
246 246 if os.path.exists(old_file):
247 247 os.remove(old_file)
248 248 os.rename(new_filename,old_file)
249 249 shutil.copy(new_full_path,new_filename)
250 250 else:
251 251 raise ValueError('unrecognized mode for install: %r' % mode)
252 252
253 253 # Fix line-endings to those native to each platform in the config
254 254 # directory.
255 255 try:
256 256 os.chdir(ipythondir)
257 257 except:
258 258 printf("""
259 259 Problem: changing to directory %s failed.
260 260 Details:
261 261 %s
262 262
263 263 Some configuration files may have incorrect line endings. This should not
264 264 cause any problems during execution. """ % (ipythondir,sys.exc_info()[1]) )
265 265 wait()
266 266 else:
267 267 for fname in glb('ipythonrc*'):
268 268 try:
269 269 native_line_ends(fname,backup=0)
270 270 except IOError:
271 271 pass
272 272
273 273 if mode == 'install':
274 274 printf("""
275 275 Successful installation!
276 276
277 277 Please read the sections 'Initial Configuration' and 'Quick Tips' in the
278 278 IPython manual (there are both HTML and PDF versions supplied with the
279 279 distribution) to make sure that your system environment is properly configured
280 280 to take advantage of IPython's features.
281 281
282 282 Important note: the configuration system has changed! The old system is
283 283 still in place, but its setting may be partly overridden by the settings in
284 284 "~/.ipython/ipy_user_conf.py" config file. Please take a look at the file
285 285 if some of the new settings bother you.
286 286
287 287 """)
288 288 else:
289 289 printf("""
290 290 Successful upgrade!
291 291
292 292 All files in your directory:
293 293 %(ipythondir)s
294 294 which would have been overwritten by the upgrade were backed up with a .old
295 295 extension. If you had made particular customizations in those files you may
296 296 want to merge them back into the new files.""" % locals() )
297 297 wait()
298 298 os.chdir(cwd)
299 299
300 300 #****************************************************************************
301 301 # Local use exceptions
302 302 class SpaceInInput(exceptions.Exception): pass
303 303
304 304
305 305 #****************************************************************************
306 306 # Local use classes
307 307 class Bunch: pass
308 308
309 309 class Undefined: pass
310 310
311 311 class Quitter(object):
312 312 """Simple class to handle exit, similar to Python 2.5's.
313 313
314 314 It handles exiting in an ipython-safe manner, which the one in Python 2.5
315 315 doesn't do (obviously, since it doesn't know about ipython)."""
316 316
317 317 def __init__(self,shell,name):
318 318 self.shell = shell
319 319 self.name = name
320 320
321 321 def __repr__(self):
322 322 return 'Type %s() to exit.' % self.name
323 323 __str__ = __repr__
324 324
325 325 def __call__(self):
326 326 self.shell.exit()
327 327
328 328 class InputList(list):
329 329 """Class to store user input.
330 330
331 331 It's basically a list, but slices return a string instead of a list, thus
332 332 allowing things like (assuming 'In' is an instance):
333 333
334 334 exec In[4:7]
335 335
336 336 or
337 337
338 338 exec In[5:9] + In[14] + In[21:25]"""
339 339
340 340 def __getslice__(self,i,j):
341 341 return ''.join(list.__getslice__(self,i,j))
342 342
343 343 class SyntaxTB(ultratb.ListTB):
344 344 """Extension which holds some state: the last exception value"""
345 345
346 346 def __init__(self,color_scheme = 'NoColor'):
347 347 ultratb.ListTB.__init__(self,color_scheme)
348 348 self.last_syntax_error = None
349 349
350 350 def __call__(self, etype, value, elist):
351 351 self.last_syntax_error = value
352 352 ultratb.ListTB.__call__(self,etype,value,elist)
353 353
354 354 def clear_err_state(self):
355 355 """Return the current error state and clear it"""
356 356 e = self.last_syntax_error
357 357 self.last_syntax_error = None
358 358 return e
359 359
360 360 #****************************************************************************
361 361 # Main IPython class
362 362
363 363 # FIXME: the Magic class is a mixin for now, and will unfortunately remain so
364 364 # until a full rewrite is made. I've cleaned all cross-class uses of
365 365 # attributes and methods, but too much user code out there relies on the
366 366 # equlity %foo == __IP.magic_foo, so I can't actually remove the mixin usage.
367 367 #
368 368 # But at least now, all the pieces have been separated and we could, in
369 369 # principle, stop using the mixin. This will ease the transition to the
370 370 # chainsaw branch.
371 371
372 372 # For reference, the following is the list of 'self.foo' uses in the Magic
373 373 # class as of 2005-12-28. These are names we CAN'T use in the main ipython
374 374 # class, to prevent clashes.
375 375
376 376 # ['self.__class__', 'self.__dict__', 'self._inspect', 'self._ofind',
377 377 # 'self.arg_err', 'self.extract_input', 'self.format_', 'self.lsmagic',
378 378 # 'self.magic_', 'self.options_table', 'self.parse', 'self.shell',
379 379 # 'self.value']
380 380
381 381 class InteractiveShell(object,Magic):
382 382 """An enhanced console for Python."""
383 383
384 384 # class attribute to indicate whether the class supports threads or not.
385 385 # Subclasses with thread support should override this as needed.
386 386 isthreaded = False
387 387
388 388 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
389 389 user_ns=None,user_global_ns=None,banner2='',
390 390 custom_exceptions=((),None),embedded=False):
391 391
392 392 # log system
393 393 self.logger = Logger(self,logfname='ipython_log.py',logmode='rotate')
394 394
395 395 # Job manager (for jobs run as background threads)
396 396 self.jobs = BackgroundJobManager()
397 397
398 398 # Store the actual shell's name
399 399 self.name = name
400 400 self.more = False
401 401
402 402 # We need to know whether the instance is meant for embedding, since
403 403 # global/local namespaces need to be handled differently in that case
404 404 self.embedded = embedded
405 405 if embedded:
406 406 # Control variable so users can, from within the embedded instance,
407 407 # permanently deactivate it.
408 408 self.embedded_active = True
409 409
410 410 # command compiler
411 411 self.compile = codeop.CommandCompiler()
412 412
413 413 # User input buffer
414 414 self.buffer = []
415 415
416 416 # Default name given in compilation of code
417 417 self.filename = '<ipython console>'
418 418
419 419 # Install our own quitter instead of the builtins. For python2.3-2.4,
420 420 # this brings in behavior like 2.5, and for 2.5 it's identical.
421 421 __builtin__.exit = Quitter(self,'exit')
422 422 __builtin__.quit = Quitter(self,'quit')
423 423
424 424 # Make an empty namespace, which extension writers can rely on both
425 425 # existing and NEVER being used by ipython itself. This gives them a
426 426 # convenient location for storing additional information and state
427 427 # their extensions may require, without fear of collisions with other
428 428 # ipython names that may develop later.
429 429 self.meta = Struct()
430 430
431 431 # Create the namespace where the user will operate. user_ns is
432 432 # normally the only one used, and it is passed to the exec calls as
433 433 # the locals argument. But we do carry a user_global_ns namespace
434 434 # given as the exec 'globals' argument, This is useful in embedding
435 435 # situations where the ipython shell opens in a context where the
436 436 # distinction between locals and globals is meaningful. For
437 437 # non-embedded contexts, it is just the same object as the user_ns dict.
438 438
439 439 # FIXME. For some strange reason, __builtins__ is showing up at user
440 440 # level as a dict instead of a module. This is a manual fix, but I
441 441 # should really track down where the problem is coming from. Alex
442 442 # Schmolck reported this problem first.
443 443
444 444 # A useful post by Alex Martelli on this topic:
445 445 # Re: inconsistent value from __builtins__
446 446 # Von: Alex Martelli <aleaxit@yahoo.com>
447 447 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
448 448 # Gruppen: comp.lang.python
449 449
450 450 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
451 451 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
452 452 # > <type 'dict'>
453 453 # > >>> print type(__builtins__)
454 454 # > <type 'module'>
455 455 # > Is this difference in return value intentional?
456 456
457 457 # Well, it's documented that '__builtins__' can be either a dictionary
458 458 # or a module, and it's been that way for a long time. Whether it's
459 459 # intentional (or sensible), I don't know. In any case, the idea is
460 460 # that if you need to access the built-in namespace directly, you
461 461 # should start with "import __builtin__" (note, no 's') which will
462 462 # definitely give you a module. Yeah, it's somewhat confusing:-(.
463 463
464 464 # These routines return properly built dicts as needed by the rest of
465 465 # the code, and can also be used by extension writers to generate
466 466 # properly initialized namespaces.
467 467 user_ns, user_global_ns = ipapi.make_user_namespaces(user_ns,
468 468 user_global_ns)
469 469
470 470 # Assign namespaces
471 471 # This is the namespace where all normal user variables live
472 472 self.user_ns = user_ns
473 473 self.user_global_ns = user_global_ns
474 474
475 475 # An auxiliary namespace that checks what parts of the user_ns were
476 476 # loaded at startup, so we can list later only variables defined in
477 477 # actual interactive use. Since it is always a subset of user_ns, it
478 478 # doesn't need to be seaparately tracked in the ns_table
479 479 self.user_config_ns = {}
480 480
481 481 # A namespace to keep track of internal data structures to prevent
482 482 # them from cluttering user-visible stuff. Will be updated later
483 483 self.internal_ns = {}
484 484
485 485 # Namespace of system aliases. Each entry in the alias
486 486 # table must be a 2-tuple of the form (N,name), where N is the number
487 487 # of positional arguments of the alias.
488 488 self.alias_table = {}
489 489
490 490 # Now that FakeModule produces a real module, we've run into a nasty
491 491 # problem: after script execution (via %run), the module where the user
492 492 # code ran is deleted. Now that this object is a true module (needed
493 493 # so docetst and other tools work correctly), the Python module
494 494 # teardown mechanism runs over it, and sets to None every variable
495 495 # present in that module. Top-level references to objects from the
496 496 # script survive, because the user_ns is updated with them. However,
497 497 # calling functions defined in the script that use other things from
498 498 # the script will fail, because the function's closure had references
499 499 # to the original objects, which are now all None. So we must protect
500 500 # these modules from deletion by keeping a cache.
501 501 #
502 502 # To avoid keeping stale modules around (we only need the one from the
503 503 # last run), we use a dict keyed with the full path to the script, so
504 504 # only the last version of the module is held in the cache. Note,
505 505 # however, that we must cache the module *namespace contents* (their
506 506 # __dict__). Because if we try to cache the actual modules, old ones
507 507 # (uncached) could be destroyed while still holding references (such as
508 508 # those held by GUI objects that tend to be long-lived)>
509 509 #
510 510 # The %reset command will flush this cache. See the cache_main_mod()
511 511 # and clear_main_mod_cache() methods for details on use.
512 512
513 513 # This is the cache used for 'main' namespaces
514 514 self._main_ns_cache = {}
515 515 # And this is the single instance of FakeModule whose __dict__ we keep
516 516 # copying and clearing for reuse on each %run
517 517 self._user_main_module = FakeModule()
518 518
519 519 # A table holding all the namespaces IPython deals with, so that
520 520 # introspection facilities can search easily.
521 521 self.ns_table = {'user':user_ns,
522 522 'user_global':user_global_ns,
523 523 'alias':self.alias_table,
524 524 'internal':self.internal_ns,
525 525 'builtin':__builtin__.__dict__
526 526 }
527 527
528 528 # Similarly, track all namespaces where references can be held and that
529 529 # we can safely clear (so it can NOT include builtin). This one can be
530 530 # a simple list.
531 531 self.ns_refs_table = [ user_ns, user_global_ns, self.user_config_ns,
532 532 self.alias_table, self.internal_ns,
533 533 self._main_ns_cache ]
534 534
535 535 # We need to insert into sys.modules something that looks like a
536 536 # module but which accesses the IPython namespace, for shelve and
537 537 # pickle to work interactively. Normally they rely on getting
538 538 # everything out of __main__, but for embedding purposes each IPython
539 539 # instance has its own private namespace, so we can't go shoving
540 540 # everything into __main__.
541 541
542 542 # note, however, that we should only do this for non-embedded
543 543 # ipythons, which really mimic the __main__.__dict__ with their own
544 544 # namespace. Embedded instances, on the other hand, should not do
545 545 # this because they need to manage the user local/global namespaces
546 546 # only, but they live within a 'normal' __main__ (meaning, they
547 547 # shouldn't overtake the execution environment of the script they're
548 548 # embedded in).
549 549
550 550 if not embedded:
551 551 try:
552 552 main_name = self.user_ns['__name__']
553 553 except KeyError:
554 554 raise KeyError,'user_ns dictionary MUST have a "__name__" key'
555 555 else:
556 556 #print "pickle hack in place" # dbg
557 557 #print 'main_name:',main_name # dbg
558 558 sys.modules[main_name] = FakeModule(self.user_ns)
559 559
560 560 # List of input with multi-line handling.
561 561 self.input_hist = InputList()
562 562 # This one will hold the 'raw' input history, without any
563 563 # pre-processing. This will allow users to retrieve the input just as
564 564 # it was exactly typed in by the user, with %hist -r.
565 565 self.input_hist_raw = InputList()
566 566
567 567 # list of visited directories
568 568 try:
569 569 self.dir_hist = [os.getcwd()]
570 570 except OSError:
571 571 self.dir_hist = []
572 572
573 573 # dict of output history
574 574 self.output_hist = {}
575 575
576 576 # Get system encoding at startup time. Certain terminals (like Emacs
577 577 # under Win32 have it set to None, and we need to have a known valid
578 578 # encoding to use in the raw_input() method
579 579 try:
580 580 self.stdin_encoding = sys.stdin.encoding or 'ascii'
581 581 except AttributeError:
582 582 self.stdin_encoding = 'ascii'
583 583
584 584 # dict of things NOT to alias (keywords, builtins and some magics)
585 585 no_alias = {}
586 586 no_alias_magics = ['cd','popd','pushd','dhist','alias','unalias']
587 587 for key in keyword.kwlist + no_alias_magics:
588 588 no_alias[key] = 1
589 589 no_alias.update(__builtin__.__dict__)
590 590 self.no_alias = no_alias
591 591
592 592 # Object variable to store code object waiting execution. This is
593 593 # used mainly by the multithreaded shells, but it can come in handy in
594 594 # other situations. No need to use a Queue here, since it's a single
595 595 # item which gets cleared once run.
596 596 self.code_to_run = None
597 597
598 598 # escapes for automatic behavior on the command line
599 599 self.ESC_SHELL = '!'
600 600 self.ESC_SH_CAP = '!!'
601 601 self.ESC_HELP = '?'
602 602 self.ESC_MAGIC = '%'
603 603 self.ESC_QUOTE = ','
604 604 self.ESC_QUOTE2 = ';'
605 605 self.ESC_PAREN = '/'
606 606
607 607 # And their associated handlers
608 608 self.esc_handlers = {self.ESC_PAREN : self.handle_auto,
609 609 self.ESC_QUOTE : self.handle_auto,
610 610 self.ESC_QUOTE2 : self.handle_auto,
611 611 self.ESC_MAGIC : self.handle_magic,
612 612 self.ESC_HELP : self.handle_help,
613 613 self.ESC_SHELL : self.handle_shell_escape,
614 614 self.ESC_SH_CAP : self.handle_shell_escape,
615 615 }
616 616
617 617 # class initializations
618 618 Magic.__init__(self,self)
619 619
620 620 # Python source parser/formatter for syntax highlighting
621 621 pyformat = PyColorize.Parser().format
622 622 self.pycolorize = lambda src: pyformat(src,'str',self.rc['colors'])
623 623
624 624 # hooks holds pointers used for user-side customizations
625 625 self.hooks = Struct()
626 626
627 627 self.strdispatchers = {}
628 628
629 629 # Set all default hooks, defined in the IPython.hooks module.
630 630 import IPython.core.hooks
631 631 hooks = IPython.core.hooks
632 632 for hook_name in hooks.__all__:
633 633 # default hooks have priority 100, i.e. low; user hooks should have
634 634 # 0-100 priority
635 635 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
636 636 #print "bound hook",hook_name
637 637
638 638 # Flag to mark unconditional exit
639 639 self.exit_now = False
640 640
641 641 self.usage_min = """\
642 642 An enhanced console for Python.
643 643 Some of its features are:
644 644 - Readline support if the readline library is present.
645 645 - Tab completion in the local namespace.
646 646 - Logging of input, see command-line options.
647 647 - System shell escape via ! , eg !ls.
648 648 - Magic commands, starting with a % (like %ls, %pwd, %cd, etc.)
649 649 - Keeps track of locally defined variables via %who, %whos.
650 650 - Show object information with a ? eg ?x or x? (use ?? for more info).
651 651 """
652 652 if usage: self.usage = usage
653 653 else: self.usage = self.usage_min
654 654
655 655 # Storage
656 656 self.rc = rc # This will hold all configuration information
657 657 self.pager = 'less'
658 658 # temporary files used for various purposes. Deleted at exit.
659 659 self.tempfiles = []
660 660
661 661 # Keep track of readline usage (later set by init_readline)
662 662 self.has_readline = False
663 663
664 664 # template for logfile headers. It gets resolved at runtime by the
665 665 # logstart method.
666 666 self.loghead_tpl = \
667 667 """#log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE ***
668 668 #log# DO NOT CHANGE THIS LINE OR THE TWO BELOW
669 669 #log# opts = %s
670 670 #log# args = %s
671 671 #log# It is safe to make manual edits below here.
672 672 #log#-----------------------------------------------------------------------
673 673 """
674 674 # for pushd/popd management
675 675 try:
676 676 self.home_dir = get_home_dir()
677 677 except HomeDirError,msg:
678 678 fatal(msg)
679 679
680 680 self.dir_stack = []
681 681
682 682 # Functions to call the underlying shell.
683 683
684 684 # The first is similar to os.system, but it doesn't return a value,
685 685 # and it allows interpolation of variables in the user's namespace.
686 686 self.system = lambda cmd: \
687 687 self.hooks.shell_hook(self.var_expand(cmd,depth=2))
688 688
689 689 # These are for getoutput and getoutputerror:
690 690 self.getoutput = lambda cmd: \
691 691 getoutput(self.var_expand(cmd,depth=2),
692 692 header=self.rc.system_header,
693 693 verbose=self.rc.system_verbose)
694 694
695 695 self.getoutputerror = lambda cmd: \
696 696 getoutputerror(self.var_expand(cmd,depth=2),
697 697 header=self.rc.system_header,
698 698 verbose=self.rc.system_verbose)
699 699
700 700
701 701 # keep track of where we started running (mainly for crash post-mortem)
702 702 self.starting_dir = os.getcwd()
703 703
704 704 # Various switches which can be set
705 705 self.CACHELENGTH = 5000 # this is cheap, it's just text
706 706 self.BANNER = "Python %(version)s on %(platform)s\n" % sys.__dict__
707 707 self.banner2 = banner2
708 708
709 709 # TraceBack handlers:
710 710
711 711 # Syntax error handler.
712 712 self.SyntaxTB = SyntaxTB(color_scheme='NoColor')
713 713
714 714 # The interactive one is initialized with an offset, meaning we always
715 715 # want to remove the topmost item in the traceback, which is our own
716 716 # internal code. Valid modes: ['Plain','Context','Verbose']
717 717 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
718 718 color_scheme='NoColor',
719 719 tb_offset = 1)
720 720
721 721 # IPython itself shouldn't crash. This will produce a detailed
722 722 # post-mortem if it does. But we only install the crash handler for
723 723 # non-threaded shells, the threaded ones use a normal verbose reporter
724 724 # and lose the crash handler. This is because exceptions in the main
725 725 # thread (such as in GUI code) propagate directly to sys.excepthook,
726 726 # and there's no point in printing crash dumps for every user exception.
727 727 if self.isthreaded:
728 728 ipCrashHandler = ultratb.FormattedTB()
729 729 else:
730 730 from IPython.core import crashhandler
731 731 ipCrashHandler = crashhandler.IPythonCrashHandler(self)
732 732 self.set_crash_handler(ipCrashHandler)
733 733
734 734 # and add any custom exception handlers the user may have specified
735 735 self.set_custom_exc(*custom_exceptions)
736 736
737 737 # indentation management
738 738 self.autoindent = False
739 739 self.indent_current_nsp = 0
740 740
741 741 # Make some aliases automatically
742 742 # Prepare list of shell aliases to auto-define
743 743 if os.name == 'posix':
744 744 auto_alias = ('mkdir mkdir', 'rmdir rmdir',
745 745 'mv mv -i','rm rm -i','cp cp -i',
746 746 'cat cat','less less','clear clear',
747 747 # a better ls
748 748 'ls ls -F',
749 749 # long ls
750 750 'll ls -lF')
751 751 # Extra ls aliases with color, which need special treatment on BSD
752 752 # variants
753 753 ls_extra = ( # color ls
754 754 'lc ls -F -o --color',
755 755 # ls normal files only
756 756 'lf ls -F -o --color %l | grep ^-',
757 757 # ls symbolic links
758 758 'lk ls -F -o --color %l | grep ^l',
759 759 # directories or links to directories,
760 760 'ldir ls -F -o --color %l | grep /$',
761 761 # things which are executable
762 762 'lx ls -F -o --color %l | grep ^-..x',
763 763 )
764 764 # The BSDs don't ship GNU ls, so they don't understand the
765 765 # --color switch out of the box
766 766 if 'bsd' in sys.platform:
767 767 ls_extra = ( # ls normal files only
768 768 'lf ls -lF | grep ^-',
769 769 # ls symbolic links
770 770 'lk ls -lF | grep ^l',
771 771 # directories or links to directories,
772 772 'ldir ls -lF | grep /$',
773 773 # things which are executable
774 774 'lx ls -lF | grep ^-..x',
775 775 )
776 776 auto_alias = auto_alias + ls_extra
777 777 elif os.name in ['nt','dos']:
778 778 auto_alias = ('ls dir /on',
779 779 'ddir dir /ad /on', 'ldir dir /ad /on',
780 780 'mkdir mkdir','rmdir rmdir','echo echo',
781 781 'ren ren','cls cls','copy copy')
782 782 else:
783 783 auto_alias = ()
784 784 self.auto_alias = [s.split(None,1) for s in auto_alias]
785 785
786 786 # Produce a public API instance
787 787 self.api = ipapi.IPApi(self)
788 788
789 789 # Initialize all user-visible namespaces
790 790 self.init_namespaces()
791 791
792 792 # Call the actual (public) initializer
793 793 self.init_auto_alias()
794 794
795 795 # track which builtins we add, so we can clean up later
796 796 self.builtins_added = {}
797 797 # This method will add the necessary builtins for operation, but
798 798 # tracking what it did via the builtins_added dict.
799 799
800 800 #TODO: remove this, redundant
801 801 self.add_builtins()
802 802 # end __init__
803 803
804 804 def var_expand(self,cmd,depth=0):
805 805 """Expand python variables in a string.
806 806
807 807 The depth argument indicates how many frames above the caller should
808 808 be walked to look for the local namespace where to expand variables.
809 809
810 810 The global namespace for expansion is always the user's interactive
811 811 namespace.
812 812 """
813 813
814 814 return str(ItplNS(cmd,
815 815 self.user_ns, # globals
816 816 # Skip our own frame in searching for locals:
817 817 sys._getframe(depth+1).f_locals # locals
818 818 ))
819 819
820 820 def pre_config_initialization(self):
821 821 """Pre-configuration init method
822 822
823 823 This is called before the configuration files are processed to
824 824 prepare the services the config files might need.
825 825
826 826 self.rc already has reasonable default values at this point.
827 827 """
828 828 rc = self.rc
829 829 try:
830 830 self.db = pickleshare.PickleShareDB(rc.ipythondir + "/db")
831 831 except exceptions.UnicodeDecodeError:
832 832 print "Your ipythondir can't be decoded to unicode!"
833 833 print "Please set HOME environment variable to something that"
834 834 print r"only has ASCII characters, e.g. c:\home"
835 835 print "Now it is",rc.ipythondir
836 836 sys.exit()
837 837 self.shadowhist = IPython.core.history.ShadowHist(self.db)
838 838
839 839 def post_config_initialization(self):
840 840 """Post configuration init method
841 841
842 842 This is called after the configuration files have been processed to
843 843 'finalize' the initialization."""
844 844
845 845 rc = self.rc
846 846
847 847 # Object inspector
848 848 self.inspector = oinspect.Inspector(oinspect.InspectColors,
849 849 PyColorize.ANSICodeColors,
850 850 'NoColor',
851 851 rc.object_info_string_level)
852 852
853 853 self.rl_next_input = None
854 854 self.rl_do_indent = False
855 855 # Load readline proper
856 856 if rc.readline:
857 857 self.init_readline()
858 858
859 859 # local shortcut, this is used a LOT
860 860 self.log = self.logger.log
861 861
862 862 # Initialize cache, set in/out prompts and printing system
863 863 self.outputcache = CachedOutput(self,
864 864 rc.cache_size,
865 865 rc.pprint,
866 866 input_sep = rc.separate_in,
867 867 output_sep = rc.separate_out,
868 868 output_sep2 = rc.separate_out2,
869 869 ps1 = rc.prompt_in1,
870 870 ps2 = rc.prompt_in2,
871 871 ps_out = rc.prompt_out,
872 872 pad_left = rc.prompts_pad_left)
873 873
874 874 # user may have over-ridden the default print hook:
875 875 try:
876 876 self.outputcache.__class__.display = self.hooks.display
877 877 except AttributeError:
878 878 pass
879 879
880 880 # I don't like assigning globally to sys, because it means when
881 881 # embedding instances, each embedded instance overrides the previous
882 882 # choice. But sys.displayhook seems to be called internally by exec,
883 883 # so I don't see a way around it. We first save the original and then
884 884 # overwrite it.
885 885 self.sys_displayhook = sys.displayhook
886 886 sys.displayhook = self.outputcache
887 887
888 888 # Do a proper resetting of doctest, including the necessary displayhook
889 889 # monkeypatching
890 890 try:
891 891 doctest_reload()
892 892 except ImportError:
893 893 warn("doctest module does not exist.")
894 894
895 895 # Set user colors (don't do it in the constructor above so that it
896 896 # doesn't crash if colors option is invalid)
897 897 self.magic_colors(rc.colors)
898 898
899 899 # Set calling of pdb on exceptions
900 900 self.call_pdb = rc.pdb
901 901
902 902 # Load user aliases
903 903 for alias in rc.alias:
904 904 self.magic_alias(alias)
905 905
906 906 self.hooks.late_startup_hook()
907 907
908 908 for cmd in self.rc.autoexec:
909 909 #print "autoexec>",cmd #dbg
910 910 self.api.runlines(cmd)
911 911
912 912 batchrun = False
913 913 for batchfile in [path(arg) for arg in self.rc.args
914 914 if arg.lower().endswith('.ipy')]:
915 915 if not batchfile.isfile():
916 916 print "No such batch file:", batchfile
917 917 continue
918 918 self.api.runlines(batchfile.text())
919 919 batchrun = True
920 920 # without -i option, exit after running the batch file
921 921 if batchrun and not self.rc.interact:
922 922 self.ask_exit()
923 923
924 924 def init_namespaces(self):
925 925 """Initialize all user-visible namespaces to their minimum defaults.
926 926
927 927 Certain history lists are also initialized here, as they effectively
928 928 act as user namespaces.
929 929
930 Note
931 ----
930 Notes
931 -----
932 932 All data structures here are only filled in, they are NOT reset by this
933 933 method. If they were not empty before, data will simply be added to
934 934 therm.
935 935 """
936 936 # The user namespace MUST have a pointer to the shell itself.
937 937 self.user_ns[self.name] = self
938 938
939 939 # Store the public api instance
940 940 self.user_ns['_ip'] = self.api
941 941
942 942 # make global variables for user access to the histories
943 943 self.user_ns['_ih'] = self.input_hist
944 944 self.user_ns['_oh'] = self.output_hist
945 945 self.user_ns['_dh'] = self.dir_hist
946 946
947 947 # user aliases to input and output histories
948 948 self.user_ns['In'] = self.input_hist
949 949 self.user_ns['Out'] = self.output_hist
950 950
951 951 self.user_ns['_sh'] = shadowns
952 952
953 953 # Fill the history zero entry, user counter starts at 1
954 954 self.input_hist.append('\n')
955 955 self.input_hist_raw.append('\n')
956 956
957 957 def add_builtins(self):
958 958 """Store ipython references into the builtin namespace.
959 959
960 960 Some parts of ipython operate via builtins injected here, which hold a
961 961 reference to IPython itself."""
962 962
963 963 # TODO: deprecate all of these, they are unsafe
964 964 builtins_new = dict(__IPYTHON__ = self,
965 965 ip_set_hook = self.set_hook,
966 966 jobs = self.jobs,
967 967 ipmagic = wrap_deprecated(self.ipmagic,'_ip.magic()'),
968 968 ipalias = wrap_deprecated(self.ipalias),
969 969 ipsystem = wrap_deprecated(self.ipsystem,'_ip.system()'),
970 970 #_ip = self.api
971 971 )
972 972 for biname,bival in builtins_new.items():
973 973 try:
974 974 # store the orignal value so we can restore it
975 975 self.builtins_added[biname] = __builtin__.__dict__[biname]
976 976 except KeyError:
977 977 # or mark that it wasn't defined, and we'll just delete it at
978 978 # cleanup
979 979 self.builtins_added[biname] = Undefined
980 980 __builtin__.__dict__[biname] = bival
981 981
982 982 # Keep in the builtins a flag for when IPython is active. We set it
983 983 # with setdefault so that multiple nested IPythons don't clobber one
984 984 # another. Each will increase its value by one upon being activated,
985 985 # which also gives us a way to determine the nesting level.
986 986 __builtin__.__dict__.setdefault('__IPYTHON__active',0)
987 987
988 988 def clean_builtins(self):
989 989 """Remove any builtins which might have been added by add_builtins, or
990 990 restore overwritten ones to their previous values."""
991 991 for biname,bival in self.builtins_added.items():
992 992 if bival is Undefined:
993 993 del __builtin__.__dict__[biname]
994 994 else:
995 995 __builtin__.__dict__[biname] = bival
996 996 self.builtins_added.clear()
997 997
998 998 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
999 999 """set_hook(name,hook) -> sets an internal IPython hook.
1000 1000
1001 1001 IPython exposes some of its internal API as user-modifiable hooks. By
1002 1002 adding your function to one of these hooks, you can modify IPython's
1003 1003 behavior to call at runtime your own routines."""
1004 1004
1005 1005 # At some point in the future, this should validate the hook before it
1006 1006 # accepts it. Probably at least check that the hook takes the number
1007 1007 # of args it's supposed to.
1008 1008
1009 1009 f = new.instancemethod(hook,self,self.__class__)
1010 1010
1011 1011 # check if the hook is for strdispatcher first
1012 1012 if str_key is not None:
1013 1013 sdp = self.strdispatchers.get(name, StrDispatch())
1014 1014 sdp.add_s(str_key, f, priority )
1015 1015 self.strdispatchers[name] = sdp
1016 1016 return
1017 1017 if re_key is not None:
1018 1018 sdp = self.strdispatchers.get(name, StrDispatch())
1019 1019 sdp.add_re(re.compile(re_key), f, priority )
1020 1020 self.strdispatchers[name] = sdp
1021 1021 return
1022 1022
1023 1023 dp = getattr(self.hooks, name, None)
1024 1024 if name not in IPython.core.hooks.__all__:
1025 1025 print "Warning! Hook '%s' is not one of %s" % (name, IPython.core.hooks.__all__ )
1026 1026 if not dp:
1027 1027 dp = IPython.core.hooks.CommandChainDispatcher()
1028 1028
1029 1029 try:
1030 1030 dp.add(f,priority)
1031 1031 except AttributeError:
1032 1032 # it was not commandchain, plain old func - replace
1033 1033 dp = f
1034 1034
1035 1035 setattr(self.hooks,name, dp)
1036 1036
1037 1037
1038 1038 #setattr(self.hooks,name,new.instancemethod(hook,self,self.__class__))
1039 1039
1040 1040 def set_crash_handler(self,crashHandler):
1041 1041 """Set the IPython crash handler.
1042 1042
1043 1043 This must be a callable with a signature suitable for use as
1044 1044 sys.excepthook."""
1045 1045
1046 1046 # Install the given crash handler as the Python exception hook
1047 1047 sys.excepthook = crashHandler
1048 1048
1049 1049 # The instance will store a pointer to this, so that runtime code
1050 1050 # (such as magics) can access it. This is because during the
1051 1051 # read-eval loop, it gets temporarily overwritten (to deal with GUI
1052 1052 # frameworks).
1053 1053 self.sys_excepthook = sys.excepthook
1054 1054
1055 1055
1056 1056 def set_custom_exc(self,exc_tuple,handler):
1057 1057 """set_custom_exc(exc_tuple,handler)
1058 1058
1059 1059 Set a custom exception handler, which will be called if any of the
1060 1060 exceptions in exc_tuple occur in the mainloop (specifically, in the
1061 1061 runcode() method.
1062 1062
1063 1063 Inputs:
1064 1064
1065 1065 - exc_tuple: a *tuple* of valid exceptions to call the defined
1066 1066 handler for. It is very important that you use a tuple, and NOT A
1067 1067 LIST here, because of the way Python's except statement works. If
1068 1068 you only want to trap a single exception, use a singleton tuple:
1069 1069
1070 1070 exc_tuple == (MyCustomException,)
1071 1071
1072 1072 - handler: this must be defined as a function with the following
1073 1073 basic interface: def my_handler(self,etype,value,tb).
1074 1074
1075 1075 This will be made into an instance method (via new.instancemethod)
1076 1076 of IPython itself, and it will be called if any of the exceptions
1077 1077 listed in the exc_tuple are caught. If the handler is None, an
1078 1078 internal basic one is used, which just prints basic info.
1079 1079
1080 1080 WARNING: by putting in your own exception handler into IPython's main
1081 1081 execution loop, you run a very good chance of nasty crashes. This
1082 1082 facility should only be used if you really know what you are doing."""
1083 1083
1084 1084 assert type(exc_tuple)==type(()) , \
1085 1085 "The custom exceptions must be given AS A TUPLE."
1086 1086
1087 1087 def dummy_handler(self,etype,value,tb):
1088 1088 print '*** Simple custom exception handler ***'
1089 1089 print 'Exception type :',etype
1090 1090 print 'Exception value:',value
1091 1091 print 'Traceback :',tb
1092 1092 print 'Source code :','\n'.join(self.buffer)
1093 1093
1094 1094 if handler is None: handler = dummy_handler
1095 1095
1096 1096 self.CustomTB = new.instancemethod(handler,self,self.__class__)
1097 1097 self.custom_exceptions = exc_tuple
1098 1098
1099 1099 def set_custom_completer(self,completer,pos=0):
1100 1100 """set_custom_completer(completer,pos=0)
1101 1101
1102 1102 Adds a new custom completer function.
1103 1103
1104 1104 The position argument (defaults to 0) is the index in the completers
1105 1105 list where you want the completer to be inserted."""
1106 1106
1107 1107 newcomp = new.instancemethod(completer,self.Completer,
1108 1108 self.Completer.__class__)
1109 1109 self.Completer.matchers.insert(pos,newcomp)
1110 1110
1111 1111 def set_completer(self):
1112 1112 """reset readline's completer to be our own."""
1113 1113 self.readline.set_completer(self.Completer.complete)
1114 1114
1115 1115 def _get_call_pdb(self):
1116 1116 return self._call_pdb
1117 1117
1118 1118 def _set_call_pdb(self,val):
1119 1119
1120 1120 if val not in (0,1,False,True):
1121 1121 raise ValueError,'new call_pdb value must be boolean'
1122 1122
1123 1123 # store value in instance
1124 1124 self._call_pdb = val
1125 1125
1126 1126 # notify the actual exception handlers
1127 1127 self.InteractiveTB.call_pdb = val
1128 1128 if self.isthreaded:
1129 1129 try:
1130 1130 self.sys_excepthook.call_pdb = val
1131 1131 except:
1132 1132 warn('Failed to activate pdb for threaded exception handler')
1133 1133
1134 1134 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
1135 1135 'Control auto-activation of pdb at exceptions')
1136 1136
1137 1137 # These special functions get installed in the builtin namespace, to
1138 1138 # provide programmatic (pure python) access to magics, aliases and system
1139 1139 # calls. This is important for logging, user scripting, and more.
1140 1140
1141 1141 # We are basically exposing, via normal python functions, the three
1142 1142 # mechanisms in which ipython offers special call modes (magics for
1143 1143 # internal control, aliases for direct system access via pre-selected
1144 1144 # names, and !cmd for calling arbitrary system commands).
1145 1145
1146 1146 def ipmagic(self,arg_s):
1147 1147 """Call a magic function by name.
1148 1148
1149 1149 Input: a string containing the name of the magic function to call and any
1150 1150 additional arguments to be passed to the magic.
1151 1151
1152 1152 ipmagic('name -opt foo bar') is equivalent to typing at the ipython
1153 1153 prompt:
1154 1154
1155 1155 In[1]: %name -opt foo bar
1156 1156
1157 1157 To call a magic without arguments, simply use ipmagic('name').
1158 1158
1159 1159 This provides a proper Python function to call IPython's magics in any
1160 1160 valid Python code you can type at the interpreter, including loops and
1161 1161 compound statements. It is added by IPython to the Python builtin
1162 1162 namespace upon initialization."""
1163 1163
1164 1164 args = arg_s.split(' ',1)
1165 1165 magic_name = args[0]
1166 1166 magic_name = magic_name.lstrip(self.ESC_MAGIC)
1167 1167
1168 1168 try:
1169 1169 magic_args = args[1]
1170 1170 except IndexError:
1171 1171 magic_args = ''
1172 1172 fn = getattr(self,'magic_'+magic_name,None)
1173 1173 if fn is None:
1174 1174 error("Magic function `%s` not found." % magic_name)
1175 1175 else:
1176 1176 magic_args = self.var_expand(magic_args,1)
1177 1177 return fn(magic_args)
1178 1178
1179 1179 def ipalias(self,arg_s):
1180 1180 """Call an alias by name.
1181 1181
1182 1182 Input: a string containing the name of the alias to call and any
1183 1183 additional arguments to be passed to the magic.
1184 1184
1185 1185 ipalias('name -opt foo bar') is equivalent to typing at the ipython
1186 1186 prompt:
1187 1187
1188 1188 In[1]: name -opt foo bar
1189 1189
1190 1190 To call an alias without arguments, simply use ipalias('name').
1191 1191
1192 1192 This provides a proper Python function to call IPython's aliases in any
1193 1193 valid Python code you can type at the interpreter, including loops and
1194 1194 compound statements. It is added by IPython to the Python builtin
1195 1195 namespace upon initialization."""
1196 1196
1197 1197 args = arg_s.split(' ',1)
1198 1198 alias_name = args[0]
1199 1199 try:
1200 1200 alias_args = args[1]
1201 1201 except IndexError:
1202 1202 alias_args = ''
1203 1203 if alias_name in self.alias_table:
1204 1204 self.call_alias(alias_name,alias_args)
1205 1205 else:
1206 1206 error("Alias `%s` not found." % alias_name)
1207 1207
1208 1208 def ipsystem(self,arg_s):
1209 1209 """Make a system call, using IPython."""
1210 1210
1211 1211 self.system(arg_s)
1212 1212
1213 1213 def complete(self,text):
1214 1214 """Return a sorted list of all possible completions on text.
1215 1215
1216 1216 Inputs:
1217 1217
1218 1218 - text: a string of text to be completed on.
1219 1219
1220 1220 This is a wrapper around the completion mechanism, similar to what
1221 1221 readline does at the command line when the TAB key is hit. By
1222 1222 exposing it as a method, it can be used by other non-readline
1223 1223 environments (such as GUIs) for text completion.
1224 1224
1225 1225 Simple usage example:
1226 1226
1227 1227 In [7]: x = 'hello'
1228 1228
1229 1229 In [8]: x
1230 1230 Out[8]: 'hello'
1231 1231
1232 1232 In [9]: print x
1233 1233 hello
1234 1234
1235 1235 In [10]: _ip.IP.complete('x.l')
1236 1236 Out[10]: ['x.ljust', 'x.lower', 'x.lstrip']
1237 1237 """
1238 1238
1239 1239 complete = self.Completer.complete
1240 1240 state = 0
1241 1241 # use a dict so we get unique keys, since ipyhton's multiple
1242 1242 # completers can return duplicates. When we make 2.4 a requirement,
1243 1243 # start using sets instead, which are faster.
1244 1244 comps = {}
1245 1245 while True:
1246 1246 newcomp = complete(text,state,line_buffer=text)
1247 1247 if newcomp is None:
1248 1248 break
1249 1249 comps[newcomp] = 1
1250 1250 state += 1
1251 1251 outcomps = comps.keys()
1252 1252 outcomps.sort()
1253 1253 #print "T:",text,"OC:",outcomps # dbg
1254 1254 #print "vars:",self.user_ns.keys()
1255 1255 return outcomps
1256 1256
1257 1257 def set_completer_frame(self, frame=None):
1258 1258 if frame:
1259 1259 self.Completer.namespace = frame.f_locals
1260 1260 self.Completer.global_namespace = frame.f_globals
1261 1261 else:
1262 1262 self.Completer.namespace = self.user_ns
1263 1263 self.Completer.global_namespace = self.user_global_ns
1264 1264
1265 1265 def init_auto_alias(self):
1266 1266 """Define some aliases automatically.
1267 1267
1268 1268 These are ALL parameter-less aliases"""
1269 1269
1270 1270 for alias,cmd in self.auto_alias:
1271 1271 self.getapi().defalias(alias,cmd)
1272 1272
1273 1273
1274 1274 def alias_table_validate(self,verbose=0):
1275 1275 """Update information about the alias table.
1276 1276
1277 1277 In particular, make sure no Python keywords/builtins are in it."""
1278 1278
1279 1279 no_alias = self.no_alias
1280 1280 for k in self.alias_table.keys():
1281 1281 if k in no_alias:
1282 1282 del self.alias_table[k]
1283 1283 if verbose:
1284 1284 print ("Deleting alias <%s>, it's a Python "
1285 1285 "keyword or builtin." % k)
1286 1286
1287 1287 def set_autoindent(self,value=None):
1288 1288 """Set the autoindent flag, checking for readline support.
1289 1289
1290 1290 If called with no arguments, it acts as a toggle."""
1291 1291
1292 1292 if not self.has_readline:
1293 1293 if os.name == 'posix':
1294 1294 warn("The auto-indent feature requires the readline library")
1295 1295 self.autoindent = 0
1296 1296 return
1297 1297 if value is None:
1298 1298 self.autoindent = not self.autoindent
1299 1299 else:
1300 1300 self.autoindent = value
1301 1301
1302 1302 def rc_set_toggle(self,rc_field,value=None):
1303 1303 """Set or toggle a field in IPython's rc config. structure.
1304 1304
1305 1305 If called with no arguments, it acts as a toggle.
1306 1306
1307 1307 If called with a non-existent field, the resulting AttributeError
1308 1308 exception will propagate out."""
1309 1309
1310 1310 rc_val = getattr(self.rc,rc_field)
1311 1311 if value is None:
1312 1312 value = not rc_val
1313 1313 setattr(self.rc,rc_field,value)
1314 1314
1315 1315 def user_setup(self,ipythondir,rc_suffix,mode='install'):
1316 1316 """Install the user configuration directory.
1317 1317
1318 Note
1319 ----
1318 Notes
1319 -----
1320 1320 DEPRECATED: use the top-level user_setup() function instead.
1321 1321 """
1322 1322 return user_setup(ipythondir,rc_suffix,mode)
1323 1323
1324 1324 def atexit_operations(self):
1325 1325 """This will be executed at the time of exit.
1326 1326
1327 1327 Saving of persistent data should be performed here. """
1328 1328
1329 1329 #print '*** IPython exit cleanup ***' # dbg
1330 1330 # input history
1331 1331 self.savehist()
1332 1332
1333 1333 # Cleanup all tempfiles left around
1334 1334 for tfile in self.tempfiles:
1335 1335 try:
1336 1336 os.unlink(tfile)
1337 1337 except OSError:
1338 1338 pass
1339 1339
1340 1340 # Clear all user namespaces to release all references cleanly.
1341 1341 self.reset()
1342 1342
1343 1343 # Run user hooks
1344 1344 self.hooks.shutdown_hook()
1345 1345
1346 1346 def reset(self):
1347 1347 """Clear all internal namespaces.
1348 1348
1349 1349 Note that this is much more aggressive than %reset, since it clears
1350 1350 fully all namespaces, as well as all input/output lists.
1351 1351 """
1352 1352 for ns in self.ns_refs_table:
1353 1353 ns.clear()
1354 1354
1355 1355 # Clear input and output histories
1356 1356 self.input_hist[:] = []
1357 1357 self.input_hist_raw[:] = []
1358 1358 self.output_hist.clear()
1359 1359 # Restore the user namespaces to minimal usability
1360 1360 self.init_namespaces()
1361 1361
1362 1362 def savehist(self):
1363 1363 """Save input history to a file (via readline library)."""
1364 1364
1365 1365 if not self.has_readline:
1366 1366 return
1367 1367
1368 1368 try:
1369 1369 self.readline.write_history_file(self.histfile)
1370 1370 except:
1371 1371 print 'Unable to save IPython command history to file: ' + \
1372 1372 `self.histfile`
1373 1373
1374 1374 def reloadhist(self):
1375 1375 """Reload the input history from disk file."""
1376 1376
1377 1377 if self.has_readline:
1378 1378 try:
1379 1379 self.readline.clear_history()
1380 1380 self.readline.read_history_file(self.shell.histfile)
1381 1381 except AttributeError:
1382 1382 pass
1383 1383
1384 1384
1385 1385 def history_saving_wrapper(self, func):
1386 1386 """ Wrap func for readline history saving
1387 1387
1388 1388 Convert func into callable that saves & restores
1389 1389 history around the call """
1390 1390
1391 1391 if not self.has_readline:
1392 1392 return func
1393 1393
1394 1394 def wrapper():
1395 1395 self.savehist()
1396 1396 try:
1397 1397 func()
1398 1398 finally:
1399 1399 readline.read_history_file(self.histfile)
1400 1400 return wrapper
1401 1401
1402 1402 def pre_readline(self):
1403 1403 """readline hook to be used at the start of each line.
1404 1404
1405 1405 Currently it handles auto-indent only."""
1406 1406
1407 1407 #debugx('self.indent_current_nsp','pre_readline:')
1408 1408
1409 1409 if self.rl_do_indent:
1410 1410 self.readline.insert_text(self.indent_current_str())
1411 1411 if self.rl_next_input is not None:
1412 1412 self.readline.insert_text(self.rl_next_input)
1413 1413 self.rl_next_input = None
1414 1414
1415 1415 def init_readline(self):
1416 1416 """Command history completion/saving/reloading."""
1417 1417
1418 1418
1419 1419 import IPython.utils.rlineimpl as readline
1420 1420
1421 1421 if not readline.have_readline:
1422 1422 self.has_readline = 0
1423 1423 self.readline = None
1424 1424 # no point in bugging windows users with this every time:
1425 1425 warn('Readline services not available on this platform.')
1426 1426 else:
1427 1427 sys.modules['readline'] = readline
1428 1428 import atexit
1429 1429 from IPython.core.completer import IPCompleter
1430 1430 self.Completer = IPCompleter(self,
1431 1431 self.user_ns,
1432 1432 self.user_global_ns,
1433 1433 self.rc.readline_omit__names,
1434 1434 self.alias_table)
1435 1435 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1436 1436 self.strdispatchers['complete_command'] = sdisp
1437 1437 self.Completer.custom_completers = sdisp
1438 1438 # Platform-specific configuration
1439 1439 if os.name == 'nt':
1440 1440 self.readline_startup_hook = readline.set_pre_input_hook
1441 1441 else:
1442 1442 self.readline_startup_hook = readline.set_startup_hook
1443 1443
1444 1444 # Load user's initrc file (readline config)
1445 1445 # Or if libedit is used, load editrc.
1446 1446 inputrc_name = os.environ.get('INPUTRC')
1447 1447 if inputrc_name is None:
1448 1448 home_dir = get_home_dir()
1449 1449 if home_dir is not None:
1450 1450 inputrc_name = '.inputrc'
1451 1451 if readline.uses_libedit:
1452 1452 inputrc_name = '.editrc'
1453 1453 inputrc_name = os.path.join(home_dir, inputrc_name)
1454 1454 if os.path.isfile(inputrc_name):
1455 1455 try:
1456 1456 readline.read_init_file(inputrc_name)
1457 1457 except:
1458 1458 warn('Problems reading readline initialization file <%s>'
1459 1459 % inputrc_name)
1460 1460
1461 1461 self.has_readline = 1
1462 1462 self.readline = readline
1463 1463 # save this in sys so embedded copies can restore it properly
1464 1464 sys.ipcompleter = self.Completer.complete
1465 1465 self.set_completer()
1466 1466
1467 1467 # Configure readline according to user's prefs
1468 1468 # This is only done if GNU readline is being used. If libedit
1469 1469 # is being used (as on Leopard) the readline config is
1470 1470 # not run as the syntax for libedit is different.
1471 1471 if not readline.uses_libedit:
1472 1472 for rlcommand in self.rc.readline_parse_and_bind:
1473 1473 #print "loading rl:",rlcommand # dbg
1474 1474 readline.parse_and_bind(rlcommand)
1475 1475
1476 1476 # Remove some chars from the delimiters list. If we encounter
1477 1477 # unicode chars, discard them.
1478 1478 delims = readline.get_completer_delims().encode("ascii", "ignore")
1479 1479 delims = delims.translate(string._idmap,
1480 1480 self.rc.readline_remove_delims)
1481 1481 readline.set_completer_delims(delims)
1482 1482 # otherwise we end up with a monster history after a while:
1483 1483 readline.set_history_length(1000)
1484 1484 try:
1485 1485 #print '*** Reading readline history' # dbg
1486 1486 readline.read_history_file(self.histfile)
1487 1487 except IOError:
1488 1488 pass # It doesn't exist yet.
1489 1489
1490 1490 atexit.register(self.atexit_operations)
1491 1491 del atexit
1492 1492
1493 1493 # Configure auto-indent for all platforms
1494 1494 self.set_autoindent(self.rc.autoindent)
1495 1495
1496 1496 def ask_yes_no(self,prompt,default=True):
1497 1497 if self.rc.quiet:
1498 1498 return True
1499 1499 return ask_yes_no(prompt,default)
1500 1500
1501 1501 def new_main_mod(self,ns=None):
1502 1502 """Return a new 'main' module object for user code execution.
1503 1503 """
1504 1504 main_mod = self._user_main_module
1505 1505 init_fakemod_dict(main_mod,ns)
1506 1506 return main_mod
1507 1507
1508 1508 def cache_main_mod(self,ns,fname):
1509 1509 """Cache a main module's namespace.
1510 1510
1511 1511 When scripts are executed via %run, we must keep a reference to the
1512 1512 namespace of their __main__ module (a FakeModule instance) around so
1513 1513 that Python doesn't clear it, rendering objects defined therein
1514 1514 useless.
1515 1515
1516 1516 This method keeps said reference in a private dict, keyed by the
1517 1517 absolute path of the module object (which corresponds to the script
1518 1518 path). This way, for multiple executions of the same script we only
1519 1519 keep one copy of the namespace (the last one), thus preventing memory
1520 1520 leaks from old references while allowing the objects from the last
1521 1521 execution to be accessible.
1522 1522
1523 1523 Note: we can not allow the actual FakeModule instances to be deleted,
1524 1524 because of how Python tears down modules (it hard-sets all their
1525 1525 references to None without regard for reference counts). This method
1526 1526 must therefore make a *copy* of the given namespace, to allow the
1527 1527 original module's __dict__ to be cleared and reused.
1528 1528
1529 1529
1530 1530 Parameters
1531 1531 ----------
1532 1532 ns : a namespace (a dict, typically)
1533 1533
1534 1534 fname : str
1535 1535 Filename associated with the namespace.
1536 1536
1537 1537 Examples
1538 1538 --------
1539 1539
1540 1540 In [10]: import IPython
1541 1541
1542 1542 In [11]: _ip.IP.cache_main_mod(IPython.__dict__,IPython.__file__)
1543 1543
1544 1544 In [12]: IPython.__file__ in _ip.IP._main_ns_cache
1545 1545 Out[12]: True
1546 1546 """
1547 1547 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
1548 1548
1549 1549 def clear_main_mod_cache(self):
1550 1550 """Clear the cache of main modules.
1551 1551
1552 1552 Mainly for use by utilities like %reset.
1553 1553
1554 1554 Examples
1555 1555 --------
1556 1556
1557 1557 In [15]: import IPython
1558 1558
1559 1559 In [16]: _ip.IP.cache_main_mod(IPython.__dict__,IPython.__file__)
1560 1560
1561 1561 In [17]: len(_ip.IP._main_ns_cache) > 0
1562 1562 Out[17]: True
1563 1563
1564 1564 In [18]: _ip.IP.clear_main_mod_cache()
1565 1565
1566 1566 In [19]: len(_ip.IP._main_ns_cache) == 0
1567 1567 Out[19]: True
1568 1568 """
1569 1569 self._main_ns_cache.clear()
1570 1570
1571 1571 def _should_recompile(self,e):
1572 1572 """Utility routine for edit_syntax_error"""
1573 1573
1574 1574 if e.filename in ('<ipython console>','<input>','<string>',
1575 1575 '<console>','<BackgroundJob compilation>',
1576 1576 None):
1577 1577
1578 1578 return False
1579 1579 try:
1580 1580 if (self.rc.autoedit_syntax and
1581 1581 not self.ask_yes_no('Return to editor to correct syntax error? '
1582 1582 '[Y/n] ','y')):
1583 1583 return False
1584 1584 except EOFError:
1585 1585 return False
1586 1586
1587 1587 def int0(x):
1588 1588 try:
1589 1589 return int(x)
1590 1590 except TypeError:
1591 1591 return 0
1592 1592 # always pass integer line and offset values to editor hook
1593 1593 try:
1594 1594 self.hooks.fix_error_editor(e.filename,
1595 1595 int0(e.lineno),int0(e.offset),e.msg)
1596 1596 except ipapi.TryNext:
1597 1597 warn('Could not open editor')
1598 1598 return False
1599 1599 return True
1600 1600
1601 1601 def edit_syntax_error(self):
1602 1602 """The bottom half of the syntax error handler called in the main loop.
1603 1603
1604 1604 Loop until syntax error is fixed or user cancels.
1605 1605 """
1606 1606
1607 1607 while self.SyntaxTB.last_syntax_error:
1608 1608 # copy and clear last_syntax_error
1609 1609 err = self.SyntaxTB.clear_err_state()
1610 1610 if not self._should_recompile(err):
1611 1611 return
1612 1612 try:
1613 1613 # may set last_syntax_error again if a SyntaxError is raised
1614 1614 self.safe_execfile(err.filename,self.user_ns)
1615 1615 except:
1616 1616 self.showtraceback()
1617 1617 else:
1618 1618 try:
1619 1619 f = file(err.filename)
1620 1620 try:
1621 1621 sys.displayhook(f.read())
1622 1622 finally:
1623 1623 f.close()
1624 1624 except:
1625 1625 self.showtraceback()
1626 1626
1627 1627 def showsyntaxerror(self, filename=None):
1628 1628 """Display the syntax error that just occurred.
1629 1629
1630 1630 This doesn't display a stack trace because there isn't one.
1631 1631
1632 1632 If a filename is given, it is stuffed in the exception instead
1633 1633 of what was there before (because Python's parser always uses
1634 1634 "<string>" when reading from a string).
1635 1635 """
1636 1636 etype, value, last_traceback = sys.exc_info()
1637 1637
1638 1638 # See note about these variables in showtraceback() below
1639 1639 sys.last_type = etype
1640 1640 sys.last_value = value
1641 1641 sys.last_traceback = last_traceback
1642 1642
1643 1643 if filename and etype is SyntaxError:
1644 1644 # Work hard to stuff the correct filename in the exception
1645 1645 try:
1646 1646 msg, (dummy_filename, lineno, offset, line) = value
1647 1647 except:
1648 1648 # Not the format we expect; leave it alone
1649 1649 pass
1650 1650 else:
1651 1651 # Stuff in the right filename
1652 1652 try:
1653 1653 # Assume SyntaxError is a class exception
1654 1654 value = SyntaxError(msg, (filename, lineno, offset, line))
1655 1655 except:
1656 1656 # If that failed, assume SyntaxError is a string
1657 1657 value = msg, (filename, lineno, offset, line)
1658 1658 self.SyntaxTB(etype,value,[])
1659 1659
1660 1660 def debugger(self,force=False):
1661 1661 """Call the pydb/pdb debugger.
1662 1662
1663 1663 Keywords:
1664 1664
1665 1665 - force(False): by default, this routine checks the instance call_pdb
1666 1666 flag and does not actually invoke the debugger if the flag is false.
1667 1667 The 'force' option forces the debugger to activate even if the flag
1668 1668 is false.
1669 1669 """
1670 1670
1671 1671 if not (force or self.call_pdb):
1672 1672 return
1673 1673
1674 1674 if not hasattr(sys,'last_traceback'):
1675 1675 error('No traceback has been produced, nothing to debug.')
1676 1676 return
1677 1677
1678 1678 # use pydb if available
1679 1679 if debugger.has_pydb:
1680 1680 from pydb import pm
1681 1681 else:
1682 1682 # fallback to our internal debugger
1683 1683 pm = lambda : self.InteractiveTB.debugger(force=True)
1684 1684 self.history_saving_wrapper(pm)()
1685 1685
1686 1686 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None):
1687 1687 """Display the exception that just occurred.
1688 1688
1689 1689 If nothing is known about the exception, this is the method which
1690 1690 should be used throughout the code for presenting user tracebacks,
1691 1691 rather than directly invoking the InteractiveTB object.
1692 1692
1693 1693 A specific showsyntaxerror() also exists, but this method can take
1694 1694 care of calling it if needed, so unless you are explicitly catching a
1695 1695 SyntaxError exception, don't try to analyze the stack manually and
1696 1696 simply call this method."""
1697 1697
1698 1698
1699 1699 # Though this won't be called by syntax errors in the input line,
1700 1700 # there may be SyntaxError cases whith imported code.
1701 1701
1702 1702 try:
1703 1703 if exc_tuple is None:
1704 1704 etype, value, tb = sys.exc_info()
1705 1705 else:
1706 1706 etype, value, tb = exc_tuple
1707 1707
1708 1708 if etype is SyntaxError:
1709 1709 self.showsyntaxerror(filename)
1710 1710 elif etype is ipapi.UsageError:
1711 1711 print "UsageError:", value
1712 1712 else:
1713 1713 # WARNING: these variables are somewhat deprecated and not
1714 1714 # necessarily safe to use in a threaded environment, but tools
1715 1715 # like pdb depend on their existence, so let's set them. If we
1716 1716 # find problems in the field, we'll need to revisit their use.
1717 1717 sys.last_type = etype
1718 1718 sys.last_value = value
1719 1719 sys.last_traceback = tb
1720 1720
1721 1721 if etype in self.custom_exceptions:
1722 1722 self.CustomTB(etype,value,tb)
1723 1723 else:
1724 1724 self.InteractiveTB(etype,value,tb,tb_offset=tb_offset)
1725 1725 if self.InteractiveTB.call_pdb and self.has_readline:
1726 1726 # pdb mucks up readline, fix it back
1727 1727 self.set_completer()
1728 1728 except KeyboardInterrupt:
1729 1729 self.write("\nKeyboardInterrupt\n")
1730 1730
1731 1731 def mainloop(self,banner=None):
1732 1732 """Creates the local namespace and starts the mainloop.
1733 1733
1734 1734 If an optional banner argument is given, it will override the
1735 1735 internally created default banner."""
1736 1736
1737 1737 if self.rc.c: # Emulate Python's -c option
1738 1738 self.exec_init_cmd()
1739 1739 if banner is None:
1740 1740 if not self.rc.banner:
1741 1741 banner = ''
1742 1742 # banner is string? Use it directly!
1743 1743 elif isinstance(self.rc.banner,basestring):
1744 1744 banner = self.rc.banner
1745 1745 else:
1746 1746 banner = self.BANNER+self.banner2
1747 1747
1748 1748 # if you run stuff with -c <cmd>, raw hist is not updated
1749 1749 # ensure that it's in sync
1750 1750 if len(self.input_hist) != len (self.input_hist_raw):
1751 1751 self.input_hist_raw = InputList(self.input_hist)
1752 1752
1753 1753 while 1:
1754 1754 try:
1755 1755 self.interact(banner)
1756 1756 #self.interact_with_readline()
1757 1757
1758 1758 # XXX for testing of a readline-decoupled repl loop, call
1759 1759 # interact_with_readline above
1760 1760
1761 1761 break
1762 1762 except KeyboardInterrupt:
1763 1763 # this should not be necessary, but KeyboardInterrupt
1764 1764 # handling seems rather unpredictable...
1765 1765 self.write("\nKeyboardInterrupt in interact()\n")
1766 1766
1767 1767 def exec_init_cmd(self):
1768 1768 """Execute a command given at the command line.
1769 1769
1770 1770 This emulates Python's -c option."""
1771 1771
1772 1772 #sys.argv = ['-c']
1773 1773 self.push(self.prefilter(self.rc.c, False))
1774 1774 if not self.rc.interact:
1775 1775 self.ask_exit()
1776 1776
1777 1777 def embed_mainloop(self,header='',local_ns=None,global_ns=None,stack_depth=0):
1778 1778 """Embeds IPython into a running python program.
1779 1779
1780 1780 Input:
1781 1781
1782 1782 - header: An optional header message can be specified.
1783 1783
1784 1784 - local_ns, global_ns: working namespaces. If given as None, the
1785 1785 IPython-initialized one is updated with __main__.__dict__, so that
1786 1786 program variables become visible but user-specific configuration
1787 1787 remains possible.
1788 1788
1789 1789 - stack_depth: specifies how many levels in the stack to go to
1790 1790 looking for namespaces (when local_ns and global_ns are None). This
1791 1791 allows an intermediate caller to make sure that this function gets
1792 1792 the namespace from the intended level in the stack. By default (0)
1793 1793 it will get its locals and globals from the immediate caller.
1794 1794
1795 1795 Warning: it's possible to use this in a program which is being run by
1796 1796 IPython itself (via %run), but some funny things will happen (a few
1797 1797 globals get overwritten). In the future this will be cleaned up, as
1798 1798 there is no fundamental reason why it can't work perfectly."""
1799 1799
1800 1800 # Get locals and globals from caller
1801 1801 if local_ns is None or global_ns is None:
1802 1802 call_frame = sys._getframe(stack_depth).f_back
1803 1803
1804 1804 if local_ns is None:
1805 1805 local_ns = call_frame.f_locals
1806 1806 if global_ns is None:
1807 1807 global_ns = call_frame.f_globals
1808 1808
1809 1809 # Update namespaces and fire up interpreter
1810 1810
1811 1811 # The global one is easy, we can just throw it in
1812 1812 self.user_global_ns = global_ns
1813 1813
1814 1814 # but the user/local one is tricky: ipython needs it to store internal
1815 1815 # data, but we also need the locals. We'll copy locals in the user
1816 1816 # one, but will track what got copied so we can delete them at exit.
1817 1817 # This is so that a later embedded call doesn't see locals from a
1818 1818 # previous call (which most likely existed in a separate scope).
1819 1819 local_varnames = local_ns.keys()
1820 1820 self.user_ns.update(local_ns)
1821 1821 #self.user_ns['local_ns'] = local_ns # dbg
1822 1822
1823 1823 # Patch for global embedding to make sure that things don't overwrite
1824 1824 # user globals accidentally. Thanks to Richard <rxe@renre-europe.com>
1825 1825 # FIXME. Test this a bit more carefully (the if.. is new)
1826 1826 if local_ns is None and global_ns is None:
1827 1827 self.user_global_ns.update(__main__.__dict__)
1828 1828
1829 1829 # make sure the tab-completer has the correct frame information, so it
1830 1830 # actually completes using the frame's locals/globals
1831 1831 self.set_completer_frame()
1832 1832
1833 1833 # before activating the interactive mode, we need to make sure that
1834 1834 # all names in the builtin namespace needed by ipython point to
1835 1835 # ourselves, and not to other instances.
1836 1836 self.add_builtins()
1837 1837
1838 1838 self.interact(header)
1839 1839
1840 1840 # now, purge out the user namespace from anything we might have added
1841 1841 # from the caller's local namespace
1842 1842 delvar = self.user_ns.pop
1843 1843 for var in local_varnames:
1844 1844 delvar(var,None)
1845 1845 # and clean builtins we may have overridden
1846 1846 self.clean_builtins()
1847 1847
1848 1848 def interact_prompt(self):
1849 1849 """ Print the prompt (in read-eval-print loop)
1850 1850
1851 1851 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1852 1852 used in standard IPython flow.
1853 1853 """
1854 1854 if self.more:
1855 1855 try:
1856 1856 prompt = self.hooks.generate_prompt(True)
1857 1857 except:
1858 1858 self.showtraceback()
1859 1859 if self.autoindent:
1860 1860 self.rl_do_indent = True
1861 1861
1862 1862 else:
1863 1863 try:
1864 1864 prompt = self.hooks.generate_prompt(False)
1865 1865 except:
1866 1866 self.showtraceback()
1867 1867 self.write(prompt)
1868 1868
1869 1869 def interact_handle_input(self,line):
1870 1870 """ Handle the input line (in read-eval-print loop)
1871 1871
1872 1872 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1873 1873 used in standard IPython flow.
1874 1874 """
1875 1875 if line.lstrip() == line:
1876 1876 self.shadowhist.add(line.strip())
1877 1877 lineout = self.prefilter(line,self.more)
1878 1878
1879 1879 if line.strip():
1880 1880 if self.more:
1881 1881 self.input_hist_raw[-1] += '%s\n' % line
1882 1882 else:
1883 1883 self.input_hist_raw.append('%s\n' % line)
1884 1884
1885 1885
1886 1886 self.more = self.push(lineout)
1887 1887 if (self.SyntaxTB.last_syntax_error and
1888 1888 self.rc.autoedit_syntax):
1889 1889 self.edit_syntax_error()
1890 1890
1891 1891 def interact_with_readline(self):
1892 1892 """ Demo of using interact_handle_input, interact_prompt
1893 1893
1894 1894 This is the main read-eval-print loop. If you need to implement your own (e.g. for GUI),
1895 1895 it should work like this.
1896 1896 """
1897 1897 self.readline_startup_hook(self.pre_readline)
1898 1898 while not self.exit_now:
1899 1899 self.interact_prompt()
1900 1900 if self.more:
1901 1901 self.rl_do_indent = True
1902 1902 else:
1903 1903 self.rl_do_indent = False
1904 1904 line = raw_input_original().decode(self.stdin_encoding)
1905 1905 self.interact_handle_input(line)
1906 1906
1907 1907
1908 1908 def interact(self, banner=None):
1909 1909 """Closely emulate the interactive Python console.
1910 1910
1911 1911 The optional banner argument specify the banner to print
1912 1912 before the first interaction; by default it prints a banner
1913 1913 similar to the one printed by the real Python interpreter,
1914 1914 followed by the current class name in parentheses (so as not
1915 1915 to confuse this with the real interpreter -- since it's so
1916 1916 close!).
1917 1917
1918 1918 """
1919 1919
1920 1920 if self.exit_now:
1921 1921 # batch run -> do not interact
1922 1922 return
1923 1923 cprt = 'Type "copyright", "credits" or "license" for more information.'
1924 1924 if banner is None:
1925 1925 self.write("Python %s on %s\n%s\n(%s)\n" %
1926 1926 (sys.version, sys.platform, cprt,
1927 1927 self.__class__.__name__))
1928 1928 else:
1929 1929 self.write(banner)
1930 1930
1931 1931 more = 0
1932 1932
1933 1933 # Mark activity in the builtins
1934 1934 __builtin__.__dict__['__IPYTHON__active'] += 1
1935 1935
1936 1936 if self.has_readline:
1937 1937 self.readline_startup_hook(self.pre_readline)
1938 1938 # exit_now is set by a call to %Exit or %Quit, through the
1939 1939 # ask_exit callback.
1940 1940
1941 1941 while not self.exit_now:
1942 1942 self.hooks.pre_prompt_hook()
1943 1943 if more:
1944 1944 try:
1945 1945 prompt = self.hooks.generate_prompt(True)
1946 1946 except:
1947 1947 self.showtraceback()
1948 1948 if self.autoindent:
1949 1949 self.rl_do_indent = True
1950 1950
1951 1951 else:
1952 1952 try:
1953 1953 prompt = self.hooks.generate_prompt(False)
1954 1954 except:
1955 1955 self.showtraceback()
1956 1956 try:
1957 1957 line = self.raw_input(prompt,more)
1958 1958 if self.exit_now:
1959 1959 # quick exit on sys.std[in|out] close
1960 1960 break
1961 1961 if self.autoindent:
1962 1962 self.rl_do_indent = False
1963 1963
1964 1964 except KeyboardInterrupt:
1965 1965 #double-guard against keyboardinterrupts during kbdint handling
1966 1966 try:
1967 1967 self.write('\nKeyboardInterrupt\n')
1968 1968 self.resetbuffer()
1969 1969 # keep cache in sync with the prompt counter:
1970 1970 self.outputcache.prompt_count -= 1
1971 1971
1972 1972 if self.autoindent:
1973 1973 self.indent_current_nsp = 0
1974 1974 more = 0
1975 1975 except KeyboardInterrupt:
1976 1976 pass
1977 1977 except EOFError:
1978 1978 if self.autoindent:
1979 1979 self.rl_do_indent = False
1980 1980 self.readline_startup_hook(None)
1981 1981 self.write('\n')
1982 1982 self.exit()
1983 1983 except bdb.BdbQuit:
1984 1984 warn('The Python debugger has exited with a BdbQuit exception.\n'
1985 1985 'Because of how pdb handles the stack, it is impossible\n'
1986 1986 'for IPython to properly format this particular exception.\n'
1987 1987 'IPython will resume normal operation.')
1988 1988 except:
1989 1989 # exceptions here are VERY RARE, but they can be triggered
1990 1990 # asynchronously by signal handlers, for example.
1991 1991 self.showtraceback()
1992 1992 else:
1993 1993 more = self.push(line)
1994 1994 if (self.SyntaxTB.last_syntax_error and
1995 1995 self.rc.autoedit_syntax):
1996 1996 self.edit_syntax_error()
1997 1997
1998 1998 # We are off again...
1999 1999 __builtin__.__dict__['__IPYTHON__active'] -= 1
2000 2000
2001 2001 def excepthook(self, etype, value, tb):
2002 2002 """One more defense for GUI apps that call sys.excepthook.
2003 2003
2004 2004 GUI frameworks like wxPython trap exceptions and call
2005 2005 sys.excepthook themselves. I guess this is a feature that
2006 2006 enables them to keep running after exceptions that would
2007 2007 otherwise kill their mainloop. This is a bother for IPython
2008 2008 which excepts to catch all of the program exceptions with a try:
2009 2009 except: statement.
2010 2010
2011 2011 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
2012 2012 any app directly invokes sys.excepthook, it will look to the user like
2013 2013 IPython crashed. In order to work around this, we can disable the
2014 2014 CrashHandler and replace it with this excepthook instead, which prints a
2015 2015 regular traceback using our InteractiveTB. In this fashion, apps which
2016 2016 call sys.excepthook will generate a regular-looking exception from
2017 2017 IPython, and the CrashHandler will only be triggered by real IPython
2018 2018 crashes.
2019 2019
2020 2020 This hook should be used sparingly, only in places which are not likely
2021 2021 to be true IPython errors.
2022 2022 """
2023 2023 self.showtraceback((etype,value,tb),tb_offset=0)
2024 2024
2025 2025 def expand_aliases(self,fn,rest):
2026 2026 """ Expand multiple levels of aliases:
2027 2027
2028 2028 if:
2029 2029
2030 2030 alias foo bar /tmp
2031 2031 alias baz foo
2032 2032
2033 2033 then:
2034 2034
2035 2035 baz huhhahhei -> bar /tmp huhhahhei
2036 2036
2037 2037 """
2038 2038 line = fn + " " + rest
2039 2039
2040 2040 done = set()
2041 2041 while 1:
2042 2042 pre,fn,rest = prefilter.splitUserInput(line,
2043 2043 prefilter.shell_line_split)
2044 2044 if fn in self.alias_table:
2045 2045 if fn in done:
2046 2046 warn("Cyclic alias definition, repeated '%s'" % fn)
2047 2047 return ""
2048 2048 done.add(fn)
2049 2049
2050 2050 l2 = self.transform_alias(fn,rest)
2051 2051 # dir -> dir
2052 2052 # print "alias",line, "->",l2 #dbg
2053 2053 if l2 == line:
2054 2054 break
2055 2055 # ls -> ls -F should not recurse forever
2056 2056 if l2.split(None,1)[0] == line.split(None,1)[0]:
2057 2057 line = l2
2058 2058 break
2059 2059
2060 2060 line=l2
2061 2061
2062 2062
2063 2063 # print "al expand to",line #dbg
2064 2064 else:
2065 2065 break
2066 2066
2067 2067 return line
2068 2068
2069 2069 def transform_alias(self, alias,rest=''):
2070 2070 """ Transform alias to system command string.
2071 2071 """
2072 2072 trg = self.alias_table[alias]
2073 2073
2074 2074 nargs,cmd = trg
2075 2075 # print trg #dbg
2076 2076 if ' ' in cmd and os.path.isfile(cmd):
2077 2077 cmd = '"%s"' % cmd
2078 2078
2079 2079 # Expand the %l special to be the user's input line
2080 2080 if cmd.find('%l') >= 0:
2081 2081 cmd = cmd.replace('%l',rest)
2082 2082 rest = ''
2083 2083 if nargs==0:
2084 2084 # Simple, argument-less aliases
2085 2085 cmd = '%s %s' % (cmd,rest)
2086 2086 else:
2087 2087 # Handle aliases with positional arguments
2088 2088 args = rest.split(None,nargs)
2089 2089 if len(args)< nargs:
2090 2090 error('Alias <%s> requires %s arguments, %s given.' %
2091 2091 (alias,nargs,len(args)))
2092 2092 return None
2093 2093 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
2094 2094 # Now call the macro, evaluating in the user's namespace
2095 2095 #print 'new command: <%r>' % cmd # dbg
2096 2096 return cmd
2097 2097
2098 2098 def call_alias(self,alias,rest=''):
2099 2099 """Call an alias given its name and the rest of the line.
2100 2100
2101 2101 This is only used to provide backwards compatibility for users of
2102 2102 ipalias(), use of which is not recommended for anymore."""
2103 2103
2104 2104 # Now call the macro, evaluating in the user's namespace
2105 2105 cmd = self.transform_alias(alias, rest)
2106 2106 try:
2107 2107 self.system(cmd)
2108 2108 except:
2109 2109 self.showtraceback()
2110 2110
2111 2111 def indent_current_str(self):
2112 2112 """return the current level of indentation as a string"""
2113 2113 return self.indent_current_nsp * ' '
2114 2114
2115 2115 def autoindent_update(self,line):
2116 2116 """Keep track of the indent level."""
2117 2117
2118 2118 #debugx('line')
2119 2119 #debugx('self.indent_current_nsp')
2120 2120 if self.autoindent:
2121 2121 if line:
2122 2122 inisp = num_ini_spaces(line)
2123 2123 if inisp < self.indent_current_nsp:
2124 2124 self.indent_current_nsp = inisp
2125 2125
2126 2126 if line[-1] == ':':
2127 2127 self.indent_current_nsp += 4
2128 2128 elif dedent_re.match(line):
2129 2129 self.indent_current_nsp -= 4
2130 2130 else:
2131 2131 self.indent_current_nsp = 0
2132 2132
2133 2133 def runlines(self,lines):
2134 2134 """Run a string of one or more lines of source.
2135 2135
2136 2136 This method is capable of running a string containing multiple source
2137 2137 lines, as if they had been entered at the IPython prompt. Since it
2138 2138 exposes IPython's processing machinery, the given strings can contain
2139 2139 magic calls (%magic), special shell access (!cmd), etc."""
2140 2140
2141 2141 # We must start with a clean buffer, in case this is run from an
2142 2142 # interactive IPython session (via a magic, for example).
2143 2143 self.resetbuffer()
2144 2144 lines = lines.split('\n')
2145 2145 more = 0
2146 2146
2147 2147 for line in lines:
2148 2148 # skip blank lines so we don't mess up the prompt counter, but do
2149 2149 # NOT skip even a blank line if we are in a code block (more is
2150 2150 # true)
2151 2151
2152 2152 if line or more:
2153 2153 # push to raw history, so hist line numbers stay in sync
2154 2154 self.input_hist_raw.append("# " + line + "\n")
2155 2155 more = self.push(self.prefilter(line,more))
2156 2156 # IPython's runsource returns None if there was an error
2157 2157 # compiling the code. This allows us to stop processing right
2158 2158 # away, so the user gets the error message at the right place.
2159 2159 if more is None:
2160 2160 break
2161 2161 else:
2162 2162 self.input_hist_raw.append("\n")
2163 2163 # final newline in case the input didn't have it, so that the code
2164 2164 # actually does get executed
2165 2165 if more:
2166 2166 self.push('\n')
2167 2167
2168 2168 def runsource(self, source, filename='<input>', symbol='single'):
2169 2169 """Compile and run some source in the interpreter.
2170 2170
2171 2171 Arguments are as for compile_command().
2172 2172
2173 2173 One several things can happen:
2174 2174
2175 2175 1) The input is incorrect; compile_command() raised an
2176 2176 exception (SyntaxError or OverflowError). A syntax traceback
2177 2177 will be printed by calling the showsyntaxerror() method.
2178 2178
2179 2179 2) The input is incomplete, and more input is required;
2180 2180 compile_command() returned None. Nothing happens.
2181 2181
2182 2182 3) The input is complete; compile_command() returned a code
2183 2183 object. The code is executed by calling self.runcode() (which
2184 2184 also handles run-time exceptions, except for SystemExit).
2185 2185
2186 2186 The return value is:
2187 2187
2188 2188 - True in case 2
2189 2189
2190 2190 - False in the other cases, unless an exception is raised, where
2191 2191 None is returned instead. This can be used by external callers to
2192 2192 know whether to continue feeding input or not.
2193 2193
2194 2194 The return value can be used to decide whether to use sys.ps1 or
2195 2195 sys.ps2 to prompt the next line."""
2196 2196
2197 2197 # if the source code has leading blanks, add 'if 1:\n' to it
2198 2198 # this allows execution of indented pasted code. It is tempting
2199 2199 # to add '\n' at the end of source to run commands like ' a=1'
2200 2200 # directly, but this fails for more complicated scenarios
2201 2201 source=source.encode(self.stdin_encoding)
2202 2202 if source[:1] in [' ', '\t']:
2203 2203 source = 'if 1:\n%s' % source
2204 2204
2205 2205 try:
2206 2206 code = self.compile(source,filename,symbol)
2207 2207 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
2208 2208 # Case 1
2209 2209 self.showsyntaxerror(filename)
2210 2210 return None
2211 2211
2212 2212 if code is None:
2213 2213 # Case 2
2214 2214 return True
2215 2215
2216 2216 # Case 3
2217 2217 # We store the code object so that threaded shells and
2218 2218 # custom exception handlers can access all this info if needed.
2219 2219 # The source corresponding to this can be obtained from the
2220 2220 # buffer attribute as '\n'.join(self.buffer).
2221 2221 self.code_to_run = code
2222 2222 # now actually execute the code object
2223 2223 if self.runcode(code) == 0:
2224 2224 return False
2225 2225 else:
2226 2226 return None
2227 2227
2228 2228 def runcode(self,code_obj):
2229 2229 """Execute a code object.
2230 2230
2231 2231 When an exception occurs, self.showtraceback() is called to display a
2232 2232 traceback.
2233 2233
2234 2234 Return value: a flag indicating whether the code to be run completed
2235 2235 successfully:
2236 2236
2237 2237 - 0: successful execution.
2238 2238 - 1: an error occurred.
2239 2239 """
2240 2240
2241 2241 # Set our own excepthook in case the user code tries to call it
2242 2242 # directly, so that the IPython crash handler doesn't get triggered
2243 2243 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2244 2244
2245 2245 # we save the original sys.excepthook in the instance, in case config
2246 2246 # code (such as magics) needs access to it.
2247 2247 self.sys_excepthook = old_excepthook
2248 2248 outflag = 1 # happens in more places, so it's easier as default
2249 2249 try:
2250 2250 try:
2251 2251 self.hooks.pre_runcode_hook()
2252 2252 exec code_obj in self.user_global_ns, self.user_ns
2253 2253 finally:
2254 2254 # Reset our crash handler in place
2255 2255 sys.excepthook = old_excepthook
2256 2256 except SystemExit:
2257 2257 self.resetbuffer()
2258 2258 self.showtraceback()
2259 2259 warn("Type %exit or %quit to exit IPython "
2260 2260 "(%Exit or %Quit do so unconditionally).",level=1)
2261 2261 except self.custom_exceptions:
2262 2262 etype,value,tb = sys.exc_info()
2263 2263 self.CustomTB(etype,value,tb)
2264 2264 except:
2265 2265 self.showtraceback()
2266 2266 else:
2267 2267 outflag = 0
2268 2268 if softspace(sys.stdout, 0):
2269 2269 print
2270 2270 # Flush out code object which has been run (and source)
2271 2271 self.code_to_run = None
2272 2272 return outflag
2273 2273
2274 2274 def push(self, line):
2275 2275 """Push a line to the interpreter.
2276 2276
2277 2277 The line should not have a trailing newline; it may have
2278 2278 internal newlines. The line is appended to a buffer and the
2279 2279 interpreter's runsource() method is called with the
2280 2280 concatenated contents of the buffer as source. If this
2281 2281 indicates that the command was executed or invalid, the buffer
2282 2282 is reset; otherwise, the command is incomplete, and the buffer
2283 2283 is left as it was after the line was appended. The return
2284 2284 value is 1 if more input is required, 0 if the line was dealt
2285 2285 with in some way (this is the same as runsource()).
2286 2286 """
2287 2287
2288 2288 # autoindent management should be done here, and not in the
2289 2289 # interactive loop, since that one is only seen by keyboard input. We
2290 2290 # need this done correctly even for code run via runlines (which uses
2291 2291 # push).
2292 2292
2293 2293 #print 'push line: <%s>' % line # dbg
2294 2294 for subline in line.splitlines():
2295 2295 self.autoindent_update(subline)
2296 2296 self.buffer.append(line)
2297 2297 more = self.runsource('\n'.join(self.buffer), self.filename)
2298 2298 if not more:
2299 2299 self.resetbuffer()
2300 2300 return more
2301 2301
2302 2302 def split_user_input(self, line):
2303 2303 # This is really a hold-over to support ipapi and some extensions
2304 2304 return prefilter.splitUserInput(line)
2305 2305
2306 2306 def resetbuffer(self):
2307 2307 """Reset the input buffer."""
2308 2308 self.buffer[:] = []
2309 2309
2310 2310 def raw_input(self,prompt='',continue_prompt=False):
2311 2311 """Write a prompt and read a line.
2312 2312
2313 2313 The returned line does not include the trailing newline.
2314 2314 When the user enters the EOF key sequence, EOFError is raised.
2315 2315
2316 2316 Optional inputs:
2317 2317
2318 2318 - prompt(''): a string to be printed to prompt the user.
2319 2319
2320 2320 - continue_prompt(False): whether this line is the first one or a
2321 2321 continuation in a sequence of inputs.
2322 2322 """
2323 2323
2324 2324 # Code run by the user may have modified the readline completer state.
2325 2325 # We must ensure that our completer is back in place.
2326 2326 if self.has_readline:
2327 2327 self.set_completer()
2328 2328
2329 2329 try:
2330 2330 line = raw_input_original(prompt).decode(self.stdin_encoding)
2331 2331 except ValueError:
2332 2332 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
2333 2333 " or sys.stdout.close()!\nExiting IPython!")
2334 2334 self.ask_exit()
2335 2335 return ""
2336 2336
2337 2337 # Try to be reasonably smart about not re-indenting pasted input more
2338 2338 # than necessary. We do this by trimming out the auto-indent initial
2339 2339 # spaces, if the user's actual input started itself with whitespace.
2340 2340 #debugx('self.buffer[-1]')
2341 2341
2342 2342 if self.autoindent:
2343 2343 if num_ini_spaces(line) > self.indent_current_nsp:
2344 2344 line = line[self.indent_current_nsp:]
2345 2345 self.indent_current_nsp = 0
2346 2346
2347 2347 # store the unfiltered input before the user has any chance to modify
2348 2348 # it.
2349 2349 if line.strip():
2350 2350 if continue_prompt:
2351 2351 self.input_hist_raw[-1] += '%s\n' % line
2352 2352 if self.has_readline: # and some config option is set?
2353 2353 try:
2354 2354 histlen = self.readline.get_current_history_length()
2355 2355 if histlen > 1:
2356 2356 newhist = self.input_hist_raw[-1].rstrip()
2357 2357 self.readline.remove_history_item(histlen-1)
2358 2358 self.readline.replace_history_item(histlen-2,
2359 2359 newhist.encode(self.stdin_encoding))
2360 2360 except AttributeError:
2361 2361 pass # re{move,place}_history_item are new in 2.4.
2362 2362 else:
2363 2363 self.input_hist_raw.append('%s\n' % line)
2364 2364 # only entries starting at first column go to shadow history
2365 2365 if line.lstrip() == line:
2366 2366 self.shadowhist.add(line.strip())
2367 2367 elif not continue_prompt:
2368 2368 self.input_hist_raw.append('\n')
2369 2369 try:
2370 2370 lineout = self.prefilter(line,continue_prompt)
2371 2371 except:
2372 2372 # blanket except, in case a user-defined prefilter crashes, so it
2373 2373 # can't take all of ipython with it.
2374 2374 self.showtraceback()
2375 2375 return ''
2376 2376 else:
2377 2377 return lineout
2378 2378
2379 2379 def _prefilter(self, line, continue_prompt):
2380 2380 """Calls different preprocessors, depending on the form of line."""
2381 2381
2382 2382 # All handlers *must* return a value, even if it's blank ('').
2383 2383
2384 2384 # Lines are NOT logged here. Handlers should process the line as
2385 2385 # needed, update the cache AND log it (so that the input cache array
2386 2386 # stays synced).
2387 2387
2388 2388 #.....................................................................
2389 2389 # Code begins
2390 2390
2391 2391 #if line.startswith('%crash'): raise RuntimeError,'Crash now!' # dbg
2392 2392
2393 2393 # save the line away in case we crash, so the post-mortem handler can
2394 2394 # record it
2395 2395 self._last_input_line = line
2396 2396
2397 2397 #print '***line: <%s>' % line # dbg
2398 2398
2399 2399 if not line:
2400 2400 # Return immediately on purely empty lines, so that if the user
2401 2401 # previously typed some whitespace that started a continuation
2402 2402 # prompt, he can break out of that loop with just an empty line.
2403 2403 # This is how the default python prompt works.
2404 2404
2405 2405 # Only return if the accumulated input buffer was just whitespace!
2406 2406 if ''.join(self.buffer).isspace():
2407 2407 self.buffer[:] = []
2408 2408 return ''
2409 2409
2410 2410 line_info = prefilter.LineInfo(line, continue_prompt)
2411 2411
2412 2412 # the input history needs to track even empty lines
2413 2413 stripped = line.strip()
2414 2414
2415 2415 if not stripped:
2416 2416 if not continue_prompt:
2417 2417 self.outputcache.prompt_count -= 1
2418 2418 return self.handle_normal(line_info)
2419 2419
2420 2420 # print '***cont',continue_prompt # dbg
2421 2421 # special handlers are only allowed for single line statements
2422 2422 if continue_prompt and not self.rc.multi_line_specials:
2423 2423 return self.handle_normal(line_info)
2424 2424
2425 2425
2426 2426 # See whether any pre-existing handler can take care of it
2427 2427 rewritten = self.hooks.input_prefilter(stripped)
2428 2428 if rewritten != stripped: # ok, some prefilter did something
2429 2429 rewritten = line_info.pre + rewritten # add indentation
2430 2430 return self.handle_normal(prefilter.LineInfo(rewritten,
2431 2431 continue_prompt))
2432 2432
2433 2433 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
2434 2434
2435 2435 return prefilter.prefilter(line_info, self)
2436 2436
2437 2437
2438 2438 def _prefilter_dumb(self, line, continue_prompt):
2439 2439 """simple prefilter function, for debugging"""
2440 2440 return self.handle_normal(line,continue_prompt)
2441 2441
2442 2442
2443 2443 def multiline_prefilter(self, line, continue_prompt):
2444 2444 """ Run _prefilter for each line of input
2445 2445
2446 2446 Covers cases where there are multiple lines in the user entry,
2447 2447 which is the case when the user goes back to a multiline history
2448 2448 entry and presses enter.
2449 2449
2450 2450 """
2451 2451 out = []
2452 2452 for l in line.rstrip('\n').split('\n'):
2453 2453 out.append(self._prefilter(l, continue_prompt))
2454 2454 return '\n'.join(out)
2455 2455
2456 2456 # Set the default prefilter() function (this can be user-overridden)
2457 2457 prefilter = multiline_prefilter
2458 2458
2459 2459 def handle_normal(self,line_info):
2460 2460 """Handle normal input lines. Use as a template for handlers."""
2461 2461
2462 2462 # With autoindent on, we need some way to exit the input loop, and I
2463 2463 # don't want to force the user to have to backspace all the way to
2464 2464 # clear the line. The rule will be in this case, that either two
2465 2465 # lines of pure whitespace in a row, or a line of pure whitespace but
2466 2466 # of a size different to the indent level, will exit the input loop.
2467 2467 line = line_info.line
2468 2468 continue_prompt = line_info.continue_prompt
2469 2469
2470 2470 if (continue_prompt and self.autoindent and line.isspace() and
2471 2471 (0 < abs(len(line) - self.indent_current_nsp) <= 2 or
2472 2472 (self.buffer[-1]).isspace() )):
2473 2473 line = ''
2474 2474
2475 2475 self.log(line,line,continue_prompt)
2476 2476 return line
2477 2477
2478 2478 def handle_alias(self,line_info):
2479 2479 """Handle alias input lines. """
2480 2480 tgt = self.alias_table[line_info.iFun]
2481 2481 # print "=>",tgt #dbg
2482 2482 if callable(tgt):
2483 2483 if '$' in line_info.line:
2484 2484 call_meth = '(_ip, _ip.itpl(%s))'
2485 2485 else:
2486 2486 call_meth = '(_ip,%s)'
2487 2487 line_out = ("%s_sh.%s" + call_meth) % (line_info.preWhitespace,
2488 2488 line_info.iFun,
2489 2489 make_quoted_expr(line_info.line))
2490 2490 else:
2491 2491 transformed = self.expand_aliases(line_info.iFun,line_info.theRest)
2492 2492
2493 2493 # pre is needed, because it carries the leading whitespace. Otherwise
2494 2494 # aliases won't work in indented sections.
2495 2495 line_out = '%s_ip.system(%s)' % (line_info.preWhitespace,
2496 2496 make_quoted_expr( transformed ))
2497 2497
2498 2498 self.log(line_info.line,line_out,line_info.continue_prompt)
2499 2499 #print 'line out:',line_out # dbg
2500 2500 return line_out
2501 2501
2502 2502 def handle_shell_escape(self, line_info):
2503 2503 """Execute the line in a shell, empty return value"""
2504 2504 #print 'line in :', `line` # dbg
2505 2505 line = line_info.line
2506 2506 if line.lstrip().startswith('!!'):
2507 2507 # rewrite LineInfo's line, iFun and theRest to properly hold the
2508 2508 # call to %sx and the actual command to be executed, so
2509 2509 # handle_magic can work correctly. Note that this works even if
2510 2510 # the line is indented, so it handles multi_line_specials
2511 2511 # properly.
2512 2512 new_rest = line.lstrip()[2:]
2513 2513 line_info.line = '%ssx %s' % (self.ESC_MAGIC,new_rest)
2514 2514 line_info.iFun = 'sx'
2515 2515 line_info.theRest = new_rest
2516 2516 return self.handle_magic(line_info)
2517 2517 else:
2518 2518 cmd = line.lstrip().lstrip('!')
2519 2519 line_out = '%s_ip.system(%s)' % (line_info.preWhitespace,
2520 2520 make_quoted_expr(cmd))
2521 2521 # update cache/log and return
2522 2522 self.log(line,line_out,line_info.continue_prompt)
2523 2523 return line_out
2524 2524
2525 2525 def handle_magic(self, line_info):
2526 2526 """Execute magic functions."""
2527 2527 iFun = line_info.iFun
2528 2528 theRest = line_info.theRest
2529 2529 cmd = '%s_ip.magic(%s)' % (line_info.preWhitespace,
2530 2530 make_quoted_expr(iFun + " " + theRest))
2531 2531 self.log(line_info.line,cmd,line_info.continue_prompt)
2532 2532 #print 'in handle_magic, cmd=<%s>' % cmd # dbg
2533 2533 return cmd
2534 2534
2535 2535 def handle_auto(self, line_info):
2536 2536 """Hande lines which can be auto-executed, quoting if requested."""
2537 2537
2538 2538 line = line_info.line
2539 2539 iFun = line_info.iFun
2540 2540 theRest = line_info.theRest
2541 2541 pre = line_info.pre
2542 2542 continue_prompt = line_info.continue_prompt
2543 2543 obj = line_info.ofind(self)['obj']
2544 2544
2545 2545 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
2546 2546
2547 2547 # This should only be active for single-line input!
2548 2548 if continue_prompt:
2549 2549 self.log(line,line,continue_prompt)
2550 2550 return line
2551 2551
2552 2552 force_auto = isinstance(obj, ipapi.IPyAutocall)
2553 2553 auto_rewrite = True
2554 2554
2555 2555 if pre == self.ESC_QUOTE:
2556 2556 # Auto-quote splitting on whitespace
2557 2557 newcmd = '%s("%s")' % (iFun,'", "'.join(theRest.split()) )
2558 2558 elif pre == self.ESC_QUOTE2:
2559 2559 # Auto-quote whole string
2560 2560 newcmd = '%s("%s")' % (iFun,theRest)
2561 2561 elif pre == self.ESC_PAREN:
2562 2562 newcmd = '%s(%s)' % (iFun,",".join(theRest.split()))
2563 2563 else:
2564 2564 # Auto-paren.
2565 2565 # We only apply it to argument-less calls if the autocall
2566 2566 # parameter is set to 2. We only need to check that autocall is <
2567 2567 # 2, since this function isn't called unless it's at least 1.
2568 2568 if not theRest and (self.rc.autocall < 2) and not force_auto:
2569 2569 newcmd = '%s %s' % (iFun,theRest)
2570 2570 auto_rewrite = False
2571 2571 else:
2572 2572 if not force_auto and theRest.startswith('['):
2573 2573 if hasattr(obj,'__getitem__'):
2574 2574 # Don't autocall in this case: item access for an object
2575 2575 # which is BOTH callable and implements __getitem__.
2576 2576 newcmd = '%s %s' % (iFun,theRest)
2577 2577 auto_rewrite = False
2578 2578 else:
2579 2579 # if the object doesn't support [] access, go ahead and
2580 2580 # autocall
2581 2581 newcmd = '%s(%s)' % (iFun.rstrip(),theRest)
2582 2582 elif theRest.endswith(';'):
2583 2583 newcmd = '%s(%s);' % (iFun.rstrip(),theRest[:-1])
2584 2584 else:
2585 2585 newcmd = '%s(%s)' % (iFun.rstrip(), theRest)
2586 2586
2587 2587 if auto_rewrite:
2588 2588 rw = self.outputcache.prompt1.auto_rewrite() + newcmd
2589 2589
2590 2590 try:
2591 2591 # plain ascii works better w/ pyreadline, on some machines, so
2592 2592 # we use it and only print uncolored rewrite if we have unicode
2593 2593 rw = str(rw)
2594 2594 print >>Term.cout, rw
2595 2595 except UnicodeEncodeError:
2596 2596 print "-------------->" + newcmd
2597 2597
2598 2598 # log what is now valid Python, not the actual user input (without the
2599 2599 # final newline)
2600 2600 self.log(line,newcmd,continue_prompt)
2601 2601 return newcmd
2602 2602
2603 2603 def handle_help(self, line_info):
2604 2604 """Try to get some help for the object.
2605 2605
2606 2606 obj? or ?obj -> basic information.
2607 2607 obj?? or ??obj -> more details.
2608 2608 """
2609 2609
2610 2610 line = line_info.line
2611 2611 # We need to make sure that we don't process lines which would be
2612 2612 # otherwise valid python, such as "x=1 # what?"
2613 2613 try:
2614 2614 codeop.compile_command(line)
2615 2615 except SyntaxError:
2616 2616 # We should only handle as help stuff which is NOT valid syntax
2617 2617 if line[0]==self.ESC_HELP:
2618 2618 line = line[1:]
2619 2619 elif line[-1]==self.ESC_HELP:
2620 2620 line = line[:-1]
2621 2621 self.log(line,'#?'+line,line_info.continue_prompt)
2622 2622 if line:
2623 2623 #print 'line:<%r>' % line # dbg
2624 2624 self.magic_pinfo(line)
2625 2625 else:
2626 2626 page(self.usage,screen_lines=self.rc.screen_length)
2627 2627 return '' # Empty string is needed here!
2628 2628 except:
2629 2629 # Pass any other exceptions through to the normal handler
2630 2630 return self.handle_normal(line_info)
2631 2631 else:
2632 2632 # If the code compiles ok, we should handle it normally
2633 2633 return self.handle_normal(line_info)
2634 2634
2635 2635 def getapi(self):
2636 2636 """ Get an IPApi object for this shell instance
2637 2637
2638 2638 Getting an IPApi object is always preferable to accessing the shell
2639 2639 directly, but this holds true especially for extensions.
2640 2640
2641 2641 It should always be possible to implement an extension with IPApi
2642 2642 alone. If not, contact maintainer to request an addition.
2643 2643
2644 2644 """
2645 2645 return self.api
2646 2646
2647 2647 def handle_emacs(self, line_info):
2648 2648 """Handle input lines marked by python-mode."""
2649 2649
2650 2650 # Currently, nothing is done. Later more functionality can be added
2651 2651 # here if needed.
2652 2652
2653 2653 # The input cache shouldn't be updated
2654 2654 return line_info.line
2655 2655
2656 2656
2657 2657 def mktempfile(self,data=None):
2658 2658 """Make a new tempfile and return its filename.
2659 2659
2660 2660 This makes a call to tempfile.mktemp, but it registers the created
2661 2661 filename internally so ipython cleans it up at exit time.
2662 2662
2663 2663 Optional inputs:
2664 2664
2665 2665 - data(None): if data is given, it gets written out to the temp file
2666 2666 immediately, and the file is closed again."""
2667 2667
2668 2668 filename = tempfile.mktemp('.py','ipython_edit_')
2669 2669 self.tempfiles.append(filename)
2670 2670
2671 2671 if data:
2672 2672 tmp_file = open(filename,'w')
2673 2673 tmp_file.write(data)
2674 2674 tmp_file.close()
2675 2675 return filename
2676 2676
2677 2677 def write(self,data):
2678 2678 """Write a string to the default output"""
2679 2679 Term.cout.write(data)
2680 2680
2681 2681 def write_err(self,data):
2682 2682 """Write a string to the default error output"""
2683 2683 Term.cerr.write(data)
2684 2684
2685 2685 def ask_exit(self):
2686 2686 """ Call for exiting. Can be overiden and used as a callback. """
2687 2687 self.exit_now = True
2688 2688
2689 2689 def exit(self):
2690 2690 """Handle interactive exit.
2691 2691
2692 2692 This method calls the ask_exit callback."""
2693 2693
2694 2694 if self.rc.confirm_exit:
2695 2695 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
2696 2696 self.ask_exit()
2697 2697 else:
2698 2698 self.ask_exit()
2699 2699
2700 2700 def safe_execfile(self,fname,*where,**kw):
2701 2701 """A safe version of the builtin execfile().
2702 2702
2703 2703 This version will never throw an exception, and knows how to handle
2704 2704 ipython logs as well.
2705 2705
2706 2706 :Parameters:
2707 2707 fname : string
2708 2708 Name of the file to be executed.
2709 2709
2710 2710 where : tuple
2711 2711 One or two namespaces, passed to execfile() as (globals,locals).
2712 2712 If only one is given, it is passed as both.
2713 2713
2714 2714 :Keywords:
2715 2715 islog : boolean (False)
2716 2716
2717 2717 quiet : boolean (True)
2718 2718
2719 2719 exit_ignore : boolean (False)
2720 2720 """
2721 2721
2722 2722 def syspath_cleanup():
2723 2723 """Internal cleanup routine for sys.path."""
2724 2724 if add_dname:
2725 2725 try:
2726 2726 sys.path.remove(dname)
2727 2727 except ValueError:
2728 2728 # For some reason the user has already removed it, ignore.
2729 2729 pass
2730 2730
2731 2731 fname = os.path.expanduser(fname)
2732 2732
2733 2733 # Find things also in current directory. This is needed to mimic the
2734 2734 # behavior of running a script from the system command line, where
2735 2735 # Python inserts the script's directory into sys.path
2736 2736 dname = os.path.dirname(os.path.abspath(fname))
2737 2737 add_dname = False
2738 2738 if dname not in sys.path:
2739 2739 sys.path.insert(0,dname)
2740 2740 add_dname = True
2741 2741
2742 2742 try:
2743 2743 xfile = open(fname)
2744 2744 except:
2745 2745 print >> Term.cerr, \
2746 2746 'Could not open file <%s> for safe execution.' % fname
2747 2747 syspath_cleanup()
2748 2748 return None
2749 2749
2750 2750 kw.setdefault('islog',0)
2751 2751 kw.setdefault('quiet',1)
2752 2752 kw.setdefault('exit_ignore',0)
2753 2753
2754 2754 first = xfile.readline()
2755 2755 loghead = str(self.loghead_tpl).split('\n',1)[0].strip()
2756 2756 xfile.close()
2757 2757 # line by line execution
2758 2758 if first.startswith(loghead) or kw['islog']:
2759 2759 print 'Loading log file <%s> one line at a time...' % fname
2760 2760 if kw['quiet']:
2761 2761 stdout_save = sys.stdout
2762 2762 sys.stdout = StringIO.StringIO()
2763 2763 try:
2764 2764 globs,locs = where[0:2]
2765 2765 except:
2766 2766 try:
2767 2767 globs = locs = where[0]
2768 2768 except:
2769 2769 globs = locs = globals()
2770 2770 badblocks = []
2771 2771
2772 2772 # we also need to identify indented blocks of code when replaying
2773 2773 # logs and put them together before passing them to an exec
2774 2774 # statement. This takes a bit of regexp and look-ahead work in the
2775 2775 # file. It's easiest if we swallow the whole thing in memory
2776 2776 # first, and manually walk through the lines list moving the
2777 2777 # counter ourselves.
2778 2778 indent_re = re.compile('\s+\S')
2779 2779 xfile = open(fname)
2780 2780 filelines = xfile.readlines()
2781 2781 xfile.close()
2782 2782 nlines = len(filelines)
2783 2783 lnum = 0
2784 2784 while lnum < nlines:
2785 2785 line = filelines[lnum]
2786 2786 lnum += 1
2787 2787 # don't re-insert logger status info into cache
2788 2788 if line.startswith('#log#'):
2789 2789 continue
2790 2790 else:
2791 2791 # build a block of code (maybe a single line) for execution
2792 2792 block = line
2793 2793 try:
2794 2794 next = filelines[lnum] # lnum has already incremented
2795 2795 except:
2796 2796 next = None
2797 2797 while next and indent_re.match(next):
2798 2798 block += next
2799 2799 lnum += 1
2800 2800 try:
2801 2801 next = filelines[lnum]
2802 2802 except:
2803 2803 next = None
2804 2804 # now execute the block of one or more lines
2805 2805 try:
2806 2806 exec block in globs,locs
2807 2807 except SystemExit:
2808 2808 pass
2809 2809 except:
2810 2810 badblocks.append(block.rstrip())
2811 2811 if kw['quiet']: # restore stdout
2812 2812 sys.stdout.close()
2813 2813 sys.stdout = stdout_save
2814 2814 print 'Finished replaying log file <%s>' % fname
2815 2815 if badblocks:
2816 2816 print >> sys.stderr, ('\nThe following lines/blocks in file '
2817 2817 '<%s> reported errors:' % fname)
2818 2818
2819 2819 for badline in badblocks:
2820 2820 print >> sys.stderr, badline
2821 2821 else: # regular file execution
2822 2822 try:
2823 2823 if sys.platform == 'win32' and sys.version_info < (2,5,1):
2824 2824 # Work around a bug in Python for Windows. The bug was
2825 2825 # fixed in in Python 2.5 r54159 and 54158, but that's still
2826 2826 # SVN Python as of March/07. For details, see:
2827 2827 # http://projects.scipy.org/ipython/ipython/ticket/123
2828 2828 try:
2829 2829 globs,locs = where[0:2]
2830 2830 except:
2831 2831 try:
2832 2832 globs = locs = where[0]
2833 2833 except:
2834 2834 globs = locs = globals()
2835 2835 exec file(fname) in globs,locs
2836 2836 else:
2837 2837 execfile(fname,*where)
2838 2838 except SyntaxError:
2839 2839 self.showsyntaxerror()
2840 2840 warn('Failure executing file: <%s>' % fname)
2841 2841 except SystemExit,status:
2842 2842 # Code that correctly sets the exit status flag to success (0)
2843 2843 # shouldn't be bothered with a traceback. Note that a plain
2844 2844 # sys.exit() does NOT set the message to 0 (it's empty) so that
2845 2845 # will still get a traceback. Note that the structure of the
2846 2846 # SystemExit exception changed between Python 2.4 and 2.5, so
2847 2847 # the checks must be done in a version-dependent way.
2848 2848 show = False
2849 2849
2850 2850 if sys.version_info[:2] > (2,5):
2851 2851 if status.message!=0 and not kw['exit_ignore']:
2852 2852 show = True
2853 2853 else:
2854 2854 if status.code and not kw['exit_ignore']:
2855 2855 show = True
2856 2856 if show:
2857 2857 self.showtraceback()
2858 2858 warn('Failure executing file: <%s>' % fname)
2859 2859 except:
2860 2860 self.showtraceback()
2861 2861 warn('Failure executing file: <%s>' % fname)
2862 2862
2863 2863 syspath_cleanup()
2864 2864
2865 2865 #************************* end of file <iplib.py> *****************************
@@ -1,3457 +1,3527 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Magic functions for InteractiveShell.
3 3 """
4 4
5 5 #*****************************************************************************
6 6 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
7 7 # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #*****************************************************************************
12 12
13 13 #****************************************************************************
14 14 # Modules and globals
15 15
16 16 # Python standard modules
17 17 import __builtin__
18 18 import bdb
19 19 import inspect
20 20 import os
21 21 import pdb
22 22 import pydoc
23 23 import sys
24 24 import re
25 25 import tempfile
26 26 import time
27 27 import cPickle as pickle
28 28 import textwrap
29 29 from cStringIO import StringIO
30 30 from getopt import getopt,GetoptError
31 31 from pprint import pprint, pformat
32 32
33 33 # cProfile was added in Python2.5
34 34 try:
35 35 import cProfile as profile
36 36 import pstats
37 37 except ImportError:
38 38 # profile isn't bundled by default in Debian for license reasons
39 39 try:
40 40 import profile,pstats
41 41 except ImportError:
42 42 profile = pstats = None
43 43
44 44 # Homebrewed
45 45 import IPython
46 46 from IPython.utils import wildcard
47 47 from IPython.core import debugger, oinspect
48 48 from IPython.core.fakemodule import FakeModule
49 49 from IPython.external.Itpl import Itpl, itpl, printpl,itplns
50 50 from IPython.utils.PyColorize import Parser
51 51 from IPython.utils.ipstruct import Struct
52 52 from IPython.core.macro import Macro
53 53 from IPython.utils.genutils import *
54 54 from IPython.utils import platutils
55 55 import IPython.utils.generics
56 56 from IPython.core import ipapi
57 57 from IPython.core.ipapi import UsageError
58 58 from IPython.testing import decorators as testdec
59 59
60 60 #***************************************************************************
61 61 # Utility functions
62 62 def on_off(tag):
63 63 """Return an ON/OFF string for a 1/0 input. Simple utility function."""
64 64 return ['OFF','ON'][tag]
65 65
66 66 class Bunch: pass
67 67
68 68 def compress_dhist(dh):
69 69 head, tail = dh[:-10], dh[-10:]
70 70
71 71 newhead = []
72 72 done = set()
73 73 for h in head:
74 74 if h in done:
75 75 continue
76 76 newhead.append(h)
77 77 done.add(h)
78 78
79 79 return newhead + tail
80 80
81 81
82 82 #***************************************************************************
83 83 # Main class implementing Magic functionality
84 84 class Magic:
85 85 """Magic functions for InteractiveShell.
86 86
87 87 Shell functions which can be reached as %function_name. All magic
88 88 functions should accept a string, which they can parse for their own
89 89 needs. This can make some functions easier to type, eg `%cd ../`
90 90 vs. `%cd("../")`
91 91
92 92 ALL definitions MUST begin with the prefix magic_. The user won't need it
93 93 at the command line, but it is is needed in the definition. """
94 94
95 95 # class globals
96 96 auto_status = ['Automagic is OFF, % prefix IS needed for magic functions.',
97 97 'Automagic is ON, % prefix NOT needed for magic functions.']
98 98
99 99 #......................................................................
100 100 # some utility functions
101 101
102 102 def __init__(self,shell):
103 103
104 104 self.options_table = {}
105 105 if profile is None:
106 106 self.magic_prun = self.profile_missing_notice
107 107 self.shell = shell
108 108
109 109 # namespace for holding state we may need
110 110 self._magic_state = Bunch()
111 111
112 112 def profile_missing_notice(self, *args, **kwargs):
113 113 error("""\
114 114 The profile module could not be found. It has been removed from the standard
115 115 python packages because of its non-free license. To use profiling, install the
116 116 python-profiler package from non-free.""")
117 117
118 118 def default_option(self,fn,optstr):
119 119 """Make an entry in the options_table for fn, with value optstr"""
120 120
121 121 if fn not in self.lsmagic():
122 122 error("%s is not a magic function" % fn)
123 123 self.options_table[fn] = optstr
124 124
125 125 def lsmagic(self):
126 126 """Return a list of currently available magic functions.
127 127
128 128 Gives a list of the bare names after mangling (['ls','cd', ...], not
129 129 ['magic_ls','magic_cd',...]"""
130 130
131 131 # FIXME. This needs a cleanup, in the way the magics list is built.
132 132
133 133 # magics in class definition
134 134 class_magic = lambda fn: fn.startswith('magic_') and \
135 135 callable(Magic.__dict__[fn])
136 136 # in instance namespace (run-time user additions)
137 137 inst_magic = lambda fn: fn.startswith('magic_') and \
138 138 callable(self.__dict__[fn])
139 139 # and bound magics by user (so they can access self):
140 140 inst_bound_magic = lambda fn: fn.startswith('magic_') and \
141 141 callable(self.__class__.__dict__[fn])
142 142 magics = filter(class_magic,Magic.__dict__.keys()) + \
143 143 filter(inst_magic,self.__dict__.keys()) + \
144 144 filter(inst_bound_magic,self.__class__.__dict__.keys())
145 145 out = []
146 146 for fn in set(magics):
147 147 out.append(fn.replace('magic_','',1))
148 148 out.sort()
149 149 return out
150 150
151 151 def extract_input_slices(self,slices,raw=False):
152 152 """Return as a string a set of input history slices.
153 153
154 154 Inputs:
155 155
156 156 - slices: the set of slices is given as a list of strings (like
157 157 ['1','4:8','9'], since this function is for use by magic functions
158 158 which get their arguments as strings.
159 159
160 160 Optional inputs:
161 161
162 162 - raw(False): by default, the processed input is used. If this is
163 163 true, the raw input history is used instead.
164 164
165 165 Note that slices can be called with two notations:
166 166
167 167 N:M -> standard python form, means including items N...(M-1).
168 168
169 169 N-M -> include items N..M (closed endpoint)."""
170 170
171 171 if raw:
172 172 hist = self.shell.input_hist_raw
173 173 else:
174 174 hist = self.shell.input_hist
175 175
176 176 cmds = []
177 177 for chunk in slices:
178 178 if ':' in chunk:
179 179 ini,fin = map(int,chunk.split(':'))
180 180 elif '-' in chunk:
181 181 ini,fin = map(int,chunk.split('-'))
182 182 fin += 1
183 183 else:
184 184 ini = int(chunk)
185 185 fin = ini+1
186 186 cmds.append(hist[ini:fin])
187 187 return cmds
188 188
189 189 def _ofind(self, oname, namespaces=None):
190 190 """Find an object in the available namespaces.
191 191
192 192 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
193 193
194 194 Has special code to detect magic functions.
195 195 """
196 196
197 197 oname = oname.strip()
198 198
199 199 alias_ns = None
200 200 if namespaces is None:
201 201 # Namespaces to search in:
202 202 # Put them in a list. The order is important so that we
203 203 # find things in the same order that Python finds them.
204 204 namespaces = [ ('Interactive', self.shell.user_ns),
205 205 ('IPython internal', self.shell.internal_ns),
206 206 ('Python builtin', __builtin__.__dict__),
207 207 ('Alias', self.shell.alias_table),
208 208 ]
209 209 alias_ns = self.shell.alias_table
210 210
211 211 # initialize results to 'null'
212 212 found = 0; obj = None; ospace = None; ds = None;
213 213 ismagic = 0; isalias = 0; parent = None
214 214
215 215 # Look for the given name by splitting it in parts. If the head is
216 216 # found, then we look for all the remaining parts as members, and only
217 217 # declare success if we can find them all.
218 218 oname_parts = oname.split('.')
219 219 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
220 220 for nsname,ns in namespaces:
221 221 try:
222 222 obj = ns[oname_head]
223 223 except KeyError:
224 224 continue
225 225 else:
226 226 #print 'oname_rest:', oname_rest # dbg
227 227 for part in oname_rest:
228 228 try:
229 229 parent = obj
230 230 obj = getattr(obj,part)
231 231 except:
232 232 # Blanket except b/c some badly implemented objects
233 233 # allow __getattr__ to raise exceptions other than
234 234 # AttributeError, which then crashes IPython.
235 235 break
236 236 else:
237 237 # If we finish the for loop (no break), we got all members
238 238 found = 1
239 239 ospace = nsname
240 240 if ns == alias_ns:
241 241 isalias = 1
242 242 break # namespace loop
243 243
244 244 # Try to see if it's magic
245 245 if not found:
246 246 if oname.startswith(self.shell.ESC_MAGIC):
247 247 oname = oname[1:]
248 248 obj = getattr(self,'magic_'+oname,None)
249 249 if obj is not None:
250 250 found = 1
251 251 ospace = 'IPython internal'
252 252 ismagic = 1
253 253
254 254 # Last try: special-case some literals like '', [], {}, etc:
255 255 if not found and oname_head in ["''",'""','[]','{}','()']:
256 256 obj = eval(oname_head)
257 257 found = 1
258 258 ospace = 'Interactive'
259 259
260 260 return {'found':found, 'obj':obj, 'namespace':ospace,
261 261 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
262 262
263 263 def arg_err(self,func):
264 264 """Print docstring if incorrect arguments were passed"""
265 265 print 'Error in arguments:'
266 266 print OInspect.getdoc(func)
267 267
268 268 def format_latex(self,strng):
269 269 """Format a string for latex inclusion."""
270 270
271 271 # Characters that need to be escaped for latex:
272 272 escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE)
273 273 # Magic command names as headers:
274 274 cmd_name_re = re.compile(r'^(%s.*?):' % self.shell.ESC_MAGIC,
275 275 re.MULTILINE)
276 276 # Magic commands
277 277 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % self.shell.ESC_MAGIC,
278 278 re.MULTILINE)
279 279 # Paragraph continue
280 280 par_re = re.compile(r'\\$',re.MULTILINE)
281 281
282 282 # The "\n" symbol
283 283 newline_re = re.compile(r'\\n')
284 284
285 285 # Now build the string for output:
286 286 #strng = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',strng)
287 287 strng = cmd_name_re.sub(r'\n\\bigskip\n\\texttt{\\textbf{ \1}}:',
288 288 strng)
289 289 strng = cmd_re.sub(r'\\texttt{\g<cmd>}',strng)
290 290 strng = par_re.sub(r'\\\\',strng)
291 291 strng = escape_re.sub(r'\\\1',strng)
292 292 strng = newline_re.sub(r'\\textbackslash{}n',strng)
293 293 return strng
294 294
295 295 def format_screen(self,strng):
296 296 """Format a string for screen printing.
297 297
298 298 This removes some latex-type format codes."""
299 299 # Paragraph continue
300 300 par_re = re.compile(r'\\$',re.MULTILINE)
301 301 strng = par_re.sub('',strng)
302 302 return strng
303 303
304 304 def parse_options(self,arg_str,opt_str,*long_opts,**kw):
305 305 """Parse options passed to an argument string.
306 306
307 307 The interface is similar to that of getopt(), but it returns back a
308 308 Struct with the options as keys and the stripped argument string still
309 309 as a string.
310 310
311 311 arg_str is quoted as a true sys.argv vector by using shlex.split.
312 312 This allows us to easily expand variables, glob files, quote
313 313 arguments, etc.
314 314
315 315 Options:
316 316 -mode: default 'string'. If given as 'list', the argument string is
317 317 returned as a list (split on whitespace) instead of a string.
318 318
319 319 -list_all: put all option values in lists. Normally only options
320 320 appearing more than once are put in a list.
321 321
322 322 -posix (True): whether to split the input line in POSIX mode or not,
323 323 as per the conventions outlined in the shlex module from the
324 324 standard library."""
325 325
326 326 # inject default options at the beginning of the input line
327 327 caller = sys._getframe(1).f_code.co_name.replace('magic_','')
328 328 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
329 329
330 330 mode = kw.get('mode','string')
331 331 if mode not in ['string','list']:
332 332 raise ValueError,'incorrect mode given: %s' % mode
333 333 # Get options
334 334 list_all = kw.get('list_all',0)
335 335 posix = kw.get('posix',True)
336 336
337 337 # Check if we have more than one argument to warrant extra processing:
338 338 odict = {} # Dictionary with options
339 339 args = arg_str.split()
340 340 if len(args) >= 1:
341 341 # If the list of inputs only has 0 or 1 thing in it, there's no
342 342 # need to look for options
343 343 argv = arg_split(arg_str,posix)
344 344 # Do regular option processing
345 345 try:
346 346 opts,args = getopt(argv,opt_str,*long_opts)
347 347 except GetoptError,e:
348 348 raise UsageError('%s ( allowed: "%s" %s)' % (e.msg,opt_str,
349 349 " ".join(long_opts)))
350 350 for o,a in opts:
351 351 if o.startswith('--'):
352 352 o = o[2:]
353 353 else:
354 354 o = o[1:]
355 355 try:
356 356 odict[o].append(a)
357 357 except AttributeError:
358 358 odict[o] = [odict[o],a]
359 359 except KeyError:
360 360 if list_all:
361 361 odict[o] = [a]
362 362 else:
363 363 odict[o] = a
364 364
365 365 # Prepare opts,args for return
366 366 opts = Struct(odict)
367 367 if mode == 'string':
368 368 args = ' '.join(args)
369 369
370 370 return opts,args
371 371
372 372 #......................................................................
373 373 # And now the actual magic functions
374 374
375 375 # Functions for IPython shell work (vars,funcs, config, etc)
376 376 def magic_lsmagic(self, parameter_s = ''):
377 377 """List currently available magic functions."""
378 378 mesc = self.shell.ESC_MAGIC
379 379 print 'Available magic functions:\n'+mesc+\
380 380 (' '+mesc).join(self.lsmagic())
381 381 print '\n' + Magic.auto_status[self.shell.rc.automagic]
382 382 return None
383 383
384 384 def magic_magic(self, parameter_s = ''):
385 385 """Print information about the magic function system.
386 386
387 387 Supported formats: -latex, -brief, -rest
388 388 """
389 389
390 390 mode = ''
391 391 try:
392 392 if parameter_s.split()[0] == '-latex':
393 393 mode = 'latex'
394 394 if parameter_s.split()[0] == '-brief':
395 395 mode = 'brief'
396 396 if parameter_s.split()[0] == '-rest':
397 397 mode = 'rest'
398 398 rest_docs = []
399 399 except:
400 400 pass
401 401
402 402 magic_docs = []
403 403 for fname in self.lsmagic():
404 404 mname = 'magic_' + fname
405 405 for space in (Magic,self,self.__class__):
406 406 try:
407 407 fn = space.__dict__[mname]
408 408 except KeyError:
409 409 pass
410 410 else:
411 411 break
412 412 if mode == 'brief':
413 413 # only first line
414 414 if fn.__doc__:
415 415 fndoc = fn.__doc__.split('\n',1)[0]
416 416 else:
417 417 fndoc = 'No documentation'
418 418 else:
419 419 if fn.__doc__:
420 420 fndoc = fn.__doc__.rstrip()
421 421 else:
422 422 fndoc = 'No documentation'
423 423
424 424
425 425 if mode == 'rest':
426 426 rest_docs.append('**%s%s**::\n\n\t%s\n\n' %(self.shell.ESC_MAGIC,
427 427 fname,fndoc))
428 428
429 429 else:
430 430 magic_docs.append('%s%s:\n\t%s\n' %(self.shell.ESC_MAGIC,
431 431 fname,fndoc))
432 432
433 433 magic_docs = ''.join(magic_docs)
434 434
435 435 if mode == 'rest':
436 436 return "".join(rest_docs)
437 437
438 438 if mode == 'latex':
439 439 print self.format_latex(magic_docs)
440 440 return
441 441 else:
442 442 magic_docs = self.format_screen(magic_docs)
443 443 if mode == 'brief':
444 444 return magic_docs
445 445
446 446 outmsg = """
447 447 IPython's 'magic' functions
448 448 ===========================
449 449
450 450 The magic function system provides a series of functions which allow you to
451 451 control the behavior of IPython itself, plus a lot of system-type
452 452 features. All these functions are prefixed with a % character, but parameters
453 453 are given without parentheses or quotes.
454 454
455 455 NOTE: If you have 'automagic' enabled (via the command line option or with the
456 456 %automagic function), you don't need to type in the % explicitly. By default,
457 457 IPython ships with automagic on, so you should only rarely need the % escape.
458 458
459 459 Example: typing '%cd mydir' (without the quotes) changes you working directory
460 460 to 'mydir', if it exists.
461 461
462 462 You can define your own magic functions to extend the system. See the supplied
463 463 ipythonrc and example-magic.py files for details (in your ipython
464 464 configuration directory, typically $HOME/.ipython/).
465 465
466 466 You can also define your own aliased names for magic functions. In your
467 467 ipythonrc file, placing a line like:
468 468
469 469 execute __IPYTHON__.magic_pf = __IPYTHON__.magic_profile
470 470
471 471 will define %pf as a new name for %profile.
472 472
473 473 You can also call magics in code using the ipmagic() function, which IPython
474 474 automatically adds to the builtin namespace. Type 'ipmagic?' for details.
475 475
476 476 For a list of the available magic functions, use %lsmagic. For a description
477 477 of any of them, type %magic_name?, e.g. '%cd?'.
478 478
479 479 Currently the magic system has the following functions:\n"""
480 480
481 481 mesc = self.shell.ESC_MAGIC
482 482 outmsg = ("%s\n%s\n\nSummary of magic functions (from %slsmagic):"
483 483 "\n\n%s%s\n\n%s" % (outmsg,
484 484 magic_docs,mesc,mesc,
485 485 (' '+mesc).join(self.lsmagic()),
486 486 Magic.auto_status[self.shell.rc.automagic] ) )
487 487
488 488 page(outmsg,screen_lines=self.shell.rc.screen_length)
489 489
490 490
491 491 def magic_autoindent(self, parameter_s = ''):
492 492 """Toggle autoindent on/off (if available)."""
493 493
494 494 self.shell.set_autoindent()
495 495 print "Automatic indentation is:",['OFF','ON'][self.shell.autoindent]
496 496
497 497
498 498 def magic_automagic(self, parameter_s = ''):
499 499 """Make magic functions callable without having to type the initial %.
500 500
501 501 Without argumentsl toggles on/off (when off, you must call it as
502 502 %automagic, of course). With arguments it sets the value, and you can
503 503 use any of (case insensitive):
504 504
505 505 - on,1,True: to activate
506 506
507 507 - off,0,False: to deactivate.
508 508
509 509 Note that magic functions have lowest priority, so if there's a
510 510 variable whose name collides with that of a magic fn, automagic won't
511 511 work for that function (you get the variable instead). However, if you
512 512 delete the variable (del var), the previously shadowed magic function
513 513 becomes visible to automagic again."""
514 514
515 515 rc = self.shell.rc
516 516 arg = parameter_s.lower()
517 517 if parameter_s in ('on','1','true'):
518 518 rc.automagic = True
519 519 elif parameter_s in ('off','0','false'):
520 520 rc.automagic = False
521 521 else:
522 522 rc.automagic = not rc.automagic
523 523 print '\n' + Magic.auto_status[rc.automagic]
524 524
525 525 @testdec.skip_doctest
526 526 def magic_autocall(self, parameter_s = ''):
527 527 """Make functions callable without having to type parentheses.
528 528
529 529 Usage:
530 530
531 531 %autocall [mode]
532 532
533 533 The mode can be one of: 0->Off, 1->Smart, 2->Full. If not given, the
534 534 value is toggled on and off (remembering the previous state).
535 535
536 536 In more detail, these values mean:
537 537
538 538 0 -> fully disabled
539 539
540 540 1 -> active, but do not apply if there are no arguments on the line.
541 541
542 542 In this mode, you get:
543 543
544 544 In [1]: callable
545 545 Out[1]: <built-in function callable>
546 546
547 547 In [2]: callable 'hello'
548 548 ------> callable('hello')
549 549 Out[2]: False
550 550
551 551 2 -> Active always. Even if no arguments are present, the callable
552 552 object is called:
553 553
554 554 In [2]: float
555 555 ------> float()
556 556 Out[2]: 0.0
557 557
558 558 Note that even with autocall off, you can still use '/' at the start of
559 559 a line to treat the first argument on the command line as a function
560 560 and add parentheses to it:
561 561
562 562 In [8]: /str 43
563 563 ------> str(43)
564 564 Out[8]: '43'
565 565
566 566 # all-random (note for auto-testing)
567 567 """
568 568
569 569 rc = self.shell.rc
570 570
571 571 if parameter_s:
572 572 arg = int(parameter_s)
573 573 else:
574 574 arg = 'toggle'
575 575
576 576 if not arg in (0,1,2,'toggle'):
577 577 error('Valid modes: (0->Off, 1->Smart, 2->Full')
578 578 return
579 579
580 580 if arg in (0,1,2):
581 581 rc.autocall = arg
582 582 else: # toggle
583 583 if rc.autocall:
584 584 self._magic_state.autocall_save = rc.autocall
585 585 rc.autocall = 0
586 586 else:
587 587 try:
588 588 rc.autocall = self._magic_state.autocall_save
589 589 except AttributeError:
590 590 rc.autocall = self._magic_state.autocall_save = 1
591 591
592 592 print "Automatic calling is:",['OFF','Smart','Full'][rc.autocall]
593 593
594 594 def magic_system_verbose(self, parameter_s = ''):
595 595 """Set verbose printing of system calls.
596 596
597 597 If called without an argument, act as a toggle"""
598 598
599 599 if parameter_s:
600 600 val = bool(eval(parameter_s))
601 601 else:
602 602 val = None
603 603
604 604 self.shell.rc_set_toggle('system_verbose',val)
605 605 print "System verbose printing is:",\
606 606 ['OFF','ON'][self.shell.rc.system_verbose]
607 607
608 608
609 609 def magic_page(self, parameter_s=''):
610 610 """Pretty print the object and display it through a pager.
611 611
612 612 %page [options] OBJECT
613 613
614 614 If no object is given, use _ (last output).
615 615
616 616 Options:
617 617
618 618 -r: page str(object), don't pretty-print it."""
619 619
620 620 # After a function contributed by Olivier Aubert, slightly modified.
621 621
622 622 # Process options/args
623 623 opts,args = self.parse_options(parameter_s,'r')
624 624 raw = 'r' in opts
625 625
626 626 oname = args and args or '_'
627 627 info = self._ofind(oname)
628 628 if info['found']:
629 629 txt = (raw and str or pformat)( info['obj'] )
630 630 page(txt)
631 631 else:
632 632 print 'Object `%s` not found' % oname
633 633
634 634 def magic_profile(self, parameter_s=''):
635 635 """Print your currently active IPyhton profile."""
636 636 if self.shell.rc.profile:
637 637 printpl('Current IPython profile: $self.shell.rc.profile.')
638 638 else:
639 639 print 'No profile active.'
640 640
641 641 def magic_pinfo(self, parameter_s='', namespaces=None):
642 642 """Provide detailed information about an object.
643 643
644 644 '%pinfo object' is just a synonym for object? or ?object."""
645 645
646 646 #print 'pinfo par: <%s>' % parameter_s # dbg
647 647
648 648
649 649 # detail_level: 0 -> obj? , 1 -> obj??
650 650 detail_level = 0
651 651 # We need to detect if we got called as 'pinfo pinfo foo', which can
652 652 # happen if the user types 'pinfo foo?' at the cmd line.
653 653 pinfo,qmark1,oname,qmark2 = \
654 654 re.match('(pinfo )?(\?*)(.*?)(\??$)',parameter_s).groups()
655 655 if pinfo or qmark1 or qmark2:
656 656 detail_level = 1
657 657 if "*" in oname:
658 658 self.magic_psearch(oname)
659 659 else:
660 660 self._inspect('pinfo', oname, detail_level=detail_level,
661 661 namespaces=namespaces)
662 662
663 663 def magic_pdef(self, parameter_s='', namespaces=None):
664 664 """Print the definition header for any callable object.
665 665
666 666 If the object is a class, print the constructor information."""
667 667 self._inspect('pdef',parameter_s, namespaces)
668 668
669 669 def magic_pdoc(self, parameter_s='', namespaces=None):
670 670 """Print the docstring for an object.
671 671
672 672 If the given object is a class, it will print both the class and the
673 673 constructor docstrings."""
674 674 self._inspect('pdoc',parameter_s, namespaces)
675 675
676 676 def magic_psource(self, parameter_s='', namespaces=None):
677 677 """Print (or run through pager) the source code for an object."""
678 678 self._inspect('psource',parameter_s, namespaces)
679 679
680 680 def magic_pfile(self, parameter_s=''):
681 681 """Print (or run through pager) the file where an object is defined.
682 682
683 683 The file opens at the line where the object definition begins. IPython
684 684 will honor the environment variable PAGER if set, and otherwise will
685 685 do its best to print the file in a convenient form.
686 686
687 687 If the given argument is not an object currently defined, IPython will
688 688 try to interpret it as a filename (automatically adding a .py extension
689 689 if needed). You can thus use %pfile as a syntax highlighting code
690 690 viewer."""
691 691
692 692 # first interpret argument as an object name
693 693 out = self._inspect('pfile',parameter_s)
694 694 # if not, try the input as a filename
695 695 if out == 'not found':
696 696 try:
697 697 filename = get_py_filename(parameter_s)
698 698 except IOError,msg:
699 699 print msg
700 700 return
701 701 page(self.shell.inspector.format(file(filename).read()))
702 702
703 703 def _inspect(self,meth,oname,namespaces=None,**kw):
704 704 """Generic interface to the inspector system.
705 705
706 706 This function is meant to be called by pdef, pdoc & friends."""
707 707
708 708 #oname = oname.strip()
709 709 #print '1- oname: <%r>' % oname # dbg
710 710 try:
711 711 oname = oname.strip().encode('ascii')
712 712 #print '2- oname: <%r>' % oname # dbg
713 713 except UnicodeEncodeError:
714 714 print 'Python identifiers can only contain ascii characters.'
715 715 return 'not found'
716 716
717 717 info = Struct(self._ofind(oname, namespaces))
718 718
719 719 if info.found:
720 720 try:
721 721 IPython.utils.generics.inspect_object(info.obj)
722 722 return
723 723 except ipapi.TryNext:
724 724 pass
725 725 # Get the docstring of the class property if it exists.
726 726 path = oname.split('.')
727 727 root = '.'.join(path[:-1])
728 728 if info.parent is not None:
729 729 try:
730 730 target = getattr(info.parent, '__class__')
731 731 # The object belongs to a class instance.
732 732 try:
733 733 target = getattr(target, path[-1])
734 734 # The class defines the object.
735 735 if isinstance(target, property):
736 736 oname = root + '.__class__.' + path[-1]
737 737 info = Struct(self._ofind(oname))
738 738 except AttributeError: pass
739 739 except AttributeError: pass
740 740
741 741 pmethod = getattr(self.shell.inspector,meth)
742 742 formatter = info.ismagic and self.format_screen or None
743 743 if meth == 'pdoc':
744 744 pmethod(info.obj,oname,formatter)
745 745 elif meth == 'pinfo':
746 746 pmethod(info.obj,oname,formatter,info,**kw)
747 747 else:
748 748 pmethod(info.obj,oname)
749 749 else:
750 750 print 'Object `%s` not found.' % oname
751 751 return 'not found' # so callers can take other action
752 752
753 753 def magic_psearch(self, parameter_s=''):
754 754 """Search for object in namespaces by wildcard.
755 755
756 756 %psearch [options] PATTERN [OBJECT TYPE]
757 757
758 758 Note: ? can be used as a synonym for %psearch, at the beginning or at
759 759 the end: both a*? and ?a* are equivalent to '%psearch a*'. Still, the
760 760 rest of the command line must be unchanged (options come first), so
761 761 for example the following forms are equivalent
762 762
763 763 %psearch -i a* function
764 764 -i a* function?
765 765 ?-i a* function
766 766
767 767 Arguments:
768 768
769 769 PATTERN
770 770
771 771 where PATTERN is a string containing * as a wildcard similar to its
772 772 use in a shell. The pattern is matched in all namespaces on the
773 773 search path. By default objects starting with a single _ are not
774 774 matched, many IPython generated objects have a single
775 775 underscore. The default is case insensitive matching. Matching is
776 776 also done on the attributes of objects and not only on the objects
777 777 in a module.
778 778
779 779 [OBJECT TYPE]
780 780
781 781 Is the name of a python type from the types module. The name is
782 782 given in lowercase without the ending type, ex. StringType is
783 783 written string. By adding a type here only objects matching the
784 784 given type are matched. Using all here makes the pattern match all
785 785 types (this is the default).
786 786
787 787 Options:
788 788
789 789 -a: makes the pattern match even objects whose names start with a
790 790 single underscore. These names are normally ommitted from the
791 791 search.
792 792
793 793 -i/-c: make the pattern case insensitive/sensitive. If neither of
794 794 these options is given, the default is read from your ipythonrc
795 795 file. The option name which sets this value is
796 796 'wildcards_case_sensitive'. If this option is not specified in your
797 797 ipythonrc file, IPython's internal default is to do a case sensitive
798 798 search.
799 799
800 800 -e/-s NAMESPACE: exclude/search a given namespace. The pattern you
801 801 specifiy can be searched in any of the following namespaces:
802 802 'builtin', 'user', 'user_global','internal', 'alias', where
803 803 'builtin' and 'user' are the search defaults. Note that you should
804 804 not use quotes when specifying namespaces.
805 805
806 806 'Builtin' contains the python module builtin, 'user' contains all
807 807 user data, 'alias' only contain the shell aliases and no python
808 808 objects, 'internal' contains objects used by IPython. The
809 809 'user_global' namespace is only used by embedded IPython instances,
810 810 and it contains module-level globals. You can add namespaces to the
811 811 search with -s or exclude them with -e (these options can be given
812 812 more than once).
813 813
814 814 Examples:
815 815
816 816 %psearch a* -> objects beginning with an a
817 817 %psearch -e builtin a* -> objects NOT in the builtin space starting in a
818 818 %psearch a* function -> all functions beginning with an a
819 819 %psearch re.e* -> objects beginning with an e in module re
820 820 %psearch r*.e* -> objects that start with e in modules starting in r
821 821 %psearch r*.* string -> all strings in modules beginning with r
822 822
823 823 Case sensitve search:
824 824
825 825 %psearch -c a* list all object beginning with lower case a
826 826
827 827 Show objects beginning with a single _:
828 828
829 829 %psearch -a _* list objects beginning with a single underscore"""
830 830 try:
831 831 parameter_s = parameter_s.encode('ascii')
832 832 except UnicodeEncodeError:
833 833 print 'Python identifiers can only contain ascii characters.'
834 834 return
835 835
836 836 # default namespaces to be searched
837 837 def_search = ['user','builtin']
838 838
839 839 # Process options/args
840 840 opts,args = self.parse_options(parameter_s,'cias:e:',list_all=True)
841 841 opt = opts.get
842 842 shell = self.shell
843 843 psearch = shell.inspector.psearch
844 844
845 845 # select case options
846 846 if opts.has_key('i'):
847 847 ignore_case = True
848 848 elif opts.has_key('c'):
849 849 ignore_case = False
850 850 else:
851 851 ignore_case = not shell.rc.wildcards_case_sensitive
852 852
853 853 # Build list of namespaces to search from user options
854 854 def_search.extend(opt('s',[]))
855 855 ns_exclude = ns_exclude=opt('e',[])
856 856 ns_search = [nm for nm in def_search if nm not in ns_exclude]
857 857
858 858 # Call the actual search
859 859 try:
860 860 psearch(args,shell.ns_table,ns_search,
861 861 show_all=opt('a'),ignore_case=ignore_case)
862 862 except:
863 863 shell.showtraceback()
864 864
865 865 def magic_who_ls(self, parameter_s=''):
866 866 """Return a sorted list of all interactive variables.
867 867
868 868 If arguments are given, only variables of types matching these
869 869 arguments are returned."""
870 870
871 871 user_ns = self.shell.user_ns
872 872 internal_ns = self.shell.internal_ns
873 873 user_config_ns = self.shell.user_config_ns
874 874 out = []
875 875 typelist = parameter_s.split()
876 876
877 877 for i in user_ns:
878 878 if not (i.startswith('_') or i.startswith('_i')) \
879 879 and not (i in internal_ns or i in user_config_ns):
880 880 if typelist:
881 881 if type(user_ns[i]).__name__ in typelist:
882 882 out.append(i)
883 883 else:
884 884 out.append(i)
885 885 out.sort()
886 886 return out
887 887
888 888 def magic_who(self, parameter_s=''):
889 889 """Print all interactive variables, with some minimal formatting.
890 890
891 891 If any arguments are given, only variables whose type matches one of
892 892 these are printed. For example:
893 893
894 894 %who function str
895 895
896 896 will only list functions and strings, excluding all other types of
897 897 variables. To find the proper type names, simply use type(var) at a
898 898 command line to see how python prints type names. For example:
899 899
900 900 In [1]: type('hello')\\
901 901 Out[1]: <type 'str'>
902 902
903 903 indicates that the type name for strings is 'str'.
904 904
905 905 %who always excludes executed names loaded through your configuration
906 906 file and things which are internal to IPython.
907 907
908 908 This is deliberate, as typically you may load many modules and the
909 909 purpose of %who is to show you only what you've manually defined."""
910 910
911 911 varlist = self.magic_who_ls(parameter_s)
912 912 if not varlist:
913 913 if parameter_s:
914 914 print 'No variables match your requested type.'
915 915 else:
916 916 print 'Interactive namespace is empty.'
917 917 return
918 918
919 919 # if we have variables, move on...
920 920 count = 0
921 921 for i in varlist:
922 922 print i+'\t',
923 923 count += 1
924 924 if count > 8:
925 925 count = 0
926 926 print
927 927 print
928 928
929 929 def magic_whos(self, parameter_s=''):
930 930 """Like %who, but gives some extra information about each variable.
931 931
932 932 The same type filtering of %who can be applied here.
933 933
934 934 For all variables, the type is printed. Additionally it prints:
935 935
936 936 - For {},[],(): their length.
937 937
938 938 - For numpy and Numeric arrays, a summary with shape, number of
939 939 elements, typecode and size in memory.
940 940
941 941 - Everything else: a string representation, snipping their middle if
942 942 too long."""
943 943
944 944 varnames = self.magic_who_ls(parameter_s)
945 945 if not varnames:
946 946 if parameter_s:
947 947 print 'No variables match your requested type.'
948 948 else:
949 949 print 'Interactive namespace is empty.'
950 950 return
951 951
952 952 # if we have variables, move on...
953 953
954 954 # for these types, show len() instead of data:
955 955 seq_types = [types.DictType,types.ListType,types.TupleType]
956 956
957 957 # for numpy/Numeric arrays, display summary info
958 958 try:
959 959 import numpy
960 960 except ImportError:
961 961 ndarray_type = None
962 962 else:
963 963 ndarray_type = numpy.ndarray.__name__
964 964 try:
965 965 import Numeric
966 966 except ImportError:
967 967 array_type = None
968 968 else:
969 969 array_type = Numeric.ArrayType.__name__
970 970
971 971 # Find all variable names and types so we can figure out column sizes
972 972 def get_vars(i):
973 973 return self.shell.user_ns[i]
974 974
975 975 # some types are well known and can be shorter
976 976 abbrevs = {'IPython.core.macro.Macro' : 'Macro'}
977 977 def type_name(v):
978 978 tn = type(v).__name__
979 979 return abbrevs.get(tn,tn)
980 980
981 981 varlist = map(get_vars,varnames)
982 982
983 983 typelist = []
984 984 for vv in varlist:
985 985 tt = type_name(vv)
986 986
987 987 if tt=='instance':
988 988 typelist.append( abbrevs.get(str(vv.__class__),
989 989 str(vv.__class__)))
990 990 else:
991 991 typelist.append(tt)
992 992
993 993 # column labels and # of spaces as separator
994 994 varlabel = 'Variable'
995 995 typelabel = 'Type'
996 996 datalabel = 'Data/Info'
997 997 colsep = 3
998 998 # variable format strings
999 999 vformat = "$vname.ljust(varwidth)$vtype.ljust(typewidth)"
1000 1000 vfmt_short = '$vstr[:25]<...>$vstr[-25:]'
1001 1001 aformat = "%s: %s elems, type `%s`, %s bytes"
1002 1002 # find the size of the columns to format the output nicely
1003 1003 varwidth = max(max(map(len,varnames)), len(varlabel)) + colsep
1004 1004 typewidth = max(max(map(len,typelist)), len(typelabel)) + colsep
1005 1005 # table header
1006 1006 print varlabel.ljust(varwidth) + typelabel.ljust(typewidth) + \
1007 1007 ' '+datalabel+'\n' + '-'*(varwidth+typewidth+len(datalabel)+1)
1008 1008 # and the table itself
1009 1009 kb = 1024
1010 1010 Mb = 1048576 # kb**2
1011 1011 for vname,var,vtype in zip(varnames,varlist,typelist):
1012 1012 print itpl(vformat),
1013 1013 if vtype in seq_types:
1014 1014 print len(var)
1015 1015 elif vtype in [array_type,ndarray_type]:
1016 1016 vshape = str(var.shape).replace(',','').replace(' ','x')[1:-1]
1017 1017 if vtype==ndarray_type:
1018 1018 # numpy
1019 1019 vsize = var.size
1020 1020 vbytes = vsize*var.itemsize
1021 1021 vdtype = var.dtype
1022 1022 else:
1023 1023 # Numeric
1024 1024 vsize = Numeric.size(var)
1025 1025 vbytes = vsize*var.itemsize()
1026 1026 vdtype = var.typecode()
1027 1027
1028 1028 if vbytes < 100000:
1029 1029 print aformat % (vshape,vsize,vdtype,vbytes)
1030 1030 else:
1031 1031 print aformat % (vshape,vsize,vdtype,vbytes),
1032 1032 if vbytes < Mb:
1033 1033 print '(%s kb)' % (vbytes/kb,)
1034 1034 else:
1035 1035 print '(%s Mb)' % (vbytes/Mb,)
1036 1036 else:
1037 1037 try:
1038 1038 vstr = str(var)
1039 1039 except UnicodeEncodeError:
1040 1040 vstr = unicode(var).encode(sys.getdefaultencoding(),
1041 1041 'backslashreplace')
1042 1042 vstr = vstr.replace('\n','\\n')
1043 1043 if len(vstr) < 50:
1044 1044 print vstr
1045 1045 else:
1046 1046 printpl(vfmt_short)
1047 1047
1048 1048 def magic_reset(self, parameter_s=''):
1049 1049 """Resets the namespace by removing all names defined by the user.
1050 1050
1051 1051 Input/Output history are left around in case you need them.
1052 1052
1053 1053 Parameters
1054 1054 ----------
1055 1055 -y : force reset without asking for confirmation.
1056 1056
1057 1057 Examples
1058 1058 --------
1059 1059 In [6]: a = 1
1060 1060
1061 1061 In [7]: a
1062 1062 Out[7]: 1
1063 1063
1064 1064 In [8]: 'a' in _ip.user_ns
1065 1065 Out[8]: True
1066 1066
1067 1067 In [9]: %reset -f
1068 1068
1069 1069 In [10]: 'a' in _ip.user_ns
1070 1070 Out[10]: False
1071 1071 """
1072 1072
1073 1073 if parameter_s == '-f':
1074 1074 ans = True
1075 1075 else:
1076 1076 ans = self.shell.ask_yes_no(
1077 1077 "Once deleted, variables cannot be recovered. Proceed (y/[n])? ")
1078 1078 if not ans:
1079 1079 print 'Nothing done.'
1080 1080 return
1081 1081 user_ns = self.shell.user_ns
1082 1082 for i in self.magic_who_ls():
1083 1083 del(user_ns[i])
1084 1084
1085 1085 # Also flush the private list of module references kept for script
1086 1086 # execution protection
1087 1087 self.shell.clear_main_mod_cache()
1088 1088
1089 1089 def magic_logstart(self,parameter_s=''):
1090 1090 """Start logging anywhere in a session.
1091 1091
1092 1092 %logstart [-o|-r|-t] [log_name [log_mode]]
1093 1093
1094 1094 If no name is given, it defaults to a file named 'ipython_log.py' in your
1095 1095 current directory, in 'rotate' mode (see below).
1096 1096
1097 1097 '%logstart name' saves to file 'name' in 'backup' mode. It saves your
1098 1098 history up to that point and then continues logging.
1099 1099
1100 1100 %logstart takes a second optional parameter: logging mode. This can be one
1101 1101 of (note that the modes are given unquoted):\\
1102 1102 append: well, that says it.\\
1103 1103 backup: rename (if exists) to name~ and start name.\\
1104 1104 global: single logfile in your home dir, appended to.\\
1105 1105 over : overwrite existing log.\\
1106 1106 rotate: create rotating logs name.1~, name.2~, etc.
1107 1107
1108 1108 Options:
1109 1109
1110 1110 -o: log also IPython's output. In this mode, all commands which
1111 1111 generate an Out[NN] prompt are recorded to the logfile, right after
1112 1112 their corresponding input line. The output lines are always
1113 1113 prepended with a '#[Out]# ' marker, so that the log remains valid
1114 1114 Python code.
1115 1115
1116 1116 Since this marker is always the same, filtering only the output from
1117 1117 a log is very easy, using for example a simple awk call:
1118 1118
1119 1119 awk -F'#\\[Out\\]# ' '{if($2) {print $2}}' ipython_log.py
1120 1120
1121 1121 -r: log 'raw' input. Normally, IPython's logs contain the processed
1122 1122 input, so that user lines are logged in their final form, converted
1123 1123 into valid Python. For example, %Exit is logged as
1124 1124 '_ip.magic("Exit"). If the -r flag is given, all input is logged
1125 1125 exactly as typed, with no transformations applied.
1126 1126
1127 1127 -t: put timestamps before each input line logged (these are put in
1128 1128 comments)."""
1129 1129
1130 1130 opts,par = self.parse_options(parameter_s,'ort')
1131 1131 log_output = 'o' in opts
1132 1132 log_raw_input = 'r' in opts
1133 1133 timestamp = 't' in opts
1134 1134
1135 1135 rc = self.shell.rc
1136 1136 logger = self.shell.logger
1137 1137
1138 1138 # if no args are given, the defaults set in the logger constructor by
1139 1139 # ipytohn remain valid
1140 1140 if par:
1141 1141 try:
1142 1142 logfname,logmode = par.split()
1143 1143 except:
1144 1144 logfname = par
1145 1145 logmode = 'backup'
1146 1146 else:
1147 1147 logfname = logger.logfname
1148 1148 logmode = logger.logmode
1149 1149 # put logfname into rc struct as if it had been called on the command
1150 1150 # line, so it ends up saved in the log header Save it in case we need
1151 1151 # to restore it...
1152 1152 old_logfile = rc.opts.get('logfile','')
1153 1153 if logfname:
1154 1154 logfname = os.path.expanduser(logfname)
1155 1155 rc.opts.logfile = logfname
1156 1156 loghead = self.shell.loghead_tpl % (rc.opts,rc.args)
1157 1157 try:
1158 1158 started = logger.logstart(logfname,loghead,logmode,
1159 1159 log_output,timestamp,log_raw_input)
1160 1160 except:
1161 1161 rc.opts.logfile = old_logfile
1162 1162 warn("Couldn't start log: %s" % sys.exc_info()[1])
1163 1163 else:
1164 1164 # log input history up to this point, optionally interleaving
1165 1165 # output if requested
1166 1166
1167 1167 if timestamp:
1168 1168 # disable timestamping for the previous history, since we've
1169 1169 # lost those already (no time machine here).
1170 1170 logger.timestamp = False
1171 1171
1172 1172 if log_raw_input:
1173 1173 input_hist = self.shell.input_hist_raw
1174 1174 else:
1175 1175 input_hist = self.shell.input_hist
1176 1176
1177 1177 if log_output:
1178 1178 log_write = logger.log_write
1179 1179 output_hist = self.shell.output_hist
1180 1180 for n in range(1,len(input_hist)-1):
1181 1181 log_write(input_hist[n].rstrip())
1182 1182 if n in output_hist:
1183 1183 log_write(repr(output_hist[n]),'output')
1184 1184 else:
1185 1185 logger.log_write(input_hist[1:])
1186 1186 if timestamp:
1187 1187 # re-enable timestamping
1188 1188 logger.timestamp = True
1189 1189
1190 1190 print ('Activating auto-logging. '
1191 1191 'Current session state plus future input saved.')
1192 1192 logger.logstate()
1193 1193
1194 1194 def magic_logstop(self,parameter_s=''):
1195 1195 """Fully stop logging and close log file.
1196 1196
1197 1197 In order to start logging again, a new %logstart call needs to be made,
1198 1198 possibly (though not necessarily) with a new filename, mode and other
1199 1199 options."""
1200 1200 self.logger.logstop()
1201 1201
1202 1202 def magic_logoff(self,parameter_s=''):
1203 1203 """Temporarily stop logging.
1204 1204
1205 1205 You must have previously started logging."""
1206 1206 self.shell.logger.switch_log(0)
1207 1207
1208 1208 def magic_logon(self,parameter_s=''):
1209 1209 """Restart logging.
1210 1210
1211 1211 This function is for restarting logging which you've temporarily
1212 1212 stopped with %logoff. For starting logging for the first time, you
1213 1213 must use the %logstart function, which allows you to specify an
1214 1214 optional log filename."""
1215 1215
1216 1216 self.shell.logger.switch_log(1)
1217 1217
1218 1218 def magic_logstate(self,parameter_s=''):
1219 1219 """Print the status of the logging system."""
1220 1220
1221 1221 self.shell.logger.logstate()
1222 1222
1223 1223 def magic_pdb(self, parameter_s=''):
1224 1224 """Control the automatic calling of the pdb interactive debugger.
1225 1225
1226 1226 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
1227 1227 argument it works as a toggle.
1228 1228
1229 1229 When an exception is triggered, IPython can optionally call the
1230 1230 interactive pdb debugger after the traceback printout. %pdb toggles
1231 1231 this feature on and off.
1232 1232
1233 1233 The initial state of this feature is set in your ipythonrc
1234 1234 configuration file (the variable is called 'pdb').
1235 1235
1236 1236 If you want to just activate the debugger AFTER an exception has fired,
1237 1237 without having to type '%pdb on' and rerunning your code, you can use
1238 1238 the %debug magic."""
1239 1239
1240 1240 par = parameter_s.strip().lower()
1241 1241
1242 1242 if par:
1243 1243 try:
1244 1244 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
1245 1245 except KeyError:
1246 1246 print ('Incorrect argument. Use on/1, off/0, '
1247 1247 'or nothing for a toggle.')
1248 1248 return
1249 1249 else:
1250 1250 # toggle
1251 1251 new_pdb = not self.shell.call_pdb
1252 1252
1253 1253 # set on the shell
1254 1254 self.shell.call_pdb = new_pdb
1255 1255 print 'Automatic pdb calling has been turned',on_off(new_pdb)
1256 1256
1257 1257 def magic_debug(self, parameter_s=''):
1258 1258 """Activate the interactive debugger in post-mortem mode.
1259 1259
1260 1260 If an exception has just occurred, this lets you inspect its stack
1261 1261 frames interactively. Note that this will always work only on the last
1262 1262 traceback that occurred, so you must call this quickly after an
1263 1263 exception that you wish to inspect has fired, because if another one
1264 1264 occurs, it clobbers the previous one.
1265 1265
1266 1266 If you want IPython to automatically do this on every exception, see
1267 1267 the %pdb magic for more details.
1268 1268 """
1269 1269
1270 1270 self.shell.debugger(force=True)
1271 1271
1272 1272 @testdec.skip_doctest
1273 1273 def magic_prun(self, parameter_s ='',user_mode=1,
1274 1274 opts=None,arg_lst=None,prog_ns=None):
1275 1275
1276 1276 """Run a statement through the python code profiler.
1277 1277
1278 1278 Usage:
1279 1279 %prun [options] statement
1280 1280
1281 1281 The given statement (which doesn't require quote marks) is run via the
1282 1282 python profiler in a manner similar to the profile.run() function.
1283 1283 Namespaces are internally managed to work correctly; profile.run
1284 1284 cannot be used in IPython because it makes certain assumptions about
1285 1285 namespaces which do not hold under IPython.
1286 1286
1287 1287 Options:
1288 1288
1289 1289 -l <limit>: you can place restrictions on what or how much of the
1290 1290 profile gets printed. The limit value can be:
1291 1291
1292 1292 * A string: only information for function names containing this string
1293 1293 is printed.
1294 1294
1295 1295 * An integer: only these many lines are printed.
1296 1296
1297 1297 * A float (between 0 and 1): this fraction of the report is printed
1298 1298 (for example, use a limit of 0.4 to see the topmost 40% only).
1299 1299
1300 1300 You can combine several limits with repeated use of the option. For
1301 1301 example, '-l __init__ -l 5' will print only the topmost 5 lines of
1302 1302 information about class constructors.
1303 1303
1304 1304 -r: return the pstats.Stats object generated by the profiling. This
1305 1305 object has all the information about the profile in it, and you can
1306 1306 later use it for further analysis or in other functions.
1307 1307
1308 1308 -s <key>: sort profile by given key. You can provide more than one key
1309 1309 by using the option several times: '-s key1 -s key2 -s key3...'. The
1310 1310 default sorting key is 'time'.
1311 1311
1312 1312 The following is copied verbatim from the profile documentation
1313 1313 referenced below:
1314 1314
1315 1315 When more than one key is provided, additional keys are used as
1316 1316 secondary criteria when the there is equality in all keys selected
1317 1317 before them.
1318 1318
1319 1319 Abbreviations can be used for any key names, as long as the
1320 1320 abbreviation is unambiguous. The following are the keys currently
1321 1321 defined:
1322 1322
1323 1323 Valid Arg Meaning
1324 1324 "calls" call count
1325 1325 "cumulative" cumulative time
1326 1326 "file" file name
1327 1327 "module" file name
1328 1328 "pcalls" primitive call count
1329 1329 "line" line number
1330 1330 "name" function name
1331 1331 "nfl" name/file/line
1332 1332 "stdname" standard name
1333 1333 "time" internal time
1334 1334
1335 1335 Note that all sorts on statistics are in descending order (placing
1336 1336 most time consuming items first), where as name, file, and line number
1337 1337 searches are in ascending order (i.e., alphabetical). The subtle
1338 1338 distinction between "nfl" and "stdname" is that the standard name is a
1339 1339 sort of the name as printed, which means that the embedded line
1340 1340 numbers get compared in an odd way. For example, lines 3, 20, and 40
1341 1341 would (if the file names were the same) appear in the string order
1342 1342 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
1343 1343 line numbers. In fact, sort_stats("nfl") is the same as
1344 1344 sort_stats("name", "file", "line").
1345 1345
1346 1346 -T <filename>: save profile results as shown on screen to a text
1347 1347 file. The profile is still shown on screen.
1348 1348
1349 1349 -D <filename>: save (via dump_stats) profile statistics to given
1350 1350 filename. This data is in a format understod by the pstats module, and
1351 1351 is generated by a call to the dump_stats() method of profile
1352 1352 objects. The profile is still shown on screen.
1353 1353
1354 1354 If you want to run complete programs under the profiler's control, use
1355 1355 '%run -p [prof_opts] filename.py [args to program]' where prof_opts
1356 1356 contains profiler specific options as described here.
1357 1357
1358 1358 You can read the complete documentation for the profile module with::
1359 1359
1360 1360 In [1]: import profile; profile.help()
1361 1361 """
1362 1362
1363 1363 opts_def = Struct(D=[''],l=[],s=['time'],T=[''])
1364 1364 # protect user quote marks
1365 1365 parameter_s = parameter_s.replace('"',r'\"').replace("'",r"\'")
1366 1366
1367 1367 if user_mode: # regular user call
1368 1368 opts,arg_str = self.parse_options(parameter_s,'D:l:rs:T:',
1369 1369 list_all=1)
1370 1370 namespace = self.shell.user_ns
1371 1371 else: # called to run a program by %run -p
1372 1372 try:
1373 1373 filename = get_py_filename(arg_lst[0])
1374 1374 except IOError,msg:
1375 1375 error(msg)
1376 1376 return
1377 1377
1378 1378 arg_str = 'execfile(filename,prog_ns)'
1379 1379 namespace = locals()
1380 1380
1381 1381 opts.merge(opts_def)
1382 1382
1383 1383 prof = profile.Profile()
1384 1384 try:
1385 1385 prof = prof.runctx(arg_str,namespace,namespace)
1386 1386 sys_exit = ''
1387 1387 except SystemExit:
1388 1388 sys_exit = """*** SystemExit exception caught in code being profiled."""
1389 1389
1390 1390 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
1391 1391
1392 1392 lims = opts.l
1393 1393 if lims:
1394 1394 lims = [] # rebuild lims with ints/floats/strings
1395 1395 for lim in opts.l:
1396 1396 try:
1397 1397 lims.append(int(lim))
1398 1398 except ValueError:
1399 1399 try:
1400 1400 lims.append(float(lim))
1401 1401 except ValueError:
1402 1402 lims.append(lim)
1403 1403
1404 1404 # Trap output.
1405 1405 stdout_trap = StringIO()
1406 1406
1407 1407 if hasattr(stats,'stream'):
1408 1408 # In newer versions of python, the stats object has a 'stream'
1409 1409 # attribute to write into.
1410 1410 stats.stream = stdout_trap
1411 1411 stats.print_stats(*lims)
1412 1412 else:
1413 1413 # For older versions, we manually redirect stdout during printing
1414 1414 sys_stdout = sys.stdout
1415 1415 try:
1416 1416 sys.stdout = stdout_trap
1417 1417 stats.print_stats(*lims)
1418 1418 finally:
1419 1419 sys.stdout = sys_stdout
1420 1420
1421 1421 output = stdout_trap.getvalue()
1422 1422 output = output.rstrip()
1423 1423
1424 1424 page(output,screen_lines=self.shell.rc.screen_length)
1425 1425 print sys_exit,
1426 1426
1427 1427 dump_file = opts.D[0]
1428 1428 text_file = opts.T[0]
1429 1429 if dump_file:
1430 1430 prof.dump_stats(dump_file)
1431 1431 print '\n*** Profile stats marshalled to file',\
1432 1432 `dump_file`+'.',sys_exit
1433 1433 if text_file:
1434 1434 pfile = file(text_file,'w')
1435 1435 pfile.write(output)
1436 1436 pfile.close()
1437 1437 print '\n*** Profile printout saved to text file',\
1438 1438 `text_file`+'.',sys_exit
1439 1439
1440 1440 if opts.has_key('r'):
1441 1441 return stats
1442 1442 else:
1443 1443 return None
1444 1444
1445 1445 @testdec.skip_doctest
1446 1446 def magic_run(self, parameter_s ='',runner=None,
1447 1447 file_finder=get_py_filename):
1448 1448 """Run the named file inside IPython as a program.
1449 1449
1450 1450 Usage:\\
1451 1451 %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options]] file [args]
1452 1452
1453 1453 Parameters after the filename are passed as command-line arguments to
1454 1454 the program (put in sys.argv). Then, control returns to IPython's
1455 1455 prompt.
1456 1456
1457 1457 This is similar to running at a system prompt:\\
1458 1458 $ python file args\\
1459 1459 but with the advantage of giving you IPython's tracebacks, and of
1460 1460 loading all variables into your interactive namespace for further use
1461 1461 (unless -p is used, see below).
1462 1462
1463 1463 The file is executed in a namespace initially consisting only of
1464 1464 __name__=='__main__' and sys.argv constructed as indicated. It thus
1465 1465 sees its environment as if it were being run as a stand-alone program
1466 1466 (except for sharing global objects such as previously imported
1467 1467 modules). But after execution, the IPython interactive namespace gets
1468 1468 updated with all variables defined in the program (except for __name__
1469 1469 and sys.argv). This allows for very convenient loading of code for
1470 1470 interactive work, while giving each program a 'clean sheet' to run in.
1471 1471
1472 1472 Options:
1473 1473
1474 1474 -n: __name__ is NOT set to '__main__', but to the running file's name
1475 1475 without extension (as python does under import). This allows running
1476 1476 scripts and reloading the definitions in them without calling code
1477 1477 protected by an ' if __name__ == "__main__" ' clause.
1478 1478
1479 1479 -i: run the file in IPython's namespace instead of an empty one. This
1480 1480 is useful if you are experimenting with code written in a text editor
1481 1481 which depends on variables defined interactively.
1482 1482
1483 1483 -e: ignore sys.exit() calls or SystemExit exceptions in the script
1484 1484 being run. This is particularly useful if IPython is being used to
1485 1485 run unittests, which always exit with a sys.exit() call. In such
1486 1486 cases you are interested in the output of the test results, not in
1487 1487 seeing a traceback of the unittest module.
1488 1488
1489 1489 -t: print timing information at the end of the run. IPython will give
1490 1490 you an estimated CPU time consumption for your script, which under
1491 1491 Unix uses the resource module to avoid the wraparound problems of
1492 1492 time.clock(). Under Unix, an estimate of time spent on system tasks
1493 1493 is also given (for Windows platforms this is reported as 0.0).
1494 1494
1495 1495 If -t is given, an additional -N<N> option can be given, where <N>
1496 1496 must be an integer indicating how many times you want the script to
1497 1497 run. The final timing report will include total and per run results.
1498 1498
1499 1499 For example (testing the script uniq_stable.py):
1500 1500
1501 1501 In [1]: run -t uniq_stable
1502 1502
1503 1503 IPython CPU timings (estimated):\\
1504 1504 User : 0.19597 s.\\
1505 1505 System: 0.0 s.\\
1506 1506
1507 1507 In [2]: run -t -N5 uniq_stable
1508 1508
1509 1509 IPython CPU timings (estimated):\\
1510 1510 Total runs performed: 5\\
1511 1511 Times : Total Per run\\
1512 1512 User : 0.910862 s, 0.1821724 s.\\
1513 1513 System: 0.0 s, 0.0 s.
1514 1514
1515 1515 -d: run your program under the control of pdb, the Python debugger.
1516 1516 This allows you to execute your program step by step, watch variables,
1517 1517 etc. Internally, what IPython does is similar to calling:
1518 1518
1519 1519 pdb.run('execfile("YOURFILENAME")')
1520 1520
1521 1521 with a breakpoint set on line 1 of your file. You can change the line
1522 1522 number for this automatic breakpoint to be <N> by using the -bN option
1523 1523 (where N must be an integer). For example:
1524 1524
1525 1525 %run -d -b40 myscript
1526 1526
1527 1527 will set the first breakpoint at line 40 in myscript.py. Note that
1528 1528 the first breakpoint must be set on a line which actually does
1529 1529 something (not a comment or docstring) for it to stop execution.
1530 1530
1531 1531 When the pdb debugger starts, you will see a (Pdb) prompt. You must
1532 1532 first enter 'c' (without qoutes) to start execution up to the first
1533 1533 breakpoint.
1534 1534
1535 1535 Entering 'help' gives information about the use of the debugger. You
1536 1536 can easily see pdb's full documentation with "import pdb;pdb.help()"
1537 1537 at a prompt.
1538 1538
1539 1539 -p: run program under the control of the Python profiler module (which
1540 1540 prints a detailed report of execution times, function calls, etc).
1541 1541
1542 1542 You can pass other options after -p which affect the behavior of the
1543 1543 profiler itself. See the docs for %prun for details.
1544 1544
1545 1545 In this mode, the program's variables do NOT propagate back to the
1546 1546 IPython interactive namespace (because they remain in the namespace
1547 1547 where the profiler executes them).
1548 1548
1549 1549 Internally this triggers a call to %prun, see its documentation for
1550 1550 details on the options available specifically for profiling.
1551 1551
1552 1552 There is one special usage for which the text above doesn't apply:
1553 1553 if the filename ends with .ipy, the file is run as ipython script,
1554 1554 just as if the commands were written on IPython prompt.
1555 1555 """
1556 1556
1557 1557 # get arguments and set sys.argv for program to be run.
1558 1558 opts,arg_lst = self.parse_options(parameter_s,'nidtN:b:pD:l:rs:T:e',
1559 1559 mode='list',list_all=1)
1560 1560
1561 1561 try:
1562 1562 filename = file_finder(arg_lst[0])
1563 1563 except IndexError:
1564 1564 warn('you must provide at least a filename.')
1565 1565 print '\n%run:\n',oinspect.getdoc(self.magic_run)
1566 1566 return
1567 1567 except IOError,msg:
1568 1568 error(msg)
1569 1569 return
1570 1570
1571 1571 if filename.lower().endswith('.ipy'):
1572 1572 self.api.runlines(open(filename).read())
1573 1573 return
1574 1574
1575 1575 # Control the response to exit() calls made by the script being run
1576 1576 exit_ignore = opts.has_key('e')
1577 1577
1578 1578 # Make sure that the running script gets a proper sys.argv as if it
1579 1579 # were run from a system shell.
1580 1580 save_argv = sys.argv # save it for later restoring
1581 1581 sys.argv = [filename]+ arg_lst[1:] # put in the proper filename
1582 1582
1583 1583 if opts.has_key('i'):
1584 1584 # Run in user's interactive namespace
1585 1585 prog_ns = self.shell.user_ns
1586 1586 __name__save = self.shell.user_ns['__name__']
1587 1587 prog_ns['__name__'] = '__main__'
1588 1588 main_mod = self.shell.new_main_mod(prog_ns)
1589 1589 else:
1590 1590 # Run in a fresh, empty namespace
1591 1591 if opts.has_key('n'):
1592 1592 name = os.path.splitext(os.path.basename(filename))[0]
1593 1593 else:
1594 1594 name = '__main__'
1595 1595
1596 1596 main_mod = self.shell.new_main_mod()
1597 1597 prog_ns = main_mod.__dict__
1598 1598 prog_ns['__name__'] = name
1599 1599
1600 1600 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
1601 1601 # set the __file__ global in the script's namespace
1602 1602 prog_ns['__file__'] = filename
1603 1603
1604 1604 # pickle fix. See iplib for an explanation. But we need to make sure
1605 1605 # that, if we overwrite __main__, we replace it at the end
1606 1606 main_mod_name = prog_ns['__name__']
1607 1607
1608 1608 if main_mod_name == '__main__':
1609 1609 restore_main = sys.modules['__main__']
1610 1610 else:
1611 1611 restore_main = False
1612 1612
1613 1613 # This needs to be undone at the end to prevent holding references to
1614 1614 # every single object ever created.
1615 1615 sys.modules[main_mod_name] = main_mod
1616 1616
1617 1617 stats = None
1618 1618 try:
1619 1619 self.shell.savehist()
1620 1620
1621 1621 if opts.has_key('p'):
1622 1622 stats = self.magic_prun('',0,opts,arg_lst,prog_ns)
1623 1623 else:
1624 1624 if opts.has_key('d'):
1625 1625 deb = debugger.Pdb(self.shell.rc.colors)
1626 1626 # reset Breakpoint state, which is moronically kept
1627 1627 # in a class
1628 1628 bdb.Breakpoint.next = 1
1629 1629 bdb.Breakpoint.bplist = {}
1630 1630 bdb.Breakpoint.bpbynumber = [None]
1631 1631 # Set an initial breakpoint to stop execution
1632 1632 maxtries = 10
1633 1633 bp = int(opts.get('b',[1])[0])
1634 1634 checkline = deb.checkline(filename,bp)
1635 1635 if not checkline:
1636 1636 for bp in range(bp+1,bp+maxtries+1):
1637 1637 if deb.checkline(filename,bp):
1638 1638 break
1639 1639 else:
1640 1640 msg = ("\nI failed to find a valid line to set "
1641 1641 "a breakpoint\n"
1642 1642 "after trying up to line: %s.\n"
1643 1643 "Please set a valid breakpoint manually "
1644 1644 "with the -b option." % bp)
1645 1645 error(msg)
1646 1646 return
1647 1647 # if we find a good linenumber, set the breakpoint
1648 1648 deb.do_break('%s:%s' % (filename,bp))
1649 1649 # Start file run
1650 1650 print "NOTE: Enter 'c' at the",
1651 1651 print "%s prompt to start your script." % deb.prompt
1652 1652 try:
1653 1653 deb.run('execfile("%s")' % filename,prog_ns)
1654 1654
1655 1655 except:
1656 1656 etype, value, tb = sys.exc_info()
1657 1657 # Skip three frames in the traceback: the %run one,
1658 1658 # one inside bdb.py, and the command-line typed by the
1659 1659 # user (run by exec in pdb itself).
1660 1660 self.shell.InteractiveTB(etype,value,tb,tb_offset=3)
1661 1661 else:
1662 1662 if runner is None:
1663 1663 runner = self.shell.safe_execfile
1664 1664 if opts.has_key('t'):
1665 1665 # timed execution
1666 1666 try:
1667 1667 nruns = int(opts['N'][0])
1668 1668 if nruns < 1:
1669 1669 error('Number of runs must be >=1')
1670 1670 return
1671 1671 except (KeyError):
1672 1672 nruns = 1
1673 1673 if nruns == 1:
1674 1674 t0 = clock2()
1675 1675 runner(filename,prog_ns,prog_ns,
1676 1676 exit_ignore=exit_ignore)
1677 1677 t1 = clock2()
1678 1678 t_usr = t1[0]-t0[0]
1679 1679 t_sys = t1[1]-t0[1]
1680 1680 print "\nIPython CPU timings (estimated):"
1681 1681 print " User : %10s s." % t_usr
1682 1682 print " System: %10s s." % t_sys
1683 1683 else:
1684 1684 runs = range(nruns)
1685 1685 t0 = clock2()
1686 1686 for nr in runs:
1687 1687 runner(filename,prog_ns,prog_ns,
1688 1688 exit_ignore=exit_ignore)
1689 1689 t1 = clock2()
1690 1690 t_usr = t1[0]-t0[0]
1691 1691 t_sys = t1[1]-t0[1]
1692 1692 print "\nIPython CPU timings (estimated):"
1693 1693 print "Total runs performed:",nruns
1694 1694 print " Times : %10s %10s" % ('Total','Per run')
1695 1695 print " User : %10s s, %10s s." % (t_usr,t_usr/nruns)
1696 1696 print " System: %10s s, %10s s." % (t_sys,t_sys/nruns)
1697 1697
1698 1698 else:
1699 1699 # regular execution
1700 1700 runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore)
1701 1701
1702 1702 if opts.has_key('i'):
1703 1703 self.shell.user_ns['__name__'] = __name__save
1704 1704 else:
1705 1705 # The shell MUST hold a reference to prog_ns so after %run
1706 1706 # exits, the python deletion mechanism doesn't zero it out
1707 1707 # (leaving dangling references).
1708 1708 self.shell.cache_main_mod(prog_ns,filename)
1709 1709 # update IPython interactive namespace
1710 del prog_ns['__name__']
1710
1711 # Some forms of read errors on the file may mean the
1712 # __name__ key was never set; using pop we don't have to
1713 # worry about a possible KeyError.
1714 prog_ns.pop('__name__', None)
1715
1711 1716 self.shell.user_ns.update(prog_ns)
1712 1717 finally:
1713 1718 # It's a bit of a mystery why, but __builtins__ can change from
1714 1719 # being a module to becoming a dict missing some key data after
1715 1720 # %run. As best I can see, this is NOT something IPython is doing
1716 1721 # at all, and similar problems have been reported before:
1717 1722 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
1718 1723 # Since this seems to be done by the interpreter itself, the best
1719 1724 # we can do is to at least restore __builtins__ for the user on
1720 1725 # exit.
1721 1726 self.shell.user_ns['__builtins__'] = __builtin__
1722 1727
1723 1728 # Ensure key global structures are restored
1724 1729 sys.argv = save_argv
1725 1730 if restore_main:
1726 1731 sys.modules['__main__'] = restore_main
1727 1732 else:
1728 1733 # Remove from sys.modules the reference to main_mod we'd
1729 1734 # added. Otherwise it will trap references to objects
1730 1735 # contained therein.
1731 1736 del sys.modules[main_mod_name]
1732 1737
1733 1738 self.shell.reloadhist()
1734 1739
1735 1740 return stats
1736 1741
1737 1742 def magic_runlog(self, parameter_s =''):
1738 1743 """Run files as logs.
1739 1744
1740 1745 Usage:\\
1741 1746 %runlog file1 file2 ...
1742 1747
1743 1748 Run the named files (treating them as log files) in sequence inside
1744 1749 the interpreter, and return to the prompt. This is much slower than
1745 1750 %run because each line is executed in a try/except block, but it
1746 1751 allows running files with syntax errors in them.
1747 1752
1748 1753 Normally IPython will guess when a file is one of its own logfiles, so
1749 1754 you can typically use %run even for logs. This shorthand allows you to
1750 1755 force any file to be treated as a log file."""
1751 1756
1752 1757 for f in parameter_s.split():
1753 1758 self.shell.safe_execfile(f,self.shell.user_ns,
1754 1759 self.shell.user_ns,islog=1)
1755 1760
1756 1761 @testdec.skip_doctest
1757 1762 def magic_timeit(self, parameter_s =''):
1758 1763 """Time execution of a Python statement or expression
1759 1764
1760 1765 Usage:\\
1761 1766 %timeit [-n<N> -r<R> [-t|-c]] statement
1762 1767
1763 1768 Time execution of a Python statement or expression using the timeit
1764 1769 module.
1765 1770
1766 1771 Options:
1767 1772 -n<N>: execute the given statement <N> times in a loop. If this value
1768 1773 is not given, a fitting value is chosen.
1769 1774
1770 1775 -r<R>: repeat the loop iteration <R> times and take the best result.
1771 1776 Default: 3
1772 1777
1773 1778 -t: use time.time to measure the time, which is the default on Unix.
1774 1779 This function measures wall time.
1775 1780
1776 1781 -c: use time.clock to measure the time, which is the default on
1777 1782 Windows and measures wall time. On Unix, resource.getrusage is used
1778 1783 instead and returns the CPU user time.
1779 1784
1780 1785 -p<P>: use a precision of <P> digits to display the timing result.
1781 1786 Default: 3
1782 1787
1783 1788
1784 1789 Examples:
1785 1790
1786 1791 In [1]: %timeit pass
1787 1792 10000000 loops, best of 3: 53.3 ns per loop
1788 1793
1789 1794 In [2]: u = None
1790 1795
1791 1796 In [3]: %timeit u is None
1792 1797 10000000 loops, best of 3: 184 ns per loop
1793 1798
1794 1799 In [4]: %timeit -r 4 u == None
1795 1800 1000000 loops, best of 4: 242 ns per loop
1796 1801
1797 1802 In [5]: import time
1798 1803
1799 1804 In [6]: %timeit -n1 time.sleep(2)
1800 1805 1 loops, best of 3: 2 s per loop
1801 1806
1802 1807
1803 1808 The times reported by %timeit will be slightly higher than those
1804 1809 reported by the timeit.py script when variables are accessed. This is
1805 1810 due to the fact that %timeit executes the statement in the namespace
1806 1811 of the shell, compared with timeit.py, which uses a single setup
1807 1812 statement to import function or create variables. Generally, the bias
1808 1813 does not matter as long as results from timeit.py are not mixed with
1809 1814 those from %timeit."""
1810 1815
1811 1816 import timeit
1812 1817 import math
1813 1818
1814 1819 # XXX: Unfortunately the unicode 'micro' symbol can cause problems in
1815 1820 # certain terminals. Until we figure out a robust way of
1816 1821 # auto-detecting if the terminal can deal with it, use plain 'us' for
1817 1822 # microseconds. I am really NOT happy about disabling the proper
1818 1823 # 'micro' prefix, but crashing is worse... If anyone knows what the
1819 1824 # right solution for this is, I'm all ears...
1820 1825 #
1821 1826 # Note: using
1822 1827 #
1823 1828 # s = u'\xb5'
1824 1829 # s.encode(sys.getdefaultencoding())
1825 1830 #
1826 1831 # is not sufficient, as I've seen terminals where that fails but
1827 1832 # print s
1828 1833 #
1829 1834 # succeeds
1830 1835 #
1831 1836 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1832 1837
1833 1838 #units = [u"s", u"ms",u'\xb5',"ns"]
1834 1839 units = [u"s", u"ms",u'us',"ns"]
1835 1840
1836 1841 scaling = [1, 1e3, 1e6, 1e9]
1837 1842
1838 1843 opts, stmt = self.parse_options(parameter_s,'n:r:tcp:',
1839 1844 posix=False)
1840 1845 if stmt == "":
1841 1846 return
1842 1847 timefunc = timeit.default_timer
1843 1848 number = int(getattr(opts, "n", 0))
1844 1849 repeat = int(getattr(opts, "r", timeit.default_repeat))
1845 1850 precision = int(getattr(opts, "p", 3))
1846 1851 if hasattr(opts, "t"):
1847 1852 timefunc = time.time
1848 1853 if hasattr(opts, "c"):
1849 1854 timefunc = clock
1850 1855
1851 1856 timer = timeit.Timer(timer=timefunc)
1852 1857 # this code has tight coupling to the inner workings of timeit.Timer,
1853 1858 # but is there a better way to achieve that the code stmt has access
1854 1859 # to the shell namespace?
1855 1860
1856 1861 src = timeit.template % {'stmt': timeit.reindent(stmt, 8),
1857 1862 'setup': "pass"}
1858 1863 # Track compilation time so it can be reported if too long
1859 1864 # Minimum time above which compilation time will be reported
1860 1865 tc_min = 0.1
1861 1866
1862 1867 t0 = clock()
1863 1868 code = compile(src, "<magic-timeit>", "exec")
1864 1869 tc = clock()-t0
1865 1870
1866 1871 ns = {}
1867 1872 exec code in self.shell.user_ns, ns
1868 1873 timer.inner = ns["inner"]
1869 1874
1870 1875 if number == 0:
1871 1876 # determine number so that 0.2 <= total time < 2.0
1872 1877 number = 1
1873 1878 for i in range(1, 10):
1874 1879 if timer.timeit(number) >= 0.2:
1875 1880 break
1876 1881 number *= 10
1877 1882
1878 1883 best = min(timer.repeat(repeat, number)) / number
1879 1884
1880 1885 if best > 0.0:
1881 1886 order = min(-int(math.floor(math.log10(best)) // 3), 3)
1882 1887 else:
1883 1888 order = 3
1884 1889 print u"%d loops, best of %d: %.*g %s per loop" % (number, repeat,
1885 1890 precision,
1886 1891 best * scaling[order],
1887 1892 units[order])
1888 1893 if tc > tc_min:
1889 1894 print "Compiler time: %.2f s" % tc
1890 1895
1891 1896 @testdec.skip_doctest
1892 1897 def magic_time(self,parameter_s = ''):
1893 1898 """Time execution of a Python statement or expression.
1894 1899
1895 1900 The CPU and wall clock times are printed, and the value of the
1896 1901 expression (if any) is returned. Note that under Win32, system time
1897 1902 is always reported as 0, since it can not be measured.
1898 1903
1899 1904 This function provides very basic timing functionality. In Python
1900 1905 2.3, the timeit module offers more control and sophistication, so this
1901 1906 could be rewritten to use it (patches welcome).
1902 1907
1903 1908 Some examples:
1904 1909
1905 1910 In [1]: time 2**128
1906 1911 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1907 1912 Wall time: 0.00
1908 1913 Out[1]: 340282366920938463463374607431768211456L
1909 1914
1910 1915 In [2]: n = 1000000
1911 1916
1912 1917 In [3]: time sum(range(n))
1913 1918 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1914 1919 Wall time: 1.37
1915 1920 Out[3]: 499999500000L
1916 1921
1917 1922 In [4]: time print 'hello world'
1918 1923 hello world
1919 1924 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1920 1925 Wall time: 0.00
1921 1926
1922 1927 Note that the time needed by Python to compile the given expression
1923 1928 will be reported if it is more than 0.1s. In this example, the
1924 1929 actual exponentiation is done by Python at compilation time, so while
1925 1930 the expression can take a noticeable amount of time to compute, that
1926 1931 time is purely due to the compilation:
1927 1932
1928 1933 In [5]: time 3**9999;
1929 1934 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1930 1935 Wall time: 0.00 s
1931 1936
1932 1937 In [6]: time 3**999999;
1933 1938 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1934 1939 Wall time: 0.00 s
1935 1940 Compiler : 0.78 s
1936 1941 """
1937 1942
1938 1943 # fail immediately if the given expression can't be compiled
1939 1944
1940 1945 expr = self.shell.prefilter(parameter_s,False)
1941 1946
1942 1947 # Minimum time above which compilation time will be reported
1943 1948 tc_min = 0.1
1944 1949
1945 1950 try:
1946 1951 mode = 'eval'
1947 1952 t0 = clock()
1948 1953 code = compile(expr,'<timed eval>',mode)
1949 1954 tc = clock()-t0
1950 1955 except SyntaxError:
1951 1956 mode = 'exec'
1952 1957 t0 = clock()
1953 1958 code = compile(expr,'<timed exec>',mode)
1954 1959 tc = clock()-t0
1955 1960 # skew measurement as little as possible
1956 1961 glob = self.shell.user_ns
1957 1962 clk = clock2
1958 1963 wtime = time.time
1959 1964 # time execution
1960 1965 wall_st = wtime()
1961 1966 if mode=='eval':
1962 1967 st = clk()
1963 1968 out = eval(code,glob)
1964 1969 end = clk()
1965 1970 else:
1966 1971 st = clk()
1967 1972 exec code in glob
1968 1973 end = clk()
1969 1974 out = None
1970 1975 wall_end = wtime()
1971 1976 # Compute actual times and report
1972 1977 wall_time = wall_end-wall_st
1973 1978 cpu_user = end[0]-st[0]
1974 1979 cpu_sys = end[1]-st[1]
1975 1980 cpu_tot = cpu_user+cpu_sys
1976 1981 print "CPU times: user %.2f s, sys: %.2f s, total: %.2f s" % \
1977 1982 (cpu_user,cpu_sys,cpu_tot)
1978 1983 print "Wall time: %.2f s" % wall_time
1979 1984 if tc > tc_min:
1980 1985 print "Compiler : %.2f s" % tc
1981 1986 return out
1982 1987
1983 1988 @testdec.skip_doctest
1984 1989 def magic_macro(self,parameter_s = ''):
1985 1990 """Define a set of input lines as a macro for future re-execution.
1986 1991
1987 1992 Usage:\\
1988 1993 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1989 1994
1990 1995 Options:
1991 1996
1992 1997 -r: use 'raw' input. By default, the 'processed' history is used,
1993 1998 so that magics are loaded in their transformed version to valid
1994 1999 Python. If this option is given, the raw input as typed as the
1995 2000 command line is used instead.
1996 2001
1997 2002 This will define a global variable called `name` which is a string
1998 2003 made of joining the slices and lines you specify (n1,n2,... numbers
1999 2004 above) from your input history into a single string. This variable
2000 2005 acts like an automatic function which re-executes those lines as if
2001 2006 you had typed them. You just type 'name' at the prompt and the code
2002 2007 executes.
2003 2008
2004 2009 The notation for indicating number ranges is: n1-n2 means 'use line
2005 2010 numbers n1,...n2' (the endpoint is included). That is, '5-7' means
2006 2011 using the lines numbered 5,6 and 7.
2007 2012
2008 2013 Note: as a 'hidden' feature, you can also use traditional python slice
2009 2014 notation, where N:M means numbers N through M-1.
2010 2015
2011 2016 For example, if your history contains (%hist prints it):
2012 2017
2013 2018 44: x=1
2014 2019 45: y=3
2015 2020 46: z=x+y
2016 2021 47: print x
2017 2022 48: a=5
2018 2023 49: print 'x',x,'y',y
2019 2024
2020 2025 you can create a macro with lines 44 through 47 (included) and line 49
2021 2026 called my_macro with:
2022 2027
2023 2028 In [55]: %macro my_macro 44-47 49
2024 2029
2025 2030 Now, typing `my_macro` (without quotes) will re-execute all this code
2026 2031 in one pass.
2027 2032
2028 2033 You don't need to give the line-numbers in order, and any given line
2029 2034 number can appear multiple times. You can assemble macros with any
2030 2035 lines from your input history in any order.
2031 2036
2032 2037 The macro is a simple object which holds its value in an attribute,
2033 2038 but IPython's display system checks for macros and executes them as
2034 2039 code instead of printing them when you type their name.
2035 2040
2036 2041 You can view a macro's contents by explicitly printing it with:
2037 2042
2038 2043 'print macro_name'.
2039 2044
2040 2045 For one-off cases which DON'T contain magic function calls in them you
2041 2046 can obtain similar results by explicitly executing slices from your
2042 2047 input history with:
2043 2048
2044 2049 In [60]: exec In[44:48]+In[49]"""
2045 2050
2046 2051 opts,args = self.parse_options(parameter_s,'r',mode='list')
2047 2052 if not args:
2048 2053 macs = [k for k,v in self.shell.user_ns.items() if isinstance(v, Macro)]
2049 2054 macs.sort()
2050 2055 return macs
2051 2056 if len(args) == 1:
2052 2057 raise UsageError(
2053 2058 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
2054 2059 name,ranges = args[0], args[1:]
2055 2060
2056 2061 #print 'rng',ranges # dbg
2057 2062 lines = self.extract_input_slices(ranges,opts.has_key('r'))
2058 2063 macro = Macro(lines)
2059 2064 self.shell.user_ns.update({name:macro})
2060 2065 print 'Macro `%s` created. To execute, type its name (without quotes).' % name
2061 2066 print 'Macro contents:'
2062 2067 print macro,
2063 2068
2064 2069 def magic_save(self,parameter_s = ''):
2065 2070 """Save a set of lines to a given filename.
2066 2071
2067 2072 Usage:\\
2068 2073 %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ...
2069 2074
2070 2075 Options:
2071 2076
2072 2077 -r: use 'raw' input. By default, the 'processed' history is used,
2073 2078 so that magics are loaded in their transformed version to valid
2074 2079 Python. If this option is given, the raw input as typed as the
2075 2080 command line is used instead.
2076 2081
2077 2082 This function uses the same syntax as %macro for line extraction, but
2078 2083 instead of creating a macro it saves the resulting string to the
2079 2084 filename you specify.
2080 2085
2081 2086 It adds a '.py' extension to the file if you don't do so yourself, and
2082 2087 it asks for confirmation before overwriting existing files."""
2083 2088
2084 2089 opts,args = self.parse_options(parameter_s,'r',mode='list')
2085 2090 fname,ranges = args[0], args[1:]
2086 2091 if not fname.endswith('.py'):
2087 2092 fname += '.py'
2088 2093 if os.path.isfile(fname):
2089 2094 ans = raw_input('File `%s` exists. Overwrite (y/[N])? ' % fname)
2090 2095 if ans.lower() not in ['y','yes']:
2091 2096 print 'Operation cancelled.'
2092 2097 return
2093 2098 cmds = ''.join(self.extract_input_slices(ranges,opts.has_key('r')))
2094 2099 f = file(fname,'w')
2095 2100 f.write(cmds)
2096 2101 f.close()
2097 2102 print 'The following commands were written to file `%s`:' % fname
2098 2103 print cmds
2099 2104
2100 2105 def _edit_macro(self,mname,macro):
2101 2106 """open an editor with the macro data in a file"""
2102 2107 filename = self.shell.mktempfile(macro.value)
2103 2108 self.shell.hooks.editor(filename)
2104 2109
2105 2110 # and make a new macro object, to replace the old one
2106 2111 mfile = open(filename)
2107 2112 mvalue = mfile.read()
2108 2113 mfile.close()
2109 2114 self.shell.user_ns[mname] = Macro(mvalue)
2110 2115
2111 2116 def magic_ed(self,parameter_s=''):
2112 2117 """Alias to %edit."""
2113 2118 return self.magic_edit(parameter_s)
2114 2119
2115 2120 @testdec.skip_doctest
2116 2121 def magic_edit(self,parameter_s='',last_call=['','']):
2117 2122 """Bring up an editor and execute the resulting code.
2118 2123
2119 2124 Usage:
2120 2125 %edit [options] [args]
2121 2126
2122 2127 %edit runs IPython's editor hook. The default version of this hook is
2123 2128 set to call the __IPYTHON__.rc.editor command. This is read from your
2124 2129 environment variable $EDITOR. If this isn't found, it will default to
2125 2130 vi under Linux/Unix and to notepad under Windows. See the end of this
2126 2131 docstring for how to change the editor hook.
2127 2132
2128 2133 You can also set the value of this editor via the command line option
2129 2134 '-editor' or in your ipythonrc file. This is useful if you wish to use
2130 2135 specifically for IPython an editor different from your typical default
2131 2136 (and for Windows users who typically don't set environment variables).
2132 2137
2133 2138 This command allows you to conveniently edit multi-line code right in
2134 2139 your IPython session.
2135 2140
2136 2141 If called without arguments, %edit opens up an empty editor with a
2137 2142 temporary file and will execute the contents of this file when you
2138 2143 close it (don't forget to save it!).
2139 2144
2140 2145
2141 2146 Options:
2142 2147
2143 2148 -n <number>: open the editor at a specified line number. By default,
2144 2149 the IPython editor hook uses the unix syntax 'editor +N filename', but
2145 2150 you can configure this by providing your own modified hook if your
2146 2151 favorite editor supports line-number specifications with a different
2147 2152 syntax.
2148 2153
2149 2154 -p: this will call the editor with the same data as the previous time
2150 2155 it was used, regardless of how long ago (in your current session) it
2151 2156 was.
2152 2157
2153 2158 -r: use 'raw' input. This option only applies to input taken from the
2154 2159 user's history. By default, the 'processed' history is used, so that
2155 2160 magics are loaded in their transformed version to valid Python. If
2156 2161 this option is given, the raw input as typed as the command line is
2157 2162 used instead. When you exit the editor, it will be executed by
2158 2163 IPython's own processor.
2159 2164
2160 2165 -x: do not execute the edited code immediately upon exit. This is
2161 2166 mainly useful if you are editing programs which need to be called with
2162 2167 command line arguments, which you can then do using %run.
2163 2168
2164 2169
2165 2170 Arguments:
2166 2171
2167 2172 If arguments are given, the following possibilites exist:
2168 2173
2169 2174 - The arguments are numbers or pairs of colon-separated numbers (like
2170 2175 1 4:8 9). These are interpreted as lines of previous input to be
2171 2176 loaded into the editor. The syntax is the same of the %macro command.
2172 2177
2173 2178 - If the argument doesn't start with a number, it is evaluated as a
2174 2179 variable and its contents loaded into the editor. You can thus edit
2175 2180 any string which contains python code (including the result of
2176 2181 previous edits).
2177 2182
2178 2183 - If the argument is the name of an object (other than a string),
2179 2184 IPython will try to locate the file where it was defined and open the
2180 2185 editor at the point where it is defined. You can use `%edit function`
2181 2186 to load an editor exactly at the point where 'function' is defined,
2182 2187 edit it and have the file be executed automatically.
2183 2188
2184 2189 If the object is a macro (see %macro for details), this opens up your
2185 2190 specified editor with a temporary file containing the macro's data.
2186 2191 Upon exit, the macro is reloaded with the contents of the file.
2187 2192
2188 2193 Note: opening at an exact line is only supported under Unix, and some
2189 2194 editors (like kedit and gedit up to Gnome 2.8) do not understand the
2190 2195 '+NUMBER' parameter necessary for this feature. Good editors like
2191 2196 (X)Emacs, vi, jed, pico and joe all do.
2192 2197
2193 2198 - If the argument is not found as a variable, IPython will look for a
2194 2199 file with that name (adding .py if necessary) and load it into the
2195 2200 editor. It will execute its contents with execfile() when you exit,
2196 2201 loading any code in the file into your interactive namespace.
2197 2202
2198 2203 After executing your code, %edit will return as output the code you
2199 2204 typed in the editor (except when it was an existing file). This way
2200 2205 you can reload the code in further invocations of %edit as a variable,
2201 2206 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
2202 2207 the output.
2203 2208
2204 2209 Note that %edit is also available through the alias %ed.
2205 2210
2206 2211 This is an example of creating a simple function inside the editor and
2207 2212 then modifying it. First, start up the editor:
2208 2213
2209 2214 In [1]: ed
2210 2215 Editing... done. Executing edited code...
2211 2216 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
2212 2217
2213 2218 We can then call the function foo():
2214 2219
2215 2220 In [2]: foo()
2216 2221 foo() was defined in an editing session
2217 2222
2218 2223 Now we edit foo. IPython automatically loads the editor with the
2219 2224 (temporary) file where foo() was previously defined:
2220 2225
2221 2226 In [3]: ed foo
2222 2227 Editing... done. Executing edited code...
2223 2228
2224 2229 And if we call foo() again we get the modified version:
2225 2230
2226 2231 In [4]: foo()
2227 2232 foo() has now been changed!
2228 2233
2229 2234 Here is an example of how to edit a code snippet successive
2230 2235 times. First we call the editor:
2231 2236
2232 2237 In [5]: ed
2233 2238 Editing... done. Executing edited code...
2234 2239 hello
2235 2240 Out[5]: "print 'hello'n"
2236 2241
2237 2242 Now we call it again with the previous output (stored in _):
2238 2243
2239 2244 In [6]: ed _
2240 2245 Editing... done. Executing edited code...
2241 2246 hello world
2242 2247 Out[6]: "print 'hello world'n"
2243 2248
2244 2249 Now we call it with the output #8 (stored in _8, also as Out[8]):
2245 2250
2246 2251 In [7]: ed _8
2247 2252 Editing... done. Executing edited code...
2248 2253 hello again
2249 2254 Out[7]: "print 'hello again'n"
2250 2255
2251 2256
2252 2257 Changing the default editor hook:
2253 2258
2254 2259 If you wish to write your own editor hook, you can put it in a
2255 2260 configuration file which you load at startup time. The default hook
2256 2261 is defined in the IPython.core.hooks module, and you can use that as a
2257 2262 starting example for further modifications. That file also has
2258 2263 general instructions on how to set a new hook for use once you've
2259 2264 defined it."""
2260 2265
2261 2266 # FIXME: This function has become a convoluted mess. It needs a
2262 2267 # ground-up rewrite with clean, simple logic.
2263 2268
2264 2269 def make_filename(arg):
2265 2270 "Make a filename from the given args"
2266 2271 try:
2267 2272 filename = get_py_filename(arg)
2268 2273 except IOError:
2269 2274 if args.endswith('.py'):
2270 2275 filename = arg
2271 2276 else:
2272 2277 filename = None
2273 2278 return filename
2274 2279
2275 2280 # custom exceptions
2276 2281 class DataIsObject(Exception): pass
2277 2282
2278 2283 opts,args = self.parse_options(parameter_s,'prxn:')
2279 2284 # Set a few locals from the options for convenience:
2280 2285 opts_p = opts.has_key('p')
2281 2286 opts_r = opts.has_key('r')
2282 2287
2283 2288 # Default line number value
2284 2289 lineno = opts.get('n',None)
2285 2290
2286 2291 if opts_p:
2287 2292 args = '_%s' % last_call[0]
2288 2293 if not self.shell.user_ns.has_key(args):
2289 2294 args = last_call[1]
2290 2295
2291 2296 # use last_call to remember the state of the previous call, but don't
2292 2297 # let it be clobbered by successive '-p' calls.
2293 2298 try:
2294 2299 last_call[0] = self.shell.outputcache.prompt_count
2295 2300 if not opts_p:
2296 2301 last_call[1] = parameter_s
2297 2302 except:
2298 2303 pass
2299 2304
2300 2305 # by default this is done with temp files, except when the given
2301 2306 # arg is a filename
2302 2307 use_temp = 1
2303 2308
2304 2309 if re.match(r'\d',args):
2305 2310 # Mode where user specifies ranges of lines, like in %macro.
2306 2311 # This means that you can't edit files whose names begin with
2307 2312 # numbers this way. Tough.
2308 2313 ranges = args.split()
2309 2314 data = ''.join(self.extract_input_slices(ranges,opts_r))
2310 2315 elif args.endswith('.py'):
2311 2316 filename = make_filename(args)
2312 2317 data = ''
2313 2318 use_temp = 0
2314 2319 elif args:
2315 2320 try:
2316 2321 # Load the parameter given as a variable. If not a string,
2317 2322 # process it as an object instead (below)
2318 2323
2319 2324 #print '*** args',args,'type',type(args) # dbg
2320 2325 data = eval(args,self.shell.user_ns)
2321 2326 if not type(data) in StringTypes:
2322 2327 raise DataIsObject
2323 2328
2324 2329 except (NameError,SyntaxError):
2325 2330 # given argument is not a variable, try as a filename
2326 2331 filename = make_filename(args)
2327 2332 if filename is None:
2328 2333 warn("Argument given (%s) can't be found as a variable "
2329 2334 "or as a filename." % args)
2330 2335 return
2331 2336
2332 2337 data = ''
2333 2338 use_temp = 0
2334 2339 except DataIsObject:
2335 2340
2336 2341 # macros have a special edit function
2337 2342 if isinstance(data,Macro):
2338 2343 self._edit_macro(args,data)
2339 2344 return
2340 2345
2341 2346 # For objects, try to edit the file where they are defined
2342 2347 try:
2343 2348 filename = inspect.getabsfile(data)
2344 2349 if 'fakemodule' in filename.lower() and inspect.isclass(data):
2345 2350 # class created by %edit? Try to find source
2346 2351 # by looking for method definitions instead, the
2347 2352 # __module__ in those classes is FakeModule.
2348 2353 attrs = [getattr(data, aname) for aname in dir(data)]
2349 2354 for attr in attrs:
2350 2355 if not inspect.ismethod(attr):
2351 2356 continue
2352 2357 filename = inspect.getabsfile(attr)
2353 2358 if filename and 'fakemodule' not in filename.lower():
2354 2359 # change the attribute to be the edit target instead
2355 2360 data = attr
2356 2361 break
2357 2362
2358 2363 datafile = 1
2359 2364 except TypeError:
2360 2365 filename = make_filename(args)
2361 2366 datafile = 1
2362 2367 warn('Could not find file where `%s` is defined.\n'
2363 2368 'Opening a file named `%s`' % (args,filename))
2364 2369 # Now, make sure we can actually read the source (if it was in
2365 2370 # a temp file it's gone by now).
2366 2371 if datafile:
2367 2372 try:
2368 2373 if lineno is None:
2369 2374 lineno = inspect.getsourcelines(data)[1]
2370 2375 except IOError:
2371 2376 filename = make_filename(args)
2372 2377 if filename is None:
2373 2378 warn('The file `%s` where `%s` was defined cannot '
2374 2379 'be read.' % (filename,data))
2375 2380 return
2376 2381 use_temp = 0
2377 2382 else:
2378 2383 data = ''
2379 2384
2380 2385 if use_temp:
2381 2386 filename = self.shell.mktempfile(data)
2382 2387 print 'IPython will make a temporary file named:',filename
2383 2388
2384 2389 # do actual editing here
2385 2390 print 'Editing...',
2386 2391 sys.stdout.flush()
2387 2392 try:
2388 2393 self.shell.hooks.editor(filename,lineno)
2389 2394 except ipapi.TryNext:
2390 2395 warn('Could not open editor')
2391 2396 return
2392 2397
2393 2398 # XXX TODO: should this be generalized for all string vars?
2394 2399 # For now, this is special-cased to blocks created by cpaste
2395 2400 if args.strip() == 'pasted_block':
2396 2401 self.shell.user_ns['pasted_block'] = file_read(filename)
2397 2402
2398 2403 if opts.has_key('x'): # -x prevents actual execution
2399 2404 print
2400 2405 else:
2401 2406 print 'done. Executing edited code...'
2402 2407 if opts_r:
2403 2408 self.shell.runlines(file_read(filename))
2404 2409 else:
2405 2410 self.shell.safe_execfile(filename,self.shell.user_ns,
2406 2411 self.shell.user_ns)
2407 2412
2408 2413
2409 2414 if use_temp:
2410 2415 try:
2411 2416 return open(filename).read()
2412 2417 except IOError,msg:
2413 2418 if msg.filename == filename:
2414 2419 warn('File not found. Did you forget to save?')
2415 2420 return
2416 2421 else:
2417 2422 self.shell.showtraceback()
2418 2423
2419 2424 def magic_xmode(self,parameter_s = ''):
2420 2425 """Switch modes for the exception handlers.
2421 2426
2422 2427 Valid modes: Plain, Context and Verbose.
2423 2428
2424 2429 If called without arguments, acts as a toggle."""
2425 2430
2426 2431 def xmode_switch_err(name):
2427 2432 warn('Error changing %s exception modes.\n%s' %
2428 2433 (name,sys.exc_info()[1]))
2429 2434
2430 2435 shell = self.shell
2431 2436 new_mode = parameter_s.strip().capitalize()
2432 2437 try:
2433 2438 shell.InteractiveTB.set_mode(mode=new_mode)
2434 2439 print 'Exception reporting mode:',shell.InteractiveTB.mode
2435 2440 except:
2436 2441 xmode_switch_err('user')
2437 2442
2438 2443 # threaded shells use a special handler in sys.excepthook
2439 2444 if shell.isthreaded:
2440 2445 try:
2441 2446 shell.sys_excepthook.set_mode(mode=new_mode)
2442 2447 except:
2443 2448 xmode_switch_err('threaded')
2444 2449
2445 2450 def magic_colors(self,parameter_s = ''):
2446 2451 """Switch color scheme for prompts, info system and exception handlers.
2447 2452
2448 2453 Currently implemented schemes: NoColor, Linux, LightBG.
2449 2454
2450 2455 Color scheme names are not case-sensitive."""
2451 2456
2452 2457 def color_switch_err(name):
2453 2458 warn('Error changing %s color schemes.\n%s' %
2454 2459 (name,sys.exc_info()[1]))
2455 2460
2456 2461
2457 2462 new_scheme = parameter_s.strip()
2458 2463 if not new_scheme:
2459 2464 raise UsageError(
2460 2465 "%colors: you must specify a color scheme. See '%colors?'")
2461 2466 return
2462 2467 # local shortcut
2463 2468 shell = self.shell
2464 2469
2465 2470 import IPython.utils.rlineimpl as readline
2466 2471
2467 2472 if not readline.have_readline and sys.platform == "win32":
2468 2473 msg = """\
2469 2474 Proper color support under MS Windows requires the pyreadline library.
2470 2475 You can find it at:
2471 2476 http://ipython.scipy.org/moin/PyReadline/Intro
2472 2477 Gary's readline needs the ctypes module, from:
2473 2478 http://starship.python.net/crew/theller/ctypes
2474 2479 (Note that ctypes is already part of Python versions 2.5 and newer).
2475 2480
2476 2481 Defaulting color scheme to 'NoColor'"""
2477 2482 new_scheme = 'NoColor'
2478 2483 warn(msg)
2479 2484
2480 2485 # readline option is 0
2481 2486 if not shell.has_readline:
2482 2487 new_scheme = 'NoColor'
2483 2488
2484 2489 # Set prompt colors
2485 2490 try:
2486 2491 shell.outputcache.set_colors(new_scheme)
2487 2492 except:
2488 2493 color_switch_err('prompt')
2489 2494 else:
2490 2495 shell.rc.colors = \
2491 2496 shell.outputcache.color_table.active_scheme_name
2492 2497 # Set exception colors
2493 2498 try:
2494 2499 shell.InteractiveTB.set_colors(scheme = new_scheme)
2495 2500 shell.SyntaxTB.set_colors(scheme = new_scheme)
2496 2501 except:
2497 2502 color_switch_err('exception')
2498 2503
2499 2504 # threaded shells use a verbose traceback in sys.excepthook
2500 2505 if shell.isthreaded:
2501 2506 try:
2502 2507 shell.sys_excepthook.set_colors(scheme=new_scheme)
2503 2508 except:
2504 2509 color_switch_err('system exception handler')
2505 2510
2506 2511 # Set info (for 'object?') colors
2507 2512 if shell.rc.color_info:
2508 2513 try:
2509 2514 shell.inspector.set_active_scheme(new_scheme)
2510 2515 except:
2511 2516 color_switch_err('object inspector')
2512 2517 else:
2513 2518 shell.inspector.set_active_scheme('NoColor')
2514 2519
2515 2520 def magic_color_info(self,parameter_s = ''):
2516 2521 """Toggle color_info.
2517 2522
2518 2523 The color_info configuration parameter controls whether colors are
2519 2524 used for displaying object details (by things like %psource, %pfile or
2520 2525 the '?' system). This function toggles this value with each call.
2521 2526
2522 2527 Note that unless you have a fairly recent pager (less works better
2523 2528 than more) in your system, using colored object information displays
2524 2529 will not work properly. Test it and see."""
2525 2530
2526 2531 self.shell.rc.color_info = 1 - self.shell.rc.color_info
2527 2532 self.magic_colors(self.shell.rc.colors)
2528 2533 print 'Object introspection functions have now coloring:',
2529 2534 print ['OFF','ON'][self.shell.rc.color_info]
2530 2535
2531 2536 def magic_Pprint(self, parameter_s=''):
2532 2537 """Toggle pretty printing on/off."""
2533 2538
2534 2539 self.shell.rc.pprint = 1 - self.shell.rc.pprint
2535 2540 print 'Pretty printing has been turned', \
2536 2541 ['OFF','ON'][self.shell.rc.pprint]
2537 2542
2538 2543 def magic_exit(self, parameter_s=''):
2539 2544 """Exit IPython, confirming if configured to do so.
2540 2545
2541 2546 You can configure whether IPython asks for confirmation upon exit by
2542 2547 setting the confirm_exit flag in the ipythonrc file."""
2543 2548
2544 2549 self.shell.exit()
2545 2550
2546 2551 def magic_quit(self, parameter_s=''):
2547 2552 """Exit IPython, confirming if configured to do so (like %exit)"""
2548 2553
2549 2554 self.shell.exit()
2550 2555
2551 2556 def magic_Exit(self, parameter_s=''):
2552 2557 """Exit IPython without confirmation."""
2553 2558
2554 2559 self.shell.ask_exit()
2555 2560
2556 2561 #......................................................................
2557 2562 # Functions to implement unix shell-type things
2558 2563
2559 2564 @testdec.skip_doctest
2560 2565 def magic_alias(self, parameter_s = ''):
2561 2566 """Define an alias for a system command.
2562 2567
2563 2568 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
2564 2569
2565 2570 Then, typing 'alias_name params' will execute the system command 'cmd
2566 2571 params' (from your underlying operating system).
2567 2572
2568 2573 Aliases have lower precedence than magic functions and Python normal
2569 2574 variables, so if 'foo' is both a Python variable and an alias, the
2570 2575 alias can not be executed until 'del foo' removes the Python variable.
2571 2576
2572 2577 You can use the %l specifier in an alias definition to represent the
2573 2578 whole line when the alias is called. For example:
2574 2579
2575 2580 In [2]: alias all echo "Input in brackets: <%l>"
2576 2581 In [3]: all hello world
2577 2582 Input in brackets: <hello world>
2578 2583
2579 2584 You can also define aliases with parameters using %s specifiers (one
2580 2585 per parameter):
2581 2586
2582 2587 In [1]: alias parts echo first %s second %s
2583 2588 In [2]: %parts A B
2584 2589 first A second B
2585 2590 In [3]: %parts A
2586 2591 Incorrect number of arguments: 2 expected.
2587 2592 parts is an alias to: 'echo first %s second %s'
2588 2593
2589 2594 Note that %l and %s are mutually exclusive. You can only use one or
2590 2595 the other in your aliases.
2591 2596
2592 2597 Aliases expand Python variables just like system calls using ! or !!
2593 2598 do: all expressions prefixed with '$' get expanded. For details of
2594 2599 the semantic rules, see PEP-215:
2595 2600 http://www.python.org/peps/pep-0215.html. This is the library used by
2596 2601 IPython for variable expansion. If you want to access a true shell
2597 2602 variable, an extra $ is necessary to prevent its expansion by IPython:
2598 2603
2599 2604 In [6]: alias show echo
2600 2605 In [7]: PATH='A Python string'
2601 2606 In [8]: show $PATH
2602 2607 A Python string
2603 2608 In [9]: show $$PATH
2604 2609 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
2605 2610
2606 2611 You can use the alias facility to acess all of $PATH. See the %rehash
2607 2612 and %rehashx functions, which automatically create aliases for the
2608 2613 contents of your $PATH.
2609 2614
2610 2615 If called with no parameters, %alias prints the current alias table."""
2611 2616
2612 2617 par = parameter_s.strip()
2613 2618 if not par:
2614 2619 stored = self.db.get('stored_aliases', {} )
2615 2620 atab = self.shell.alias_table
2616 2621 aliases = atab.keys()
2617 2622 aliases.sort()
2618 2623 res = []
2619 2624 showlast = []
2620 2625 for alias in aliases:
2621 2626 special = False
2622 2627 try:
2623 2628 tgt = atab[alias][1]
2624 2629 except (TypeError, AttributeError):
2625 2630 # unsubscriptable? probably a callable
2626 2631 tgt = atab[alias]
2627 2632 special = True
2628 2633 # 'interesting' aliases
2629 2634 if (alias in stored or
2630 2635 special or
2631 2636 alias.lower() != os.path.splitext(tgt)[0].lower() or
2632 2637 ' ' in tgt):
2633 2638 showlast.append((alias, tgt))
2634 2639 else:
2635 2640 res.append((alias, tgt ))
2636 2641
2637 2642 # show most interesting aliases last
2638 2643 res.extend(showlast)
2639 2644 print "Total number of aliases:",len(aliases)
2640 2645 return res
2641 2646 try:
2642 2647 alias,cmd = par.split(None,1)
2643 2648 except:
2644 2649 print oinspect.getdoc(self.magic_alias)
2645 2650 else:
2646 2651 nargs = cmd.count('%s')
2647 2652 if nargs>0 and cmd.find('%l')>=0:
2648 2653 error('The %s and %l specifiers are mutually exclusive '
2649 2654 'in alias definitions.')
2650 2655 else: # all looks OK
2651 2656 self.shell.alias_table[alias] = (nargs,cmd)
2652 2657 self.shell.alias_table_validate(verbose=0)
2653 2658 # end magic_alias
2654 2659
2655 2660 def magic_unalias(self, parameter_s = ''):
2656 2661 """Remove an alias"""
2657 2662
2658 2663 aname = parameter_s.strip()
2659 2664 if aname in self.shell.alias_table:
2660 2665 del self.shell.alias_table[aname]
2661 2666 stored = self.db.get('stored_aliases', {} )
2662 2667 if aname in stored:
2663 2668 print "Removing %stored alias",aname
2664 2669 del stored[aname]
2665 2670 self.db['stored_aliases'] = stored
2666 2671
2667 2672
2668 2673 def magic_rehashx(self, parameter_s = ''):
2669 2674 """Update the alias table with all executable files in $PATH.
2670 2675
2671 2676 This version explicitly checks that every entry in $PATH is a file
2672 2677 with execute access (os.X_OK), so it is much slower than %rehash.
2673 2678
2674 2679 Under Windows, it checks executability as a match agains a
2675 2680 '|'-separated string of extensions, stored in the IPython config
2676 2681 variable win_exec_ext. This defaults to 'exe|com|bat'.
2677 2682
2678 2683 This function also resets the root module cache of module completer,
2679 2684 used on slow filesystems.
2680 2685 """
2681 2686
2682 2687
2683 2688 ip = self.api
2684 2689
2685 2690 # for the benefit of module completer in ipy_completers.py
2686 2691 del ip.db['rootmodules']
2687 2692
2688 2693 path = [os.path.abspath(os.path.expanduser(p)) for p in
2689 2694 os.environ.get('PATH','').split(os.pathsep)]
2690 2695 path = filter(os.path.isdir,path)
2691 2696
2692 2697 alias_table = self.shell.alias_table
2693 2698 syscmdlist = []
2694 2699 if os.name == 'posix':
2695 2700 isexec = lambda fname:os.path.isfile(fname) and \
2696 2701 os.access(fname,os.X_OK)
2697 2702 else:
2698 2703
2699 2704 try:
2700 2705 winext = os.environ['pathext'].replace(';','|').replace('.','')
2701 2706 except KeyError:
2702 2707 winext = 'exe|com|bat|py'
2703 2708 if 'py' not in winext:
2704 2709 winext += '|py'
2705 2710 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
2706 2711 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
2707 2712 savedir = os.getcwd()
2708 2713 try:
2709 2714 # write the whole loop for posix/Windows so we don't have an if in
2710 2715 # the innermost part
2711 2716 if os.name == 'posix':
2712 2717 for pdir in path:
2713 2718 os.chdir(pdir)
2714 2719 for ff in os.listdir(pdir):
2715 2720 if isexec(ff) and ff not in self.shell.no_alias:
2716 2721 # each entry in the alias table must be (N,name),
2717 2722 # where N is the number of positional arguments of the
2718 2723 # alias.
2719 2724 # Dots will be removed from alias names, since ipython
2720 2725 # assumes names with dots to be python code
2721 2726 alias_table[ff.replace('.','')] = (0,ff)
2722 2727 syscmdlist.append(ff)
2723 2728 else:
2724 2729 for pdir in path:
2725 2730 os.chdir(pdir)
2726 2731 for ff in os.listdir(pdir):
2727 2732 base, ext = os.path.splitext(ff)
2728 2733 if isexec(ff) and base.lower() not in self.shell.no_alias:
2729 2734 if ext.lower() == '.exe':
2730 2735 ff = base
2731 2736 alias_table[base.lower().replace('.','')] = (0,ff)
2732 2737 syscmdlist.append(ff)
2733 2738 # Make sure the alias table doesn't contain keywords or builtins
2734 2739 self.shell.alias_table_validate()
2735 2740 # Call again init_auto_alias() so we get 'rm -i' and other
2736 2741 # modified aliases since %rehashx will probably clobber them
2737 2742
2738 2743 # no, we don't want them. if %rehashx clobbers them, good,
2739 2744 # we'll probably get better versions
2740 2745 # self.shell.init_auto_alias()
2741 2746 db = ip.db
2742 2747 db['syscmdlist'] = syscmdlist
2743 2748 finally:
2744 2749 os.chdir(savedir)
2745 2750
2746 2751 def magic_pwd(self, parameter_s = ''):
2747 2752 """Return the current working directory path."""
2748 2753 return os.getcwd()
2749 2754
2750 2755 def magic_cd(self, parameter_s=''):
2751 2756 """Change the current working directory.
2752 2757
2753 2758 This command automatically maintains an internal list of directories
2754 2759 you visit during your IPython session, in the variable _dh. The
2755 2760 command %dhist shows this history nicely formatted. You can also
2756 2761 do 'cd -<tab>' to see directory history conveniently.
2757 2762
2758 2763 Usage:
2759 2764
2760 2765 cd 'dir': changes to directory 'dir'.
2761 2766
2762 2767 cd -: changes to the last visited directory.
2763 2768
2764 2769 cd -<n>: changes to the n-th directory in the directory history.
2765 2770
2766 2771 cd --foo: change to directory that matches 'foo' in history
2767 2772
2768 2773 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
2769 2774 (note: cd <bookmark_name> is enough if there is no
2770 2775 directory <bookmark_name>, but a bookmark with the name exists.)
2771 2776 'cd -b <tab>' allows you to tab-complete bookmark names.
2772 2777
2773 2778 Options:
2774 2779
2775 2780 -q: quiet. Do not print the working directory after the cd command is
2776 2781 executed. By default IPython's cd command does print this directory,
2777 2782 since the default prompts do not display path information.
2778 2783
2779 2784 Note that !cd doesn't work for this purpose because the shell where
2780 2785 !command runs is immediately discarded after executing 'command'."""
2781 2786
2782 2787 parameter_s = parameter_s.strip()
2783 2788 #bkms = self.shell.persist.get("bookmarks",{})
2784 2789
2785 2790 oldcwd = os.getcwd()
2786 2791 numcd = re.match(r'(-)(\d+)$',parameter_s)
2787 2792 # jump in directory history by number
2788 2793 if numcd:
2789 2794 nn = int(numcd.group(2))
2790 2795 try:
2791 2796 ps = self.shell.user_ns['_dh'][nn]
2792 2797 except IndexError:
2793 2798 print 'The requested directory does not exist in history.'
2794 2799 return
2795 2800 else:
2796 2801 opts = {}
2797 2802 elif parameter_s.startswith('--'):
2798 2803 ps = None
2799 2804 fallback = None
2800 2805 pat = parameter_s[2:]
2801 2806 dh = self.shell.user_ns['_dh']
2802 2807 # first search only by basename (last component)
2803 2808 for ent in reversed(dh):
2804 2809 if pat in os.path.basename(ent) and os.path.isdir(ent):
2805 2810 ps = ent
2806 2811 break
2807 2812
2808 2813 if fallback is None and pat in ent and os.path.isdir(ent):
2809 2814 fallback = ent
2810 2815
2811 2816 # if we have no last part match, pick the first full path match
2812 2817 if ps is None:
2813 2818 ps = fallback
2814 2819
2815 2820 if ps is None:
2816 2821 print "No matching entry in directory history"
2817 2822 return
2818 2823 else:
2819 2824 opts = {}
2820 2825
2821 2826
2822 2827 else:
2823 2828 #turn all non-space-escaping backslashes to slashes,
2824 2829 # for c:\windows\directory\names\
2825 2830 parameter_s = re.sub(r'\\(?! )','/', parameter_s)
2826 2831 opts,ps = self.parse_options(parameter_s,'qb',mode='string')
2827 2832 # jump to previous
2828 2833 if ps == '-':
2829 2834 try:
2830 2835 ps = self.shell.user_ns['_dh'][-2]
2831 2836 except IndexError:
2832 2837 raise UsageError('%cd -: No previous directory to change to.')
2833 2838 # jump to bookmark if needed
2834 2839 else:
2835 2840 if not os.path.isdir(ps) or opts.has_key('b'):
2836 2841 bkms = self.db.get('bookmarks', {})
2837 2842
2838 2843 if bkms.has_key(ps):
2839 2844 target = bkms[ps]
2840 2845 print '(bookmark:%s) -> %s' % (ps,target)
2841 2846 ps = target
2842 2847 else:
2843 2848 if opts.has_key('b'):
2844 2849 raise UsageError("Bookmark '%s' not found. "
2845 2850 "Use '%%bookmark -l' to see your bookmarks." % ps)
2846 2851
2847 2852 # at this point ps should point to the target dir
2848 2853 if ps:
2849 2854 try:
2850 2855 os.chdir(os.path.expanduser(ps))
2851 2856 if self.shell.rc.term_title:
2852 2857 #print 'set term title:',self.shell.rc.term_title # dbg
2853 2858 platutils.set_term_title('IPy ' + abbrev_cwd())
2854 2859 except OSError:
2855 2860 print sys.exc_info()[1]
2856 2861 else:
2857 2862 cwd = os.getcwd()
2858 2863 dhist = self.shell.user_ns['_dh']
2859 2864 if oldcwd != cwd:
2860 2865 dhist.append(cwd)
2861 2866 self.db['dhist'] = compress_dhist(dhist)[-100:]
2862 2867
2863 2868 else:
2864 2869 os.chdir(self.shell.home_dir)
2865 2870 if self.shell.rc.term_title:
2866 2871 platutils.set_term_title("IPy ~")
2867 2872 cwd = os.getcwd()
2868 2873 dhist = self.shell.user_ns['_dh']
2869 2874
2870 2875 if oldcwd != cwd:
2871 2876 dhist.append(cwd)
2872 2877 self.db['dhist'] = compress_dhist(dhist)[-100:]
2873 2878 if not 'q' in opts and self.shell.user_ns['_dh']:
2874 2879 print self.shell.user_ns['_dh'][-1]
2875 2880
2876 2881
2877 2882 def magic_env(self, parameter_s=''):
2878 2883 """List environment variables."""
2879 2884
2880 2885 return os.environ.data
2881 2886
2882 2887 def magic_pushd(self, parameter_s=''):
2883 2888 """Place the current dir on stack and change directory.
2884 2889
2885 2890 Usage:\\
2886 2891 %pushd ['dirname']
2887 2892 """
2888 2893
2889 2894 dir_s = self.shell.dir_stack
2890 2895 tgt = os.path.expanduser(parameter_s)
2891 2896 cwd = os.getcwd().replace(self.home_dir,'~')
2892 2897 if tgt:
2893 2898 self.magic_cd(parameter_s)
2894 2899 dir_s.insert(0,cwd)
2895 2900 return self.magic_dirs()
2896 2901
2897 2902 def magic_popd(self, parameter_s=''):
2898 2903 """Change to directory popped off the top of the stack.
2899 2904 """
2900 2905 if not self.shell.dir_stack:
2901 2906 raise UsageError("%popd on empty stack")
2902 2907 top = self.shell.dir_stack.pop(0)
2903 2908 self.magic_cd(top)
2904 2909 print "popd ->",top
2905 2910
2906 2911 def magic_dirs(self, parameter_s=''):
2907 2912 """Return the current directory stack."""
2908 2913
2909 2914 return self.shell.dir_stack
2910 2915
2911 2916 def magic_dhist(self, parameter_s=''):
2912 2917 """Print your history of visited directories.
2913 2918
2914 2919 %dhist -> print full history\\
2915 2920 %dhist n -> print last n entries only\\
2916 2921 %dhist n1 n2 -> print entries between n1 and n2 (n1 not included)\\
2917 2922
2918 2923 This history is automatically maintained by the %cd command, and
2919 2924 always available as the global list variable _dh. You can use %cd -<n>
2920 2925 to go to directory number <n>.
2921 2926
2922 2927 Note that most of time, you should view directory history by entering
2923 2928 cd -<TAB>.
2924 2929
2925 2930 """
2926 2931
2927 2932 dh = self.shell.user_ns['_dh']
2928 2933 if parameter_s:
2929 2934 try:
2930 2935 args = map(int,parameter_s.split())
2931 2936 except:
2932 2937 self.arg_err(Magic.magic_dhist)
2933 2938 return
2934 2939 if len(args) == 1:
2935 2940 ini,fin = max(len(dh)-(args[0]),0),len(dh)
2936 2941 elif len(args) == 2:
2937 2942 ini,fin = args
2938 2943 else:
2939 2944 self.arg_err(Magic.magic_dhist)
2940 2945 return
2941 2946 else:
2942 2947 ini,fin = 0,len(dh)
2943 2948 nlprint(dh,
2944 2949 header = 'Directory history (kept in _dh)',
2945 2950 start=ini,stop=fin)
2946 2951
2947 2952 @testdec.skip_doctest
2948 2953 def magic_sc(self, parameter_s=''):
2949 2954 """Shell capture - execute a shell command and capture its output.
2950 2955
2951 2956 DEPRECATED. Suboptimal, retained for backwards compatibility.
2952 2957
2953 2958 You should use the form 'var = !command' instead. Example:
2954 2959
2955 2960 "%sc -l myfiles = ls ~" should now be written as
2956 2961
2957 2962 "myfiles = !ls ~"
2958 2963
2959 2964 myfiles.s, myfiles.l and myfiles.n still apply as documented
2960 2965 below.
2961 2966
2962 2967 --
2963 2968 %sc [options] varname=command
2964 2969
2965 2970 IPython will run the given command using commands.getoutput(), and
2966 2971 will then update the user's interactive namespace with a variable
2967 2972 called varname, containing the value of the call. Your command can
2968 2973 contain shell wildcards, pipes, etc.
2969 2974
2970 2975 The '=' sign in the syntax is mandatory, and the variable name you
2971 2976 supply must follow Python's standard conventions for valid names.
2972 2977
2973 2978 (A special format without variable name exists for internal use)
2974 2979
2975 2980 Options:
2976 2981
2977 2982 -l: list output. Split the output on newlines into a list before
2978 2983 assigning it to the given variable. By default the output is stored
2979 2984 as a single string.
2980 2985
2981 2986 -v: verbose. Print the contents of the variable.
2982 2987
2983 2988 In most cases you should not need to split as a list, because the
2984 2989 returned value is a special type of string which can automatically
2985 2990 provide its contents either as a list (split on newlines) or as a
2986 2991 space-separated string. These are convenient, respectively, either
2987 2992 for sequential processing or to be passed to a shell command.
2988 2993
2989 2994 For example:
2990 2995
2991 2996 # all-random
2992 2997
2993 2998 # Capture into variable a
2994 2999 In [1]: sc a=ls *py
2995 3000
2996 3001 # a is a string with embedded newlines
2997 3002 In [2]: a
2998 3003 Out[2]: 'setup.py\\nwin32_manual_post_install.py'
2999 3004
3000 3005 # which can be seen as a list:
3001 3006 In [3]: a.l
3002 3007 Out[3]: ['setup.py', 'win32_manual_post_install.py']
3003 3008
3004 3009 # or as a whitespace-separated string:
3005 3010 In [4]: a.s
3006 3011 Out[4]: 'setup.py win32_manual_post_install.py'
3007 3012
3008 3013 # a.s is useful to pass as a single command line:
3009 3014 In [5]: !wc -l $a.s
3010 3015 146 setup.py
3011 3016 130 win32_manual_post_install.py
3012 3017 276 total
3013 3018
3014 3019 # while the list form is useful to loop over:
3015 3020 In [6]: for f in a.l:
3016 3021 ...: !wc -l $f
3017 3022 ...:
3018 3023 146 setup.py
3019 3024 130 win32_manual_post_install.py
3020 3025
3021 3026 Similiarly, the lists returned by the -l option are also special, in
3022 3027 the sense that you can equally invoke the .s attribute on them to
3023 3028 automatically get a whitespace-separated string from their contents:
3024 3029
3025 3030 In [7]: sc -l b=ls *py
3026 3031
3027 3032 In [8]: b
3028 3033 Out[8]: ['setup.py', 'win32_manual_post_install.py']
3029 3034
3030 3035 In [9]: b.s
3031 3036 Out[9]: 'setup.py win32_manual_post_install.py'
3032 3037
3033 3038 In summary, both the lists and strings used for ouptut capture have
3034 3039 the following special attributes:
3035 3040
3036 3041 .l (or .list) : value as list.
3037 3042 .n (or .nlstr): value as newline-separated string.
3038 3043 .s (or .spstr): value as space-separated string.
3039 3044 """
3040 3045
3041 3046 opts,args = self.parse_options(parameter_s,'lv')
3042 3047 # Try to get a variable name and command to run
3043 3048 try:
3044 3049 # the variable name must be obtained from the parse_options
3045 3050 # output, which uses shlex.split to strip options out.
3046 3051 var,_ = args.split('=',1)
3047 3052 var = var.strip()
3048 3053 # But the the command has to be extracted from the original input
3049 3054 # parameter_s, not on what parse_options returns, to avoid the
3050 3055 # quote stripping which shlex.split performs on it.
3051 3056 _,cmd = parameter_s.split('=',1)
3052 3057 except ValueError:
3053 3058 var,cmd = '',''
3054 3059 # If all looks ok, proceed
3055 3060 out,err = self.shell.getoutputerror(cmd)
3056 3061 if err:
3057 3062 print >> Term.cerr,err
3058 3063 if opts.has_key('l'):
3059 3064 out = SList(out.split('\n'))
3060 3065 else:
3061 3066 out = LSString(out)
3062 3067 if opts.has_key('v'):
3063 3068 print '%s ==\n%s' % (var,pformat(out))
3064 3069 if var:
3065 3070 self.shell.user_ns.update({var:out})
3066 3071 else:
3067 3072 return out
3068 3073
3069 3074 def magic_sx(self, parameter_s=''):
3070 3075 """Shell execute - run a shell command and capture its output.
3071 3076
3072 3077 %sx command
3073 3078
3074 3079 IPython will run the given command using commands.getoutput(), and
3075 3080 return the result formatted as a list (split on '\\n'). Since the
3076 3081 output is _returned_, it will be stored in ipython's regular output
3077 3082 cache Out[N] and in the '_N' automatic variables.
3078 3083
3079 3084 Notes:
3080 3085
3081 3086 1) If an input line begins with '!!', then %sx is automatically
3082 3087 invoked. That is, while:
3083 3088 !ls
3084 3089 causes ipython to simply issue system('ls'), typing
3085 3090 !!ls
3086 3091 is a shorthand equivalent to:
3087 3092 %sx ls
3088 3093
3089 3094 2) %sx differs from %sc in that %sx automatically splits into a list,
3090 3095 like '%sc -l'. The reason for this is to make it as easy as possible
3091 3096 to process line-oriented shell output via further python commands.
3092 3097 %sc is meant to provide much finer control, but requires more
3093 3098 typing.
3094 3099
3095 3100 3) Just like %sc -l, this is a list with special attributes:
3096 3101
3097 3102 .l (or .list) : value as list.
3098 3103 .n (or .nlstr): value as newline-separated string.
3099 3104 .s (or .spstr): value as whitespace-separated string.
3100 3105
3101 3106 This is very useful when trying to use such lists as arguments to
3102 3107 system commands."""
3103 3108
3104 3109 if parameter_s:
3105 3110 out,err = self.shell.getoutputerror(parameter_s)
3106 3111 if err:
3107 3112 print >> Term.cerr,err
3108 3113 return SList(out.split('\n'))
3109 3114
3110 3115 def magic_bg(self, parameter_s=''):
3111 3116 """Run a job in the background, in a separate thread.
3112 3117
3113 3118 For example,
3114 3119
3115 3120 %bg myfunc(x,y,z=1)
3116 3121
3117 3122 will execute 'myfunc(x,y,z=1)' in a background thread. As soon as the
3118 3123 execution starts, a message will be printed indicating the job
3119 3124 number. If your job number is 5, you can use
3120 3125
3121 3126 myvar = jobs.result(5) or myvar = jobs[5].result
3122 3127
3123 3128 to assign this result to variable 'myvar'.
3124 3129
3125 3130 IPython has a job manager, accessible via the 'jobs' object. You can
3126 3131 type jobs? to get more information about it, and use jobs.<TAB> to see
3127 3132 its attributes. All attributes not starting with an underscore are
3128 3133 meant for public use.
3129 3134
3130 3135 In particular, look at the jobs.new() method, which is used to create
3131 3136 new jobs. This magic %bg function is just a convenience wrapper
3132 3137 around jobs.new(), for expression-based jobs. If you want to create a
3133 3138 new job with an explicit function object and arguments, you must call
3134 3139 jobs.new() directly.
3135 3140
3136 3141 The jobs.new docstring also describes in detail several important
3137 3142 caveats associated with a thread-based model for background job
3138 3143 execution. Type jobs.new? for details.
3139 3144
3140 3145 You can check the status of all jobs with jobs.status().
3141 3146
3142 3147 The jobs variable is set by IPython into the Python builtin namespace.
3143 3148 If you ever declare a variable named 'jobs', you will shadow this
3144 3149 name. You can either delete your global jobs variable to regain
3145 3150 access to the job manager, or make a new name and assign it manually
3146 3151 to the manager (stored in IPython's namespace). For example, to
3147 3152 assign the job manager to the Jobs name, use:
3148 3153
3149 3154 Jobs = __builtins__.jobs"""
3150 3155
3151 3156 self.shell.jobs.new(parameter_s,self.shell.user_ns)
3152 3157
3153 3158 def magic_r(self, parameter_s=''):
3154 3159 """Repeat previous input.
3155 3160
3156 3161 Note: Consider using the more powerfull %rep instead!
3157 3162
3158 3163 If given an argument, repeats the previous command which starts with
3159 3164 the same string, otherwise it just repeats the previous input.
3160 3165
3161 3166 Shell escaped commands (with ! as first character) are not recognized
3162 3167 by this system, only pure python code and magic commands.
3163 3168 """
3164 3169
3165 3170 start = parameter_s.strip()
3166 3171 esc_magic = self.shell.ESC_MAGIC
3167 3172 # Identify magic commands even if automagic is on (which means
3168 3173 # the in-memory version is different from that typed by the user).
3169 3174 if self.shell.rc.automagic:
3170 3175 start_magic = esc_magic+start
3171 3176 else:
3172 3177 start_magic = start
3173 3178 # Look through the input history in reverse
3174 3179 for n in range(len(self.shell.input_hist)-2,0,-1):
3175 3180 input = self.shell.input_hist[n]
3176 3181 # skip plain 'r' lines so we don't recurse to infinity
3177 3182 if input != '_ip.magic("r")\n' and \
3178 3183 (input.startswith(start) or input.startswith(start_magic)):
3179 3184 #print 'match',`input` # dbg
3180 3185 print 'Executing:',input,
3181 3186 self.shell.runlines(input)
3182 3187 return
3183 3188 print 'No previous input matching `%s` found.' % start
3184 3189
3185 3190
3186 3191 def magic_bookmark(self, parameter_s=''):
3187 3192 """Manage IPython's bookmark system.
3188 3193
3189 3194 %bookmark <name> - set bookmark to current dir
3190 3195 %bookmark <name> <dir> - set bookmark to <dir>
3191 3196 %bookmark -l - list all bookmarks
3192 3197 %bookmark -d <name> - remove bookmark
3193 3198 %bookmark -r - remove all bookmarks
3194 3199
3195 3200 You can later on access a bookmarked folder with:
3196 3201 %cd -b <name>
3197 3202 or simply '%cd <name>' if there is no directory called <name> AND
3198 3203 there is such a bookmark defined.
3199 3204
3200 3205 Your bookmarks persist through IPython sessions, but they are
3201 3206 associated with each profile."""
3202 3207
3203 3208 opts,args = self.parse_options(parameter_s,'drl',mode='list')
3204 3209 if len(args) > 2:
3205 3210 raise UsageError("%bookmark: too many arguments")
3206 3211
3207 3212 bkms = self.db.get('bookmarks',{})
3208 3213
3209 3214 if opts.has_key('d'):
3210 3215 try:
3211 3216 todel = args[0]
3212 3217 except IndexError:
3213 3218 raise UsageError(
3214 3219 "%bookmark -d: must provide a bookmark to delete")
3215 3220 else:
3216 3221 try:
3217 3222 del bkms[todel]
3218 3223 except KeyError:
3219 3224 raise UsageError(
3220 3225 "%%bookmark -d: Can't delete bookmark '%s'" % todel)
3221 3226
3222 3227 elif opts.has_key('r'):
3223 3228 bkms = {}
3224 3229 elif opts.has_key('l'):
3225 3230 bks = bkms.keys()
3226 3231 bks.sort()
3227 3232 if bks:
3228 3233 size = max(map(len,bks))
3229 3234 else:
3230 3235 size = 0
3231 3236 fmt = '%-'+str(size)+'s -> %s'
3232 3237 print 'Current bookmarks:'
3233 3238 for bk in bks:
3234 3239 print fmt % (bk,bkms[bk])
3235 3240 else:
3236 3241 if not args:
3237 3242 raise UsageError("%bookmark: You must specify the bookmark name")
3238 3243 elif len(args)==1:
3239 3244 bkms[args[0]] = os.getcwd()
3240 3245 elif len(args)==2:
3241 3246 bkms[args[0]] = args[1]
3242 3247 self.db['bookmarks'] = bkms
3243 3248
3244 3249 def magic_pycat(self, parameter_s=''):
3245 3250 """Show a syntax-highlighted file through a pager.
3246 3251
3247 3252 This magic is similar to the cat utility, but it will assume the file
3248 3253 to be Python source and will show it with syntax highlighting. """
3249 3254
3250 3255 try:
3251 3256 filename = get_py_filename(parameter_s)
3252 3257 cont = file_read(filename)
3253 3258 except IOError:
3254 3259 try:
3255 3260 cont = eval(parameter_s,self.user_ns)
3256 3261 except NameError:
3257 3262 cont = None
3258 3263 if cont is None:
3259 3264 print "Error: no such file or variable"
3260 3265 return
3261 3266
3262 3267 page(self.shell.pycolorize(cont),
3263 3268 screen_lines=self.shell.rc.screen_length)
3264 3269
3270 def _rerun_pasted(self):
3271 """ Rerun a previously pasted command.
3272 """
3273 b = self.user_ns.get('pasted_block', None)
3274 if b is None:
3275 raise UsageError('No previous pasted block available')
3276 print "Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b))
3277 exec b in self.user_ns
3278
3279 def _get_pasted_lines(self, sentinel):
3280 """ Yield pasted lines until the user enters the given sentinel value.
3281 """
3282 from IPython.core import iplib
3283 print "Pasting code; enter '%s' alone on the line to stop." % sentinel
3284 while True:
3285 l = iplib.raw_input_original(':')
3286 if l == sentinel:
3287 return
3288 else:
3289 yield l
3290
3291 def _strip_pasted_lines_for_code(self, raw_lines):
3292 """ Strip non-code parts of a sequence of lines to return a block of
3293 code.
3294 """
3295 # Regular expressions that declare text we strip from the input:
3296 strip_re = [r'^\s*In \[\d+\]:', # IPython input prompt
3297 r'^\s*(\s?>)+', # Python input prompt
3298 r'^\s*\.{3,}', # Continuation prompts
3299 r'^\++',
3300 ]
3301
3302 strip_from_start = map(re.compile,strip_re)
3303
3304 lines = []
3305 for l in raw_lines:
3306 for pat in strip_from_start:
3307 l = pat.sub('',l)
3308 lines.append(l)
3309
3310 block = "\n".join(lines) + '\n'
3311 #print "block:\n",block
3312 return block
3313
3314 def _execute_block(self, block, par):
3315 """ Execute a block, or store it in a variable, per the user's request.
3316 """
3317 if not par:
3318 b = textwrap.dedent(block)
3319 self.user_ns['pasted_block'] = b
3320 exec b in self.user_ns
3321 else:
3322 self.user_ns[par] = SList(block.splitlines())
3323 print "Block assigned to '%s'" % par
3324
3265 3325 def magic_cpaste(self, parameter_s=''):
3266 3326 """Allows you to paste & execute a pre-formatted code block from clipboard.
3267 3327
3268 3328 You must terminate the block with '--' (two minus-signs) alone on the
3269 3329 line. You can also provide your own sentinel with '%paste -s %%' ('%%'
3270 3330 is the new sentinel for this operation)
3271 3331
3272 3332 The block is dedented prior to execution to enable execution of method
3273 3333 definitions. '>' and '+' characters at the beginning of a line are
3274 3334 ignored, to allow pasting directly from e-mails, diff files and
3275 3335 doctests (the '...' continuation prompt is also stripped). The
3276 3336 executed block is also assigned to variable named 'pasted_block' for
3277 3337 later editing with '%edit pasted_block'.
3278 3338
3279 3339 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
3280 3340 This assigns the pasted block to variable 'foo' as string, without
3281 3341 dedenting or executing it (preceding >>> and + is still stripped)
3282 3342
3283 3343 '%cpaste -r' re-executes the block previously entered by cpaste.
3284 3344
3285 3345 Do not be alarmed by garbled output on Windows (it's a readline bug).
3286 3346 Just press enter and type -- (and press enter again) and the block
3287 3347 will be what was just pasted.
3288 3348
3289 3349 IPython statements (magics, shell escapes) are not supported (yet).
3350
3351 See also
3352 --------
3353 paste: automatically pull code from clipboard.
3290 3354 """
3355
3291 3356 opts,args = self.parse_options(parameter_s,'rs:',mode='string')
3292 3357 par = args.strip()
3293 3358 if opts.has_key('r'):
3294 b = self.user_ns.get('pasted_block', None)
3295 if b is None:
3296 raise UsageError('No previous pasted block available')
3297 print "Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b))
3298 exec b in self.user_ns
3359 self._rerun_pasted()
3299 3360 return
3300 3361
3301 3362 sentinel = opts.get('s','--')
3302 3363
3303 # Regular expressions that declare text we strip from the input:
3304 strip_re = [r'^\s*In \[\d+\]:', # IPython input prompt
3305 r'^\s*(\s?>)+', # Python input prompt
3306 r'^\s*\.{3,}', # Continuation prompts
3307 r'^\++',
3308 ]
3364 block = self._strip_pasted_lines_for_code(
3365 self._get_pasted_lines(sentinel))
3309 3366
3310 strip_from_start = map(re.compile,strip_re)
3367 self._execute_block(block, par)
3311 3368
3312 from IPython.core import iplib
3313 lines = []
3314 print "Pasting code; enter '%s' alone on the line to stop." % sentinel
3315 while 1:
3316 l = iplib.raw_input_original(':')
3317 if l ==sentinel:
3318 break
3369 def magic_paste(self, parameter_s=''):
3370 """Allows you to paste & execute a pre-formatted code block from clipboard.
3319 3371
3320 for pat in strip_from_start:
3321 l = pat.sub('',l)
3322 lines.append(l)
3372 The text is pulled directly from the clipboard without user
3373 intervention.
3323 3374
3324 block = "\n".join(lines) + '\n'
3325 #print "block:\n",block
3326 if not par:
3327 b = textwrap.dedent(block)
3328 self.user_ns['pasted_block'] = b
3329 exec b in self.user_ns
3330 else:
3331 self.user_ns[par] = SList(block.splitlines())
3332 print "Block assigned to '%s'" % par
3375 The block is dedented prior to execution to enable execution of method
3376 definitions. '>' and '+' characters at the beginning of a line are
3377 ignored, to allow pasting directly from e-mails, diff files and
3378 doctests (the '...' continuation prompt is also stripped). The
3379 executed block is also assigned to variable named 'pasted_block' for
3380 later editing with '%edit pasted_block'.
3381
3382 You can also pass a variable name as an argument, e.g. '%paste foo'.
3383 This assigns the pasted block to variable 'foo' as string, without
3384 dedenting or executing it (preceding >>> and + is still stripped)
3385
3386 '%paste -r' re-executes the block previously entered by cpaste.
3387
3388 IPython statements (magics, shell escapes) are not supported (yet).
3389
3390 See also
3391 --------
3392 cpaste: manually paste code into terminal until you mark its end.
3393 """
3394 opts,args = self.parse_options(parameter_s,'r:',mode='string')
3395 par = args.strip()
3396 if opts.has_key('r'):
3397 self._rerun_pasted()
3398 return
3399
3400 text = self.shell.hooks.clipboard_get()
3401 block = self._strip_pasted_lines_for_code(text.splitlines())
3402 self._execute_block(block, par)
3333 3403
3334 3404 def magic_quickref(self,arg):
3335 3405 """ Show a quick reference sheet """
3336 3406 import IPython.core.usage
3337 3407 qr = IPython.core.usage.quick_reference + self.magic_magic('-brief')
3338 3408
3339 3409 page(qr)
3340 3410
3341 3411 def magic_upgrade(self,arg):
3342 3412 """ Upgrade your IPython installation
3343 3413
3344 3414 This will copy the config files that don't yet exist in your
3345 3415 ipython dir from the system config dir. Use this after upgrading
3346 3416 IPython if you don't wish to delete your .ipython dir.
3347 3417
3348 3418 Call with -nolegacy to get rid of ipythonrc* files (recommended for
3349 3419 new users)
3350 3420
3351 3421 """
3352 3422 ip = self.getapi()
3353 3423 ipinstallation = path(IPython.__file__).dirname()
3354 3424 upgrade_script = '%s "%s"' % (sys.executable,ipinstallation / 'utils' / 'upgradedir.py')
3355 3425 src_config = ipinstallation / 'config' / 'userconfig'
3356 3426 userdir = path(ip.options.ipythondir)
3357 3427 cmd = '%s "%s" "%s"' % (upgrade_script, src_config, userdir)
3358 3428 print ">",cmd
3359 3429 shell(cmd)
3360 3430 if arg == '-nolegacy':
3361 3431 legacy = userdir.files('ipythonrc*')
3362 3432 print "Nuking legacy files:",legacy
3363 3433
3364 3434 [p.remove() for p in legacy]
3365 3435 suffix = (sys.platform == 'win32' and '.ini' or '')
3366 3436 (userdir / ('ipythonrc' + suffix)).write_text('# Empty, see ipy_user_conf.py\n')
3367 3437
3368 3438
3369 3439 def magic_doctest_mode(self,parameter_s=''):
3370 3440 """Toggle doctest mode on and off.
3371 3441
3372 3442 This mode allows you to toggle the prompt behavior between normal
3373 3443 IPython prompts and ones that are as similar to the default IPython
3374 3444 interpreter as possible.
3375 3445
3376 3446 It also supports the pasting of code snippets that have leading '>>>'
3377 3447 and '...' prompts in them. This means that you can paste doctests from
3378 3448 files or docstrings (even if they have leading whitespace), and the
3379 3449 code will execute correctly. You can then use '%history -tn' to see
3380 3450 the translated history without line numbers; this will give you the
3381 3451 input after removal of all the leading prompts and whitespace, which
3382 3452 can be pasted back into an editor.
3383 3453
3384 3454 With these features, you can switch into this mode easily whenever you
3385 3455 need to do testing and changes to doctests, without having to leave
3386 3456 your existing IPython session.
3387 3457 """
3388 3458
3389 3459 # XXX - Fix this to have cleaner activate/deactivate calls.
3390 3460 from IPython.extensions import InterpreterPasteInput as ipaste
3391 3461 from IPython.utils.ipstruct import Struct
3392 3462
3393 3463 # Shorthands
3394 3464 shell = self.shell
3395 3465 oc = shell.outputcache
3396 3466 rc = shell.rc
3397 3467 meta = shell.meta
3398 3468 # dstore is a data store kept in the instance metadata bag to track any
3399 3469 # changes we make, so we can undo them later.
3400 3470 dstore = meta.setdefault('doctest_mode',Struct())
3401 3471 save_dstore = dstore.setdefault
3402 3472
3403 3473 # save a few values we'll need to recover later
3404 3474 mode = save_dstore('mode',False)
3405 3475 save_dstore('rc_pprint',rc.pprint)
3406 3476 save_dstore('xmode',shell.InteractiveTB.mode)
3407 3477 save_dstore('rc_separate_out',rc.separate_out)
3408 3478 save_dstore('rc_separate_out2',rc.separate_out2)
3409 3479 save_dstore('rc_prompts_pad_left',rc.prompts_pad_left)
3410 3480 save_dstore('rc_separate_in',rc.separate_in)
3411 3481
3412 3482 if mode == False:
3413 3483 # turn on
3414 3484 ipaste.activate_prefilter()
3415 3485
3416 3486 oc.prompt1.p_template = '>>> '
3417 3487 oc.prompt2.p_template = '... '
3418 3488 oc.prompt_out.p_template = ''
3419 3489
3420 3490 # Prompt separators like plain python
3421 3491 oc.input_sep = oc.prompt1.sep = ''
3422 3492 oc.output_sep = ''
3423 3493 oc.output_sep2 = ''
3424 3494
3425 3495 oc.prompt1.pad_left = oc.prompt2.pad_left = \
3426 3496 oc.prompt_out.pad_left = False
3427 3497
3428 3498 rc.pprint = False
3429 3499
3430 3500 shell.magic_xmode('Plain')
3431 3501
3432 3502 else:
3433 3503 # turn off
3434 3504 ipaste.deactivate_prefilter()
3435 3505
3436 3506 oc.prompt1.p_template = rc.prompt_in1
3437 3507 oc.prompt2.p_template = rc.prompt_in2
3438 3508 oc.prompt_out.p_template = rc.prompt_out
3439 3509
3440 3510 oc.input_sep = oc.prompt1.sep = dstore.rc_separate_in
3441 3511
3442 3512 oc.output_sep = dstore.rc_separate_out
3443 3513 oc.output_sep2 = dstore.rc_separate_out2
3444 3514
3445 3515 oc.prompt1.pad_left = oc.prompt2.pad_left = \
3446 3516 oc.prompt_out.pad_left = dstore.rc_prompts_pad_left
3447 3517
3448 3518 rc.pprint = dstore.rc_pprint
3449 3519
3450 3520 shell.magic_xmode(dstore.xmode)
3451 3521
3452 3522 # Store new mode and inform
3453 3523 dstore.mode = bool(1-int(mode))
3454 3524 print 'Doctest mode is:',
3455 3525 print ['OFF','ON'][dstore.mode]
3456 3526
3457 3527 # end Magic
@@ -1,121 +1,121 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Release data for the IPython project."""
3 3
4 4 #*****************************************************************************
5 # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
6 #
5 # Copyright (C) 2008-2009 The IPython Development Team
6 # Copyright (C) 2001-2008 Fernando Perez <fperez@colorado.edu>
7 7 # Copyright (c) 2001 Janko Hauser <jhauser@zscout.de> and Nathaniel Gray
8 8 # <n8gray@caltech.edu>
9 9 #
10 10 # Distributed under the terms of the BSD License. The full license is in
11 11 # the file COPYING, distributed as part of this software.
12 12 #*****************************************************************************
13 13
14 14 # Name of the package for release purposes. This is the name which labels
15 15 # the tarballs and RPMs made by distutils, so it's best to lowercase it.
16 16 name = 'ipython'
17 17
18 18 # For versions with substrings (like 0.6.16.svn), use an extra . to separate
19 19 # the new substring. We have to avoid using either dashes or underscores,
20 20 # because bdist_rpm does not accept dashes (an RPM) convention, and
21 21 # bdist_deb does not accept underscores (a Debian convention).
22 22
23 development = True # change this to False to do a release
23 development = False # change this to False to do a release
24 24 version_base = '0.10'
25 25 branch = 'ipython'
26 revision = '1163'
26 revision = '1188'
27 27
28 28 if development:
29 29 if branch == 'ipython':
30 30 version = '%s.bzr.r%s' % (version_base, revision)
31 31 else:
32 32 version = '%s.bzr.r%s.%s' % (version_base, revision, branch)
33 33 else:
34 34 version = version_base
35 35
36 36
37 37 description = "An interactive computing environment for Python"
38 38
39 39 long_description = \
40 40 """
41 41 The goal of IPython is to create a comprehensive environment for
42 42 interactive and exploratory computing. To support this goal, IPython
43 43 has two main components:
44 44
45 45 * An enhanced interactive Python shell.
46 46
47 47 * An architecture for interactive parallel computing.
48 48
49 49 The enhanced interactive Python shell has the following main features:
50 50
51 51 * Comprehensive object introspection.
52 52
53 53 * Input history, persistent across sessions.
54 54
55 55 * Caching of output results during a session with automatically generated
56 56 references.
57 57
58 58 * Readline based name completion.
59 59
60 60 * Extensible system of 'magic' commands for controlling the environment and
61 61 performing many tasks related either to IPython or the operating system.
62 62
63 63 * Configuration system with easy switching between different setups (simpler
64 64 than changing $PYTHONSTARTUP environment variables every time).
65 65
66 66 * Session logging and reloading.
67 67
68 68 * Extensible syntax processing for special purpose situations.
69 69
70 70 * Access to the system shell with user-extensible alias system.
71 71
72 72 * Easily embeddable in other Python programs and wxPython GUIs.
73 73
74 74 * Integrated access to the pdb debugger and the Python profiler.
75 75
76 76 The parallel computing architecture has the following main features:
77 77
78 78 * Quickly parallelize Python code from an interactive Python/IPython session.
79 79
80 80 * A flexible and dynamic process model that be deployed on anything from
81 81 multicore workstations to supercomputers.
82 82
83 83 * An architecture that supports many different styles of parallelism, from
84 84 message passing to task farming.
85 85
86 86 * Both blocking and fully asynchronous interfaces.
87 87
88 88 * High level APIs that enable many things to be parallelized in a few lines
89 89 of code.
90 90
91 91 * Share live parallel jobs with other users securely.
92 92
93 93 * Dynamically load balanced task farming system.
94 94
95 95 * Robust error handling in parallel code.
96 96
97 97 The latest development version is always available from IPython's `Launchpad
98 98 site <http://launchpad.net/ipython>`_.
99 99 """
100 100
101 101 license = 'BSD'
102 102
103 authors = {'Fernando' : ('Fernando Perez','fperez@colorado.edu'),
103 authors = {'Fernando' : ('Fernando Perez','fperez.net@gmail.com'),
104 104 'Janko' : ('Janko Hauser','jhauser@zscout.de'),
105 105 'Nathan' : ('Nathaniel Gray','n8gray@caltech.edu'),
106 106 'Ville' : ('Ville Vainio','vivainio@gmail.com'),
107 107 'Brian' : ('Brian E Granger', 'ellisonbg@gmail.com'),
108 108 'Min' : ('Min Ragan-Kelley', 'benjaminrk@gmail.com')
109 109 }
110 110
111 111 author = 'The IPython Development Team'
112 112
113 113 author_email = 'ipython-dev@scipy.org'
114 114
115 115 url = 'http://ipython.scipy.org'
116 116
117 117 download_url = 'http://ipython.scipy.org/dist'
118 118
119 119 platforms = ['Linux','Mac OSX','Windows XP/2000/NT','Windows 95/98/ME']
120 120
121 121 keywords = ['Interactive','Interpreter','Shell','Parallel','Distributed']
@@ -1,249 +1,302 b''
1 1 """Tests for various magic functions.
2 2
3 3 Needs to be run by nose (to make ipython session available).
4 4 """
5 5
6 6 import os
7 7 import sys
8 8 import tempfile
9 9 import types
10 10
11 11 import nose.tools as nt
12 12
13 13 from IPython.utils.platutils import find_cmd, get_long_path_name
14 14 from IPython.testing import decorators as dec
15 15 from IPython.testing import tools as tt
16 16
17 17 #-----------------------------------------------------------------------------
18 18 # Test functions begin
19 19
20 20 def test_rehashx():
21 21 # clear up everything
22 22 _ip.IP.alias_table.clear()
23 23 del _ip.db['syscmdlist']
24 24
25 25 _ip.magic('rehashx')
26 26 # Practically ALL ipython development systems will have more than 10 aliases
27 27
28 assert len(_ip.IP.alias_table) > 10
28 yield (nt.assert_true, len(_ip.IP.alias_table) > 10)
29 29 for key, val in _ip.IP.alias_table.items():
30 30 # we must strip dots from alias names
31 assert '.' not in key
31 nt.assert_true('.' not in key)
32 32
33 33 # rehashx must fill up syscmdlist
34 34 scoms = _ip.db['syscmdlist']
35 assert len(scoms) > 10
35 yield (nt.assert_true, len(scoms) > 10)
36 36
37 37
38 38 def doctest_hist_f():
39 39 """Test %hist -f with temporary filename.
40 40
41 41 In [9]: import tempfile
42 42
43 43 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
44 44
45 In [11]: %history -n -f $tfile 3
45 In [11]: %hist -n -f $tfile 3
46 46 """
47 47
48 48
49 49 def doctest_hist_r():
50 50 """Test %hist -r
51 51
52 52 XXX - This test is not recording the output correctly. Not sure why...
53 53
54 In [20]: 'hist' in _ip.IP.lsmagic()
55 Out[20]: True
56
54 57 In [6]: x=1
55 58
56 In [7]: hist -n -r 2
59 In [7]: %hist -n -r 2
57 60 x=1 # random
58 61 hist -n -r 2 # random
59 62 """
60 63
61 64 # This test is known to fail on win32.
62 65 # See ticket https://bugs.launchpad.net/bugs/366334
63 66 def test_obj_del():
64 67 """Test that object's __del__ methods are called on exit."""
65 68 test_dir = os.path.dirname(__file__)
66 69 del_file = os.path.join(test_dir,'obj_del.py')
67 70 ipython_cmd = find_cmd('ipython')
68 71 out = _ip.IP.getoutput('%s %s' % (ipython_cmd, del_file))
69 72 nt.assert_equals(out,'obj_del.py: object A deleted')
70 73
71 74
72 75 def test_shist():
73 76 # Simple tests of ShadowHist class - test generator.
74 77 import os, shutil, tempfile
75 78
76 79 from IPython.extensions import pickleshare
77 80 from IPython.core.history import ShadowHist
78 81
79 82 tfile = tempfile.mktemp('','tmp-ipython-')
80 83
81 84 db = pickleshare.PickleShareDB(tfile)
82 85 s = ShadowHist(db)
83 86 s.add('hello')
84 87 s.add('world')
85 88 s.add('hello')
86 89 s.add('hello')
87 90 s.add('karhu')
88 91
89 92 yield nt.assert_equals,s.all(),[(1, 'hello'), (2, 'world'), (3, 'karhu')]
90 93
91 94 yield nt.assert_equal,s.get(2),'world'
92 95
93 96 shutil.rmtree(tfile)
94 97
95 98 @dec.skipif_not_numpy
96 99 def test_numpy_clear_array_undec():
100 from IPython.extensions import clearcmd
101
97 102 _ip.ex('import numpy as np')
98 103 _ip.ex('a = np.empty(2)')
99
100 yield nt.assert_true,'a' in _ip.user_ns
104 yield (nt.assert_true, 'a' in _ip.user_ns)
101 105 _ip.magic('clear array')
102 yield nt.assert_false,'a' in _ip.user_ns
106 yield (nt.assert_false, 'a' in _ip.user_ns)
103 107
104 108
105 109 @dec.skip()
106 110 def test_fail_dec(*a,**k):
107 111 yield nt.assert_true, False
108 112
109 113 @dec.skip('This one shouldn not run')
110 114 def test_fail_dec2(*a,**k):
111 115 yield nt.assert_true, False
112 116
113 117 @dec.skipknownfailure
114 118 def test_fail_dec3(*a,**k):
115 119 yield nt.assert_true, False
116 120
117 121
118 122 def doctest_refbug():
119 123 """Very nasty problem with references held by multiple runs of a script.
120 124 See: https://bugs.launchpad.net/ipython/+bug/269966
121 125
122 126 In [1]: _ip.IP.clear_main_mod_cache()
123 127
124 128 In [2]: run refbug
125 129
126 130 In [3]: call_f()
127 131 lowercased: hello
128 132
129 133 In [4]: run refbug
130 134
131 135 In [5]: call_f()
132 136 lowercased: hello
133 137 lowercased: hello
134 138 """
135 139
136 140 #-----------------------------------------------------------------------------
137 141 # Tests for %run
138 142 #-----------------------------------------------------------------------------
139 143
140 144 # %run is critical enough that it's a good idea to have a solid collection of
141 145 # tests for it, some as doctests and some as normal tests.
142 146
143 147 def doctest_run_ns():
144 148 """Classes declared %run scripts must be instantiable afterwards.
145 149
146 150 In [11]: run tclass foo
147 151
148 152 In [12]: isinstance(f(),foo)
149 153 Out[12]: True
150 154 """
151 155
152 156
153 157 def doctest_run_ns2():
154 158 """Classes declared %run scripts must be instantiable afterwards.
155 159
156 160 In [4]: run tclass C-first_pass
157 161
158 162 In [5]: run tclass C-second_pass
159 163 tclass.py: deleting object: C-first_pass
160 164 """
161 165
162 @dec.skip_win32
163 166 def doctest_run_builtins():
164 167 """Check that %run doesn't damage __builtins__ via a doctest.
165 168
166 169 This is similar to the test_run_builtins, but I want *both* forms of the
167 170 test to catch any possible glitches in our testing machinery, since that
168 171 modifies %run somewhat. So for this, we have both a normal test (below)
169 172 and a doctest (this one).
170 173
171 174 In [1]: import tempfile
172 175
173 176 In [2]: bid1 = id(__builtins__)
174 177
175 In [3]: f = tempfile.NamedTemporaryFile()
178 In [3]: fname = tempfile.mkstemp()[1]
179
180 In [3]: f = open(fname,'w')
176 181
177 182 In [4]: f.write('pass\\n')
178 183
179 184 In [5]: f.flush()
180 185
181 In [6]: print 'B1:',type(__builtins__)
182 B1: <type 'module'>
186 In [6]: print type(__builtins__)
187 <type 'module'>
183 188
184 In [7]: %run $f.name
189 In [7]: %run "$fname"
190
191 In [7]: f.close()
185 192
186 193 In [8]: bid2 = id(__builtins__)
187 194
188 In [9]: print 'B2:',type(__builtins__)
189 B2: <type 'module'>
195 In [9]: print type(__builtins__)
196 <type 'module'>
190 197
191 198 In [10]: bid1 == bid2
192 199 Out[10]: True
200
201 In [12]: try:
202 ....: os.unlink(fname)
203 ....: except:
204 ....: pass
205 ....:
193 206 """
194 207
195 208 # For some tests, it will be handy to organize them in a class with a common
196 209 # setup that makes a temp file
197 210
198 211 class TestMagicRun(object):
199 212
200 213 def setup(self):
201 214 """Make a valid python temp file."""
202 f = tempfile.NamedTemporaryFile()
215 fname = tempfile.mkstemp()[1]
216 f = open(fname,'w')
203 217 f.write('pass\n')
204 218 f.flush()
205 219 self.tmpfile = f
220 self.fname = fname
206 221
207 222 def run_tmpfile(self):
208 223 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
209 224 # See below and ticket https://bugs.launchpad.net/bugs/366353
210 _ip.magic('run %s' % self.tmpfile.name)
211
212 # See https://bugs.launchpad.net/bugs/366353
213 @dec.skip_if_not_win32
214 def test_run_tempfile_path(self):
215 tt.assert_equals(True,False,"%run doesn't work with tempfile paths on win32.")
225 _ip.magic('run "%s"' % self.fname)
216 226
217 # See https://bugs.launchpad.net/bugs/366353
218 @dec.skip_win32
219 227 def test_builtins_id(self):
220 228 """Check that %run doesn't damage __builtins__ """
221 229
222 230 # Test that the id of __builtins__ is not modified by %run
223 231 bid1 = id(_ip.user_ns['__builtins__'])
224 232 self.run_tmpfile()
225 233 bid2 = id(_ip.user_ns['__builtins__'])
226 234 tt.assert_equals(bid1, bid2)
227 235
228 # See https://bugs.launchpad.net/bugs/366353
229 @dec.skip_win32
230 236 def test_builtins_type(self):
231 237 """Check that the type of __builtins__ doesn't change with %run.
232 238
233 239 However, the above could pass if __builtins__ was already modified to
234 240 be a dict (it should be a module) by a previous use of %run. So we
235 241 also check explicitly that it really is a module:
236 242 """
237 243 self.run_tmpfile()
238 244 tt.assert_equals(type(_ip.user_ns['__builtins__']),type(sys))
239 245
240 # See https://bugs.launchpad.net/bugs/366353
241 @dec.skip_win32
242 246 def test_prompts(self):
243 247 """Test that prompts correctly generate after %run"""
244 248 self.run_tmpfile()
245 249 p2 = str(_ip.IP.outputcache.prompt2).strip()
246 250 nt.assert_equals(p2[:3], '...')
247 251
248 252 def teardown(self):
249 253 self.tmpfile.close()
254 try:
255 os.unlink(self.fname)
256 except:
257 # On Windows, even though we close the file, we still can't delete
258 # it. I have no clue why
259 pass
260
261 # Multiple tests for clipboard pasting
262 def test_paste():
263
264 def paste(txt):
265 hooks.clipboard_get = lambda : txt
266 _ip.magic('paste')
267
268 # Inject fake clipboard hook but save original so we can restore it later
269 hooks = _ip.IP.hooks
270 user_ns = _ip.user_ns
271 original_clip = hooks.clipboard_get
272
273 try:
274 # This try/except with an emtpy except clause is here only because
275 # try/yield/finally is invalid syntax in Python 2.4. This will be
276 # removed when we drop 2.4-compatibility, and the emtpy except below
277 # will be changed to a finally.
278
279 # Run tests with fake clipboard function
280 user_ns.pop('x', None)
281 paste('x=1')
282 yield (nt.assert_equal, user_ns['x'], 1)
283
284 user_ns.pop('x', None)
285 paste('>>> x=2')
286 yield (nt.assert_equal, user_ns['x'], 2)
287
288 paste("""
289 >>> x = [1,2,3]
290 >>> y = []
291 >>> for i in x:
292 ... y.append(i**2)
293 ...
294 """)
295 yield (nt.assert_equal, user_ns['x'], [1,2,3])
296 yield (nt.assert_equal, user_ns['y'], [1,4,9])
297 except:
298 pass
299
300 # This should be in a finally clause, instead of the bare except above.
301 # Restore original hook
302 hooks.clipboard_get = original_clip
@@ -1,1057 +1,1063 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 ultratb.py -- Spice up your tracebacks!
4 4
5 5 * ColorTB
6 6 I've always found it a bit hard to visually parse tracebacks in Python. The
7 7 ColorTB class is a solution to that problem. It colors the different parts of a
8 8 traceback in a manner similar to what you would expect from a syntax-highlighting
9 9 text editor.
10 10
11 11 Installation instructions for ColorTB:
12 12 import sys,ultratb
13 13 sys.excepthook = ultratb.ColorTB()
14 14
15 15 * VerboseTB
16 16 I've also included a port of Ka-Ping Yee's "cgitb.py" that produces all kinds
17 17 of useful info when a traceback occurs. Ping originally had it spit out HTML
18 18 and intended it for CGI programmers, but why should they have all the fun? I
19 19 altered it to spit out colored text to the terminal. It's a bit overwhelming,
20 20 but kind of neat, and maybe useful for long-running programs that you believe
21 21 are bug-free. If a crash *does* occur in that type of program you want details.
22 22 Give it a shot--you'll love it or you'll hate it.
23 23
24 24 Note:
25 25
26 26 The Verbose mode prints the variables currently visible where the exception
27 27 happened (shortening their strings if too long). This can potentially be
28 28 very slow, if you happen to have a huge data structure whose string
29 29 representation is complex to compute. Your computer may appear to freeze for
30 30 a while with cpu usage at 100%. If this occurs, you can cancel the traceback
31 31 with Ctrl-C (maybe hitting it more than once).
32 32
33 33 If you encounter this kind of situation often, you may want to use the
34 34 Verbose_novars mode instead of the regular Verbose, which avoids formatting
35 35 variables (but otherwise includes the information and context given by
36 36 Verbose).
37 37
38 38
39 39 Installation instructions for ColorTB:
40 40 import sys,ultratb
41 41 sys.excepthook = ultratb.VerboseTB()
42 42
43 43 Note: Much of the code in this module was lifted verbatim from the standard
44 44 library module 'traceback.py' and Ka-Ping Yee's 'cgitb.py'.
45 45
46 46 * Color schemes
47 47 The colors are defined in the class TBTools through the use of the
48 48 ColorSchemeTable class. Currently the following exist:
49 49
50 50 - NoColor: allows all of this module to be used in any terminal (the color
51 51 escapes are just dummy blank strings).
52 52
53 53 - Linux: is meant to look good in a terminal like the Linux console (black
54 54 or very dark background).
55 55
56 56 - LightBG: similar to Linux but swaps dark/light colors to be more readable
57 57 in light background terminals.
58 58
59 59 You can implement other color schemes easily, the syntax is fairly
60 60 self-explanatory. Please send back new schemes you develop to the author for
61 61 possible inclusion in future releases.
62 62 """
63 63
64 64 #*****************************************************************************
65 65 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
66 66 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
67 67 #
68 68 # Distributed under the terms of the BSD License. The full license is in
69 69 # the file COPYING, distributed as part of this software.
70 70 #*****************************************************************************
71 71
72 72 # Required modules
73 73 import inspect
74 74 import keyword
75 75 import linecache
76 76 import os
77 77 import pydoc
78 78 import re
79 79 import string
80 80 import sys
81 81 import time
82 82 import tokenize
83 83 import traceback
84 84 import types
85 85
86 86 # For purposes of monkeypatching inspect to fix a bug in it.
87 87 from inspect import getsourcefile, getfile, getmodule,\
88 88 ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode
89 89
90 90
91 91 # IPython's own modules
92 92 # Modified pdb which doesn't damage IPython's readline handling
93 93 from IPython.utils import PyColorize
94 from IPython.core import debugger
94 from IPython.core import debugger, ipapi
95 95 from IPython.utils.ipstruct import Struct
96 96 from IPython.core.excolors import exception_colors
97 97 from IPython.utils.genutils import Term,uniq_stable,error,info
98 98
99 99 # Globals
100 100 # amount of space to put line numbers before verbose tracebacks
101 101 INDENT_SIZE = 8
102 102
103 103 # Default color scheme. This is used, for example, by the traceback
104 104 # formatter. When running in an actual IPython instance, the user's rc.colors
105 105 # value is used, but havinga module global makes this functionality available
106 106 # to users of ultratb who are NOT running inside ipython.
107 107 DEFAULT_SCHEME = 'NoColor'
108 108
109 109 #---------------------------------------------------------------------------
110 110 # Code begins
111 111
112 112 # Utility functions
113 113 def inspect_error():
114 114 """Print a message about internal inspect errors.
115 115
116 116 These are unfortunately quite common."""
117 117
118 118 error('Internal Python error in the inspect module.\n'
119 119 'Below is the traceback from this internal error.\n')
120 120
121 121
122 122 def findsource(object):
123 123 """Return the entire source file and starting line number for an object.
124 124
125 125 The argument may be a module, class, method, function, traceback, frame,
126 126 or code object. The source code is returned as a list of all the lines
127 127 in the file and the line number indexes a line in that list. An IOError
128 128 is raised if the source code cannot be retrieved.
129 129
130 130 FIXED version with which we monkeypatch the stdlib to work around a bug."""
131 131
132 132 file = getsourcefile(object) or getfile(object)
133 133 # If the object is a frame, then trying to get the globals dict from its
134 134 # module won't work. Instead, the frame object itself has the globals
135 135 # dictionary.
136 136 globals_dict = None
137 137 if inspect.isframe(object):
138 138 # XXX: can this ever be false?
139 139 globals_dict = object.f_globals
140 140 else:
141 141 module = getmodule(object, file)
142 142 if module:
143 143 globals_dict = module.__dict__
144 144 lines = linecache.getlines(file, globals_dict)
145 145 if not lines:
146 146 raise IOError('could not get source code')
147 147
148 148 if ismodule(object):
149 149 return lines, 0
150 150
151 151 if isclass(object):
152 152 name = object.__name__
153 153 pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
154 154 # make some effort to find the best matching class definition:
155 155 # use the one with the least indentation, which is the one
156 156 # that's most probably not inside a function definition.
157 157 candidates = []
158 158 for i in range(len(lines)):
159 159 match = pat.match(lines[i])
160 160 if match:
161 161 # if it's at toplevel, it's already the best one
162 162 if lines[i][0] == 'c':
163 163 return lines, i
164 164 # else add whitespace to candidate list
165 165 candidates.append((match.group(1), i))
166 166 if candidates:
167 167 # this will sort by whitespace, and by line number,
168 168 # less whitespace first
169 169 candidates.sort()
170 170 return lines, candidates[0][1]
171 171 else:
172 172 raise IOError('could not find class definition')
173 173
174 174 if ismethod(object):
175 175 object = object.im_func
176 176 if isfunction(object):
177 177 object = object.func_code
178 178 if istraceback(object):
179 179 object = object.tb_frame
180 180 if isframe(object):
181 181 object = object.f_code
182 182 if iscode(object):
183 183 if not hasattr(object, 'co_firstlineno'):
184 184 raise IOError('could not find function definition')
185 185 pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
186 186 pmatch = pat.match
187 187 # fperez - fix: sometimes, co_firstlineno can give a number larger than
188 188 # the length of lines, which causes an error. Safeguard against that.
189 189 lnum = min(object.co_firstlineno,len(lines))-1
190 190 while lnum > 0:
191 191 if pmatch(lines[lnum]): break
192 192 lnum -= 1
193 193
194 194 return lines, lnum
195 195 raise IOError('could not find code object')
196 196
197 197 # Monkeypatch inspect to apply our bugfix. This code only works with py25
198 198 if sys.version_info[:2] >= (2,5):
199 199 inspect.findsource = findsource
200 200
201 201 def fix_frame_records_filenames(records):
202 202 """Try to fix the filenames in each record from inspect.getinnerframes().
203 203
204 204 Particularly, modules loaded from within zip files have useless filenames
205 205 attached to their code object, and inspect.getinnerframes() just uses it.
206 206 """
207 207 fixed_records = []
208 208 for frame, filename, line_no, func_name, lines, index in records:
209 209 # Look inside the frame's globals dictionary for __file__, which should
210 210 # be better.
211 211 better_fn = frame.f_globals.get('__file__', None)
212 212 if isinstance(better_fn, str):
213 213 # Check the type just in case someone did something weird with
214 214 # __file__. It might also be None if the error occurred during
215 215 # import.
216 216 filename = better_fn
217 217 fixed_records.append((frame, filename, line_no, func_name, lines, index))
218 218 return fixed_records
219 219
220 220
221 221 def _fixed_getinnerframes(etb, context=1,tb_offset=0):
222 222 import linecache
223 223 LNUM_POS, LINES_POS, INDEX_POS = 2, 4, 5
224 224
225 225 records = fix_frame_records_filenames(inspect.getinnerframes(etb, context))
226 226
227 227 # If the error is at the console, don't build any context, since it would
228 228 # otherwise produce 5 blank lines printed out (there is no file at the
229 229 # console)
230 230 rec_check = records[tb_offset:]
231 231 try:
232 232 rname = rec_check[0][1]
233 233 if rname == '<ipython console>' or rname.endswith('<string>'):
234 234 return rec_check
235 235 except IndexError:
236 236 pass
237 237
238 238 aux = traceback.extract_tb(etb)
239 239 assert len(records) == len(aux)
240 240 for i, (file, lnum, _, _) in zip(range(len(records)), aux):
241 241 maybeStart = lnum-1 - context//2
242 242 start = max(maybeStart, 0)
243 243 end = start + context
244 244 lines = linecache.getlines(file)[start:end]
245 245 # pad with empty lines if necessary
246 246 if maybeStart < 0:
247 247 lines = (['\n'] * -maybeStart) + lines
248 248 if len(lines) < context:
249 249 lines += ['\n'] * (context - len(lines))
250 250 buf = list(records[i])
251 251 buf[LNUM_POS] = lnum
252 252 buf[INDEX_POS] = lnum - 1 - start
253 253 buf[LINES_POS] = lines
254 254 records[i] = tuple(buf)
255 255 return records[tb_offset:]
256 256
257 257 # Helper function -- largely belongs to VerboseTB, but we need the same
258 258 # functionality to produce a pseudo verbose TB for SyntaxErrors, so that they
259 259 # can be recognized properly by ipython.el's py-traceback-line-re
260 260 # (SyntaxErrors have to be treated specially because they have no traceback)
261 261
262 262 _parser = PyColorize.Parser()
263 263
264 264 def _formatTracebackLines(lnum, index, lines, Colors, lvals=None,scheme=None):
265 265 numbers_width = INDENT_SIZE - 1
266 266 res = []
267 267 i = lnum - index
268 268
269 269 # This lets us get fully syntax-highlighted tracebacks.
270 270 if scheme is None:
271 try:
272 scheme = __IPYTHON__.rc.colors
273 except:
271 ipinst = ipapi.get()
272 if ipinst is not None:
273 scheme = ipinst.IP.rc.colors
274 else:
274 275 scheme = DEFAULT_SCHEME
276
275 277 _line_format = _parser.format2
276 278
277 279 for line in lines:
278 280 new_line, err = _line_format(line,'str',scheme)
279 281 if not err: line = new_line
280 282
281 283 if i == lnum:
282 284 # This is the line with the error
283 285 pad = numbers_width - len(str(i))
284 286 if pad >= 3:
285 287 marker = '-'*(pad-3) + '-> '
286 288 elif pad == 2:
287 289 marker = '> '
288 290 elif pad == 1:
289 291 marker = '>'
290 292 else:
291 293 marker = ''
292 294 num = marker + str(i)
293 295 line = '%s%s%s %s%s' %(Colors.linenoEm, num,
294 296 Colors.line, line, Colors.Normal)
295 297 else:
296 298 num = '%*s' % (numbers_width,i)
297 299 line = '%s%s%s %s' %(Colors.lineno, num,
298 300 Colors.Normal, line)
299 301
300 302 res.append(line)
301 303 if lvals and i == lnum:
302 304 res.append(lvals + '\n')
303 305 i = i + 1
304 306 return res
305 307
306 308
307 309 #---------------------------------------------------------------------------
308 310 # Module classes
309 311 class TBTools:
310 312 """Basic tools used by all traceback printer classes."""
311 313
312 314 def __init__(self,color_scheme = 'NoColor',call_pdb=False):
313 315 # Whether to call the interactive pdb debugger after printing
314 316 # tracebacks or not
315 317 self.call_pdb = call_pdb
316 318
317 319 # Create color table
318 320 self.color_scheme_table = exception_colors()
319 321
320 322 self.set_colors(color_scheme)
321 323 self.old_scheme = color_scheme # save initial value for toggles
322 324
323 325 if call_pdb:
324 326 self.pdb = debugger.Pdb(self.color_scheme_table.active_scheme_name)
325 327 else:
326 328 self.pdb = None
327 329
328 330 def set_colors(self,*args,**kw):
329 331 """Shorthand access to the color table scheme selector method."""
330 332
331 333 # Set own color table
332 334 self.color_scheme_table.set_active_scheme(*args,**kw)
333 335 # for convenience, set Colors to the active scheme
334 336 self.Colors = self.color_scheme_table.active_colors
335 337 # Also set colors of debugger
336 338 if hasattr(self,'pdb') and self.pdb is not None:
337 339 self.pdb.set_colors(*args,**kw)
338 340
339 341 def color_toggle(self):
340 342 """Toggle between the currently active color scheme and NoColor."""
341 343
342 344 if self.color_scheme_table.active_scheme_name == 'NoColor':
343 345 self.color_scheme_table.set_active_scheme(self.old_scheme)
344 346 self.Colors = self.color_scheme_table.active_colors
345 347 else:
346 348 self.old_scheme = self.color_scheme_table.active_scheme_name
347 349 self.color_scheme_table.set_active_scheme('NoColor')
348 350 self.Colors = self.color_scheme_table.active_colors
349 351
350 352 #---------------------------------------------------------------------------
351 353 class ListTB(TBTools):
352 354 """Print traceback information from a traceback list, with optional color.
353 355
354 356 Calling: requires 3 arguments:
355 357 (etype, evalue, elist)
356 358 as would be obtained by:
357 359 etype, evalue, tb = sys.exc_info()
358 360 if tb:
359 361 elist = traceback.extract_tb(tb)
360 362 else:
361 363 elist = None
362 364
363 365 It can thus be used by programs which need to process the traceback before
364 366 printing (such as console replacements based on the code module from the
365 367 standard library).
366 368
367 369 Because they are meant to be called without a full traceback (only a
368 370 list), instances of this class can't call the interactive pdb debugger."""
369 371
370 372 def __init__(self,color_scheme = 'NoColor'):
371 373 TBTools.__init__(self,color_scheme = color_scheme,call_pdb=0)
372 374
373 375 def __call__(self, etype, value, elist):
374 376 Term.cout.flush()
375 377 print >> Term.cerr, self.text(etype,value,elist)
376 378 Term.cerr.flush()
377 379
378 380 def text(self,etype, value, elist,context=5):
379 381 """Return a color formatted string with the traceback info."""
380 382
381 383 Colors = self.Colors
382 384 out_string = ['%s%s%s\n' % (Colors.topline,'-'*60,Colors.Normal)]
383 385 if elist:
384 386 out_string.append('Traceback %s(most recent call last)%s:' % \
385 387 (Colors.normalEm, Colors.Normal) + '\n')
386 388 out_string.extend(self._format_list(elist))
387 389 lines = self._format_exception_only(etype, value)
388 390 for line in lines[:-1]:
389 391 out_string.append(" "+line)
390 392 out_string.append(lines[-1])
391 393 return ''.join(out_string)
392 394
393 395 def _format_list(self, extracted_list):
394 396 """Format a list of traceback entry tuples for printing.
395 397
396 398 Given a list of tuples as returned by extract_tb() or
397 399 extract_stack(), return a list of strings ready for printing.
398 400 Each string in the resulting list corresponds to the item with the
399 401 same index in the argument list. Each string ends in a newline;
400 402 the strings may contain internal newlines as well, for those items
401 403 whose source text line is not None.
402 404
403 405 Lifted almost verbatim from traceback.py
404 406 """
405 407
406 408 Colors = self.Colors
407 409 list = []
408 410 for filename, lineno, name, line in extracted_list[:-1]:
409 411 item = ' File %s"%s"%s, line %s%d%s, in %s%s%s\n' % \
410 412 (Colors.filename, filename, Colors.Normal,
411 413 Colors.lineno, lineno, Colors.Normal,
412 414 Colors.name, name, Colors.Normal)
413 415 if line:
414 416 item = item + ' %s\n' % line.strip()
415 417 list.append(item)
416 418 # Emphasize the last entry
417 419 filename, lineno, name, line = extracted_list[-1]
418 420 item = '%s File %s"%s"%s, line %s%d%s, in %s%s%s%s\n' % \
419 421 (Colors.normalEm,
420 422 Colors.filenameEm, filename, Colors.normalEm,
421 423 Colors.linenoEm, lineno, Colors.normalEm,
422 424 Colors.nameEm, name, Colors.normalEm,
423 425 Colors.Normal)
424 426 if line:
425 427 item = item + '%s %s%s\n' % (Colors.line, line.strip(),
426 428 Colors.Normal)
427 429 list.append(item)
428 430 return list
429 431
430 432 def _format_exception_only(self, etype, value):
431 433 """Format the exception part of a traceback.
432 434
433 435 The arguments are the exception type and value such as given by
434 436 sys.exc_info()[:2]. The return value is a list of strings, each ending
435 437 in a newline. Normally, the list contains a single string; however,
436 438 for SyntaxError exceptions, it contains several lines that (when
437 439 printed) display detailed information about where the syntax error
438 440 occurred. The message indicating which exception occurred is the
439 441 always last string in the list.
440 442
441 443 Also lifted nearly verbatim from traceback.py
442 444 """
443 445
444 446 have_filedata = False
445 447 Colors = self.Colors
446 448 list = []
447 449 try:
448 450 stype = Colors.excName + etype.__name__ + Colors.Normal
449 451 except AttributeError:
450 452 stype = etype # String exceptions don't get special coloring
451 453 if value is None:
452 454 list.append( str(stype) + '\n')
453 455 else:
454 456 if etype is SyntaxError:
455 457 try:
456 458 msg, (filename, lineno, offset, line) = value
457 459 except:
458 460 have_filedata = False
459 461 else:
460 462 have_filedata = True
461 463 #print 'filename is',filename # dbg
462 464 if not filename: filename = "<string>"
463 465 list.append('%s File %s"%s"%s, line %s%d%s\n' % \
464 466 (Colors.normalEm,
465 467 Colors.filenameEm, filename, Colors.normalEm,
466 468 Colors.linenoEm, lineno, Colors.Normal ))
467 469 if line is not None:
468 470 i = 0
469 471 while i < len(line) and line[i].isspace():
470 472 i = i+1
471 473 list.append('%s %s%s\n' % (Colors.line,
472 474 line.strip(),
473 475 Colors.Normal))
474 476 if offset is not None:
475 477 s = ' '
476 478 for c in line[i:offset-1]:
477 479 if c.isspace():
478 480 s = s + c
479 481 else:
480 482 s = s + ' '
481 483 list.append('%s%s^%s\n' % (Colors.caret, s,
482 484 Colors.Normal) )
483 485 value = msg
484 486 s = self._some_str(value)
485 487 if s:
486 488 list.append('%s%s:%s %s\n' % (str(stype), Colors.excName,
487 489 Colors.Normal, s))
488 490 else:
489 491 list.append('%s\n' % str(stype))
490 492
491 493 # vds:>>
492 494 if have_filedata:
493 __IPYTHON__.hooks.synchronize_with_editor(filename, lineno, 0)
495 ipinst = ipapi.get()
496 if ipinst is not None:
497 ipinst.IP.hooks.synchronize_with_editor(filename, lineno, 0)
494 498 # vds:<<
495 499
496 500 return list
497 501
498 502 def _some_str(self, value):
499 503 # Lifted from traceback.py
500 504 try:
501 505 return str(value)
502 506 except:
503 507 return '<unprintable %s object>' % type(value).__name__
504 508
505 509 #----------------------------------------------------------------------------
506 510 class VerboseTB(TBTools):
507 511 """A port of Ka-Ping Yee's cgitb.py module that outputs color text instead
508 512 of HTML. Requires inspect and pydoc. Crazy, man.
509 513
510 514 Modified version which optionally strips the topmost entries from the
511 515 traceback, to be used with alternate interpreters (because their own code
512 516 would appear in the traceback)."""
513 517
514 518 def __init__(self,color_scheme = 'Linux',tb_offset=0,long_header=0,
515 519 call_pdb = 0, include_vars=1):
516 520 """Specify traceback offset, headers and color scheme.
517 521
518 522 Define how many frames to drop from the tracebacks. Calling it with
519 523 tb_offset=1 allows use of this handler in interpreters which will have
520 524 their own code at the top of the traceback (VerboseTB will first
521 525 remove that frame before printing the traceback info)."""
522 526 TBTools.__init__(self,color_scheme=color_scheme,call_pdb=call_pdb)
523 527 self.tb_offset = tb_offset
524 528 self.long_header = long_header
525 529 self.include_vars = include_vars
526 530
527 531 def text(self, etype, evalue, etb, context=5):
528 532 """Return a nice text document describing the traceback."""
529 533
530 534 # some locals
531 535 try:
532 536 etype = etype.__name__
533 537 except AttributeError:
534 538 pass
535 539 Colors = self.Colors # just a shorthand + quicker name lookup
536 540 ColorsNormal = Colors.Normal # used a lot
537 541 col_scheme = self.color_scheme_table.active_scheme_name
538 542 indent = ' '*INDENT_SIZE
539 543 em_normal = '%s\n%s%s' % (Colors.valEm, indent,ColorsNormal)
540 544 undefined = '%sundefined%s' % (Colors.em, ColorsNormal)
541 545 exc = '%s%s%s' % (Colors.excName,etype,ColorsNormal)
542 546
543 547 # some internal-use functions
544 548 def text_repr(value):
545 549 """Hopefully pretty robust repr equivalent."""
546 550 # this is pretty horrible but should always return *something*
547 551 try:
548 552 return pydoc.text.repr(value)
549 553 except KeyboardInterrupt:
550 554 raise
551 555 except:
552 556 try:
553 557 return repr(value)
554 558 except KeyboardInterrupt:
555 559 raise
556 560 except:
557 561 try:
558 562 # all still in an except block so we catch
559 563 # getattr raising
560 564 name = getattr(value, '__name__', None)
561 565 if name:
562 566 # ick, recursion
563 567 return text_repr(name)
564 568 klass = getattr(value, '__class__', None)
565 569 if klass:
566 570 return '%s instance' % text_repr(klass)
567 571 except KeyboardInterrupt:
568 572 raise
569 573 except:
570 574 return 'UNRECOVERABLE REPR FAILURE'
571 575 def eqrepr(value, repr=text_repr): return '=%s' % repr(value)
572 576 def nullrepr(value, repr=text_repr): return ''
573 577
574 578 # meat of the code begins
575 579 try:
576 580 etype = etype.__name__
577 581 except AttributeError:
578 582 pass
579 583
580 584 if self.long_header:
581 585 # Header with the exception type, python version, and date
582 586 pyver = 'Python ' + string.split(sys.version)[0] + ': ' + sys.executable
583 587 date = time.ctime(time.time())
584 588
585 589 head = '%s%s%s\n%s%s%s\n%s' % (Colors.topline, '-'*75, ColorsNormal,
586 590 exc, ' '*(75-len(str(etype))-len(pyver)),
587 591 pyver, string.rjust(date, 75) )
588 592 head += "\nA problem occured executing Python code. Here is the sequence of function"\
589 593 "\ncalls leading up to the error, with the most recent (innermost) call last."
590 594 else:
591 595 # Simplified header
592 596 head = '%s%s%s\n%s%s' % (Colors.topline, '-'*75, ColorsNormal,exc,
593 597 string.rjust('Traceback (most recent call last)',
594 598 75 - len(str(etype)) ) )
595 599 frames = []
596 600 # Flush cache before calling inspect. This helps alleviate some of the
597 601 # problems with python 2.3's inspect.py.
598 602 linecache.checkcache()
599 603 # Drop topmost frames if requested
600 604 try:
601 605 # Try the default getinnerframes and Alex's: Alex's fixes some
602 606 # problems, but it generates empty tracebacks for console errors
603 607 # (5 blanks lines) where none should be returned.
604 608 #records = inspect.getinnerframes(etb, context)[self.tb_offset:]
605 609 #print 'python records:', records # dbg
606 610 records = _fixed_getinnerframes(etb, context,self.tb_offset)
607 611 #print 'alex records:', records # dbg
608 612 except:
609 613
610 614 # FIXME: I've been getting many crash reports from python 2.3
611 615 # users, traceable to inspect.py. If I can find a small test-case
612 616 # to reproduce this, I should either write a better workaround or
613 617 # file a bug report against inspect (if that's the real problem).
614 618 # So far, I haven't been able to find an isolated example to
615 619 # reproduce the problem.
616 620 inspect_error()
617 621 traceback.print_exc(file=Term.cerr)
618 622 info('\nUnfortunately, your original traceback can not be constructed.\n')
619 623 return ''
620 624
621 625 # build some color string templates outside these nested loops
622 626 tpl_link = '%s%%s%s' % (Colors.filenameEm,ColorsNormal)
623 627 tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm,
624 628 ColorsNormal)
625 629 tpl_call_fail = 'in %s%%s%s(***failed resolving arguments***)%s' % \
626 630 (Colors.vName, Colors.valEm, ColorsNormal)
627 631 tpl_local_var = '%s%%s%s' % (Colors.vName, ColorsNormal)
628 632 tpl_global_var = '%sglobal%s %s%%s%s' % (Colors.em, ColorsNormal,
629 633 Colors.vName, ColorsNormal)
630 634 tpl_name_val = '%%s %s= %%s%s' % (Colors.valEm, ColorsNormal)
631 635 tpl_line = '%s%%s%s %%s' % (Colors.lineno, ColorsNormal)
632 636 tpl_line_em = '%s%%s%s %%s%s' % (Colors.linenoEm,Colors.line,
633 637 ColorsNormal)
634 638
635 639 # now, loop over all records printing context and info
636 640 abspath = os.path.abspath
637 641 for frame, file, lnum, func, lines, index in records:
638 642 #print '*** record:',file,lnum,func,lines,index # dbg
639 643 try:
640 644 file = file and abspath(file) or '?'
641 645 except OSError:
642 646 # if file is '<console>' or something not in the filesystem,
643 647 # the abspath call will throw an OSError. Just ignore it and
644 648 # keep the original file string.
645 649 pass
646 650 link = tpl_link % file
647 651 try:
648 652 args, varargs, varkw, locals = inspect.getargvalues(frame)
649 653 except:
650 654 # This can happen due to a bug in python2.3. We should be
651 655 # able to remove this try/except when 2.4 becomes a
652 656 # requirement. Bug details at http://python.org/sf/1005466
653 657 inspect_error()
654 658 traceback.print_exc(file=Term.cerr)
655 659 info("\nIPython's exception reporting continues...\n")
656 660
657 661 if func == '?':
658 662 call = ''
659 663 else:
660 664 # Decide whether to include variable details or not
661 665 var_repr = self.include_vars and eqrepr or nullrepr
662 666 try:
663 667 call = tpl_call % (func,inspect.formatargvalues(args,
664 668 varargs, varkw,
665 669 locals,formatvalue=var_repr))
666 670 except KeyError:
667 671 # Very odd crash from inspect.formatargvalues(). The
668 672 # scenario under which it appeared was a call to
669 673 # view(array,scale) in NumTut.view.view(), where scale had
670 674 # been defined as a scalar (it should be a tuple). Somehow
671 675 # inspect messes up resolving the argument list of view()
672 676 # and barfs out. At some point I should dig into this one
673 677 # and file a bug report about it.
674 678 inspect_error()
675 679 traceback.print_exc(file=Term.cerr)
676 680 info("\nIPython's exception reporting continues...\n")
677 681 call = tpl_call_fail % func
678 682
679 683 # Initialize a list of names on the current line, which the
680 684 # tokenizer below will populate.
681 685 names = []
682 686
683 687 def tokeneater(token_type, token, start, end, line):
684 688 """Stateful tokeneater which builds dotted names.
685 689
686 690 The list of names it appends to (from the enclosing scope) can
687 691 contain repeated composite names. This is unavoidable, since
688 692 there is no way to disambguate partial dotted structures until
689 693 the full list is known. The caller is responsible for pruning
690 694 the final list of duplicates before using it."""
691 695
692 696 # build composite names
693 697 if token == '.':
694 698 try:
695 699 names[-1] += '.'
696 700 # store state so the next token is added for x.y.z names
697 701 tokeneater.name_cont = True
698 702 return
699 703 except IndexError:
700 704 pass
701 705 if token_type == tokenize.NAME and token not in keyword.kwlist:
702 706 if tokeneater.name_cont:
703 707 # Dotted names
704 708 names[-1] += token
705 709 tokeneater.name_cont = False
706 710 else:
707 711 # Regular new names. We append everything, the caller
708 712 # will be responsible for pruning the list later. It's
709 713 # very tricky to try to prune as we go, b/c composite
710 714 # names can fool us. The pruning at the end is easy
711 715 # to do (or the caller can print a list with repeated
712 716 # names if so desired.
713 717 names.append(token)
714 718 elif token_type == tokenize.NEWLINE:
715 719 raise IndexError
716 720 # we need to store a bit of state in the tokenizer to build
717 721 # dotted names
718 722 tokeneater.name_cont = False
719 723
720 724 def linereader(file=file, lnum=[lnum], getline=linecache.getline):
721 725 line = getline(file, lnum[0])
722 726 lnum[0] += 1
723 727 return line
724 728
725 729 # Build the list of names on this line of code where the exception
726 730 # occurred.
727 731 try:
728 732 # This builds the names list in-place by capturing it from the
729 733 # enclosing scope.
730 734 tokenize.tokenize(linereader, tokeneater)
731 735 except IndexError:
732 736 # signals exit of tokenizer
733 737 pass
734 738 except tokenize.TokenError,msg:
735 739 _m = ("An unexpected error occurred while tokenizing input\n"
736 740 "The following traceback may be corrupted or invalid\n"
737 741 "The error message is: %s\n" % msg)
738 742 error(_m)
739 743
740 744 # prune names list of duplicates, but keep the right order
741 745 unique_names = uniq_stable(names)
742 746
743 747 # Start loop over vars
744 748 lvals = []
745 749 if self.include_vars:
746 750 for name_full in unique_names:
747 751 name_base = name_full.split('.',1)[0]
748 752 if name_base in frame.f_code.co_varnames:
749 753 if locals.has_key(name_base):
750 754 try:
751 755 value = repr(eval(name_full,locals))
752 756 except:
753 757 value = undefined
754 758 else:
755 759 value = undefined
756 760 name = tpl_local_var % name_full
757 761 else:
758 762 if frame.f_globals.has_key(name_base):
759 763 try:
760 764 value = repr(eval(name_full,frame.f_globals))
761 765 except:
762 766 value = undefined
763 767 else:
764 768 value = undefined
765 769 name = tpl_global_var % name_full
766 770 lvals.append(tpl_name_val % (name,value))
767 771 if lvals:
768 772 lvals = '%s%s' % (indent,em_normal.join(lvals))
769 773 else:
770 774 lvals = ''
771 775
772 776 level = '%s %s\n' % (link,call)
773 777
774 778 if index is None:
775 779 frames.append(level)
776 780 else:
777 781 frames.append('%s%s' % (level,''.join(
778 782 _formatTracebackLines(lnum,index,lines,Colors,lvals,
779 783 col_scheme))))
780 784
781 785 # Get (safely) a string form of the exception info
782 786 try:
783 787 etype_str,evalue_str = map(str,(etype,evalue))
784 788 except:
785 789 # User exception is improperly defined.
786 790 etype,evalue = str,sys.exc_info()[:2]
787 791 etype_str,evalue_str = map(str,(etype,evalue))
788 792 # ... and format it
789 793 exception = ['%s%s%s: %s' % (Colors.excName, etype_str,
790 794 ColorsNormal, evalue_str)]
791 795 if type(evalue) is types.InstanceType:
792 796 try:
793 797 names = [w for w in dir(evalue) if isinstance(w, basestring)]
794 798 except:
795 799 # Every now and then, an object with funny inernals blows up
796 800 # when dir() is called on it. We do the best we can to report
797 801 # the problem and continue
798 802 _m = '%sException reporting error (object with broken dir())%s:'
799 803 exception.append(_m % (Colors.excName,ColorsNormal))
800 804 etype_str,evalue_str = map(str,sys.exc_info()[:2])
801 805 exception.append('%s%s%s: %s' % (Colors.excName,etype_str,
802 806 ColorsNormal, evalue_str))
803 807 names = []
804 808 for name in names:
805 809 value = text_repr(getattr(evalue, name))
806 810 exception.append('\n%s%s = %s' % (indent, name, value))
807 811
808 812 # vds: >>
809 813 if records:
810 814 filepath, lnum = records[-1][1:3]
811 815 #print "file:", str(file), "linenb", str(lnum) # dbg
812 816 filepath = os.path.abspath(filepath)
813 __IPYTHON__.hooks.synchronize_with_editor(filepath, lnum, 0)
817 ipinst = ipapi.get()
818 if ipinst is not None:
819 ipinst.IP.hooks.synchronize_with_editor(filepath, lnum, 0)
814 820 # vds: <<
815 821
816 822 # return all our info assembled as a single string
817 823 return '%s\n\n%s\n%s' % (head,'\n'.join(frames),''.join(exception[0]) )
818 824
819 825 def debugger(self,force=False):
820 826 """Call up the pdb debugger if desired, always clean up the tb
821 827 reference.
822 828
823 829 Keywords:
824 830
825 831 - force(False): by default, this routine checks the instance call_pdb
826 832 flag and does not actually invoke the debugger if the flag is false.
827 833 The 'force' option forces the debugger to activate even if the flag
828 834 is false.
829 835
830 836 If the call_pdb flag is set, the pdb interactive debugger is
831 837 invoked. In all cases, the self.tb reference to the current traceback
832 838 is deleted to prevent lingering references which hamper memory
833 839 management.
834 840
835 841 Note that each call to pdb() does an 'import readline', so if your app
836 842 requires a special setup for the readline completers, you'll have to
837 843 fix that by hand after invoking the exception handler."""
838 844
839 845 if force or self.call_pdb:
840 846 if self.pdb is None:
841 847 self.pdb = debugger.Pdb(
842 848 self.color_scheme_table.active_scheme_name)
843 849 # the system displayhook may have changed, restore the original
844 850 # for pdb
845 851 dhook = sys.displayhook
846 852 sys.displayhook = sys.__displayhook__
847 853 self.pdb.reset()
848 854 # Find the right frame so we don't pop up inside ipython itself
849 855 if hasattr(self,'tb'):
850 856 etb = self.tb
851 857 else:
852 858 etb = self.tb = sys.last_traceback
853 859 while self.tb.tb_next is not None:
854 860 self.tb = self.tb.tb_next
855 861 try:
856 862 if etb and etb.tb_next:
857 863 etb = etb.tb_next
858 864 self.pdb.botframe = etb.tb_frame
859 865 self.pdb.interaction(self.tb.tb_frame, self.tb)
860 866 finally:
861 867 sys.displayhook = dhook
862 868
863 869 if hasattr(self,'tb'):
864 870 del self.tb
865 871
866 872 def handler(self, info=None):
867 873 (etype, evalue, etb) = info or sys.exc_info()
868 874 self.tb = etb
869 875 Term.cout.flush()
870 876 print >> Term.cerr, self.text(etype, evalue, etb)
871 877 Term.cerr.flush()
872 878
873 879 # Changed so an instance can just be called as VerboseTB_inst() and print
874 880 # out the right info on its own.
875 881 def __call__(self, etype=None, evalue=None, etb=None):
876 882 """This hook can replace sys.excepthook (for Python 2.1 or higher)."""
877 883 if etb is None:
878 884 self.handler()
879 885 else:
880 886 self.handler((etype, evalue, etb))
881 887 try:
882 888 self.debugger()
883 889 except KeyboardInterrupt:
884 890 print "\nKeyboardInterrupt"
885 891
886 892 #----------------------------------------------------------------------------
887 893 class FormattedTB(VerboseTB,ListTB):
888 894 """Subclass ListTB but allow calling with a traceback.
889 895
890 896 It can thus be used as a sys.excepthook for Python > 2.1.
891 897
892 898 Also adds 'Context' and 'Verbose' modes, not available in ListTB.
893 899
894 900 Allows a tb_offset to be specified. This is useful for situations where
895 901 one needs to remove a number of topmost frames from the traceback (such as
896 902 occurs with python programs that themselves execute other python code,
897 903 like Python shells). """
898 904
899 905 def __init__(self, mode = 'Plain', color_scheme='Linux',
900 906 tb_offset = 0,long_header=0,call_pdb=0,include_vars=0):
901 907
902 908 # NEVER change the order of this list. Put new modes at the end:
903 909 self.valid_modes = ['Plain','Context','Verbose']
904 910 self.verbose_modes = self.valid_modes[1:3]
905 911
906 912 VerboseTB.__init__(self,color_scheme,tb_offset,long_header,
907 913 call_pdb=call_pdb,include_vars=include_vars)
908 914 self.set_mode(mode)
909 915
910 916 def _extract_tb(self,tb):
911 917 if tb:
912 918 return traceback.extract_tb(tb)
913 919 else:
914 920 return None
915 921
916 922 def text(self, etype, value, tb,context=5,mode=None):
917 923 """Return formatted traceback.
918 924
919 925 If the optional mode parameter is given, it overrides the current
920 926 mode."""
921 927
922 928 if mode is None:
923 929 mode = self.mode
924 930 if mode in self.verbose_modes:
925 931 # verbose modes need a full traceback
926 932 return VerboseTB.text(self,etype, value, tb,context=5)
927 933 else:
928 934 # We must check the source cache because otherwise we can print
929 935 # out-of-date source code.
930 936 linecache.checkcache()
931 937 # Now we can extract and format the exception
932 938 elist = self._extract_tb(tb)
933 939 if len(elist) > self.tb_offset:
934 940 del elist[:self.tb_offset]
935 941 return ListTB.text(self,etype,value,elist)
936 942
937 943 def set_mode(self,mode=None):
938 944 """Switch to the desired mode.
939 945
940 946 If mode is not specified, cycles through the available modes."""
941 947
942 948 if not mode:
943 949 new_idx = ( self.valid_modes.index(self.mode) + 1 ) % \
944 950 len(self.valid_modes)
945 951 self.mode = self.valid_modes[new_idx]
946 952 elif mode not in self.valid_modes:
947 953 raise ValueError, 'Unrecognized mode in FormattedTB: <'+mode+'>\n'\
948 954 'Valid modes: '+str(self.valid_modes)
949 955 else:
950 956 self.mode = mode
951 957 # include variable details only in 'Verbose' mode
952 958 self.include_vars = (self.mode == self.valid_modes[2])
953 959
954 960 # some convenient shorcuts
955 961 def plain(self):
956 962 self.set_mode(self.valid_modes[0])
957 963
958 964 def context(self):
959 965 self.set_mode(self.valid_modes[1])
960 966
961 967 def verbose(self):
962 968 self.set_mode(self.valid_modes[2])
963 969
964 970 #----------------------------------------------------------------------------
965 971 class AutoFormattedTB(FormattedTB):
966 972 """A traceback printer which can be called on the fly.
967 973
968 974 It will find out about exceptions by itself.
969 975
970 976 A brief example:
971 977
972 978 AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux')
973 979 try:
974 980 ...
975 981 except:
976 982 AutoTB() # or AutoTB(out=logfile) where logfile is an open file object
977 983 """
978 984 def __call__(self,etype=None,evalue=None,etb=None,
979 985 out=None,tb_offset=None):
980 986 """Print out a formatted exception traceback.
981 987
982 988 Optional arguments:
983 989 - out: an open file-like object to direct output to.
984 990
985 991 - tb_offset: the number of frames to skip over in the stack, on a
986 992 per-call basis (this overrides temporarily the instance's tb_offset
987 993 given at initialization time. """
988 994
989 995 if out is None:
990 996 out = Term.cerr
991 997 Term.cout.flush()
992 998 if tb_offset is not None:
993 999 tb_offset, self.tb_offset = self.tb_offset, tb_offset
994 1000 print >> out, self.text(etype, evalue, etb)
995 1001 self.tb_offset = tb_offset
996 1002 else:
997 1003 print >> out, self.text(etype, evalue, etb)
998 1004 out.flush()
999 1005 try:
1000 1006 self.debugger()
1001 1007 except KeyboardInterrupt:
1002 1008 print "\nKeyboardInterrupt"
1003 1009
1004 1010 def text(self,etype=None,value=None,tb=None,context=5,mode=None):
1005 1011 if etype is None:
1006 1012 etype,value,tb = sys.exc_info()
1007 1013 self.tb = tb
1008 1014 return FormattedTB.text(self,etype,value,tb,context=5,mode=mode)
1009 1015
1010 1016 #---------------------------------------------------------------------------
1011 1017 # A simple class to preserve Nathan's original functionality.
1012 1018 class ColorTB(FormattedTB):
1013 1019 """Shorthand to initialize a FormattedTB in Linux colors mode."""
1014 1020 def __init__(self,color_scheme='Linux',call_pdb=0):
1015 1021 FormattedTB.__init__(self,color_scheme=color_scheme,
1016 1022 call_pdb=call_pdb)
1017 1023
1018 1024 #----------------------------------------------------------------------------
1019 1025 # module testing (minimal)
1020 1026 if __name__ == "__main__":
1021 1027 def spam(c, (d, e)):
1022 1028 x = c + d
1023 1029 y = c * d
1024 1030 foo(x, y)
1025 1031
1026 1032 def foo(a, b, bar=1):
1027 1033 eggs(a, b + bar)
1028 1034
1029 1035 def eggs(f, g, z=globals()):
1030 1036 h = f + g
1031 1037 i = f - g
1032 1038 return h / i
1033 1039
1034 1040 print ''
1035 1041 print '*** Before ***'
1036 1042 try:
1037 1043 print spam(1, (2, 3))
1038 1044 except:
1039 1045 traceback.print_exc()
1040 1046 print ''
1041 1047
1042 1048 handler = ColorTB()
1043 1049 print '*** ColorTB ***'
1044 1050 try:
1045 1051 print spam(1, (2, 3))
1046 1052 except:
1047 1053 apply(handler, sys.exc_info() )
1048 1054 print ''
1049 1055
1050 1056 handler = VerboseTB()
1051 1057 print '*** VerboseTB ***'
1052 1058 try:
1053 1059 print spam(1, (2, 3))
1054 1060 except:
1055 1061 apply(handler, sys.exc_info() )
1056 1062 print ''
1057 1063
@@ -1,282 +1,285 b''
1 1 """Twisted shell support.
2 2
3 3 XXX - This module is missing proper docs.
4 4 """
5 # Tell nose to skip this module
6 __test__ = {}
7
5 8 import sys
6 9
7 10 from twisted.internet import reactor, threads
8 11
9 12 from IPython.core.ipmaker import make_IPython
10 13 from IPython.core.iplib import InteractiveShell
11 14 from IPython.utils.ipstruct import Struct
12 15 import Queue,thread,threading,signal
13 16 from signal import signal, SIGINT
14 17 from IPython.utils.genutils import Term,warn,error,flag_calls, ask_yes_no
15 18 from IPython.core import shellglobals
16 19
17 20 def install_gtk2():
18 21 """ Install gtk2 reactor, needs to be called bef """
19 22 from twisted.internet import gtk2reactor
20 23 gtk2reactor.install()
21 24
22 25
23 26 def hijack_reactor():
24 27 """Modifies Twisted's reactor with a dummy so user code does
25 28 not block IPython. This function returns the original
26 29 'twisted.internet.reactor' that has been hijacked.
27 30
28 31 NOTE: Make sure you call this *AFTER* you've installed
29 32 the reactor of your choice.
30 33 """
31 34 from twisted import internet
32 35 orig_reactor = internet.reactor
33 36
34 37 class DummyReactor(object):
35 38 def run(self):
36 39 pass
37 40 def __getattr__(self, name):
38 41 return getattr(orig_reactor, name)
39 42 def __setattr__(self, name, value):
40 43 return setattr(orig_reactor, name, value)
41 44
42 45 internet.reactor = DummyReactor()
43 46 return orig_reactor
44 47
45 48 class TwistedInteractiveShell(InteractiveShell):
46 49 """Simple multi-threaded shell."""
47 50
48 51 # Threading strategy taken from:
49 52 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65109, by Brian
50 53 # McErlean and John Finlay. Modified with corrections by Antoon Pardon,
51 54 # from the pygtk mailing list, to avoid lockups with system calls.
52 55
53 56 # class attribute to indicate whether the class supports threads or not.
54 57 # Subclasses with thread support should override this as needed.
55 58 isthreaded = True
56 59
57 60 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
58 61 user_ns=None,user_global_ns=None,banner2='',**kw):
59 62 """Similar to the normal InteractiveShell, but with threading control"""
60 63
61 64 InteractiveShell.__init__(self,name,usage,rc,user_ns,
62 65 user_global_ns,banner2)
63 66
64 67
65 68 # A queue to hold the code to be executed.
66 69 self.code_queue = Queue.Queue()
67 70
68 71 # Stuff to do at closing time
69 72 self._kill = None
70 73 on_kill = kw.get('on_kill', [])
71 74 # Check that all things to kill are callable:
72 75 for t in on_kill:
73 76 if not callable(t):
74 77 raise TypeError,'on_kill must be a list of callables'
75 78 self.on_kill = on_kill
76 79 # thread identity of the "worker thread" (that may execute code directly)
77 80 self.worker_ident = None
78 81 self.reactor_started = False
79 82 self.first_run = True
80 83
81 84 def runsource(self, source, filename="<input>", symbol="single"):
82 85 """Compile and run some source in the interpreter.
83 86
84 87 Modified version of code.py's runsource(), to handle threading issues.
85 88 See the original for full docstring details."""
86 89
87 90 # If Ctrl-C was typed, we reset the flag and return right away
88 91 if shellglobals.KBINT:
89 92 shellglobals.KBINT = False
90 93 return False
91 94
92 95 if self._kill:
93 96 # can't queue new code if we are being killed
94 97 return True
95 98
96 99 try:
97 100 code = self.compile(source, filename, symbol)
98 101 except (OverflowError, SyntaxError, ValueError):
99 102 # Case 1
100 103 self.showsyntaxerror(filename)
101 104 return False
102 105
103 106 if code is None:
104 107 # Case 2
105 108 return True
106 109
107 110 # shortcut - if we are in worker thread, or the worker thread is not running,
108 111 # execute directly (to allow recursion and prevent deadlock if code is run early
109 112 # in IPython construction)
110 113
111 114 if (not self.reactor_started or (self.worker_ident is None and not self.first_run)
112 115 or self.worker_ident == thread.get_ident() or shellglobals.run_in_frontend(source)):
113 116 InteractiveShell.runcode(self,code)
114 117 return
115 118
116 119 # Case 3
117 120 # Store code in queue, so the execution thread can handle it.
118 121
119 122 self.first_run = False
120 123 completed_ev, received_ev = threading.Event(), threading.Event()
121 124
122 125 self.code_queue.put((code,completed_ev, received_ev))
123 126
124 127 reactor.callLater(0.0,self.runcode)
125 128 received_ev.wait(5)
126 129 if not received_ev.isSet():
127 130 # the mainloop is dead, start executing code directly
128 131 print "Warning: Timeout for mainloop thread exceeded"
129 132 print "switching to nonthreaded mode (until mainloop wakes up again)"
130 133 self.worker_ident = None
131 134 else:
132 135 completed_ev.wait()
133 136
134 137 return False
135 138
136 139 def runcode(self):
137 140 """Execute a code object.
138 141
139 142 Multithreaded wrapper around IPython's runcode()."""
140 143
141 144
142 145 # we are in worker thread, stash out the id for runsource()
143 146 self.worker_ident = thread.get_ident()
144 147
145 148 if self._kill:
146 149 print >>Term.cout, 'Closing threads...',
147 150 Term.cout.flush()
148 151 for tokill in self.on_kill:
149 152 tokill()
150 153 print >>Term.cout, 'Done.'
151 154 # allow kill() to return
152 155 self._kill.set()
153 156 return True
154 157
155 158 # Install SIGINT handler. We do it every time to ensure that if user
156 159 # code modifies it, we restore our own handling.
157 160 try:
158 161 pass
159 162 signal(SIGINT,shellglobals.sigint_handler)
160 163 except SystemError:
161 164 # This happens under Windows, which seems to have all sorts
162 165 # of problems with signal handling. Oh well...
163 166 pass
164 167
165 168 # Flush queue of pending code by calling the run methood of the parent
166 169 # class with all items which may be in the queue.
167 170 code_to_run = None
168 171 while 1:
169 172 try:
170 173 code_to_run, completed_ev, received_ev = self.code_queue.get_nowait()
171 174 except Queue.Empty:
172 175 break
173 176 received_ev.set()
174 177
175 178
176 179 # Exceptions need to be raised differently depending on which
177 180 # thread is active. This convoluted try/except is only there to
178 181 # protect against asynchronous exceptions, to ensure that a shellglobals.KBINT
179 182 # at the wrong time doesn't deadlock everything. The global
180 183 # CODE_TO_RUN is set to true/false as close as possible to the
181 184 # runcode() call, so that the KBINT handler is correctly informed.
182 185 try:
183 186 try:
184 187 shellglobals.CODE_RUN = True
185 188 InteractiveShell.runcode(self,code_to_run)
186 189 except KeyboardInterrupt:
187 190 print "Keyboard interrupted in mainloop"
188 191 while not self.code_queue.empty():
189 192 code = self.code_queue.get_nowait()
190 193 break
191 194 finally:
192 195 shellglobals.CODE_RUN = False
193 196 # allow runsource() return from wait
194 197 completed_ev.set()
195 198
196 199 # This MUST return true for gtk threading to work
197 200 return True
198 201
199 202 def kill(self):
200 203 """Kill the thread, returning when it has been shut down."""
201 204 self._kill = threading.Event()
202 205 reactor.callLater(0.0,self.runcode)
203 206 self._kill.wait()
204 207
205 208
206 209
207 210 class IPShellTwisted:
208 211 """Run a Twisted reactor while in an IPython session.
209 212
210 213 Python commands can be passed to the thread where they will be
211 214 executed. This is implemented by periodically checking for
212 215 passed code using a Twisted reactor callback.
213 216 """
214 217
215 218 TIMEOUT = 0.01 # Millisecond interval between reactor runs.
216 219
217 220 def __init__(self, argv=None, user_ns=None, debug=1,
218 221 shell_class=TwistedInteractiveShell):
219 222
220 223 from twisted.internet import reactor
221 224 self.reactor = hijack_reactor()
222 225
223 226 mainquit = self.reactor.stop
224 227
225 228 # Make sure IPython keeps going after reactor stop.
226 229 def reactorstop():
227 230 pass
228 231 self.reactor.stop = reactorstop
229 232 reactorrun_orig = self.reactor.run
230 233 self.quitting = False
231 234 def reactorrun():
232 235 while True and not self.quitting:
233 236 reactorrun_orig()
234 237 self.reactor.run = reactorrun
235 238
236 239 self.IP = make_IPython(argv, user_ns=user_ns, debug=debug,
237 240 shell_class=shell_class,
238 241 on_kill=[mainquit])
239 242
240 243 # threading.Thread.__init__(self)
241 244
242 245 def run(self):
243 246 self.IP.mainloop()
244 247 self.quitting = True
245 248 self.IP.kill()
246 249
247 250 def mainloop(self):
248 251 def mainLoopThreadDeath(r):
249 252 print "mainLoopThreadDeath: ", str(r)
250 253 def spawnMainloopThread():
251 254 d=threads.deferToThread(self.run)
252 255 d.addBoth(mainLoopThreadDeath)
253 256 reactor.callWhenRunning(spawnMainloopThread)
254 257 self.IP.reactor_started = True
255 258 self.reactor.run()
256 259 print "mainloop ending...."
257 260
258 261 exists = True
259 262
260 263
261 264 if __name__ == '__main__':
262 265 # Sample usage.
263 266
264 267 # Create the shell object. This steals twisted.internet.reactor
265 268 # for its own purposes, to make sure you've already installed a
266 269 # reactor of your choice.
267 270 shell = IPShellTwisted(
268 271 argv=[],
269 272 user_ns={'__name__': '__example__',
270 273 'hello': 'world',
271 274 },
272 275 )
273 276
274 277 # Run the mainloop. This runs the actual reactor.run() method.
275 278 # The twisted.internet.reactor object at this point is a dummy
276 279 # object that passes through to the actual reactor, but prevents
277 280 # run() from being called on it again.
278 281 shell.mainloop()
279 282
280 283 # You must exit IPython to terminate your program.
281 284 print 'Goodbye!'
282 285
@@ -1,340 +1,349 b''
1 1 """
2 2 IPython extension: autoreload modules before executing the next line
3 3
4 4 Try::
5 5
6 6 %autoreload?
7 7
8 8 for documentation.
9 9 """
10 10
11 11 # Pauli Virtanen <pav@iki.fi>, 2008.
12 12 # Thomas Heller, 2000.
13 13 #
14 14 # This IPython module is written by Pauli Virtanen, based on the autoreload
15 15 # code by Thomas Heller.
16 16
17 17 #------------------------------------------------------------------------------
18 18 # Autoreload functionality
19 19 #------------------------------------------------------------------------------
20 20
21 21 import time, os, threading, sys, types, imp, inspect, traceback, atexit
22 22 import weakref
23 23
24 24 def _get_compiled_ext():
25 25 """Official way to get the extension of compiled files (.pyc or .pyo)"""
26 26 for ext, mode, typ in imp.get_suffixes():
27 27 if typ == imp.PY_COMPILED:
28 28 return ext
29 29
30 30 PY_COMPILED_EXT = _get_compiled_ext()
31 31
32 32 class ModuleReloader(object):
33 33 failed = {}
34 34 """Modules that failed to reload: {module: mtime-on-failed-reload, ...}"""
35 35
36 36 modules = {}
37 37 """Modules specially marked as autoreloadable."""
38 38
39 39 skip_modules = {}
40 40 """Modules specially marked as not autoreloadable."""
41 41
42 42 check_all = True
43 43 """Autoreload all modules, not just those listed in 'modules'"""
44 44
45 45 old_objects = {}
46 46 """(module-name, name) -> weakref, for replacing old code objects"""
47 47
48 48 def check(self, check_all=False):
49 49 """Check whether some modules need to be reloaded."""
50 50
51 51 if check_all or self.check_all:
52 52 modules = sys.modules.keys()
53 53 else:
54 54 modules = self.modules.keys()
55 55
56 56 for modname in modules:
57 57 m = sys.modules.get(modname, None)
58 58
59 59 if modname in self.skip_modules:
60 60 continue
61 61
62 62 if not hasattr(m, '__file__'):
63 63 continue
64 64
65 65 if m.__name__ == '__main__':
66 66 # we cannot reload(__main__)
67 67 continue
68 68
69 69 filename = m.__file__
70 70 dirname = os.path.dirname(filename)
71 71 path, ext = os.path.splitext(filename)
72 72
73 73 if ext.lower() == '.py':
74 74 ext = PY_COMPILED_EXT
75 75 filename = os.path.join(dirname, path + PY_COMPILED_EXT)
76 76
77 77 if ext != PY_COMPILED_EXT:
78 78 continue
79 79
80 80 try:
81 81 pymtime = os.stat(filename[:-1]).st_mtime
82 82 if pymtime <= os.stat(filename).st_mtime:
83 83 continue
84 84 if self.failed.get(filename[:-1], None) == pymtime:
85 85 continue
86 86 except OSError:
87 87 continue
88 88
89 89 try:
90 90 superreload(m, reload, self.old_objects)
91 91 if filename[:-1] in self.failed:
92 92 del self.failed[filename[:-1]]
93 93 except:
94 94 print >> sys.stderr, "[autoreload of %s failed: %s]" % (
95 95 modname, traceback.format_exc(1))
96 96 self.failed[filename[:-1]] = pymtime
97 97
98 98 #------------------------------------------------------------------------------
99 99 # superreload
100 100 #------------------------------------------------------------------------------
101 101
102 102 def update_function(old, new):
103 103 """Upgrade the code object of a function"""
104 104 for name in ['func_code', 'func_defaults', 'func_doc',
105 105 'func_closure', 'func_globals', 'func_dict']:
106 106 try:
107 107 setattr(old, name, getattr(new, name))
108 108 except (AttributeError, TypeError):
109 109 pass
110 110
111 111 def update_class(old, new):
112 112 """Replace stuff in the __dict__ of a class, and upgrade
113 113 method code objects"""
114 114 for key in old.__dict__.keys():
115 115 old_obj = getattr(old, key)
116 116
117 117 try:
118 118 new_obj = getattr(new, key)
119 119 except AttributeError:
120 120 # obsolete attribute: remove it
121 121 try:
122 122 delattr(old, key)
123 123 except (AttributeError, TypeError):
124 124 pass
125 125 continue
126 126
127 127 if update_generic(old_obj, new_obj): continue
128 128
129 129 try:
130 130 setattr(old, key, getattr(new, key))
131 131 except (AttributeError, TypeError):
132 132 pass # skip non-writable attributes
133 133
134 134 def update_property(old, new):
135 135 """Replace get/set/del functions of a property"""
136 136 update_generic(old.fdel, new.fdel)
137 137 update_generic(old.fget, new.fget)
138 138 update_generic(old.fset, new.fset)
139 139
140 140 def isinstance2(a, b, typ):
141 141 return isinstance(a, typ) and isinstance(b, typ)
142 142
143 143 UPDATE_RULES = [
144 144 (lambda a, b: isinstance2(a, b, types.ClassType),
145 145 update_class),
146 146 (lambda a, b: isinstance2(a, b, types.TypeType),
147 147 update_class),
148 148 (lambda a, b: isinstance2(a, b, types.FunctionType),
149 149 update_function),
150 150 (lambda a, b: isinstance2(a, b, property),
151 151 update_property),
152 152 (lambda a, b: isinstance2(a, b, types.MethodType),
153 153 lambda a, b: update_function(a.im_func, b.im_func)),
154 154 ]
155 155
156 156 def update_generic(a, b):
157 157 for type_check, update in UPDATE_RULES:
158 158 if type_check(a, b):
159 159 update(a, b)
160 160 return True
161 161 return False
162 162
163 163 class StrongRef(object):
164 164 def __init__(self, obj):
165 165 self.obj = obj
166 166 def __call__(self):
167 167 return self.obj
168 168
169 169 def superreload(module, reload=reload, old_objects={}):
170 170 """Enhanced version of the builtin reload function.
171 171
172 172 superreload remembers objects previously in the module, and
173 173
174 174 - upgrades the class dictionary of every old class in the module
175 175 - upgrades the code object of every old function and method
176 176 - clears the module's namespace before reloading
177 177
178 178 """
179 179
180 180 # collect old objects in the module
181 181 for name, obj in module.__dict__.items():
182 182 if not hasattr(obj, '__module__') or obj.__module__ != module.__name__:
183 183 continue
184 184 key = (module.__name__, name)
185 185 try:
186 186 old_objects.setdefault(key, []).append(weakref.ref(obj))
187 187 except TypeError:
188 188 # weakref doesn't work for all types;
189 189 # create strong references for 'important' cases
190 190 if isinstance(obj, types.ClassType):
191 191 old_objects.setdefault(key, []).append(StrongRef(obj))
192 192
193 193 # reload module
194 194 try:
195 195 # clear namespace first from old cruft
196 196 old_name = module.__name__
197 197 module.__dict__.clear()
198 198 module.__dict__['__name__'] = old_name
199 199 except (TypeError, AttributeError, KeyError):
200 200 pass
201 201 module = reload(module)
202 202
203 203 # iterate over all objects and update functions & classes
204 204 for name, new_obj in module.__dict__.items():
205 205 key = (module.__name__, name)
206 206 if key not in old_objects: continue
207 207
208 208 new_refs = []
209 209 for old_ref in old_objects[key]:
210 210 old_obj = old_ref()
211 211 if old_obj is None: continue
212 212 new_refs.append(old_ref)
213 213 update_generic(old_obj, new_obj)
214 214
215 215 if new_refs:
216 216 old_objects[key] = new_refs
217 217 else:
218 218 del old_objects[key]
219 219
220 220 return module
221 221
222 222 reloader = ModuleReloader()
223 223
224 224 #------------------------------------------------------------------------------
225 225 # IPython connectivity
226 226 #------------------------------------------------------------------------------
227 227 from IPython.core import ipapi
228 228
229 229 ip = ipapi.get()
230 230
231 231 autoreload_enabled = False
232 232
233 233 def runcode_hook(self):
234 234 if not autoreload_enabled:
235 235 raise ipapi.TryNext
236 236 try:
237 237 reloader.check()
238 238 except:
239 239 pass
240 240
241 241 def enable_autoreload():
242 242 global autoreload_enabled
243 243 autoreload_enabled = True
244 244
245 245 def disable_autoreload():
246 246 global autoreload_enabled
247 247 autoreload_enabled = False
248 248
249 249 def autoreload_f(self, parameter_s=''):
250 250 r""" %autoreload => Reload modules automatically
251 251
252 252 %autoreload
253 253 Reload all modules (except those excluded by %aimport) automatically now.
254 254
255 %autoreload 0
256 Disable automatic reloading.
257
255 258 %autoreload 1
256 259 Reload all modules imported with %aimport every time before executing
257 260 the Python code typed.
258 261
259 262 %autoreload 2
260 263 Reload all modules (except those excluded by %aimport) every time
261 264 before executing the Python code typed.
262 265
263 Reloading Python modules in a reliable way is in general difficult,
264 and unexpected things may occur. %autoreload tries to work
265 around common pitfalls by replacing code objects of functions
266 previously in the module with new versions. This makes the following
267 things to work:
266 Reloading Python modules in a reliable way is in general
267 difficult, and unexpected things may occur. %autoreload tries to
268 work around common pitfalls by replacing function code objects and
269 parts of classes previously in the module with new versions. This
270 makes the following things to work:
268 271
269 272 - Functions and classes imported via 'from xxx import foo' are upgraded
270 273 to new versions when 'xxx' is reloaded.
274
271 275 - Methods and properties of classes are upgraded on reload, so that
272 276 calling 'c.foo()' on an object 'c' created before the reload causes
273 277 the new code for 'foo' to be executed.
274 278
275 279 Some of the known remaining caveats are:
276 280
277 281 - Replacing code objects does not always succeed: changing a @property
278 282 in a class to an ordinary method or a method to a member variable
279 283 can cause problems (but in old objects only).
284
280 285 - Functions that are removed (eg. via monkey-patching) from a module
281 286 before it is reloaded are not upgraded.
287
282 288 - C extension modules cannot be reloaded, and so cannot be
283 289 autoreloaded.
284 290
285 291 """
286 292 if parameter_s == '':
287 293 reloader.check(True)
288 294 elif parameter_s == '0':
289 295 disable_autoreload()
290 296 elif parameter_s == '1':
291 297 reloader.check_all = False
292 298 enable_autoreload()
293 299 elif parameter_s == '2':
294 300 reloader.check_all = True
295 301 enable_autoreload()
296 302
297 303 def aimport_f(self, parameter_s=''):
298 304 """%aimport => Import modules for automatic reloading.
299 305
300 306 %aimport
301 307 List modules to automatically import and not to import.
302 308
303 309 %aimport foo
304 310 Import module 'foo' and mark it to be autoreloaded for %autoreload 1
305 311
306 312 %aimport -foo
307 313 Mark module 'foo' to not be autoreloaded for %autoreload 1
308 314
309 315 """
310 316
311 317 modname = parameter_s
312 318 if not modname:
313 319 to_reload = reloader.modules.keys()
314 320 to_reload.sort()
315 321 to_skip = reloader.skip_modules.keys()
316 322 to_skip.sort()
317 323 if reloader.check_all:
318 324 print "Modules to reload:\nall-expect-skipped"
319 325 else:
320 326 print "Modules to reload:\n%s" % ' '.join(to_reload)
321 327 print "\nModules to skip:\n%s" % ' '.join(to_skip)
322 328 elif modname.startswith('-'):
323 329 modname = modname[1:]
324 330 try: del reloader.modules[modname]
325 331 except KeyError: pass
326 332 reloader.skip_modules[modname] = True
327 333 else:
328 334 try: del reloader.skip_modules[modname]
329 335 except KeyError: pass
330 336 reloader.modules[modname] = True
331 337
332 mod = __import__(modname)
333 ip.to_user_ns({modname: mod})
338 # Inject module to user namespace; handle also submodules properly
339 __import__(modname)
340 basename = modname.split('.')[0]
341 mod = sys.modules[basename]
342 ip.to_user_ns({basename: mod})
334 343
335 344 def init():
336 345 ip.expose_magic('autoreload', autoreload_f)
337 346 ip.expose_magic('aimport', aimport_f)
338 347 ip.set_hook('pre_runcode_hook', runcode_hook)
339 348
340 349 init()
@@ -1,77 +1,82 b''
1 1 """
2 2 Base front end class for all async frontends.
3 3 """
4 4 __docformat__ = "restructuredtext en"
5 5
6 # Tell nose to skip this module
7 __test__ = {}
8
6 9 #-------------------------------------------------------------------------------
7 10 # Copyright (C) 2008 The IPython Development Team
8 11 #
9 12 # Distributed under the terms of the BSD License. The full license is in
10 13 # the file COPYING, distributed as part of this software.
11 14 #-------------------------------------------------------------------------------
12 15
13
14 16 #-------------------------------------------------------------------------------
15 17 # Imports
16 18 #-------------------------------------------------------------------------------
17 19
20 # Third-party
21 from twisted.python.failure import Failure
22 from zope.interface import implements, classProvides
23
24 # From IPython
18 25 from IPython.external import guid
19 26
20 from zope.interface import Interface, Attribute, implements, classProvides
21 from twisted.python.failure import Failure
22 from IPython.frontend.frontendbase import (
23 FrontEndBase, IFrontEnd, IFrontEndFactory)
27 from IPython.frontend.frontendbase import (FrontEndBase, IFrontEnd,
28 IFrontEndFactory)
24 29 from IPython.kernel.core.history import FrontEndHistory
25 30 from IPython.kernel.engineservice import IEngineCore
26 31
32 #-----------------------------------------------------------------------------
33 # Classes and functions
34 #-----------------------------------------------------------------------------
27 35
28 36 class AsyncFrontEndBase(FrontEndBase):
29 37 """
30 38 Overrides FrontEndBase to wrap execute in a deferred result.
31 39 All callbacks are made as callbacks on the deferred result.
32 40 """
33 41
34 42 implements(IFrontEnd)
35 43 classProvides(IFrontEndFactory)
36 44
37 45 def __init__(self, engine=None, history=None):
38 46 assert(engine==None or IEngineCore.providedBy(engine))
39 47 self.engine = IEngineCore(engine)
40 48 if history is None:
41 49 self.history = FrontEndHistory(input_cache=[''])
42 50 else:
43 51 self.history = history
44 52
45
46 53 def execute(self, block, blockID=None):
47 54 """Execute the block and return the deferred result.
48 55
49 56 Parameters:
50 57 block : {str, AST}
51 58 blockID : any
52 59 Caller may provide an ID to identify this block.
53 60 result['blockID'] := blockID
54 61
55 62 Result:
56 63 Deferred result of self.interpreter.execute
57 64 """
58 65
59 66 if(not self.is_complete(block)):
60 67 return Failure(Exception("Block is not compilable"))
61 68
62 69 if(blockID == None):
63 70 blockID = guid.generate()
64 71
65 72 d = self.engine.execute(block)
66 73 d.addCallback(self._add_history, block=block)
67 74 d.addCallbacks(self._add_block_id_for_result,
68 75 errback=self._add_block_id_for_failure,
69 76 callbackArgs=(blockID,),
70 77 errbackArgs=(blockID,))
71 78 d.addBoth(self.update_cell_prompt, blockID=blockID)
72 79 d.addCallbacks(self.render_result,
73 80 errback=self.render_error)
74 81
75 82 return d
76
77
1 NO CONTENT: modified file
@@ -1,372 +1,372 b''
1 1 """
2 2 Base front end class for all line-oriented frontends, rather than
3 3 block-oriented.
4 4
5 5 Currently this focuses on synchronous frontends.
6 6 """
7 7 __docformat__ = "restructuredtext en"
8 8
9 9 #-------------------------------------------------------------------------------
10 10 # Copyright (C) 2008 The IPython Development Team
11 11 #
12 12 # Distributed under the terms of the BSD License. The full license is in
13 13 # the file COPYING, distributed as part of this software.
14 14 #-------------------------------------------------------------------------------
15 15
16 16 #-------------------------------------------------------------------------------
17 17 # Imports
18 18 #-------------------------------------------------------------------------------
19 19 import re
20 20
21 21 import sys
22 22 import codeop
23 23
24 24 from frontendbase import FrontEndBase
25 25 from IPython.kernel.core.interpreter import Interpreter
26 26
27 27 def common_prefix(strings):
28 28 """ Given a list of strings, return the common prefix between all
29 29 these strings.
30 30 """
31 31 ref = strings[0]
32 32 prefix = ''
33 33 for size in range(len(ref)):
34 34 test_prefix = ref[:size+1]
35 35 for string in strings[1:]:
36 36 if not string.startswith(test_prefix):
37 37 return prefix
38 38 prefix = test_prefix
39 39
40 40 return prefix
41 41
42 42 #-------------------------------------------------------------------------------
43 43 # Base class for the line-oriented front ends
44 44 #-------------------------------------------------------------------------------
45 45 class LineFrontEndBase(FrontEndBase):
46 46 """ Concrete implementation of the FrontEndBase class. This is meant
47 47 to be the base class behind all the frontend that are line-oriented,
48 48 rather than block-oriented.
49 49 """
50 50
51 51 # We need to keep the prompt number, to be able to increment
52 52 # it when there is an exception.
53 53 prompt_number = 1
54 54
55 55 # We keep a reference to the last result: it helps testing and
56 56 # programatic control of the frontend.
57 57 last_result = dict(number=0)
58 58
59 59 # The last prompt displayed. Useful for continuation prompts.
60 60 last_prompt = ''
61 61
62 62 # The input buffer being edited
63 63 input_buffer = ''
64 64
65 65 # Set to true for debug output
66 66 debug = False
67 67
68 68 # A banner to print at startup
69 69 banner = None
70 70
71 71 #--------------------------------------------------------------------------
72 72 # FrontEndBase interface
73 73 #--------------------------------------------------------------------------
74 74
75 75 def __init__(self, shell=None, history=None, banner=None, *args, **kwargs):
76 76 if shell is None:
77 77 shell = Interpreter()
78 78 FrontEndBase.__init__(self, shell=shell, history=history)
79 79
80 80 if banner is not None:
81 81 self.banner = banner
82 82
83 83 def start(self):
84 84 """ Put the frontend in a state where it is ready for user
85 85 interaction.
86 86 """
87 87 if self.banner is not None:
88 88 self.write(self.banner, refresh=False)
89 89
90 90 self.new_prompt(self.input_prompt_template.substitute(number=1))
91 91
92 92
93 93 def complete(self, line):
94 94 """Complete line in engine's user_ns
95 95
96 96 Parameters
97 97 ----------
98 98 line : string
99 99
100 Result
101 ------
100 Returns
101 -------
102 102 The replacement for the line and the list of possible completions.
103 103 """
104 104 completions = self.shell.complete(line)
105 105 complete_sep = re.compile('[\s\{\}\[\]\(\)\=]')
106 106 if completions:
107 107 prefix = common_prefix(completions)
108 108 residual = complete_sep.split(line)[:-1]
109 109 line = line[:-len(residual)] + prefix
110 110 return line, completions
111 111
112 112
113 113 def render_result(self, result):
114 114 """ Frontend-specific rendering of the result of a calculation
115 115 that has been sent to an engine.
116 116 """
117 117 if 'stdout' in result and result['stdout']:
118 118 self.write('\n' + result['stdout'])
119 119 if 'display' in result and result['display']:
120 120 self.write("%s%s\n" % (
121 121 self.output_prompt_template.substitute(
122 122 number=result['number']),
123 123 result['display']['pprint']
124 124 ) )
125 125
126 126
127 127 def render_error(self, failure):
128 128 """ Frontend-specific rendering of error.
129 129 """
130 130 self.write('\n\n'+str(failure)+'\n\n')
131 131 return failure
132 132
133 133
134 134 def is_complete(self, string):
135 135 """ Check if a string forms a complete, executable set of
136 136 commands.
137 137
138 138 For the line-oriented frontend, multi-line code is not executed
139 139 as soon as it is complete: the users has to enter two line
140 140 returns.
141 141 """
142 142 if string in ('', '\n'):
143 143 # Prefiltering, eg through ipython0, may return an empty
144 144 # string although some operations have been accomplished. We
145 145 # thus want to consider an empty string as a complete
146 146 # statement.
147 147 return True
148 148 elif ( len(self.input_buffer.split('\n'))>2
149 149 and not re.findall(r"\n[\t ]*\n[\t ]*$", string)):
150 150 return False
151 151 else:
152 152 self.capture_output()
153 153 try:
154 154 # Add line returns here, to make sure that the statement is
155 155 # complete (except if '\' was used).
156 156 # This should probably be done in a different place (like
157 157 # maybe 'prefilter_input' method? For now, this works.
158 158 clean_string = string.rstrip('\n')
159 159 if not clean_string.endswith('\\'): clean_string +='\n\n'
160 160 is_complete = codeop.compile_command(clean_string,
161 161 "<string>", "exec")
162 162 self.release_output()
163 163 except Exception, e:
164 164 # XXX: Hack: return True so that the
165 165 # code gets executed and the error captured.
166 166 is_complete = True
167 167 return is_complete
168 168
169 169
170 170 def write(self, string, refresh=True):
171 171 """ Write some characters to the display.
172 172
173 173 Subclass should overide this method.
174 174
175 175 The refresh keyword argument is used in frontends with an
176 176 event loop, to choose whether the write should trigget an UI
177 177 refresh, and thus be syncrhonous, or not.
178 178 """
179 179 print >>sys.__stderr__, string
180 180
181 181
182 182 def execute(self, python_string, raw_string=None):
183 183 """ Stores the raw_string in the history, and sends the
184 184 python string to the interpreter.
185 185 """
186 186 if raw_string is None:
187 187 raw_string = python_string
188 188 # Create a false result, in case there is an exception
189 189 self.last_result = dict(number=self.prompt_number)
190 190
191 191 try:
192 192 try:
193 193 self.history.input_cache[-1] = raw_string.rstrip()
194 194 result = self.shell.execute(python_string)
195 195 self.last_result = result
196 196 self.render_result(result)
197 197 except:
198 198 self.show_traceback()
199 199 finally:
200 200 self.after_execute()
201 201
202 202
203 203 #--------------------------------------------------------------------------
204 204 # LineFrontEndBase interface
205 205 #--------------------------------------------------------------------------
206 206
207 207 def prefilter_input(self, string):
208 208 """ Prefilter the input to turn it in valid python.
209 209 """
210 210 string = string.replace('\r\n', '\n')
211 211 string = string.replace('\t', 4*' ')
212 212 # Clean the trailing whitespace
213 213 string = '\n'.join(l.rstrip() for l in string.split('\n'))
214 214 return string
215 215
216 216
217 217 def after_execute(self):
218 218 """ All the operations required after an execution to put the
219 219 terminal back in a shape where it is usable.
220 220 """
221 221 self.prompt_number += 1
222 222 self.new_prompt(self.input_prompt_template.substitute(
223 223 number=(self.last_result['number'] + 1)))
224 224 # Start a new empty history entry
225 225 self._add_history(None, '')
226 226 self.history_cursor = len(self.history.input_cache) - 1
227 227
228 228
229 229 def complete_current_input(self):
230 230 """ Do code completion on current line.
231 231 """
232 232 if self.debug:
233 233 print >>sys.__stdout__, "complete_current_input",
234 234 line = self.input_buffer
235 235 new_line, completions = self.complete(line)
236 236 if len(completions)>1:
237 237 self.write_completion(completions, new_line=new_line)
238 238 elif not line == new_line:
239 239 self.input_buffer = new_line
240 240 if self.debug:
241 241 print >>sys.__stdout__, 'line', line
242 242 print >>sys.__stdout__, 'new_line', new_line
243 243 print >>sys.__stdout__, completions
244 244
245 245
246 246 def get_line_width(self):
247 247 """ Return the width of the line in characters.
248 248 """
249 249 return 80
250 250
251 251
252 252 def write_completion(self, possibilities, new_line=None):
253 253 """ Write the list of possible completions.
254 254
255 255 new_line is the completed input line that should be displayed
256 256 after the completion are writen. If None, the input_buffer
257 257 before the completion is used.
258 258 """
259 259 if new_line is None:
260 260 new_line = self.input_buffer
261 261
262 262 self.write('\n')
263 263 max_len = len(max(possibilities, key=len)) + 1
264 264
265 265 # Now we check how much symbol we can put on a line...
266 266 chars_per_line = self.get_line_width()
267 267 symbols_per_line = max(1, chars_per_line/max_len)
268 268
269 269 pos = 1
270 270 completion_string = []
271 271 for symbol in possibilities:
272 272 if pos < symbols_per_line:
273 273 completion_string.append(symbol.ljust(max_len))
274 274 pos += 1
275 275 else:
276 276 completion_string.append(symbol.rstrip() + '\n')
277 277 pos = 1
278 278 self.write(''.join(completion_string))
279 279 self.new_prompt(self.input_prompt_template.substitute(
280 280 number=self.last_result['number'] + 1))
281 281 self.input_buffer = new_line
282 282
283 283
284 284 def new_prompt(self, prompt):
285 285 """ Prints a prompt and starts a new editing buffer.
286 286
287 287 Subclasses should use this method to make sure that the
288 288 terminal is put in a state favorable for a new line
289 289 input.
290 290 """
291 291 self.input_buffer = ''
292 292 self.write(prompt)
293 293
294 294
295 295 def continuation_prompt(self):
296 296 """Returns the current continuation prompt.
297 297 """
298 298 return ("."*(len(self.last_prompt)-2) + ': ')
299 299
300 300
301 301 def execute_command(self, command, hidden=False):
302 302 """ Execute a command, not only in the model, but also in the
303 303 view, if any.
304 304 """
305 305 return self.shell.execute(command)
306 306
307 307 #--------------------------------------------------------------------------
308 308 # Private API
309 309 #--------------------------------------------------------------------------
310 310
311 311 def _on_enter(self, new_line_pos=0):
312 312 """ Called when the return key is pressed in a line editing
313 313 buffer.
314 314
315 315 Parameters
316 316 ----------
317 317 new_line_pos : integer, optional
318 318 Position of the new line to add, starting from the
319 319 end (0 adds a new line after the last line, -1 before
320 320 the last line...)
321 321
322 322 Returns
323 323 -------
324 324 True if execution is triggered
325 325 """
326 326 current_buffer = self.input_buffer
327 327 # XXX: This string replace is ugly, but there should be no way it
328 328 # fails.
329 329 prompt_less_buffer = re.sub('^' + self.continuation_prompt(),
330 330 '', current_buffer).replace('\n' + self.continuation_prompt(),
331 331 '\n')
332 332 cleaned_buffer = self.prefilter_input(prompt_less_buffer)
333 333 if self.is_complete(cleaned_buffer):
334 334 self.execute(cleaned_buffer, raw_string=current_buffer)
335 335 return True
336 336 else:
337 337 # Start a new line.
338 338 new_line_pos = -new_line_pos
339 339 lines = current_buffer.split('\n')[:-1]
340 340 prompt_less_lines = prompt_less_buffer.split('\n')
341 341 # Create the new line, with the continuation prompt, and the
342 342 # same amount of indent than the line above it.
343 343 new_line = self.continuation_prompt() + \
344 344 self._get_indent_string('\n'.join(
345 345 prompt_less_lines[:new_line_pos-1]))
346 346 if len(lines) == 1:
347 347 # We are starting a first continuation line. Indent it.
348 348 new_line += '\t'
349 349 elif current_buffer[:-1].split('\n')[-1].rstrip().endswith(':'):
350 350 # The last line ends with ":", autoindent the new line.
351 351 new_line += '\t'
352 352
353 353 if new_line_pos == 0:
354 354 lines.append(new_line)
355 355 else:
356 356 lines.insert(new_line_pos, new_line)
357 357 self.input_buffer = '\n'.join(lines)
358 358
359 359
360 360 def _get_indent_string(self, string):
361 361 """ Return the string of whitespace that prefixes a line. Used to
362 362 add the right amount of indendation when creating a new line.
363 363 """
364 364 string = string.replace('\t', ' '*4)
365 365 string = string.split('\n')[-1]
366 366 indent_chars = len(string) - len(string.lstrip())
367 367 indent_string = '\t'*(indent_chars // 4) + \
368 368 ' '*(indent_chars % 4)
369 369
370 370 return indent_string
371 371
372 372
@@ -1,285 +1,285 b''
1 1 """
2 2 Frontend class that uses IPython0 to prefilter the inputs.
3 3
4 4 Using the IPython0 mechanism gives us access to the magics.
5 5
6 6 This is a transitory class, used here to do the transition between
7 7 ipython0 and ipython1. This class is meant to be short-lived as more
8 8 functionnality is abstracted out of ipython0 in reusable functions and
9 9 is added on the interpreter. This class can be a used to guide this
10 10 refactoring.
11 11 """
12 12 __docformat__ = "restructuredtext en"
13 13
14 14 #-------------------------------------------------------------------------------
15 15 # Copyright (C) 2008 The IPython Development Team
16 16 #
17 17 # Distributed under the terms of the BSD License. The full license is in
18 18 # the file COPYING, distributed as part of this software.
19 19 #-------------------------------------------------------------------------------
20 20
21 21 #-------------------------------------------------------------------------------
22 22 # Imports
23 23 #-------------------------------------------------------------------------------
24 24 import sys
25 25 import pydoc
26 26 import os
27 27 import re
28 28 import __builtin__
29 29
30 30 from IPython.core.ipmaker import make_IPython
31 31 from IPython.core.ipapi import IPApi
32 32 from IPython.kernel.core.redirector_output_trap import RedirectorOutputTrap
33 33
34 34 from IPython.kernel.core.sync_traceback_trap import SyncTracebackTrap
35 35
36 36 from IPython.utils.genutils import Term
37 37
38 38 from linefrontendbase import LineFrontEndBase, common_prefix
39 39
40 40
41 41 def mk_system_call(system_call_function, command):
42 42 """ given a os.system replacement, and a leading string command,
43 43 returns a function that will execute the command with the given
44 44 argument string.
45 45 """
46 46 def my_system_call(args):
47 47 system_call_function("%s %s" % (command, args))
48 48
49 49 my_system_call.__doc__ = "Calls %s" % command
50 50 return my_system_call
51 51
52 52 #-------------------------------------------------------------------------------
53 53 # Frontend class using ipython0 to do the prefiltering.
54 54 #-------------------------------------------------------------------------------
55 55 class PrefilterFrontEnd(LineFrontEndBase):
56 56 """ Class that uses ipython0 to do prefilter the input, do the
57 57 completion and the magics.
58 58
59 59 The core trick is to use an ipython0 instance to prefilter the
60 60 input, and share the namespace between the interpreter instance used
61 61 to execute the statements and the ipython0 used for code
62 62 completion...
63 63 """
64 64
65 65 debug = False
66 66
67 67 def __init__(self, ipython0=None, argv=None, *args, **kwargs):
68 """ Parameters:
69 -----------
68 """ Parameters
69 ----------
70 70
71 71 ipython0: an optional ipython0 instance to use for command
72 72 prefiltering and completion.
73 73
74 74 argv : list, optional
75 75 Used as the instance's argv value. If not given, [] is used.
76 76 """
77 77 if argv is None:
78 78 argv = []
79 79 # This is a hack to avoid the IPython exception hook to trigger
80 80 # on exceptions (https://bugs.launchpad.net/bugs/337105)
81 81 # XXX: This is horrible: module-leve monkey patching -> side
82 82 # effects.
83 83 from IPython.core import iplib
84 84 iplib.InteractiveShell.isthreaded = True
85 85
86 86 LineFrontEndBase.__init__(self, *args, **kwargs)
87 87 self.shell.output_trap = RedirectorOutputTrap(
88 88 out_callback=self.write,
89 89 err_callback=self.write,
90 90 )
91 91 self.shell.traceback_trap = SyncTracebackTrap(
92 92 formatters=self.shell.traceback_trap.formatters,
93 93 )
94 94
95 95 # Start the ipython0 instance:
96 96 self.save_output_hooks()
97 97 if ipython0 is None:
98 98 # Instanciate an IPython0 interpreter to be able to use the
99 99 # prefiltering.
100 100 # Suppress all key input, to avoid waiting
101 101 def my_rawinput(x=None):
102 102 return '\n'
103 103 old_rawinput = __builtin__.raw_input
104 104 __builtin__.raw_input = my_rawinput
105 105 # XXX: argv=[] is a bit bold.
106 106 ipython0 = make_IPython(argv=argv,
107 107 user_ns=self.shell.user_ns,
108 108 user_global_ns=self.shell.user_global_ns)
109 109 __builtin__.raw_input = old_rawinput
110 110 self.ipython0 = ipython0
111 111 # Set the pager:
112 112 self.ipython0.set_hook('show_in_pager',
113 113 lambda s, string: self.write("\n" + string))
114 114 self.ipython0.write = self.write
115 115 self._ip = _ip = IPApi(self.ipython0)
116 116 # Make sure the raw system call doesn't get called, as we don't
117 117 # have a stdin accessible.
118 118 self._ip.system = self.system_call
119 119 # XXX: Muck around with magics so that they work better
120 120 # in our environment
121 121 if not sys.platform.startswith('win'):
122 122 self.ipython0.magic_ls = mk_system_call(self.system_call,
123 123 'ls -CF')
124 124 # And now clean up the mess created by ipython0
125 125 self.release_output()
126 126
127 127
128 128 if not 'banner' in kwargs and self.banner is None:
129 129 self.banner = self.ipython0.BANNER
130 130
131 131 # FIXME: __init__ and start should be two different steps
132 132 self.start()
133 133
134 134 #--------------------------------------------------------------------------
135 135 # FrontEndBase interface
136 136 #--------------------------------------------------------------------------
137 137
138 138 def show_traceback(self):
139 139 """ Use ipython0 to capture the last traceback and display it.
140 140 """
141 141 # Don't do the capture; the except_hook has already done some
142 142 # modifications to the IO streams, if we store them, we'll be
143 143 # storing the wrong ones.
144 144 #self.capture_output()
145 145 self.ipython0.showtraceback(tb_offset=-1)
146 146 self.release_output()
147 147
148 148
149 149 def execute(self, python_string, raw_string=None):
150 150 if self.debug:
151 151 print 'Executing Python code:', repr(python_string)
152 152 self.capture_output()
153 153 LineFrontEndBase.execute(self, python_string,
154 154 raw_string=raw_string)
155 155 self.release_output()
156 156
157 157
158 158 def save_output_hooks(self):
159 159 """ Store all the output hooks we can think of, to be able to
160 160 restore them.
161 161
162 162 We need to do this early, as starting the ipython0 instance will
163 163 screw ouput hooks.
164 164 """
165 165 self.__old_cout_write = Term.cout.write
166 166 self.__old_cerr_write = Term.cerr.write
167 167 self.__old_stdout = sys.stdout
168 168 self.__old_stderr= sys.stderr
169 169 self.__old_help_output = pydoc.help.output
170 170 self.__old_display_hook = sys.displayhook
171 171
172 172
173 173 def capture_output(self):
174 174 """ Capture all the output mechanisms we can think of.
175 175 """
176 176 self.save_output_hooks()
177 177 Term.cout.write = self.write
178 178 Term.cerr.write = self.write
179 179 sys.stdout = Term.cout
180 180 sys.stderr = Term.cerr
181 181 pydoc.help.output = self.shell.output_trap.out
182 182
183 183
184 184 def release_output(self):
185 185 """ Release all the different captures we have made.
186 186 """
187 187 Term.cout.write = self.__old_cout_write
188 188 Term.cerr.write = self.__old_cerr_write
189 189 sys.stdout = self.__old_stdout
190 190 sys.stderr = self.__old_stderr
191 191 pydoc.help.output = self.__old_help_output
192 192 sys.displayhook = self.__old_display_hook
193 193
194 194
195 195 def complete(self, line):
196 196 # FIXME: This should be factored out in the linefrontendbase
197 197 # method.
198 198 word = self._get_completion_text(line)
199 199 completions = self.ipython0.complete(word)
200 200 # FIXME: The proper sort should be done in the complete method.
201 201 key = lambda x: x.replace('_', '')
202 202 completions.sort(key=key)
203 203 if completions:
204 204 prefix = common_prefix(completions)
205 205 line = line[:-len(word)] + prefix
206 206 return line, completions
207 207
208 208
209 209 #--------------------------------------------------------------------------
210 210 # LineFrontEndBase interface
211 211 #--------------------------------------------------------------------------
212 212
213 213 def prefilter_input(self, input_string):
214 214 """ Using IPython0 to prefilter the commands to turn them
215 215 in executable statements that are valid Python strings.
216 216 """
217 217 input_string = LineFrontEndBase.prefilter_input(self, input_string)
218 218 filtered_lines = []
219 219 # The IPython0 prefilters sometime produce output. We need to
220 220 # capture it.
221 221 self.capture_output()
222 222 self.last_result = dict(number=self.prompt_number)
223 223
224 224 ## try:
225 225 ## for line in input_string.split('\n'):
226 226 ## filtered_lines.append(
227 227 ## self.ipython0.prefilter(line, False).rstrip())
228 228 ## except:
229 229 ## # XXX: probably not the right thing to do.
230 230 ## self.ipython0.showsyntaxerror()
231 231 ## self.after_execute()
232 232 ## finally:
233 233 ## self.release_output()
234 234
235 235
236 236 try:
237 237 try:
238 238 for line in input_string.split('\n'):
239 239 filtered_lines.append(
240 240 self.ipython0.prefilter(line, False).rstrip())
241 241 except:
242 242 # XXX: probably not the right thing to do.
243 243 self.ipython0.showsyntaxerror()
244 244 self.after_execute()
245 245 finally:
246 246 self.release_output()
247 247
248 248
249 249
250 250 # Clean up the trailing whitespace, to avoid indentation errors
251 251 filtered_string = '\n'.join(filtered_lines)
252 252 return filtered_string
253 253
254 254
255 255 #--------------------------------------------------------------------------
256 256 # PrefilterFrontEnd interface
257 257 #--------------------------------------------------------------------------
258 258
259 259 def system_call(self, command_string):
260 260 """ Allows for frontend to define their own system call, to be
261 261 able capture output and redirect input.
262 262 """
263 263 return os.system(command_string)
264 264
265 265
266 266 def do_exit(self):
267 267 """ Exit the shell, cleanup and save the history.
268 268 """
269 269 self.ipython0.atexit_operations()
270 270
271 271
272 272 def _get_completion_text(self, line):
273 273 """ Returns the text to be completed by breaking the line at specified
274 274 delimiters.
275 275 """
276 276 # Break at: spaces, '=', all parentheses (except if balanced).
277 277 # FIXME2: In the future, we need to make the implementation similar to
278 278 # that in the 'pyreadline' module (modes/basemode.py) where we break at
279 279 # each delimiter and try to complete the residual line, until we get a
280 280 # successful list of completions.
281 281 expression = '\s|=|,|:|\((?!.*\))|\[(?!.*\])|\{(?!.*\})'
282 282 complete_sep = re.compile(expression)
283 283 text = complete_sep.split(line)[-1]
284 284 return text
285 285
@@ -1,109 +1,112 b''
1 1 # encoding: utf-8
2 2
3 3 """This file contains unittests for the asyncfrontendbase module."""
4 4
5 5 __docformat__ = "restructuredtext en"
6 6
7 # Tell nose to skip this module
8 __test__ = {}
9
7 10 #---------------------------------------------------------------------------
8 11 # Copyright (C) 2008 The IPython Development Team
9 12 #
10 13 # Distributed under the terms of the BSD License. The full license is in
11 14 # the file COPYING, distributed as part of this software.
12 15 #---------------------------------------------------------------------------
13 16
14 17 #---------------------------------------------------------------------------
15 18 # Imports
16 19 #---------------------------------------------------------------------------
17 20
18 # Tell nose to skip this module
19 __test__ = {}
20
21 21 from twisted.trial import unittest
22
22 23 from IPython.frontend.asyncfrontendbase import AsyncFrontEndBase
23 24 from IPython.frontend import frontendbase
24 25 from IPython.kernel.engineservice import EngineService
25 26 from IPython.testing.parametric import Parametric, parametric
26 27
28 #-----------------------------------------------------------------------------
29 # Classes and functions
30 #-----------------------------------------------------------------------------
27 31
28 32 class FrontEndCallbackChecker(AsyncFrontEndBase):
29 33 """FrontEndBase subclass for checking callbacks"""
30 34 def __init__(self, engine=None, history=None):
31 35 super(FrontEndCallbackChecker, self).__init__(engine=engine,
32 36 history=history)
33 37 self.updateCalled = False
34 38 self.renderResultCalled = False
35 39 self.renderErrorCalled = False
36 40
37 41 def update_cell_prompt(self, result, blockID=None):
38 42 self.updateCalled = True
39 43 return result
40 44
41 45 def render_result(self, result):
42 46 self.renderResultCalled = True
43 47 return result
44 48
45 49 def render_error(self, failure):
46 50 self.renderErrorCalled = True
47 51 return failure
48 52
49 53
50 54 class TestAsyncFrontendBase(unittest.TestCase):
51 55 def setUp(self):
52 56 """Setup the EngineService and FrontEndBase"""
53 57
54 58 self.fb = FrontEndCallbackChecker(engine=EngineService())
55 59
56 60 def test_implements_IFrontEnd(self):
57 61 self.assert_(frontendbase.IFrontEnd.implementedBy(
58 62 AsyncFrontEndBase))
59 63
60 64 def test_is_complete_returns_False_for_incomplete_block(self):
61 65 block = """def test(a):"""
62 66 self.assert_(self.fb.is_complete(block) == False)
63 67
64 68 def test_is_complete_returns_True_for_complete_block(self):
65 69 block = """def test(a): pass"""
66 70 self.assert_(self.fb.is_complete(block))
67 71 block = """a=3"""
68 72 self.assert_(self.fb.is_complete(block))
69 73
70 74 def test_blockID_added_to_result(self):
71 75 block = """3+3"""
72 76 d = self.fb.execute(block, blockID='TEST_ID')
73 77 d.addCallback(lambda r: self.assert_(r['blockID']=='TEST_ID'))
74 78 return d
75 79
76 80 def test_blockID_added_to_failure(self):
77 81 block = "raise Exception()"
78 82 d = self.fb.execute(block,blockID='TEST_ID')
79 83 d.addErrback(lambda f: self.assert_(f.blockID=='TEST_ID'))
80 84 return d
81 85
82 86 def test_callbacks_added_to_execute(self):
83 87 d = self.fb.execute("10+10")
84 88 d.addCallback(lambda r: self.assert_(self.fb.updateCalled and self.fb.renderResultCalled))
85 89 return d
86 90
87 91 def test_error_callback_added_to_execute(self):
88 92 """Test that render_error called on execution error."""
89 93
90 94 d = self.fb.execute("raise Exception()")
91 95 d.addErrback(lambda f: self.assert_(self.fb.renderErrorCalled))
92 96 return d
93 97
94 98 def test_history_returns_expected_block(self):
95 99 """Make sure history browsing doesn't fail."""
96 100
97 101 blocks = ["a=1","a=2","a=3"]
98 102 d = self.fb.execute(blocks[0])
99 103 d.addCallback(lambda _: self.fb.execute(blocks[1]))
100 104 d.addCallback(lambda _: self.fb.execute(blocks[2]))
101 105 d.addCallback(lambda _: self.assert_(self.fb.get_history_previous("")==blocks[-2]))
102 106 d.addCallback(lambda _: self.assert_(self.fb.get_history_previous("")==blocks[-3]))
103 107 d.addCallback(lambda _: self.assert_(self.fb.get_history_next()==blocks[-2]))
104 108 return d
105 109
106 110 def test_history_returns_none_at_startup(self):
107 111 self.assert_(self.fb.get_history_previous("")==None)
108 112 self.assert_(self.fb.get_history_next()==None)
109
@@ -1,252 +1,266 b''
1 1 # encoding: utf-8
2 2 """
3 3 Test process execution and IO redirection.
4 4 """
5 5
6 6 __docformat__ = "restructuredtext en"
7 7
8 8 #-------------------------------------------------------------------------------
9 9 # Copyright (C) 2008 The IPython Development Team
10 10 #
11 11 # Distributed under the terms of the BSD License. The full license is
12 12 # in the file COPYING, distributed as part of this software.
13 13 #-------------------------------------------------------------------------------
14 14
15 15 from copy import copy, deepcopy
16 16 from cStringIO import StringIO
17 17 import string
18 import sys
18 19
19 20 from nose.tools import assert_equal
20 21
21 22 from IPython.frontend.prefilterfrontend import PrefilterFrontEnd
22 23 from IPython.core.ipapi import get as get_ipython0
23 24 from IPython.testing.plugin.ipdoctest import default_argv
24 25
25 26
26 def safe_deepcopy(d):
27 """ Deep copy every key of the given dict, when possible. Elsewhere
28 do a copy.
29 """
30 copied_d = dict()
31 for key, value in d.iteritems():
32 try:
33 copied_d[key] = deepcopy(value)
34 except:
35 try:
36 copied_d[key] = copy(value)
37 except:
38 copied_d[key] = value
39 return copied_d
40
41
42 27 class TestPrefilterFrontEnd(PrefilterFrontEnd):
43 28
44 29 input_prompt_template = string.Template('')
45 30 output_prompt_template = string.Template('')
46 31 banner = ''
47 32
48 33 def __init__(self):
49 34 self.out = StringIO()
50 35 PrefilterFrontEnd.__init__(self,argv=default_argv())
51 36 # Some more code for isolation (yeah, crazy)
52 37 self._on_enter()
53 38 self.out.flush()
54 39 self.out.reset()
55 40 self.out.truncate()
56 41
57 42 def write(self, string, *args, **kwargs):
58 43 self.out.write(string)
59 44
60 45 def _on_enter(self):
61 46 self.input_buffer += '\n'
62 47 PrefilterFrontEnd._on_enter(self)
63 48
64 49
65 50 def isolate_ipython0(func):
66 51 """ Decorator to isolate execution that involves an iptyhon0.
67 52
68 53 Notes
69 54 -----
70 55
71 56 Apply only to functions with no arguments. Nose skips functions
72 57 with arguments.
73 58 """
74 59 def my_func():
75 iplib = get_ipython0()
76 if iplib is None:
60 ip0 = get_ipython0()
61 if ip0 is None:
77 62 return func()
78 ipython0 = iplib.IP
79 global_ns = safe_deepcopy(ipython0.user_global_ns)
80 user_ns = safe_deepcopy(ipython0.user_ns)
63 # We have a real ipython running...
64 user_ns = ip0.IP.user_ns
65 user_global_ns = ip0.IP.user_global_ns
66
67 # Previously the isolation was attempted with a deep copy of the user
68 # dicts, but we found cases where this didn't work correctly. I'm not
69 # quite sure why, but basically it did damage the user namespace, such
70 # that later tests stopped working correctly. Instead we use a simpler
71 # approach, just computing the list of added keys to the namespace and
72 # eliminating those afterwards. Existing keys that may have been
73 # modified remain modified. So far this has proven to be robust.
74
75 # Compute set of old local/global keys
76 old_locals = set(user_ns.keys())
77 old_globals = set(user_global_ns.keys())
81 78 try:
82 79 out = func()
83 80 finally:
84 ipython0.user_ns = user_ns
85 ipython0.user_global_ns = global_ns
81 # Find new keys, and if any, remove them
82 new_locals = set(user_ns.keys()) - old_locals
83 new_globals = set(user_global_ns.keys()) - old_globals
84 for k in new_locals:
85 del user_ns[k]
86 for k in new_globals:
87 del user_global_ns[k]
86 88 # Undo the hack at creation of PrefilterFrontEnd
87 89 from IPython.core import iplib
88 90 iplib.InteractiveShell.isthreaded = False
89 91 return out
90 92
91 93 my_func.__name__ = func.__name__
92 94 return my_func
93 95
94 96
95 97 @isolate_ipython0
96 98 def test_execution():
97 99 """ Test execution of a command.
98 100 """
99 101 f = TestPrefilterFrontEnd()
100 f.input_buffer = 'print 1'
102 f.input_buffer = 'print(1)'
101 103 f._on_enter()
102 104 out_value = f.out.getvalue()
103 105 assert_equal(out_value, '1\n')
104 106
105 107
106 108 @isolate_ipython0
107 109 def test_multiline():
108 110 """ Test execution of a multiline command.
109 111 """
110 112 f = TestPrefilterFrontEnd()
111 113 f.input_buffer = 'if True:'
112 114 f._on_enter()
113 115 f.input_buffer += 'print 1'
114 116 f._on_enter()
115 117 out_value = f.out.getvalue()
116 118 yield assert_equal, out_value, ''
117 119 f._on_enter()
118 120 out_value = f.out.getvalue()
119 121 yield assert_equal, out_value, '1\n'
120 122 f = TestPrefilterFrontEnd()
121 123 f.input_buffer='(1 +'
122 124 f._on_enter()
123 125 f.input_buffer += '0)'
124 126 f._on_enter()
125 127 out_value = f.out.getvalue()
126 128 yield assert_equal, out_value, ''
127 129 f._on_enter()
128 130 out_value = f.out.getvalue()
129 131 yield assert_equal, out_value, '1\n'
130 132
131 133
132 134 @isolate_ipython0
133 135 def test_capture():
134 136 """ Test the capture of output in different channels.
135 137 """
136 138 # Test on the OS-level stdout, stderr.
137 139 f = TestPrefilterFrontEnd()
138 140 f.input_buffer = \
139 141 'import os; out=os.fdopen(1, "w"); out.write("1") ; out.flush()'
140 142 f._on_enter()
141 143 out_value = f.out.getvalue()
142 144 yield assert_equal, out_value, '1'
143 145 f = TestPrefilterFrontEnd()
144 146 f.input_buffer = \
145 147 'import os; out=os.fdopen(2, "w"); out.write("1") ; out.flush()'
146 148 f._on_enter()
147 149 out_value = f.out.getvalue()
148 150 yield assert_equal, out_value, '1'
149 151
150 152
151 153 @isolate_ipython0
152 154 def test_magic():
153 155 """ Test the magic expansion and history.
154 156
155 157 This test is fairly fragile and will break when magics change.
156 158 """
157 159 f = TestPrefilterFrontEnd()
158 160 # Before checking the interactive namespace, make sure it's clear (it can
159 161 # otherwise pick up things stored in the user's local db)
160 162 f.input_buffer += '%reset -f'
161 163 f._on_enter()
162 164 f.complete_current_input()
163 165 # Now, run the %who magic and check output
164 166 f.input_buffer += '%who'
165 167 f._on_enter()
166 168 out_value = f.out.getvalue()
167 169 assert_equal(out_value, 'Interactive namespace is empty.\n')
168 170
169 171
170 172 @isolate_ipython0
171 173 def test_help():
172 174 """ Test object inspection.
173 175 """
174 176 f = TestPrefilterFrontEnd()
175 177 f.input_buffer += "def f():"
176 178 f._on_enter()
177 179 f.input_buffer += "'foobar'"
178 180 f._on_enter()
179 181 f.input_buffer += "pass"
180 182 f._on_enter()
181 183 f._on_enter()
182 184 f.input_buffer += "f?"
183 185 f._on_enter()
184 186 assert 'traceback' not in f.last_result
185 187 ## XXX: ipython doctest magic breaks this. I have no clue why
186 188 #out_value = f.out.getvalue()
187 189 #assert out_value.split()[-1] == 'foobar'
188 190
189 191
190 192 @isolate_ipython0
191 193 def test_completion_simple():
192 194 """ Test command-line completion on trivial examples.
193 195 """
194 196 f = TestPrefilterFrontEnd()
195 197 f.input_buffer = 'zzza = 1'
196 198 f._on_enter()
197 199 f.input_buffer = 'zzzb = 2'
198 200 f._on_enter()
199 201 f.input_buffer = 'zz'
200 202 f.complete_current_input()
201 203 out_value = f.out.getvalue()
202 204 yield assert_equal, out_value, '\nzzza zzzb '
203 205 yield assert_equal, f.input_buffer, 'zzz'
204 206
205 207
206 208 @isolate_ipython0
207 209 def test_completion_parenthesis():
208 210 """ Test command-line completion when a parenthesis is open.
209 211 """
210 212 f = TestPrefilterFrontEnd()
211 213 f.input_buffer = 'zzza = 1'
212 214 f._on_enter()
213 215 f.input_buffer = 'zzzb = 2'
214 216 f._on_enter()
215 217 f.input_buffer = 'map(zz'
216 218 f.complete_current_input()
217 219 out_value = f.out.getvalue()
218 220 yield assert_equal, out_value, '\nzzza zzzb '
219 221 yield assert_equal, f.input_buffer, 'map(zzz'
220 222
221 223
222 224 @isolate_ipython0
223 225 def test_completion_indexing():
224 226 """ Test command-line completion when indexing on objects.
225 227 """
226 228 f = TestPrefilterFrontEnd()
227 229 f.input_buffer = 'a = [0]'
228 230 f._on_enter()
229 231 f.input_buffer = 'a[0].'
230 232 f.complete_current_input()
233
234 if sys.version_info[:2] >= (2,6):
235 # In Python 2.6, ints picked up a few non __ methods, so now there are
236 # no completions.
237 assert_equal(f.input_buffer, 'a[0].')
238 else:
239 # Right answer for 2.4/2.5
231 240 assert_equal(f.input_buffer, 'a[0].__')
232 241
233 242
234 243 @isolate_ipython0
235 244 def test_completion_equal():
236 245 """ Test command-line completion when the delimiter is "=", not " ".
237 246 """
238 247 f = TestPrefilterFrontEnd()
239 248 f.input_buffer = 'a=1.'
240 249 f.complete_current_input()
250 if sys.version_info[:2] >= (2,6):
251 # In Python 2.6, ints picked up a few non __ methods, so now there are
252 # no completions.
253 assert_equal(f.input_buffer, 'a=1.')
254 else:
255 # Right answer for 2.4/2.5
241 256 assert_equal(f.input_buffer, 'a=1.__')
242 257
243 258
244
245 259 if __name__ == '__main__':
246 260 test_magic()
247 261 test_help()
248 262 test_execution()
249 263 test_multiline()
250 264 test_capture()
251 265 test_completion_simple()
252 266 test_completion_complex()
@@ -1,625 +1,624 b''
1 1 # encoding: utf-8
2 2 """
3 3 A Wx widget to act as a console and input commands.
4 4
5 5 This widget deals with prompts and provides an edit buffer
6 6 restricted to after the last prompt.
7 7 """
8 8
9 9 __docformat__ = "restructuredtext en"
10 10
11 11 #-------------------------------------------------------------------------------
12 12 # Copyright (C) 2008 The IPython Development Team
13 13 #
14 14 # Distributed under the terms of the BSD License. The full license is
15 15 # in the file COPYING, distributed as part of this software.
16 16 #-------------------------------------------------------------------------------
17 17
18 18 #-------------------------------------------------------------------------------
19 19 # Imports
20 20 #-------------------------------------------------------------------------------
21 21
22 22 import wx
23 23 import wx.stc as stc
24 24
25 25 from wx.py import editwindow
26 26 import time
27 27 import sys
28 28 import string
29 29
30 30 LINESEP = '\n'
31 31 if sys.platform == 'win32':
32 32 LINESEP = '\n\r'
33 33
34 34 import re
35 35
36 36 # FIXME: Need to provide an API for non user-generated display on the
37 37 # screen: this should not be editable by the user.
38 38 #-------------------------------------------------------------------------------
39 39 # Constants
40 40 #-------------------------------------------------------------------------------
41 41 _COMPLETE_BUFFER_MARKER = 31
42 42 _ERROR_MARKER = 30
43 43 _INPUT_MARKER = 29
44 44
45 45 _DEFAULT_SIZE = 10
46 46 if sys.platform == 'darwin':
47 47 _DEFAULT_SIZE = 12
48 48
49 49 _DEFAULT_STYLE = {
50 50 #background definition
51 51 'default' : 'size:%d' % _DEFAULT_SIZE,
52 52 'bracegood' : 'fore:#00AA00,back:#000000,bold',
53 53 'bracebad' : 'fore:#FF0000,back:#000000,bold',
54 54
55 55 # Edge column: a number of None
56 56 'edge_column' : -1,
57 57
58 58 # properties for the various Python lexer styles
59 59 'comment' : 'fore:#007F00',
60 60 'number' : 'fore:#007F7F',
61 61 'string' : 'fore:#7F007F,italic',
62 62 'char' : 'fore:#7F007F,italic',
63 63 'keyword' : 'fore:#00007F,bold',
64 64 'triple' : 'fore:#7F0000',
65 65 'tripledouble' : 'fore:#7F0000',
66 66 'class' : 'fore:#0000FF,bold,underline',
67 67 'def' : 'fore:#007F7F,bold',
68 68 'operator' : 'bold',
69 69
70 70 # Default colors
71 71 'trace' : '#FAFAF1', # Nice green
72 72 'stdout' : '#FDFFD3', # Nice yellow
73 73 'stderr' : '#FFF1F1', # Nice red
74 74
75 75 # Default scintilla settings
76 76 'antialiasing' : True,
77 77 'carret_color' : 'BLACK',
78 78 'background_color' :'WHITE',
79 79
80 80 #prompt definition
81 81 'prompt_in1' : \
82 82 '\n\x01\x1b[0;34m\x02In [\x01\x1b[1;34m\x02$number\x01\x1b[0;34m\x02]: \x01\x1b[0m\x02',
83 83
84 84 'prompt_out': \
85 85 '\x01\x1b[0;31m\x02Out[\x01\x1b[1;31m\x02$number\x01\x1b[0;31m\x02]: \x01\x1b[0m\x02',
86 86 }
87 87
88 88 # new style numbers
89 89 _STDOUT_STYLE = 15
90 90 _STDERR_STYLE = 16
91 91 _TRACE_STYLE = 17
92 92
93 93
94 94 # system colors
95 95 #SYS_COLOUR_BACKGROUND = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BACKGROUND)
96 96
97 97 # Translation table from ANSI escape sequences to color.
98 98 ANSI_STYLES = {'0;30': [0, 'BLACK'], '0;31': [1, 'RED'],
99 99 '0;32': [2, 'GREEN'], '0;33': [3, 'BROWN'],
100 100 '0;34': [4, 'BLUE'], '0;35': [5, 'PURPLE'],
101 101 '0;36': [6, 'CYAN'], '0;37': [7, 'LIGHT GREY'],
102 102 '1;30': [8, 'DARK GREY'], '1;31': [9, 'RED'],
103 103 '1;32': [10, 'SEA GREEN'], '1;33': [11, 'YELLOW'],
104 104 '1;34': [12, 'LIGHT BLUE'], '1;35':
105 105 [13, 'MEDIUM VIOLET RED'],
106 106 '1;36': [14, 'LIGHT STEEL BLUE'], '1;37': [15, 'YELLOW']}
107 107
108 108 # XXX: Maybe one day we should factor this code with coloransi. Right now
109 109 # coloransi is hard to reuse and makes our code more complex.
110 110
111 111 #we define platform specific fonts
112 112 if wx.Platform == '__WXMSW__':
113 113 FACES = { 'times': 'Times New Roman',
114 114 'mono' : 'Courier New',
115 115 'helv' : 'Arial',
116 116 'other': 'Comic Sans MS',
117 117 'size' : 10,
118 118 'size2': 8,
119 119 }
120 120 elif wx.Platform == '__WXMAC__':
121 121 FACES = { 'times': 'Times New Roman',
122 122 'mono' : 'Monaco',
123 123 'helv' : 'Arial',
124 124 'other': 'Comic Sans MS',
125 125 'size' : 10,
126 126 'size2': 8,
127 127 }
128 128 else:
129 129 FACES = { 'times': 'Times',
130 130 'mono' : 'Courier',
131 131 'helv' : 'Helvetica',
132 132 'other': 'new century schoolbook',
133 133 'size' : 10,
134 134 'size2': 8,
135 135 }
136 136
137 137
138 138 #-------------------------------------------------------------------------------
139 139 # The console widget class
140 140 #-------------------------------------------------------------------------------
141 141 class ConsoleWidget(editwindow.EditWindow):
142 142 """ Specialized styled text control view for console-like workflow.
143 143
144 144 This widget is mainly interested in dealing with the prompt and
145 145 keeping the cursor inside the editing line.
146 146 """
147 147
148 148 # This is where the title captured from the ANSI escape sequences are
149 149 # stored.
150 150 title = 'Console'
151 151
152 152 # Last prompt printed
153 153 last_prompt = ''
154 154
155 155 # The buffer being edited.
156 156 def _set_input_buffer(self, string):
157 157 self.SetSelection(self.current_prompt_pos, self.GetLength())
158 158 self.ReplaceSelection(string)
159 159 self.GotoPos(self.GetLength())
160 160
161 161 def _get_input_buffer(self):
162 162 """ Returns the text in current edit buffer.
163 163 """
164 164 input_buffer = self.GetTextRange(self.current_prompt_pos,
165 165 self.GetLength())
166 166 input_buffer = input_buffer.replace(LINESEP, '\n')
167 167 return input_buffer
168 168
169 169 input_buffer = property(_get_input_buffer, _set_input_buffer)
170 170
171 171 style = _DEFAULT_STYLE.copy()
172 172
173 173 # Translation table from ANSI escape sequences to color. Override
174 174 # this to specify your colors.
175 175 ANSI_STYLES = ANSI_STYLES.copy()
176 176
177 177 # Font faces
178 178 faces = FACES.copy()
179 179
180 180 # Store the last time a refresh was done
181 181 _last_refresh_time = 0
182 182
183 183 #--------------------------------------------------------------------------
184 184 # Public API
185 185 #--------------------------------------------------------------------------
186 186
187 187 def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
188 188 size=wx.DefaultSize, style=wx.WANTS_CHARS, ):
189 189 editwindow.EditWindow.__init__(self, parent, id, pos, size, style)
190 190 self.configure_scintilla()
191 191 # Track if 'enter' key as ever been processed
192 192 # This variable will only be reallowed until key goes up
193 193 self.enter_catched = False
194 194 self.current_prompt_pos = 0
195 195
196 196 self.Bind(wx.EVT_KEY_DOWN, self._on_key_down)
197 197 self.Bind(wx.EVT_KEY_UP, self._on_key_up)
198 198
199 199
200 200 def write(self, text, refresh=True):
201 201 """ Write given text to buffer, while translating the ansi escape
202 202 sequences.
203 203 """
204 204 # XXX: do not put print statements to sys.stdout/sys.stderr in
205 205 # this method, the print statements will call this method, as
206 206 # you will end up with an infinit loop
207 207 title = self.title_pat.split(text)
208 208 if len(title)>1:
209 209 self.title = title[-2]
210 210
211 211 text = self.title_pat.sub('', text)
212 212 segments = self.color_pat.split(text)
213 213 segment = segments.pop(0)
214 214 self.GotoPos(self.GetLength())
215 215 self.StartStyling(self.GetLength(), 0xFF)
216 216 try:
217 217 self.AppendText(segment)
218 218 except UnicodeDecodeError:
219 219 # XXX: Do I really want to skip the exception?
220 220 pass
221 221
222 222 if segments:
223 223 for ansi_tag, text in zip(segments[::2], segments[1::2]):
224 224 self.StartStyling(self.GetLength(), 0xFF)
225 225 try:
226 226 self.AppendText(text)
227 227 except UnicodeDecodeError:
228 228 # XXX: Do I really want to skip the exception?
229 229 pass
230 230
231 231 if ansi_tag not in self.ANSI_STYLES:
232 232 style = 0
233 233 else:
234 234 style = self.ANSI_STYLES[ansi_tag][0]
235 235
236 236 self.SetStyling(len(text), style)
237 237
238 238 self.GotoPos(self.GetLength())
239 239 if refresh:
240 240 current_time = time.time()
241 241 if current_time - self._last_refresh_time > 0.03:
242 242 if sys.platform == 'win32':
243 243 wx.SafeYield()
244 244 else:
245 245 wx.Yield()
246 246 # self.ProcessEvent(wx.PaintEvent())
247 247 self._last_refresh_time = current_time
248 248
249 249
250 250 def new_prompt(self, prompt):
251 251 """ Prints a prompt at start of line, and move the start of the
252 252 current block there.
253 253
254 254 The prompt can be given with ascii escape sequences.
255 255 """
256 256 self.write(prompt, refresh=False)
257 257 # now we update our cursor giving end of prompt
258 258 self.current_prompt_pos = self.GetLength()
259 259 self.current_prompt_line = self.GetCurrentLine()
260 260 self.EnsureCaretVisible()
261 261 self.last_prompt = prompt
262 262
263 263
264 264 def continuation_prompt(self):
265 265 """ Returns the current continuation prompt.
266 266 We need to implement this method here to deal with the
267 267 ascii escape sequences cleaning up.
268 268 """
269 269 # ASCII-less prompt
270 270 ascii_less = ''.join(self.color_pat.split(self.last_prompt)[2::2])
271 271 return "."*(len(ascii_less)-2) + ': '
272 272
273 273
274 274 def scroll_to_bottom(self):
275 275 maxrange = self.GetScrollRange(wx.VERTICAL)
276 276 self.ScrollLines(maxrange)
277 277
278 278
279 279 def pop_completion(self, possibilities, offset=0):
280 280 """ Pops up an autocompletion menu. Offset is the offset
281 281 in characters of the position at which the menu should
282 282 appear, relativ to the cursor.
283 283 """
284 284 self.AutoCompSetIgnoreCase(False)
285 285 self.AutoCompSetAutoHide(False)
286 286 self.AutoCompSetMaxHeight(len(possibilities))
287 287 self.AutoCompShow(offset, " ".join(possibilities))
288 288
289 289
290 290 def get_line_width(self):
291 291 """ Return the width of the line in characters.
292 292 """
293 293 return self.GetSize()[0]/self.GetCharWidth()
294 294
295 295
296 296 def configure_scintilla(self):
297 297 """ Set up all the styling option of the embedded scintilla
298 298 widget.
299 299 """
300 300 p = self.style.copy()
301 301
302 302 # Marker for complete buffer.
303 303 self.MarkerDefine(_COMPLETE_BUFFER_MARKER, stc.STC_MARK_BACKGROUND,
304 304 background=p['trace'])
305 305
306 306 # Marker for current input buffer.
307 307 self.MarkerDefine(_INPUT_MARKER, stc.STC_MARK_BACKGROUND,
308 308 background=p['stdout'])
309 309 # Marker for tracebacks.
310 310 self.MarkerDefine(_ERROR_MARKER, stc.STC_MARK_BACKGROUND,
311 311 background=p['stderr'])
312 312
313 313 self.SetEOLMode(stc.STC_EOL_LF)
314 314
315 315 # Ctrl"+" or Ctrl "-" can be used to zoomin/zoomout the text inside
316 316 # the widget
317 317 self.CmdKeyAssign(ord('+'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
318 318 self.CmdKeyAssign(ord('-'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
319 319 # Also allow Ctrl Shift "=" for poor non US keyboard users.
320 320 self.CmdKeyAssign(ord('='), stc.STC_SCMOD_CTRL|stc.STC_SCMOD_SHIFT,
321 321 stc.STC_CMD_ZOOMIN)
322 322
323 323 # Keys: we need to clear some of the keys the that don't play
324 324 # well with a console.
325 325 self.CmdKeyClear(ord('D'), stc.STC_SCMOD_CTRL)
326 326 self.CmdKeyClear(ord('L'), stc.STC_SCMOD_CTRL)
327 327 self.CmdKeyClear(ord('T'), stc.STC_SCMOD_CTRL)
328 328 self.CmdKeyClear(ord('A'), stc.STC_SCMOD_CTRL)
329 329
330 330 self.SetEOLMode(stc.STC_EOL_CRLF)
331 331 self.SetWrapMode(stc.STC_WRAP_CHAR)
332 332 self.SetWrapMode(stc.STC_WRAP_WORD)
333 333 self.SetBufferedDraw(True)
334 334
335 335 self.SetUseAntiAliasing(p['antialiasing'])
336 336
337 337 self.SetLayoutCache(stc.STC_CACHE_PAGE)
338 338 self.SetUndoCollection(False)
339 339 self.SetUseTabs(True)
340 340 self.SetIndent(4)
341 341 self.SetTabWidth(4)
342 342
343 343 # we don't want scintilla's autocompletion to choose
344 344 # automaticaly out of a single choice list, as we pop it up
345 345 # automaticaly
346 346 self.AutoCompSetChooseSingle(False)
347 347 self.AutoCompSetMaxHeight(10)
348 348 # XXX: this doesn't seem to have an effect.
349 349 self.AutoCompSetFillUps('\n')
350 350
351 351 self.SetMargins(3, 3) #text is moved away from border with 3px
352 352 # Suppressing Scintilla margins
353 353 self.SetMarginWidth(0, 0)
354 354 self.SetMarginWidth(1, 0)
355 355 self.SetMarginWidth(2, 0)
356 356
357 357 # Xterm escape sequences
358 358 self.color_pat = re.compile('\x01?\x1b\[(.*?)m\x02?')
359 359 self.title_pat = re.compile('\x1b]0;(.*?)\x07')
360 360
361 361 # styles
362 362
363 363 self.SetCaretForeground(p['carret_color'])
364 364
365 365 background_color = p['background_color']
366 366
367 367 if 'default' in p:
368 368 if 'back' not in p['default']:
369 369 p['default'] += ',back:%s' % background_color
370 370 if 'size' not in p['default']:
371 371 p['default'] += ',size:%s' % self.faces['size']
372 372 if 'face' not in p['default']:
373 373 p['default'] += ',face:%s' % self.faces['mono']
374 374
375 375 self.StyleSetSpec(stc.STC_STYLE_DEFAULT, p['default'])
376 376 else:
377 377 self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
378 378 "fore:%s,back:%s,size:%d,face:%s"
379 379 % (self.ANSI_STYLES['0;30'][1],
380 380 background_color,
381 381 self.faces['size'], self.faces['mono']))
382 382
383 383 self.StyleClearAll()
384 384
385 385 # XXX: two lines below are usefull if not using the lexer
386 386 #for style in self.ANSI_STYLES.values():
387 387 # self.StyleSetSpec(style[0], "bold,fore:%s" % style[1])
388 388
389 389 # prompt definition
390 390 self.prompt_in1 = p['prompt_in1']
391 391 self.prompt_out = p['prompt_out']
392 392
393 393 self.output_prompt_template = string.Template(self.prompt_out)
394 394 self.input_prompt_template = string.Template(self.prompt_in1)
395 395
396 396 self.StyleSetSpec(_STDOUT_STYLE, p['stdout'])
397 397 self.StyleSetSpec(_STDERR_STYLE, p['stderr'])
398 398 self.StyleSetSpec(_TRACE_STYLE, p['trace'])
399 399 self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT, p['bracegood'])
400 400 self.StyleSetSpec(stc.STC_STYLE_BRACEBAD, p['bracebad'])
401 401 self.StyleSetSpec(stc.STC_P_COMMENTLINE, p['comment'])
402 402 self.StyleSetSpec(stc.STC_P_NUMBER, p['number'])
403 403 self.StyleSetSpec(stc.STC_P_STRING, p['string'])
404 404 self.StyleSetSpec(stc.STC_P_CHARACTER, p['char'])
405 405 self.StyleSetSpec(stc.STC_P_WORD, p['keyword'])
406 406 self.StyleSetSpec(stc.STC_P_WORD2, p['keyword'])
407 407 self.StyleSetSpec(stc.STC_P_TRIPLE, p['triple'])
408 408 self.StyleSetSpec(stc.STC_P_TRIPLEDOUBLE, p['tripledouble'])
409 409 self.StyleSetSpec(stc.STC_P_CLASSNAME, p['class'])
410 410 self.StyleSetSpec(stc.STC_P_DEFNAME, p['def'])
411 411 self.StyleSetSpec(stc.STC_P_OPERATOR, p['operator'])
412 412 self.StyleSetSpec(stc.STC_P_COMMENTBLOCK, p['comment'])
413 413
414 414 edge_column = p['edge_column']
415 415 if edge_column is not None and edge_column > 0:
416 416 #we add a vertical line to console widget
417 417 self.SetEdgeMode(stc.STC_EDGE_LINE)
418 418 self.SetEdgeColumn(edge_column)
419 419
420 420
421 421 #--------------------------------------------------------------------------
422 422 # EditWindow API
423 423 #--------------------------------------------------------------------------
424 424
425 425 def OnUpdateUI(self, event):
426 426 """ Override the OnUpdateUI of the EditWindow class, to prevent
427 427 syntax highlighting both for faster redraw, and for more
428 428 consistent look and feel.
429 429 """
430 430
431 431
432 432 #--------------------------------------------------------------------------
433 433 # Private API
434 434 #--------------------------------------------------------------------------
435 435
436 436 def _on_key_down(self, event, skip=True):
437 437 """ Key press callback used for correcting behavior for
438 438 console-like interfaces: the cursor is constraint to be after
439 439 the last prompt.
440 440
441 441 Return True if event as been catched.
442 442 """
443 443 catched = True
444 444 # XXX: Would the right way to do this be to have a
445 445 # dictionary at the instance level associating keys with
446 446 # callbacks? How would we deal with inheritance? And Do the
447 447 # different callbacks share local variables?
448 448
449 449 # Intercept some specific keys.
450 if event.KeyCode == ord('L') and event.ControlDown() :
450 key_code = event.GetKeyCode()
451 if key_code == ord('L') and event.ControlDown() :
451 452 self.scroll_to_bottom()
452 elif event.KeyCode == ord('K') and event.ControlDown() :
453 elif key_code == ord('K') and event.ControlDown() :
453 454 self.input_buffer = ''
454 elif event.KeyCode == ord('A') and event.ControlDown() :
455 elif key_code == ord('A') and event.ControlDown() :
455 456 self.GotoPos(self.GetLength())
456 457 self.SetSelectionStart(self.current_prompt_pos)
457 458 self.SetSelectionEnd(self.GetCurrentPos())
458 459 catched = True
459 elif event.KeyCode == ord('E') and event.ControlDown() :
460 elif key_code == ord('E') and event.ControlDown() :
460 461 self.GotoPos(self.GetLength())
461 462 catched = True
462 elif event.KeyCode == wx.WXK_PAGEUP:
463 elif key_code == wx.WXK_PAGEUP:
463 464 self.ScrollPages(-1)
464 elif event.KeyCode == wx.WXK_PAGEDOWN:
465 elif key_code == wx.WXK_PAGEDOWN:
465 466 self.ScrollPages(1)
466 elif event.KeyCode == wx.WXK_HOME:
467 elif key_code == wx.WXK_HOME:
467 468 self.GotoPos(self.GetLength())
468 elif event.KeyCode == wx.WXK_END:
469 elif key_code == wx.WXK_END:
469 470 self.GotoPos(self.GetLength())
470 elif event.KeyCode == wx.WXK_UP and event.ShiftDown():
471 elif key_code == wx.WXK_UP and event.ShiftDown():
471 472 self.ScrollLines(-1)
472 elif event.KeyCode == wx.WXK_DOWN and event.ShiftDown():
473 elif key_code == wx.WXK_DOWN and event.ShiftDown():
473 474 self.ScrollLines(1)
474 475 else:
475 476 catched = False
476 477
477 478 if self.AutoCompActive():
478 479 event.Skip()
479 480 else:
480 if event.KeyCode in (13, wx.WXK_NUMPAD_ENTER) and \
481 event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN,
482 wx.MOD_SHIFT):
481 if key_code in (13, wx.WXK_NUMPAD_ENTER):
482 # XXX: not catching modifiers, to be wx2.6-compatible
483 483 catched = True
484 484 if not self.enter_catched:
485 485 self.CallTipCancel()
486 if event.Modifiers == wx.MOD_SHIFT:
486 if event.ShiftDown():
487 487 # Try to force execution
488 488 self.GotoPos(self.GetLength())
489 489 self.write('\n' + self.continuation_prompt(),
490 490 refresh=False)
491 491 self._on_enter()
492 492 else:
493 493 self._on_enter()
494 494 self.enter_catched = True
495 495
496 elif event.KeyCode == wx.WXK_HOME:
497 if event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN):
496 elif key_code == wx.WXK_HOME:
497 if not event.ShiftDown():
498 498 self.GotoPos(self.current_prompt_pos)
499 499 catched = True
500
501 elif event.Modifiers == wx.MOD_SHIFT:
500 else:
502 501 # FIXME: This behavior is not ideal: if the selection
503 502 # is already started, it will jump.
504 503 self.SetSelectionStart(self.current_prompt_pos)
505 504 self.SetSelectionEnd(self.GetCurrentPos())
506 505 catched = True
507 506
508 elif event.KeyCode == wx.WXK_UP:
507 elif key_code == wx.WXK_UP:
509 508 if self.GetCurrentLine() > self.current_prompt_line:
510 509 if self.GetCurrentLine() == self.current_prompt_line + 1 \
511 510 and self.GetColumn(self.GetCurrentPos()) < \
512 511 self.GetColumn(self.current_prompt_pos):
513 512 self.GotoPos(self.current_prompt_pos)
514 513 else:
515 514 event.Skip()
516 515 catched = True
517 516
518 elif event.KeyCode in (wx.WXK_LEFT, wx.WXK_BACK):
517 elif key_code in (wx.WXK_LEFT, wx.WXK_BACK):
519 518 if not self._keep_cursor_in_buffer(self.GetCurrentPos() - 1):
520 519 event.Skip()
521 520 catched = True
522 521
523 elif event.KeyCode == wx.WXK_RIGHT:
522 elif key_code == wx.WXK_RIGHT:
524 523 if not self._keep_cursor_in_buffer(self.GetCurrentPos() + 1):
525 524 event.Skip()
526 525 catched = True
527 526
528 527
529 elif event.KeyCode == wx.WXK_DELETE:
528 elif key_code == wx.WXK_DELETE:
530 529 if not self._keep_cursor_in_buffer(self.GetCurrentPos() - 1):
531 530 event.Skip()
532 531 catched = True
533 532
534 533 if skip and not catched:
535 534 # Put the cursor back in the edit region
536 535 if not self._keep_cursor_in_buffer():
537 536 if not (self.GetCurrentPos() == self.GetLength()
538 and event.KeyCode == wx.WXK_DELETE):
537 and key_code == wx.WXK_DELETE):
539 538 event.Skip()
540 539 catched = True
541 540
542 541 return catched
543 542
544 543
545 544 def _on_key_up(self, event, skip=True):
546 545 """ If cursor is outside the editing region, put it back.
547 546 """
548 547 if skip:
549 548 event.Skip()
550 549 self._keep_cursor_in_buffer()
551 550
552 551
553 552 # XXX: I need to avoid the problem of having an empty glass;
554 553 def _keep_cursor_in_buffer(self, pos=None):
555 554 """ Checks if the cursor is where it is allowed to be. If not,
556 555 put it back.
557 556
558 557 Returns
559 558 -------
560 559 cursor_moved: Boolean
561 560 whether or not the cursor was moved by this routine.
562 561
563 562 Notes
564 563 ------
565 564 WARNING: This does proper checks only for horizontal
566 565 movements.
567 566 """
568 567 if pos is None:
569 568 current_pos = self.GetCurrentPos()
570 569 else:
571 570 current_pos = pos
572 571 if current_pos < self.current_prompt_pos:
573 572 self.GotoPos(self.current_prompt_pos)
574 573 return True
575 574 line_num = self.LineFromPosition(current_pos)
576 575 if not current_pos > self.GetLength():
577 576 line_pos = self.GetColumn(current_pos)
578 577 else:
579 578 line_pos = self.GetColumn(self.GetLength())
580 579 line = self.GetLine(line_num)
581 580 # Jump the continuation prompt
582 581 continuation_prompt = self.continuation_prompt()
583 582 if ( line.startswith(continuation_prompt)
584 583 and line_pos < len(continuation_prompt)):
585 584 if line_pos < 2:
586 585 # We are at the beginning of the line, trying to move
587 586 # forward: jump forward.
588 587 self.GotoPos(current_pos + 1 +
589 588 len(continuation_prompt) - line_pos)
590 589 else:
591 590 # Jump back up
592 591 self.GotoPos(self.GetLineEndPosition(line_num-1))
593 592 return True
594 593 elif ( current_pos > self.GetLineEndPosition(line_num)
595 594 and not current_pos == self.GetLength()):
596 595 # Jump to next line
597 596 self.GotoPos(current_pos + 1 +
598 597 len(continuation_prompt))
599 598 return True
600 599
601 600 # We re-allow enter event processing
602 601 self.enter_catched = False
603 602 return False
604 603
605 604
606 605 if __name__ == '__main__':
607 606 # Some simple code to test the console widget.
608 607 class MainWindow(wx.Frame):
609 608 def __init__(self, parent, id, title):
610 609 wx.Frame.__init__(self, parent, id, title, size=(300, 250))
611 610 self._sizer = wx.BoxSizer(wx.VERTICAL)
612 611 self.console_widget = ConsoleWidget(self)
613 612 self._sizer.Add(self.console_widget, 1, wx.EXPAND)
614 613 self.SetSizer(self._sizer)
615 614 self.SetAutoLayout(1)
616 615 self.Show(True)
617 616
618 617 app = wx.PySimpleApp()
619 618 w = MainWindow(None, wx.ID_ANY, 'ConsoleWidget')
620 619 w.SetSize((780, 460))
621 620 w.Show()
622 621
623 622 app.MainLoop()
624 623
625 624
@@ -1,601 +1,602 b''
1 1 # encoding: utf-8 -*- test-case-name:
2 2 # FIXME: Need to add tests.
3 3 # ipython1.frontend.wx.tests.test_wx_frontend -*-
4 4
5 5 """Classes to provide a Wx frontend to the
6 6 IPython.kernel.core.interpreter.
7 7
8 8 This class inherits from ConsoleWidget, that provides a console-like
9 9 widget to provide a text-rendering widget suitable for a terminal.
10 10 """
11 11
12 12 __docformat__ = "restructuredtext en"
13 13
14 14 #-------------------------------------------------------------------------------
15 15 # Copyright (C) 2008 The IPython Development Team
16 16 #
17 17 # Distributed under the terms of the BSD License. The full license is in
18 18 # the file COPYING, distributed as part of this software.
19 19 #-------------------------------------------------------------------------------
20 20
21 21 #-------------------------------------------------------------------------------
22 22 # Imports
23 23 #-------------------------------------------------------------------------------
24 24
25 25 # Major library imports
26 26 import re
27 27 import __builtin__
28 28 import sys
29 29 from threading import Lock
30 30
31 31 import wx
32 32 from wx import stc
33 33
34 34 # Ipython-specific imports.
35 35 from IPython.frontend.process import PipedProcess
36 36 from console_widget import ConsoleWidget, _COMPLETE_BUFFER_MARKER, \
37 37 _ERROR_MARKER, _INPUT_MARKER
38 38 from IPython.frontend.prefilterfrontend import PrefilterFrontEnd
39 39
40 40 #-------------------------------------------------------------------------------
41 41 # Classes to implement the Wx frontend
42 42 #-------------------------------------------------------------------------------
43 43 class WxController(ConsoleWidget, PrefilterFrontEnd):
44 44 """Classes to provide a Wx frontend to the
45 45 IPython.kernel.core.interpreter.
46 46
47 47 This class inherits from ConsoleWidget, that provides a console-like
48 48 widget to provide a text-rendering widget suitable for a terminal.
49 49 """
50 50
51 51 # Print debug info on what is happening to the console.
52 52 debug = False
53 53
54 54 # The title of the terminal, as captured through the ANSI escape
55 55 # sequences.
56 56 def _set_title(self, title):
57 57 return self.Parent.SetTitle(title)
58 58
59 59 def _get_title(self):
60 60 return self.Parent.GetTitle()
61 61
62 62 title = property(_get_title, _set_title)
63 63
64 64
65 65 # The buffer being edited.
66 66 # We are duplicating the definition here because of multiple
67 67 # inheritence
68 68 def _set_input_buffer(self, string):
69 69 ConsoleWidget._set_input_buffer(self, string)
70 70 self._colorize_input_buffer()
71 71
72 72 def _get_input_buffer(self):
73 73 """ Returns the text in current edit buffer.
74 74 """
75 75 return ConsoleWidget._get_input_buffer(self)
76 76
77 77 input_buffer = property(_get_input_buffer, _set_input_buffer)
78 78
79 79
80 80 #--------------------------------------------------------------------------
81 81 # Private Attributes
82 82 #--------------------------------------------------------------------------
83 83
84 84 # A flag governing the behavior of the input. Can be:
85 85 #
86 86 # 'readline' for readline-like behavior with a prompt
87 87 # and an edit buffer.
88 88 # 'raw_input' similar to readline, but triggered by a raw-input
89 89 # call. Can be used by subclasses to act differently.
90 90 # 'subprocess' for sending the raw input directly to a
91 91 # subprocess.
92 92 # 'buffering' for buffering of the input, that will be used
93 93 # when the input state switches back to another state.
94 94 _input_state = 'readline'
95 95
96 96 # Attribute to store reference to the pipes of a subprocess, if we
97 97 # are running any.
98 98 _running_process = False
99 99
100 100 # A queue for writing fast streams to the screen without flooding the
101 101 # event loop
102 102 _out_buffer = []
103 103
104 104 # A lock to lock the _out_buffer to make sure we don't empty it
105 105 # while it is being swapped
106 106 _out_buffer_lock = Lock()
107 107
108 108 # The different line markers used to higlight the prompts.
109 109 _markers = dict()
110 110
111 111 #--------------------------------------------------------------------------
112 112 # Public API
113 113 #--------------------------------------------------------------------------
114 114
115 115 def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
116 116 size=wx.DefaultSize,
117 117 style=wx.CLIP_CHILDREN|wx.WANTS_CHARS,
118 118 styledef=None,
119 119 *args, **kwds):
120 120 """ Create Shell instance.
121 121
122 122 Parameters
123 123 -----------
124 124 styledef : dict, optional
125 125 styledef is the dictionary of options used to define the
126 126 style.
127 127 """
128 128 if styledef is not None:
129 129 self.style = styledef
130 130 ConsoleWidget.__init__(self, parent, id, pos, size, style)
131 131 PrefilterFrontEnd.__init__(self, **kwds)
132 132
133 133 # Stick in our own raw_input:
134 134 self.ipython0.raw_input = self.raw_input
135 135
136 136 # A time for flushing the write buffer
137 137 BUFFER_FLUSH_TIMER_ID = 100
138 138 self._buffer_flush_timer = wx.Timer(self, BUFFER_FLUSH_TIMER_ID)
139 139 wx.EVT_TIMER(self, BUFFER_FLUSH_TIMER_ID, self._buffer_flush)
140 140
141 141 if 'debug' in kwds:
142 142 self.debug = kwds['debug']
143 143 kwds.pop('debug')
144 144
145 145 # Inject self in namespace, for debug
146 146 if self.debug:
147 147 self.shell.user_ns['self'] = self
148 148 # Inject our own raw_input in namespace
149 149 self.shell.user_ns['raw_input'] = self.raw_input
150 150
151 151 def raw_input(self, prompt=''):
152 152 """ A replacement from python's raw_input.
153 153 """
154 154 self.new_prompt(prompt)
155 155 self._input_state = 'raw_input'
156 156 if hasattr(self, '_cursor'):
157 157 del self._cursor
158 158 self.SetCursor(wx.StockCursor(wx.CURSOR_CROSS))
159 159 self.__old_on_enter = self._on_enter
160 160 event_loop = wx.EventLoop()
161 161 def my_on_enter():
162 162 event_loop.Exit()
163 163 self._on_enter = my_on_enter
164 164 # XXX: Running a separate event_loop. Ugly.
165 165 event_loop.Run()
166 166 self._on_enter = self.__old_on_enter
167 167 self._input_state = 'buffering'
168 168 self._cursor = wx.BusyCursor()
169 169 return self.input_buffer.rstrip('\n')
170 170
171 171
172 172 def system_call(self, command_string):
173 173 self._input_state = 'subprocess'
174 174 event_loop = wx.EventLoop()
175 175 def _end_system_call():
176 176 self._input_state = 'buffering'
177 177 self._running_process = False
178 178 event_loop.Exit()
179 179
180 180 self._running_process = PipedProcess(command_string,
181 181 out_callback=self.buffered_write,
182 182 end_callback = _end_system_call)
183 183 self._running_process.start()
184 184 # XXX: Running a separate event_loop. Ugly.
185 185 event_loop.Run()
186 186 # Be sure to flush the buffer.
187 187 self._buffer_flush(event=None)
188 188
189 189
190 190 def do_calltip(self):
191 191 """ Analyse current and displays useful calltip for it.
192 192 """
193 193 if self.debug:
194 194 print >>sys.__stdout__, "do_calltip"
195 195 separators = re.compile('[\s\{\}\[\]\(\)\= ,:]')
196 196 symbol = self.input_buffer
197 197 symbol_string = separators.split(symbol)[-1]
198 198 base_symbol_string = symbol_string.split('.')[0]
199 199 if base_symbol_string in self.shell.user_ns:
200 200 symbol = self.shell.user_ns[base_symbol_string]
201 201 elif base_symbol_string in self.shell.user_global_ns:
202 202 symbol = self.shell.user_global_ns[base_symbol_string]
203 203 elif base_symbol_string in __builtin__.__dict__:
204 204 symbol = __builtin__.__dict__[base_symbol_string]
205 205 else:
206 206 return False
207 207 try:
208 208 for name in symbol_string.split('.')[1:] + ['__doc__']:
209 209 symbol = getattr(symbol, name)
210 210 self.AutoCompCancel()
211 211 # Check that the symbol can indeed be converted to a string:
212 212 symbol += ''
213 213 wx.CallAfter(self.CallTipShow, self.GetCurrentPos(), symbol)
214 214 except:
215 215 # The retrieve symbol couldn't be converted to a string
216 216 pass
217 217
218 218
219 219 def _popup_completion(self, create=False):
220 220 """ Updates the popup completion menu if it exists. If create is
221 221 true, open the menu.
222 222 """
223 223 if self.debug:
224 224 print >>sys.__stdout__, "_popup_completion"
225 225 line = self.input_buffer
226 226 if (self.AutoCompActive() and line and not line[-1] == '.') \
227 227 or create==True:
228 228 suggestion, completions = self.complete(line)
229 229 if completions:
230 230 offset = len(self._get_completion_text(line))
231 231 self.pop_completion(completions, offset=offset)
232 232 if self.debug:
233 233 print >>sys.__stdout__, completions
234 234
235 235
236 236 def buffered_write(self, text):
237 237 """ A write method for streams, that caches the stream in order
238 238 to avoid flooding the event loop.
239 239
240 240 This can be called outside of the main loop, in separate
241 241 threads.
242 242 """
243 243 self._out_buffer_lock.acquire()
244 244 self._out_buffer.append(text)
245 245 self._out_buffer_lock.release()
246 246 if not self._buffer_flush_timer.IsRunning():
247 247 wx.CallAfter(self._buffer_flush_timer.Start,
248 248 milliseconds=100, oneShot=True)
249 249
250 250
251 251 def clear_screen(self):
252 252 """ Empty completely the widget.
253 253 """
254 254 self.ClearAll()
255 255 self.new_prompt(self.input_prompt_template.substitute(
256 256 number=(self.last_result['number'] + 1)))
257 257
258 258
259 259 #--------------------------------------------------------------------------
260 260 # LineFrontEnd interface
261 261 #--------------------------------------------------------------------------
262 262
263 263 def execute(self, python_string, raw_string=None):
264 264 self._input_state = 'buffering'
265 265 self.CallTipCancel()
266 266 self._cursor = wx.BusyCursor()
267 267 if raw_string is None:
268 268 raw_string = python_string
269 269 end_line = self.current_prompt_line \
270 270 + max(1, len(raw_string.split('\n'))-1)
271 271 for i in range(self.current_prompt_line, end_line):
272 272 if i in self._markers:
273 273 self.MarkerDeleteHandle(self._markers[i])
274 274 self._markers[i] = self.MarkerAdd(i, _COMPLETE_BUFFER_MARKER)
275 275 # Use a callafter to update the display robustly under windows
276 276 def callback():
277 277 self.GotoPos(self.GetLength())
278 278 PrefilterFrontEnd.execute(self, python_string,
279 279 raw_string=raw_string)
280 280 wx.CallAfter(callback)
281 281
282 282
283 283 def execute_command(self, command, hidden=False):
284 284 """ Execute a command, not only in the model, but also in the
285 285 view.
286 286 """
287 287 # XXX: This method needs to be integrated in the base fronted
288 288 # interface
289 289 if hidden:
290 290 return self.shell.execute(command)
291 291 else:
292 292 # XXX: we are not storing the input buffer previous to the
293 293 # execution, as this forces us to run the execution
294 294 # input_buffer a yield, which is not good.
295 295 ##current_buffer = self.shell.control.input_buffer
296 296 command = command.rstrip()
297 297 if len(command.split('\n')) > 1:
298 298 # The input command is several lines long, we need to
299 299 # force the execution to happen
300 300 command += '\n'
301 301 cleaned_command = self.prefilter_input(command)
302 302 self.input_buffer = command
303 303 # Do not use wx.Yield() (aka GUI.process_events()) to avoid
304 304 # recursive yields.
305 305 self.ProcessEvent(wx.PaintEvent())
306 306 self.write('\n')
307 307 if not self.is_complete(cleaned_command + '\n'):
308 308 self._colorize_input_buffer()
309 309 self.render_error('Incomplete or invalid input')
310 310 self.new_prompt(self.input_prompt_template.substitute(
311 311 number=(self.last_result['number'] + 1)))
312 312 return False
313 313 self._on_enter()
314 314 return True
315 315
316 316
317 317 def save_output_hooks(self):
318 318 self.__old_raw_input = __builtin__.raw_input
319 319 PrefilterFrontEnd.save_output_hooks(self)
320 320
321 321 def capture_output(self):
322 322 self.SetLexer(stc.STC_LEX_NULL)
323 323 PrefilterFrontEnd.capture_output(self)
324 324 __builtin__.raw_input = self.raw_input
325 325
326 326
327 327 def release_output(self):
328 328 __builtin__.raw_input = self.__old_raw_input
329 329 PrefilterFrontEnd.release_output(self)
330 330 self.SetLexer(stc.STC_LEX_PYTHON)
331 331
332 332
333 333 def after_execute(self):
334 334 PrefilterFrontEnd.after_execute(self)
335 335 # Clear the wait cursor
336 336 if hasattr(self, '_cursor'):
337 337 del self._cursor
338 338 self.SetCursor(wx.StockCursor(wx.CURSOR_CHAR))
339 339
340 340
341 341 def show_traceback(self):
342 342 start_line = self.GetCurrentLine()
343 343 PrefilterFrontEnd.show_traceback(self)
344 344 self.ProcessEvent(wx.PaintEvent())
345 345 #wx.Yield()
346 346 for i in range(start_line, self.GetCurrentLine()):
347 347 self._markers[i] = self.MarkerAdd(i, _ERROR_MARKER)
348 348
349 349
350 350 #--------------------------------------------------------------------------
351 351 # FrontEndBase interface
352 352 #--------------------------------------------------------------------------
353 353
354 354 def render_error(self, e):
355 355 start_line = self.GetCurrentLine()
356 356 self.write('\n' + e + '\n')
357 357 for i in range(start_line, self.GetCurrentLine()):
358 358 self._markers[i] = self.MarkerAdd(i, _ERROR_MARKER)
359 359
360 360
361 361 #--------------------------------------------------------------------------
362 362 # ConsoleWidget interface
363 363 #--------------------------------------------------------------------------
364 364
365 365 def new_prompt(self, prompt):
366 366 """ Display a new prompt, and start a new input buffer.
367 367 """
368 368 self._input_state = 'readline'
369 369 ConsoleWidget.new_prompt(self, prompt)
370 370 i = self.current_prompt_line
371 371 self._markers[i] = self.MarkerAdd(i, _INPUT_MARKER)
372 372
373 373
374 374 def continuation_prompt(self, *args, **kwargs):
375 375 # Avoid multiple inheritence, be explicit about which
376 376 # parent method class gets called
377 377 return ConsoleWidget.continuation_prompt(self, *args, **kwargs)
378 378
379 379
380 380 def write(self, *args, **kwargs):
381 381 # Avoid multiple inheritence, be explicit about which
382 382 # parent method class gets called
383 383 return ConsoleWidget.write(self, *args, **kwargs)
384 384
385 385
386 386 def _on_key_down(self, event, skip=True):
387 387 """ Capture the character events, let the parent
388 388 widget handle them, and put our logic afterward.
389 389 """
390 390 # FIXME: This method needs to be broken down in smaller ones.
391 391 current_line_num = self.GetCurrentLine()
392 if event.KeyCode in (ord('c'), ord('C')) and event.ControlDown():
392 key_code = event.GetKeyCode()
393 if key_code in (ord('c'), ord('C')) and event.ControlDown():
393 394 # Capture Control-C
394 395 if self._input_state == 'subprocess':
395 396 if self.debug:
396 397 print >>sys.__stderr__, 'Killing running process'
397 398 if hasattr(self._running_process, 'process'):
398 399 self._running_process.process.kill()
399 400 elif self._input_state == 'buffering':
400 401 if self.debug:
401 402 print >>sys.__stderr__, 'Raising KeyboardInterrupt'
402 403 raise KeyboardInterrupt
403 404 # XXX: We need to make really sure we
404 405 # get back to a prompt.
405 406 elif self._input_state == 'subprocess' and (
406 ( event.KeyCode<256 and
407 not event.ControlDown() )
407 ( key_code <256 and not event.ControlDown() )
408 408 or
409 ( event.KeyCode in (ord('d'), ord('D')) and
409 ( key_code in (ord('d'), ord('D')) and
410 410 event.ControlDown())):
411 411 # We are running a process, we redirect keys.
412 412 ConsoleWidget._on_key_down(self, event, skip=skip)
413 char = chr(event.KeyCode)
413 char = chr(key_code)
414 414 # Deal with some inconsistency in wx keycodes:
415 415 if char == '\r':
416 416 char = '\n'
417 417 elif not event.ShiftDown():
418 418 char = char.lower()
419 if event.ControlDown() and event.KeyCode in (ord('d'), ord('D')):
419 if event.ControlDown() and key_code in (ord('d'), ord('D')):
420 420 char = '\04'
421 421 self._running_process.process.stdin.write(char)
422 422 self._running_process.process.stdin.flush()
423 elif event.KeyCode in (ord('('), 57, 53):
423 elif key_code in (ord('('), 57, 53):
424 424 # Calltips
425 425 event.Skip()
426 426 self.do_calltip()
427 elif self.AutoCompActive() and not event.KeyCode == ord('\t'):
427 elif self.AutoCompActive() and not key_code == ord('\t'):
428 428 event.Skip()
429 if event.KeyCode in (wx.WXK_BACK, wx.WXK_DELETE):
429 if key_code in (wx.WXK_BACK, wx.WXK_DELETE):
430 430 wx.CallAfter(self._popup_completion, create=True)
431 elif not event.KeyCode in (wx.WXK_UP, wx.WXK_DOWN, wx.WXK_LEFT,
431 elif not key_code in (wx.WXK_UP, wx.WXK_DOWN, wx.WXK_LEFT,
432 432 wx.WXK_RIGHT, wx.WXK_ESCAPE):
433 433 wx.CallAfter(self._popup_completion)
434 434 else:
435 435 # Up history
436 if event.KeyCode == wx.WXK_UP and (
437 ( current_line_num == self.current_prompt_line and
438 event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN) )
439 or event.ControlDown() ):
436 if key_code == wx.WXK_UP and (
437 event.ControlDown() or
438 current_line_num == self.current_prompt_line
439 ):
440 440 new_buffer = self.get_history_previous(
441 441 self.input_buffer)
442 442 if new_buffer is not None:
443 443 self.input_buffer = new_buffer
444 444 if self.GetCurrentLine() > self.current_prompt_line:
445 445 # Go to first line, for seemless history up.
446 446 self.GotoPos(self.current_prompt_pos)
447 447 # Down history
448 elif event.KeyCode == wx.WXK_DOWN and (
449 ( current_line_num == self.LineCount -1 and
450 event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN) )
451 or event.ControlDown() ):
448 elif key_code == wx.WXK_DOWN and (
449 event.ControlDown() or
450 current_line_num == self.LineCount -1
451 ):
452 452 new_buffer = self.get_history_next()
453 453 if new_buffer is not None:
454 454 self.input_buffer = new_buffer
455 455 # Tab-completion
456 elif event.KeyCode == ord('\t'):
456 elif key_code == ord('\t'):
457 457 current_line, current_line_num = self.CurLine
458 if not re.match(r'^\s*$', current_line):
458 if not re.match(r'^%s\s*$' % self.continuation_prompt(),
459 current_line):
459 460 self.complete_current_input()
460 461 if self.AutoCompActive():
461 462 wx.CallAfter(self._popup_completion, create=True)
462 463 else:
463 464 event.Skip()
464 elif event.KeyCode == wx.WXK_BACK:
465 elif key_code == wx.WXK_BACK:
465 466 # If characters where erased, check if we have to
466 467 # remove a line.
467 468 # XXX: What about DEL?
468 469 # FIXME: This logics should be in ConsoleWidget, as it is
469 470 # independant of IPython
470 471 current_line, _ = self.CurLine
471 472 current_pos = self.GetCurrentPos()
472 473 current_line_num = self.LineFromPosition(current_pos)
473 474 current_col = self.GetColumn(current_pos)
474 475 len_prompt = len(self.continuation_prompt())
475 476 if ( current_line.startswith(self.continuation_prompt())
476 477 and current_col == len_prompt):
477 478 new_lines = []
478 479 for line_num, line in enumerate(
479 480 self.input_buffer.split('\n')):
480 481 if (line_num + self.current_prompt_line ==
481 482 current_line_num):
482 483 new_lines.append(line[len_prompt:])
483 484 else:
484 485 new_lines.append('\n'+line)
485 486 # The first character is '\n', due to the above
486 487 # code:
487 488 self.input_buffer = ''.join(new_lines)[1:]
488 489 self.GotoPos(current_pos - 1 - len_prompt)
489 490 else:
490 491 ConsoleWidget._on_key_down(self, event, skip=skip)
491 492 else:
492 493 ConsoleWidget._on_key_down(self, event, skip=skip)
493 494
494 495
495 496
496 497 def _on_key_up(self, event, skip=True):
497 498 """ Called when any key is released.
498 499 """
499 if event.KeyCode in (59, ord('.')):
500 if event.GetKeyCode() in (59, ord('.')):
500 501 # Intercepting '.'
501 502 event.Skip()
502 503 wx.CallAfter(self._popup_completion, create=True)
503 504 else:
504 505 ConsoleWidget._on_key_up(self, event, skip=skip)
505 506 # Make sure the continuation_prompts are always followed by a
506 507 # whitespace
507 508 new_lines = []
508 509 if self._input_state == 'readline':
509 510 position = self.GetCurrentPos()
510 511 continuation_prompt = self.continuation_prompt()[:-1]
511 512 for line in self.input_buffer.split('\n'):
512 513 if not line == continuation_prompt:
513 514 new_lines.append(line)
514 515 self.input_buffer = '\n'.join(new_lines)
515 516 self.GotoPos(position)
516 517
517 518
518 519 def _on_enter(self):
519 520 """ Called on return key down, in readline input_state.
520 521 """
521 522 last_line_num = self.LineFromPosition(self.GetLength())
522 523 current_line_num = self.LineFromPosition(self.GetCurrentPos())
523 524 new_line_pos = (last_line_num - current_line_num)
524 525 if self.debug:
525 526 print >>sys.__stdout__, repr(self.input_buffer)
526 527 self.write('\n', refresh=False)
527 528 # Under windows scintilla seems to be doing funny
528 529 # stuff to the line returns here, but the getter for
529 530 # input_buffer filters this out.
530 531 if sys.platform == 'win32':
531 532 self.input_buffer = self.input_buffer
532 533 old_prompt_num = self.current_prompt_pos
533 534 has_executed = PrefilterFrontEnd._on_enter(self,
534 535 new_line_pos=new_line_pos)
535 536 if old_prompt_num == self.current_prompt_pos:
536 537 # No execution has happened
537 538 self.GotoPos(self.GetLineEndPosition(current_line_num + 1))
538 539 return has_executed
539 540
540 541
541 542 #--------------------------------------------------------------------------
542 543 # EditWindow API
543 544 #--------------------------------------------------------------------------
544 545
545 546 def OnUpdateUI(self, event):
546 547 """ Override the OnUpdateUI of the EditWindow class, to prevent
547 548 syntax highlighting both for faster redraw, and for more
548 549 consistent look and feel.
549 550 """
550 551 if not self._input_state == 'readline':
551 552 ConsoleWidget.OnUpdateUI(self, event)
552 553
553 554 #--------------------------------------------------------------------------
554 555 # Private API
555 556 #--------------------------------------------------------------------------
556 557
557 558 def _buffer_flush(self, event):
558 559 """ Called by the timer to flush the write buffer.
559 560
560 561 This is always called in the mainloop, by the wx timer.
561 562 """
562 563 self._out_buffer_lock.acquire()
563 564 _out_buffer = self._out_buffer
564 565 self._out_buffer = []
565 566 self._out_buffer_lock.release()
566 567 self.write(''.join(_out_buffer), refresh=False)
567 568
568 569
569 570 def _colorize_input_buffer(self):
570 571 """ Keep the input buffer lines at a bright color.
571 572 """
572 573 if not self._input_state in ('readline', 'raw_input'):
573 574 return
574 575 end_line = self.GetCurrentLine()
575 576 if not sys.platform == 'win32':
576 577 end_line += 1
577 578 for i in range(self.current_prompt_line, end_line):
578 579 if i in self._markers:
579 580 self.MarkerDeleteHandle(self._markers[i])
580 581 self._markers[i] = self.MarkerAdd(i, _INPUT_MARKER)
581 582
582 583
583 584 if __name__ == '__main__':
584 585 class MainWindow(wx.Frame):
585 586 def __init__(self, parent, id, title):
586 587 wx.Frame.__init__(self, parent, id, title, size=(300,250))
587 588 self._sizer = wx.BoxSizer(wx.VERTICAL)
588 589 self.shell = WxController(self)
589 590 self._sizer.Add(self.shell, 1, wx.EXPAND)
590 591 self.SetSizer(self._sizer)
591 592 self.SetAutoLayout(1)
592 593 self.Show(True)
593 594
594 595 app = wx.PySimpleApp()
595 596 frame = MainWindow(None, wx.ID_ANY, 'Ipython')
596 597 frame.shell.SetFocus()
597 598 frame.SetSize((680, 460))
598 599 self = frame.shell
599 600
600 601 app.MainLoop()
601 602
1 NO CONTENT: modified file
1 NO CONTENT: modified file chmod 100755 => 100644, modified file
@@ -1,141 +1,141 b''
1 1 # encoding: utf-8
2 2 # -*- test-case-name: IPython.kernel.test.test_contexts -*-
3 3 """Context managers for IPython.
4 4
5 5 Python 2.5 introduced the `with` statement, which is based on the context
6 6 manager protocol. This module offers a few context managers for common cases,
7 7 which can also be useful as templates for writing new, application-specific
8 8 managers.
9 9 """
10 10
11 11 __docformat__ = "restructuredtext en"
12 12
13 13 #-------------------------------------------------------------------------------
14 14 # Copyright (C) 2008 The IPython Development Team
15 15 #
16 16 # Distributed under the terms of the BSD License. The full license is in
17 17 # the file COPYING, distributed as part of this software.
18 18 #-------------------------------------------------------------------------------
19 19
20 20 #-------------------------------------------------------------------------------
21 21 # Imports
22 22 #-------------------------------------------------------------------------------
23 23
24 24 import linecache
25 25 import sys
26 26
27 27 from twisted.internet.error import ConnectionRefusedError
28 28
29 from IPython.ultraTB import _fixed_getinnerframes, findsource
29 from IPython.core.ultratb import _fixed_getinnerframes, findsource
30 30 from IPython.core import ipapi
31 31
32 32 from IPython.kernel import error
33 33
34 34 #---------------------------------------------------------------------------
35 35 # Utility functions needed by all context managers.
36 36 #---------------------------------------------------------------------------
37 37
38 38 def remote():
39 39 """Raises a special exception meant to be caught by context managers.
40 40 """
41 41 m = 'Special exception to stop local execution of parallel code.'
42 42 raise error.StopLocalExecution(m)
43 43
44 44
45 45 def strip_whitespace(source,require_remote=True):
46 46 """strip leading whitespace from input source.
47 47
48 48 :Parameters:
49 49
50 50 """
51 51 remote_mark = 'remote()'
52 52 # Expand tabs to avoid any confusion.
53 53 wsource = [l.expandtabs(4) for l in source]
54 54 # Detect the indentation level
55 55 done = False
56 56 for line in wsource:
57 57 if line.isspace():
58 58 continue
59 59 for col,char in enumerate(line):
60 60 if char != ' ':
61 61 done = True
62 62 break
63 63 if done:
64 64 break
65 65 # Now we know how much leading space there is in the code. Next, we
66 66 # extract up to the first line that has less indentation.
67 67 # WARNINGS: we skip comments that may be misindented, but we do NOT yet
68 68 # detect triple quoted strings that may have flush left text.
69 69 for lno,line in enumerate(wsource):
70 70 lead = line[:col]
71 71 if lead.isspace():
72 72 continue
73 73 else:
74 74 if not lead.lstrip().startswith('#'):
75 75 break
76 76 # The real 'with' source is up to lno
77 77 src_lines = [l[col:] for l in wsource[:lno+1]]
78 78
79 79 # Finally, check that the source's first non-comment line begins with the
80 80 # special call 'remote()'
81 81 if require_remote:
82 82 for nline,line in enumerate(src_lines):
83 83 if line.isspace() or line.startswith('#'):
84 84 continue
85 85 if line.startswith(remote_mark):
86 86 break
87 87 else:
88 88 raise ValueError('%s call missing at the start of code' %
89 89 remote_mark)
90 90 out_lines = src_lines[nline+1:]
91 91 else:
92 92 # If the user specified that the remote() call wasn't mandatory
93 93 out_lines = src_lines
94 94
95 95 # src = ''.join(out_lines) # dbg
96 96 #print 'SRC:\n<<<<<<<>>>>>>>\n%s<<<<<>>>>>>' % src # dbg
97 97 return ''.join(out_lines)
98 98
99 99 class RemoteContextBase(object):
100 100 def __init__(self):
101 101 self.ip = ipapi.get()
102 102
103 103 def _findsource_file(self,f):
104 104 linecache.checkcache()
105 105 s = findsource(f.f_code)
106 106 lnum = f.f_lineno
107 107 wsource = s[0][f.f_lineno:]
108 108 return strip_whitespace(wsource)
109 109
110 110 def _findsource_ipython(self,f):
111 111 from IPython.core import ipapi
112 112 self.ip = ipapi.get()
113 113 buf = self.ip.IP.input_hist_raw[-1].splitlines()[1:]
114 114 wsource = [l+'\n' for l in buf ]
115 115
116 116 return strip_whitespace(wsource)
117 117
118 118 def findsource(self,frame):
119 119 local_ns = frame.f_locals
120 120 global_ns = frame.f_globals
121 121 if frame.f_code.co_filename == '<ipython console>':
122 122 src = self._findsource_ipython(frame)
123 123 else:
124 124 src = self._findsource_file(frame)
125 125 return src
126 126
127 127 def __enter__(self):
128 128 raise NotImplementedError
129 129
130 130 def __exit__ (self, etype, value, tb):
131 131 if issubclass(etype,error.StopLocalExecution):
132 132 return True
133 133
134 134 class RemoteMultiEngine(RemoteContextBase):
135 135 def __init__(self,mec):
136 136 self.mec = mec
137 137 RemoteContextBase.__init__(self)
138 138
139 139 def __enter__(self):
140 140 src = self.findsource(sys._getframe(1))
141 141 return self.mec.execute(src)
@@ -1,761 +1,761 b''
1 1 # encoding: utf-8
2 2
3 3 """Central interpreter object for an IPython engine.
4 4
5 5 The interpreter is the object whose job is to process lines of user input and
6 6 actually execute them in the user's namespace.
7 7 """
8 8
9 9 __docformat__ = "restructuredtext en"
10 10
11 11 #-------------------------------------------------------------------------------
12 12 # Copyright (C) 2008 The IPython Development Team
13 13 #
14 14 # Distributed under the terms of the BSD License. The full license is in
15 15 # the file COPYING, distributed as part of this software.
16 16 #-------------------------------------------------------------------------------
17 17
18 18 #-------------------------------------------------------------------------------
19 19 # Imports
20 20 #-------------------------------------------------------------------------------
21 21
22 22 # Standard library imports.
23 23 from types import FunctionType
24 24
25 25 import __builtin__
26 26 import codeop
27 27 import compiler
28 28 import sys
29 29 import traceback
30 30
31 31 # Local imports.
32 from IPython.kernel.core import ultraTB
32 from IPython.core import ultratb
33 33 from IPython.kernel.core.display_trap import DisplayTrap
34 34 from IPython.kernel.core.macro import Macro
35 35 from IPython.kernel.core.prompts import CachedOutput
36 36 from IPython.kernel.core.traceback_trap import TracebackTrap
37 37 from IPython.kernel.core.util import Bunch, system_shell
38 38 from IPython.external.Itpl import ItplNS
39 39
40 40 # Global constants
41 41 COMPILER_ERROR = 'error'
42 42 INCOMPLETE_INPUT = 'incomplete'
43 43 COMPLETE_INPUT = 'complete'
44 44
45 45 ##############################################################################
46 46 # TEMPORARY!!! fake configuration, while we decide whether to use tconfig or
47 47 # not
48 48
49 49 rc = Bunch()
50 50 rc.cache_size = 100
51 51 rc.pprint = True
52 52 rc.separate_in = '\n'
53 53 rc.separate_out = '\n'
54 54 rc.separate_out2 = ''
55 55 rc.prompt_in1 = r'In [\#]: '
56 56 rc.prompt_in2 = r' .\\D.: '
57 57 rc.prompt_out = ''
58 58 rc.prompts_pad_left = False
59 59
60 60 ##############################################################################
61 61
62 62 # Top-level utilities
63 63 def default_display_formatters():
64 64 """ Return a list of default display formatters.
65 65 """
66 66
67 67 from display_formatter import PPrintDisplayFormatter, ReprDisplayFormatter
68 68 return [PPrintDisplayFormatter(), ReprDisplayFormatter()]
69 69
70 70 def default_traceback_formatters():
71 71 """ Return a list of default traceback formatters.
72 72 """
73 73
74 74 from traceback_formatter import PlainTracebackFormatter
75 75 return [PlainTracebackFormatter()]
76 76
77 77 # Top-level classes
78 78 class NotDefined(object): pass
79 79
80 80 class Interpreter(object):
81 81 """ An interpreter object.
82 82
83 83 fixme: needs to negotiate available formatters with frontends.
84 84
85 85 Important: the interpeter should be built so that it exposes a method
86 86 for each attribute/method of its sub-object. This way it can be
87 87 replaced by a network adapter.
88 88 """
89 89
90 90 def __init__(self, user_ns=None, global_ns=None,translator=None,
91 91 magic=None, display_formatters=None,
92 92 traceback_formatters=None, output_trap=None, history=None,
93 93 message_cache=None, filename='<string>', config=None):
94 94
95 95 # The local/global namespaces for code execution
96 96 local_ns = user_ns # compatibility name
97 97 if local_ns is None:
98 98 local_ns = {}
99 99 self.user_ns = local_ns
100 100 # The local namespace
101 101 if global_ns is None:
102 102 global_ns = {}
103 103 self.user_global_ns = global_ns
104 104
105 105 # An object that will translate commands into executable Python.
106 106 # The current translator does not work properly so for now we are going
107 107 # without!
108 108 # if translator is None:
109 109 # from IPython.kernel.core.translator import IPythonTranslator
110 110 # translator = IPythonTranslator()
111 111 self.translator = translator
112 112
113 113 # An object that maintains magic commands.
114 114 if magic is None:
115 115 from IPython.kernel.core.magic import Magic
116 116 magic = Magic(self)
117 117 self.magic = magic
118 118
119 119 # A list of formatters for the displayhook.
120 120 if display_formatters is None:
121 121 display_formatters = default_display_formatters()
122 122 self.display_formatters = display_formatters
123 123
124 124 # A list of formatters for tracebacks.
125 125 if traceback_formatters is None:
126 126 traceback_formatters = default_traceback_formatters()
127 127 self.traceback_formatters = traceback_formatters
128 128
129 129 # The object trapping stdout/stderr.
130 130 if output_trap is None:
131 131 from IPython.kernel.core.output_trap import OutputTrap
132 132 output_trap = OutputTrap()
133 133 self.output_trap = output_trap
134 134
135 135 # An object that manages the history.
136 136 if history is None:
137 137 from IPython.kernel.core.history import InterpreterHistory
138 138 history = InterpreterHistory()
139 139 self.history = history
140 140 self.get_history_item = history.get_history_item
141 141 self.get_history_input_cache = history.get_input_cache
142 142 self.get_history_input_after = history.get_input_after
143 143
144 144 # An object that caches all of the return messages.
145 145 if message_cache is None:
146 146 from IPython.kernel.core.message_cache import SimpleMessageCache
147 147 message_cache = SimpleMessageCache()
148 148 self.message_cache = message_cache
149 149
150 150 # The "filename" of the code that is executed in this interpreter.
151 151 self.filename = filename
152 152
153 153 # An object that contains much configuration information.
154 154 if config is None:
155 155 # fixme: Move this constant elsewhere!
156 156 config = Bunch(ESC_MAGIC='%')
157 157 self.config = config
158 158
159 159 # Hook managers.
160 160 # fixme: make the display callbacks configurable. In the meantime,
161 161 # enable macros.
162 162 self.display_trap = DisplayTrap(
163 163 formatters=self.display_formatters,
164 164 callbacks=[self._possible_macro],
165 165 )
166 166 self.traceback_trap = TracebackTrap(
167 167 formatters=self.traceback_formatters)
168 168
169 169 # This is used temporarily for reformating exceptions in certain
170 # cases. It will go away once the ultraTB stuff is ported
170 # cases. It will go away once the ultratb stuff is ported
171 171 # to ipython1
172 self.tbHandler = ultraTB.FormattedTB(color_scheme='NoColor',
172 self.tbHandler = ultratb.FormattedTB(color_scheme='NoColor',
173 173 mode='Context',
174 174 tb_offset=2)
175 175
176 176 # An object that can compile commands and remember __future__
177 177 # statements.
178 178 self.command_compiler = codeop.CommandCompiler()
179 179
180 180 # A replacement for the raw_input() and input() builtins. Change these
181 181 # attributes later to configure them.
182 182 self.raw_input_builtin = raw_input
183 183 self.input_builtin = input
184 184
185 185 # The number of the current cell.
186 186 self.current_cell_number = 1
187 187
188 188 # Initialize cache, set in/out prompts and printing system
189 189 self.outputcache = CachedOutput(self,
190 190 rc.cache_size,
191 191 rc.pprint,
192 192 input_sep = rc.separate_in,
193 193 output_sep = rc.separate_out,
194 194 output_sep2 = rc.separate_out2,
195 195 ps1 = rc.prompt_in1,
196 196 ps2 = rc.prompt_in2,
197 197 ps_out = rc.prompt_out,
198 198 pad_left = rc.prompts_pad_left)
199 199
200 200 # Need to decide later if this is the right approach, but clients
201 201 # commonly use sys.ps1/2, so it may be best to just set them here
202 202 sys.ps1 = self.outputcache.prompt1.p_str
203 203 sys.ps2 = self.outputcache.prompt2.p_str
204 204
205 205 # This is the message dictionary assigned temporarily when running the
206 206 # code.
207 207 self.message = None
208 208
209 209 self.setup_namespace()
210 210
211 211
212 212 #### Public 'Interpreter' interface ########################################
213 213
214 214 def formatTraceback(self, et, ev, tb, message=''):
215 215 """Put a formatted version of the traceback into value and reraise.
216 216
217 217 When exceptions have to be sent over the network, the traceback
218 218 needs to be put into the value of the exception in a nicely
219 219 formatted way. The method takes the type, value and tb of an
220 220 exception and puts a string representation of the tb into the
221 221 value of the exception and reraises it.
222 222
223 223 Currently this method uses the ultraTb formatter from IPython trunk.
224 224 Eventually it should simply use the traceback formatters in core
225 225 that are loaded into self.tracback_trap.formatters.
226 226 """
227 227 tbinfo = self.tbHandler.text(et,ev,tb)
228 228 ev._ipython_traceback_text = tbinfo
229 229 return et, ev, tb
230 230
231 231 def execute(self, commands, raiseException=True):
232 232 """ Execute some IPython commands.
233 233
234 234 1. Translate them into Python.
235 235 2. Run them.
236 236 3. Trap stdout/stderr.
237 237 4. Trap sys.displayhook().
238 238 5. Trap exceptions.
239 239 6. Return a message object.
240 240
241 241 Parameters
242 242 ----------
243 243 commands : str
244 244 The raw commands that the user typed into the prompt.
245 245
246 246 Returns
247 247 -------
248 248 message : dict
249 249 The dictionary of responses. See the README.txt in this directory
250 250 for an explanation of the format.
251 251 """
252 252
253 253 # Create a message dictionary with all of the information we will be
254 254 # returning to the frontend and other listeners.
255 255 message = self.setup_message()
256 256
257 257 # Massage the input and store the raw and translated commands into
258 258 # a dict.
259 259 user_input = dict(raw=commands)
260 260 if self.translator is not None:
261 261 python = self.translator(commands, message)
262 262 if python is None:
263 263 # Something went wrong with the translation. The translator
264 264 # should have added an appropriate entry to the message object.
265 265 return message
266 266 else:
267 267 python = commands
268 268 user_input['translated'] = python
269 269 message['input'] = user_input
270 270
271 271 # Set the message object so that any magics executed in the code have
272 272 # access.
273 273 self.message = message
274 274
275 275 # Set all of the output/exception traps.
276 276 self.set_traps()
277 277
278 278 # Actually execute the Python code.
279 279 status = self.execute_python(python)
280 280
281 281 # Unset all of the traps.
282 282 self.unset_traps()
283 283
284 284 # Unset the message object.
285 285 self.message = None
286 286
287 287 # Update the history variables in the namespace.
288 288 # E.g. In, Out, _, __, ___
289 289 if self.history is not None:
290 290 self.history.update_history(self, python)
291 291
292 292 # Let all of the traps contribute to the message and then clear their
293 293 # stored information.
294 294 self.output_trap.add_to_message(message)
295 295 self.output_trap.clear()
296 296 self.display_trap.add_to_message(message)
297 297 self.display_trap.clear()
298 298 self.traceback_trap.add_to_message(message)
299 299 # Pull out the type, value and tb of the current exception
300 300 # before clearing it.
301 301 einfo = self.traceback_trap.args
302 302 self.traceback_trap.clear()
303 303
304 304 # Cache the message.
305 305 self.message_cache.add_message(self.current_cell_number, message)
306 306
307 307 # Bump the number.
308 308 self.current_cell_number += 1
309 309
310 310 # This conditional lets the execute method either raise any
311 311 # exception that has occured in user code OR return the message
312 312 # dict containing the traceback and other useful info.
313 313 if raiseException and einfo:
314 314 raise einfo[0],einfo[1],einfo[2]
315 315 else:
316 316 return message
317 317
318 318 def generate_prompt(self, is_continuation):
319 319 """Calculate and return a string with the prompt to display.
320 320
321 321 :Parameters:
322 322 is_continuation : bool
323 323 Whether the input line is continuing multiline input or not, so
324 324 that a proper continuation prompt can be computed."""
325 325
326 326 if is_continuation:
327 327 return str(self.outputcache.prompt2)
328 328 else:
329 329 return str(self.outputcache.prompt1)
330 330
331 331 def execute_python(self, python):
332 332 """ Actually run the Python code in the namespace.
333 333
334 334 :Parameters:
335 335
336 336 python : str
337 337 Pure, exec'able Python code. Special IPython commands should have
338 338 already been translated into pure Python.
339 339 """
340 340
341 341 # We use a CommandCompiler instance to compile the code so as to keep
342 342 # track of __future__ imports.
343 343 try:
344 344 commands = self.split_commands(python)
345 345 except (SyntaxError, IndentationError), e:
346 346 # Save the exc_info so compilation related exceptions can be
347 347 # reraised
348 348 self.traceback_trap.args = sys.exc_info()
349 349 self.pack_exception(self.message,e)
350 350 return None
351 351
352 352 for cmd in commands:
353 353 try:
354 354 code = self.command_compiler(cmd, self.filename, 'single')
355 355 except (SyntaxError, OverflowError, ValueError), e:
356 356 self.traceback_trap.args = sys.exc_info()
357 357 self.pack_exception(self.message,e)
358 358 # No point in continuing if one block raised
359 359 return None
360 360 else:
361 361 self.execute_block(code)
362 362
363 363 def execute_block(self,code):
364 364 """Execute a single block of code in the user namespace.
365 365
366 366 Return value: a flag indicating whether the code to be run completed
367 367 successfully:
368 368
369 369 - 0: successful execution.
370 370 - 1: an error occurred.
371 371 """
372 372
373 373 outflag = 1 # start by assuming error, success will reset it
374 374 try:
375 375 exec code in self.user_ns
376 376 outflag = 0
377 377 except SystemExit:
378 378 self.resetbuffer()
379 379 self.traceback_trap.args = sys.exc_info()
380 380 except:
381 381 self.traceback_trap.args = sys.exc_info()
382 382
383 383 return outflag
384 384
385 385 def execute_macro(self, macro):
386 386 """ Execute the value of a macro.
387 387
388 388 Parameters
389 389 ----------
390 390 macro : Macro
391 391 """
392 392
393 393 python = macro.value
394 394 if self.translator is not None:
395 395 python = self.translator(python)
396 396 self.execute_python(python)
397 397
398 398 def getCommand(self, i=None):
399 399 """Gets the ith message in the message_cache.
400 400
401 401 This is implemented here for compatibility with the old ipython1 shell
402 402 I am not sure we need this though. I even seem to remember that we
403 403 were going to get rid of it.
404 404 """
405 405 return self.message_cache.get_message(i)
406 406
407 407 def reset(self):
408 408 """Reset the interpreter.
409 409
410 410 Currently this only resets the users variables in the namespace.
411 411 In the future we might want to also reset the other stateful
412 412 things like that the Interpreter has, like In, Out, etc.
413 413 """
414 414 self.user_ns.clear()
415 415 self.setup_namespace()
416 416
417 417 def complete(self,line,text=None, pos=None):
418 418 """Complete the given text.
419 419
420 420 :Parameters:
421 421
422 422 text : str
423 423 Text fragment to be completed on. Typically this is
424 424 """
425 425 # fixme: implement
426 426 raise NotImplementedError
427 427
428 428 def push(self, ns):
429 429 """ Put value into the namespace with name key.
430 430
431 431 Parameters
432 432 ----------
433 433 **kwds
434 434 """
435 435
436 436 self.user_ns.update(ns)
437 437
438 438 def push_function(self, ns):
439 439 # First set the func_globals for all functions to self.user_ns
440 440 new_kwds = {}
441 441 for k, v in ns.iteritems():
442 442 if not isinstance(v, FunctionType):
443 443 raise TypeError("function object expected")
444 444 new_kwds[k] = FunctionType(v.func_code, self.user_ns)
445 445 self.user_ns.update(new_kwds)
446 446
447 447 def pack_exception(self,message,exc):
448 448 message['exception'] = exc.__class__
449 449 message['exception_value'] = \
450 450 traceback.format_exception_only(exc.__class__, exc)
451 451
452 452 def feed_block(self, source, filename='<input>', symbol='single'):
453 453 """Compile some source in the interpreter.
454 454
455 455 One several things can happen:
456 456
457 457 1) The input is incorrect; compile_command() raised an
458 458 exception (SyntaxError or OverflowError).
459 459
460 460 2) The input is incomplete, and more input is required;
461 461 compile_command() returned None. Nothing happens.
462 462
463 463 3) The input is complete; compile_command() returned a code
464 464 object. The code is executed by calling self.runcode() (which
465 465 also handles run-time exceptions, except for SystemExit).
466 466
467 467 The return value is:
468 468
469 469 - True in case 2
470 470
471 471 - False in the other cases, unless an exception is raised, where
472 472 None is returned instead. This can be used by external callers to
473 473 know whether to continue feeding input or not.
474 474
475 475 The return value can be used to decide whether to use sys.ps1 or
476 476 sys.ps2 to prompt the next line."""
477 477
478 478 self.message = self.setup_message()
479 479
480 480 try:
481 481 code = self.command_compiler(source,filename,symbol)
482 482 except (OverflowError, SyntaxError, IndentationError, ValueError ), e:
483 483 # Case 1
484 484 self.traceback_trap.args = sys.exc_info()
485 485 self.pack_exception(self.message,e)
486 486 return COMPILER_ERROR,False
487 487
488 488 if code is None:
489 489 # Case 2: incomplete input. This means that the input can span
490 490 # multiple lines. But we still need to decide when to actually
491 491 # stop taking user input. Later we'll add auto-indentation support
492 492 # somehow. In the meantime, we'll just stop if there are two lines
493 493 # of pure whitespace at the end.
494 494 last_two = source.rsplit('\n',2)[-2:]
495 495 print 'last two:',last_two # dbg
496 496 if len(last_two)==2 and all(s.isspace() for s in last_two):
497 497 return COMPLETE_INPUT,False
498 498 else:
499 499 return INCOMPLETE_INPUT, True
500 500 else:
501 501 # Case 3
502 502 return COMPLETE_INPUT, False
503 503
504 504 def pull(self, keys):
505 505 """ Get an item out of the namespace by key.
506 506
507 507 Parameters
508 508 ----------
509 509 key : str
510 510
511 511 Returns
512 512 -------
513 513 value : object
514 514
515 515 Raises
516 516 ------
517 517 TypeError if the key is not a string.
518 518 NameError if the object doesn't exist.
519 519 """
520 520
521 521 if isinstance(keys, str):
522 522 result = self.user_ns.get(keys, NotDefined())
523 523 if isinstance(result, NotDefined):
524 524 raise NameError('name %s is not defined' % keys)
525 525 elif isinstance(keys, (list, tuple)):
526 526 result = []
527 527 for key in keys:
528 528 if not isinstance(key, str):
529 529 raise TypeError("objects must be keyed by strings.")
530 530 else:
531 531 r = self.user_ns.get(key, NotDefined())
532 532 if isinstance(r, NotDefined):
533 533 raise NameError('name %s is not defined' % key)
534 534 else:
535 535 result.append(r)
536 536 if len(keys)==1:
537 537 result = result[0]
538 538 else:
539 539 raise TypeError("keys must be a strong or a list/tuple of strings")
540 540 return result
541 541
542 542 def pull_function(self, keys):
543 543 return self.pull(keys)
544 544
545 545 #### Interactive user API ##################################################
546 546
547 547 def ipsystem(self, command):
548 548 """ Execute a command in a system shell while expanding variables in the
549 549 current namespace.
550 550
551 551 Parameters
552 552 ----------
553 553 command : str
554 554 """
555 555
556 556 # Expand $variables.
557 557 command = self.var_expand(command)
558 558
559 559 system_shell(command,
560 560 header='IPython system call: ',
561 561 verbose=self.rc.system_verbose,
562 562 )
563 563
564 564 def ipmagic(self, arg_string):
565 565 """ Call a magic function by name.
566 566
567 567 ipmagic('name -opt foo bar') is equivalent to typing at the ipython
568 568 prompt:
569 569
570 570 In[1]: %name -opt foo bar
571 571
572 572 To call a magic without arguments, simply use ipmagic('name').
573 573
574 574 This provides a proper Python function to call IPython's magics in any
575 575 valid Python code you can type at the interpreter, including loops and
576 576 compound statements. It is added by IPython to the Python builtin
577 577 namespace upon initialization.
578 578
579 579 Parameters
580 580 ----------
581 581 arg_string : str
582 582 A string containing the name of the magic function to call and any
583 583 additional arguments to be passed to the magic.
584 584
585 585 Returns
586 586 -------
587 587 something : object
588 588 The return value of the actual object.
589 589 """
590 590
591 591 # Taken from IPython.
592 592 raise NotImplementedError('Not ported yet')
593 593
594 594 args = arg_string.split(' ', 1)
595 595 magic_name = args[0]
596 596 magic_name = magic_name.lstrip(self.config.ESC_MAGIC)
597 597
598 598 try:
599 599 magic_args = args[1]
600 600 except IndexError:
601 601 magic_args = ''
602 602 fn = getattr(self.magic, 'magic_'+magic_name, None)
603 603 if fn is None:
604 604 self.error("Magic function `%s` not found." % magic_name)
605 605 else:
606 606 magic_args = self.var_expand(magic_args)
607 607 return fn(magic_args)
608 608
609 609
610 610 #### Private 'Interpreter' interface #######################################
611 611
612 612 def setup_message(self):
613 613 """Return a message object.
614 614
615 615 This method prepares and returns a message dictionary. This dict
616 616 contains the various fields that are used to transfer information about
617 617 execution, results, tracebacks, etc, to clients (either in or out of
618 618 process ones). Because of the need to work with possibly out of
619 619 process clients, this dict MUST contain strictly pickle-safe values.
620 620 """
621 621
622 622 return dict(number=self.current_cell_number)
623 623
624 624 def setup_namespace(self):
625 625 """ Add things to the namespace.
626 626 """
627 627
628 628 self.user_ns.setdefault('__name__', '__main__')
629 629 self.user_ns.setdefault('__builtins__', __builtin__)
630 630 self.user_ns['__IP'] = self
631 631 if self.raw_input_builtin is not None:
632 632 self.user_ns['raw_input'] = self.raw_input_builtin
633 633 if self.input_builtin is not None:
634 634 self.user_ns['input'] = self.input_builtin
635 635
636 636 builtin_additions = dict(
637 637 ipmagic=self.ipmagic,
638 638 )
639 639 __builtin__.__dict__.update(builtin_additions)
640 640
641 641 if self.history is not None:
642 642 self.history.setup_namespace(self.user_ns)
643 643
644 644 def set_traps(self):
645 645 """ Set all of the output, display, and traceback traps.
646 646 """
647 647
648 648 self.output_trap.set()
649 649 self.display_trap.set()
650 650 self.traceback_trap.set()
651 651
652 652 def unset_traps(self):
653 653 """ Unset all of the output, display, and traceback traps.
654 654 """
655 655
656 656 self.output_trap.unset()
657 657 self.display_trap.unset()
658 658 self.traceback_trap.unset()
659 659
660 660 def split_commands(self, python):
661 661 """ Split multiple lines of code into discrete commands that can be
662 662 executed singly.
663 663
664 664 Parameters
665 665 ----------
666 666 python : str
667 667 Pure, exec'able Python code.
668 668
669 669 Returns
670 670 -------
671 671 commands : list of str
672 672 Separate commands that can be exec'ed independently.
673 673 """
674 674
675 675 # compiler.parse treats trailing spaces after a newline as a
676 676 # SyntaxError. This is different than codeop.CommandCompiler, which
677 677 # will compile the trailng spaces just fine. We simply strip any
678 678 # trailing whitespace off. Passing a string with trailing whitespace
679 679 # to exec will fail however. There seems to be some inconsistency in
680 680 # how trailing whitespace is handled, but this seems to work.
681 681 python = python.strip()
682 682
683 683 # The compiler module does not like unicode. We need to convert
684 684 # it encode it:
685 685 if isinstance(python, unicode):
686 686 # Use the utf-8-sig BOM so the compiler detects this a UTF-8
687 687 # encode string.
688 688 python = '\xef\xbb\xbf' + python.encode('utf-8')
689 689
690 690 # The compiler module will parse the code into an abstract syntax tree.
691 691 # This has a bug with str("a\nb"), but not str("""a\nb""")!!!
692 692 ast = compiler.parse(python)
693 693
694 694 # Uncomment to help debug the ast tree
695 695 # for n in ast.node:
696 696 # print n.lineno,'->',n
697 697
698 698 # Each separate command is available by iterating over ast.node. The
699 699 # lineno attribute is the line number (1-indexed) beginning the commands
700 700 # suite.
701 701 # lines ending with ";" yield a Discard Node that doesn't have a lineno
702 702 # attribute. These nodes can and should be discarded. But there are
703 703 # other situations that cause Discard nodes that shouldn't be discarded.
704 704 # We might eventually discover other cases where lineno is None and have
705 705 # to put in a more sophisticated test.
706 706 linenos = [x.lineno-1 for x in ast.node if x.lineno is not None]
707 707
708 708 # When we finally get the slices, we will need to slice all the way to
709 709 # the end even though we don't have a line number for it. Fortunately,
710 710 # None does the job nicely.
711 711 linenos.append(None)
712 712
713 713 # Same problem at the other end: sometimes the ast tree has its
714 714 # first complete statement not starting on line 0. In this case
715 715 # we might miss part of it. This fixes ticket 266993. Thanks Gael!
716 716 linenos[0] = 0
717 717
718 718 lines = python.splitlines()
719 719
720 720 # Create a list of atomic commands.
721 721 cmds = []
722 722 for i, j in zip(linenos[:-1], linenos[1:]):
723 723 cmd = lines[i:j]
724 724 if cmd:
725 725 cmds.append('\n'.join(cmd)+'\n')
726 726
727 727 return cmds
728 728
729 729 def error(self, text):
730 730 """ Pass an error message back to the shell.
731 731
732 Preconditions
733 -------------
732 Notes
733 -----
734 734 This should only be called when self.message is set. In other words,
735 735 when code is being executed.
736 736
737 737 Parameters
738 738 ----------
739 739 text : str
740 740 """
741 741
742 742 errors = self.message.get('IPYTHON_ERROR', [])
743 743 errors.append(text)
744 744
745 745 def var_expand(self, template):
746 746 """ Expand $variables in the current namespace using Itpl.
747 747
748 748 Parameters
749 749 ----------
750 750 template : str
751 751 """
752 752
753 753 return str(ItplNS(template, self.user_ns))
754 754
755 755 def _possible_macro(self, obj):
756 756 """ If the object is a macro, execute it.
757 757 """
758 758
759 759 if isinstance(obj, Macro):
760 760 self.execute_macro(obj)
761 761
@@ -1,125 +1,125 b''
1 1 # encoding: utf-8
2 2
3 3 """The IPython Core Notification Center.
4 4
5 5 See docs/source/development/notification_blueprint.txt for an overview of the
6 6 notification module.
7 7 """
8 8
9 9 __docformat__ = "restructuredtext en"
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Copyright (C) 2008 The IPython Development Team
13 13 #
14 14 # Distributed under the terms of the BSD License. The full license is in
15 15 # the file COPYING, distributed as part of this software.
16 16 #-----------------------------------------------------------------------------
17 17
18 18 # Tell nose to skip the testing of this module
19 19 __test__ = {}
20 20
21 21 class NotificationCenter(object):
22 22 """Synchronous notification center
23 23
24 Example
25 -------
24 Examples
25 --------
26 26 >>> import IPython.kernel.core.notification as notification
27 27 >>> def callback(theType, theSender, args={}):
28 28 ... print theType,theSender,args
29 29 ...
30 30 >>> notification.sharedCenter.add_observer(callback, 'NOTIFICATION_TYPE', None)
31 31 >>> notification.sharedCenter.post_notification('NOTIFICATION_TYPE', object()) # doctest:+ELLIPSIS
32 32 NOTIFICATION_TYPE ...
33 33
34 34 """
35 35 def __init__(self):
36 36 super(NotificationCenter, self).__init__()
37 37 self._init_observers()
38 38
39 39
40 40 def _init_observers(self):
41 41 """Initialize observer storage"""
42 42
43 43 self.registered_types = set() #set of types that are observed
44 44 self.registered_senders = set() #set of senders that are observed
45 45 self.observers = {} #map (type,sender) => callback (callable)
46 46
47 47
48 48 def post_notification(self, theType, sender, **kwargs):
49 49 """Post notification (type,sender,**kwargs) to all registered
50 50 observers.
51 51
52 Implementation
53 --------------
52 Implementation notes:
53
54 54 * If no registered observers, performance is O(1).
55 55 * Notificaiton order is undefined.
56 56 * Notifications are posted synchronously.
57 57 """
58 58
59 59 if(theType==None or sender==None):
60 60 raise Exception("NotificationCenter.post_notification requires \
61 61 type and sender.")
62 62
63 63 # If there are no registered observers for the type/sender pair
64 64 if((theType not in self.registered_types and
65 65 None not in self.registered_types) or
66 66 (sender not in self.registered_senders and
67 67 None not in self.registered_senders)):
68 68 return
69 69
70 70 for o in self._observers_for_notification(theType, sender):
71 71 o(theType, sender, args=kwargs)
72 72
73 73
74 74 def _observers_for_notification(self, theType, sender):
75 75 """Find all registered observers that should recieve notification"""
76 76
77 77 keys = (
78 78 (theType,sender),
79 79 (theType, None),
80 80 (None, sender),
81 81 (None,None)
82 82 )
83 83
84 84
85 85 obs = set()
86 86 for k in keys:
87 87 obs.update(self.observers.get(k, set()))
88 88
89 89 return obs
90 90
91 91
92 92 def add_observer(self, callback, theType, sender):
93 93 """Add an observer callback to this notification center.
94 94
95 95 The given callback will be called upon posting of notifications of
96 96 the given type/sender and will receive any additional kwargs passed
97 97 to post_notification.
98 98
99 99 Parameters
100 100 ----------
101 101 observerCallback : callable
102 102 Callable. Must take at least two arguments::
103 103 observerCallback(type, sender, args={})
104 104
105 105 theType : hashable
106 106 The notification type. If None, all notifications from sender
107 107 will be posted.
108 108
109 109 sender : hashable
110 110 The notification sender. If None, all notifications of theType
111 111 will be posted.
112 112 """
113 113 assert(callback != None)
114 114 self.registered_types.add(theType)
115 115 self.registered_senders.add(sender)
116 116 self.observers.setdefault((theType,sender), set()).add(callback)
117 117
118 118 def remove_all_observers(self):
119 119 """Removes all observers from this notification center"""
120 120
121 121 self._init_observers()
122 122
123 123
124 124
125 125 sharedCenter = NotificationCenter()
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file chmod 100755 => 100644
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file chmod 100644 => 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now