##// END OF EJS Templates
ColorANSI.py -> utils/coloransi.py and all imports updated.
Brian Granger -
Show More
@@ -1,230 +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 from pprint import pprint,pformat
24 from pprint import pformat
25 25
26 26 # Our own
27 27 from IPython import Release
28 28 from IPython import ultraTB
29 from IPython.ColorANSI import ColorScheme,ColorSchemeTable # too long names
30 from IPython.Itpl import Itpl,itpl,printpl
29 from IPython.Itpl import itpl
31 30
32 31 from IPython.genutils import *
33 32
34 33 #****************************************************************************
35 34 class CrashHandler:
36 35 """Customizable crash handlers for IPython-based systems.
37 36
38 37 Instances of this class provide a __call__ method which can be used as a
39 38 sys.excepthook, i.e., the __call__ signature is:
40 39
41 40 def __call__(self,etype, evalue, etb)
42 41
43 42 """
44 43
45 44 def __init__(self,IP,app_name,contact_name,contact_email,
46 45 bug_tracker,crash_report_fname,
47 46 show_crash_traceback=True):
48 47 """New crash handler.
49 48
50 49 Inputs:
51 50
52 51 - IP: a running IPython instance, which will be queried at crash time
53 52 for internal information.
54 53
55 54 - app_name: a string containing the name of your application.
56 55
57 56 - contact_name: a string with the name of the person to contact.
58 57
59 58 - contact_email: a string with the email address of the contact.
60 59
61 60 - bug_tracker: a string with the URL for your project's bug tracker.
62 61
63 62 - crash_report_fname: a string with the filename for the crash report
64 63 to be saved in. These reports are left in the ipython user directory
65 64 as determined by the running IPython instance.
66 65
67 66 Optional inputs:
68 67
69 68 - show_crash_traceback(True): if false, don't print the crash
70 69 traceback on stderr, only generate the on-disk report
71 70
72 71
73 72 Non-argument instance attributes:
74 73
75 74 These instances contain some non-argument attributes which allow for
76 75 further customization of the crash handler's behavior. Please see the
77 76 source for further details.
78 77 """
79 78
80 79 # apply args into instance
81 80 self.IP = IP # IPython instance
82 81 self.app_name = app_name
83 82 self.contact_name = contact_name
84 83 self.contact_email = contact_email
85 84 self.bug_tracker = bug_tracker
86 85 self.crash_report_fname = crash_report_fname
87 86 self.show_crash_traceback = show_crash_traceback
88 87
89 88 # Hardcoded defaults, which can be overridden either by subclasses or
90 89 # at runtime for the instance.
91 90
92 91 # Template for the user message. Subclasses which completely override
93 92 # this, or user apps, can modify it to suit their tastes. It gets
94 93 # expanded using itpl, so calls of the kind $self.foo are valid.
95 94 self.user_message_template = """
96 95 Oops, $self.app_name crashed. We do our best to make it stable, but...
97 96
98 97 A crash report was automatically generated with the following information:
99 98 - A verbatim copy of the crash traceback.
100 99 - A copy of your input history during this session.
101 100 - Data on your current $self.app_name configuration.
102 101
103 102 It was left in the file named:
104 103 \t'$self.crash_report_fname'
105 104 If you can email this file to the developers, the information in it will help
106 105 them in understanding and correcting the problem.
107 106
108 107 You can mail it to: $self.contact_name at $self.contact_email
109 108 with the subject '$self.app_name Crash Report'.
110 109
111 110 If you want to do it now, the following command will work (under Unix):
112 111 mail -s '$self.app_name Crash Report' $self.contact_email < $self.crash_report_fname
113 112
114 113 To ensure accurate tracking of this issue, please file a report about it at:
115 114 $self.bug_tracker
116 115 """
117 116
118 117 def __call__(self,etype, evalue, etb):
119 118 """Handle an exception, call for compatible with sys.excepthook"""
120 119
121 120 # Report tracebacks shouldn't use color in general (safer for users)
122 121 color_scheme = 'NoColor'
123 122
124 123 # Use this ONLY for developer debugging (keep commented out for release)
125 124 #color_scheme = 'Linux' # dbg
126 125
127 126 try:
128 127 rptdir = self.IP.rc.ipythondir
129 128 except:
130 129 rptdir = os.getcwd()
131 130 if not os.path.isdir(rptdir):
132 131 rptdir = os.getcwd()
133 132 report_name = os.path.join(rptdir,self.crash_report_fname)
134 133 # write the report filename into the instance dict so it can get
135 134 # properly expanded out in the user message template
136 135 self.crash_report_fname = report_name
137 136 TBhandler = ultraTB.VerboseTB(color_scheme=color_scheme,
138 137 long_header=1)
139 138 traceback = TBhandler.text(etype,evalue,etb,context=31)
140 139
141 140 # print traceback to screen
142 141 if self.show_crash_traceback:
143 142 print >> sys.stderr, traceback
144 143
145 144 # and generate a complete report on disk
146 145 try:
147 146 report = open(report_name,'w')
148 147 except:
149 148 print >> sys.stderr, 'Could not create crash report on disk.'
150 149 return
151 150
152 151 # Inform user on stderr of what happened
153 152 msg = itpl('\n'+'*'*70+'\n'+self.user_message_template)
154 153 print >> sys.stderr, msg
155 154
156 155 # Construct report on disk
157 156 report.write(self.make_report(traceback))
158 157 report.close()
159 158 raw_input("Press enter to exit:")
160 159
161 160 def make_report(self,traceback):
162 161 """Return a string containing a crash report."""
163 162
164 163 sec_sep = '\n\n'+'*'*75+'\n\n'
165 164
166 165 report = []
167 166 rpt_add = report.append
168 167
169 168 rpt_add('*'*75+'\n\n'+'IPython post-mortem report\n\n')
170 169 rpt_add('IPython version: %s \n\n' % Release.version)
171 170 rpt_add('BZR revision : %s \n\n' % Release.revision)
172 171 rpt_add('Platform info : os.name -> %s, sys.platform -> %s' %
173 172 (os.name,sys.platform) )
174 173 rpt_add(sec_sep+'Current user configuration structure:\n\n')
175 174 rpt_add(pformat(self.IP.rc.dict()))
176 175 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
177 176 try:
178 177 rpt_add(sec_sep+"History of session input:")
179 178 for line in self.IP.user_ns['_ih']:
180 179 rpt_add(line)
181 180 rpt_add('\n*** Last line of input (may not be in above history):\n')
182 181 rpt_add(self.IP._last_input_line+'\n')
183 182 except:
184 183 pass
185 184
186 185 return ''.join(report)
187 186
188 187 class IPythonCrashHandler(CrashHandler):
189 188 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
190 189
191 190 def __init__(self,IP):
192 191
193 192 # Set here which of the IPython authors should be listed as contact
194 193 AUTHOR_CONTACT = 'Ville'
195 194
196 195 # Set argument defaults
197 196 app_name = 'IPython'
198 197 bug_tracker = 'https://bugs.launchpad.net/ipython/+filebug'
199 198 contact_name,contact_email = Release.authors[AUTHOR_CONTACT][:2]
200 199 crash_report_fname = 'IPython_crash_report.txt'
201 200 # Call parent constructor
202 201 CrashHandler.__init__(self,IP,app_name,contact_name,contact_email,
203 202 bug_tracker,crash_report_fname)
204 203
205 204 def make_report(self,traceback):
206 205 """Return a string containing a crash report."""
207 206
208 207 sec_sep = '\n\n'+'*'*75+'\n\n'
209 208
210 209 report = []
211 210 rpt_add = report.append
212 211
213 212 rpt_add('*'*75+'\n\n'+'IPython post-mortem report\n\n')
214 213 rpt_add('IPython version: %s \n\n' % Release.version)
215 214 rpt_add('BZR revision : %s \n\n' % Release.revision)
216 215 rpt_add('Platform info : os.name -> %s, sys.platform -> %s' %
217 216 (os.name,sys.platform) )
218 217 rpt_add(sec_sep+'Current user configuration structure:\n\n')
219 218 rpt_add(pformat(self.IP.rc.dict()))
220 219 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
221 220 try:
222 221 rpt_add(sec_sep+"History of session input:")
223 222 for line in self.IP.user_ns['_ih']:
224 223 rpt_add(line)
225 224 rpt_add('\n*** Last line of input (may not be in above history):\n')
226 225 rpt_add(self.IP._last_input_line+'\n')
227 226 except:
228 227 pass
229 228
230 229 return ''.join(report)
@@ -1,522 +1,523 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Pdb debugger class.
4 4
5 5 Modified from the standard pdb.Pdb class to avoid including readline, so that
6 6 the command line completion of other programs which include this isn't
7 7 damaged.
8 8
9 9 In the future, this class will be expanded with improvements over the standard
10 10 pdb.
11 11
12 12 The code in this file is mainly lifted out of cmd.py in Python 2.2, with minor
13 13 changes. Licensing should therefore be under the standard Python terms. For
14 14 details on the PSF (Python Software Foundation) standard license, see:
15 15
16 16 http://www.python.org/2.2.3/license.html"""
17 17
18 18 #*****************************************************************************
19 19 #
20 20 # This file is licensed under the PSF license.
21 21 #
22 22 # Copyright (C) 2001 Python Software Foundation, www.python.org
23 23 # Copyright (C) 2005-2006 Fernando Perez. <fperez@colorado.edu>
24 24 #
25 25 #
26 26 #*****************************************************************************
27 27
28 28 import bdb
29 29 import cmd
30 30 import linecache
31 31 import os
32 32 import sys
33 33
34 from IPython import PyColorize, ColorANSI, ipapi
34 from IPython import PyColorize, ipapi
35 from IPython.utils import coloransi
35 36 from IPython.genutils import Term
36 37 from IPython.excolors import exception_colors
37 38
38 39 # See if we can use pydb.
39 40 has_pydb = False
40 41 prompt = 'ipdb> '
41 42 #We have to check this directly from sys.argv, config struct not yet available
42 43 if '-pydb' in sys.argv:
43 44 try:
44 45 import pydb
45 46 if hasattr(pydb.pydb, "runl") and pydb.version>'1.17':
46 47 # Version 1.17 is broken, and that's what ships with Ubuntu Edgy, so we
47 48 # better protect against it.
48 49 has_pydb = True
49 50 except ImportError:
50 51 print "Pydb (http://bashdb.sourceforge.net/pydb/) does not seem to be available"
51 52
52 53 if has_pydb:
53 54 from pydb import Pdb as OldPdb
54 55 #print "Using pydb for %run -d and post-mortem" #dbg
55 56 prompt = 'ipydb> '
56 57 else:
57 58 from pdb import Pdb as OldPdb
58 59
59 60 # Allow the set_trace code to operate outside of an ipython instance, even if
60 61 # it does so with some limitations. The rest of this support is implemented in
61 62 # the Tracer constructor.
62 63 def BdbQuit_excepthook(et,ev,tb):
63 64 if et==bdb.BdbQuit:
64 65 print 'Exiting Debugger.'
65 66 else:
66 67 BdbQuit_excepthook.excepthook_ori(et,ev,tb)
67 68
68 69 def BdbQuit_IPython_excepthook(self,et,ev,tb):
69 70 print 'Exiting Debugger.'
70 71
71 72 class Tracer(object):
72 73 """Class for local debugging, similar to pdb.set_trace.
73 74
74 75 Instances of this class, when called, behave like pdb.set_trace, but
75 76 providing IPython's enhanced capabilities.
76 77
77 78 This is implemented as a class which must be initialized in your own code
78 79 and not as a standalone function because we need to detect at runtime
79 80 whether IPython is already active or not. That detection is done in the
80 81 constructor, ensuring that this code plays nicely with a running IPython,
81 82 while functioning acceptably (though with limitations) if outside of it.
82 83 """
83 84
84 85 def __init__(self,colors=None):
85 86 """Create a local debugger instance.
86 87
87 88 :Parameters:
88 89
89 90 - `colors` (None): a string containing the name of the color scheme to
90 91 use, it must be one of IPython's valid color schemes. If not given, the
91 92 function will default to the current IPython scheme when running inside
92 93 IPython, and to 'NoColor' otherwise.
93 94
94 95 Usage example:
95 96
96 97 from IPython.Debugger import Tracer; debug_here = Tracer()
97 98
98 99 ... later in your code
99 100 debug_here() # -> will open up the debugger at that point.
100 101
101 102 Once the debugger activates, you can use all of its regular commands to
102 103 step through code, set breakpoints, etc. See the pdb documentation
103 104 from the Python standard library for usage details.
104 105 """
105 106
106 107 global __IPYTHON__
107 108 try:
108 109 __IPYTHON__
109 110 except NameError:
110 111 # Outside of ipython, we set our own exception hook manually
111 112 __IPYTHON__ = ipapi.get(True,False)
112 113 BdbQuit_excepthook.excepthook_ori = sys.excepthook
113 114 sys.excepthook = BdbQuit_excepthook
114 115 def_colors = 'NoColor'
115 116 try:
116 117 # Limited tab completion support
117 import rlcompleter,readline
118 import readline
118 119 readline.parse_and_bind('tab: complete')
119 120 except ImportError:
120 121 pass
121 122 else:
122 123 # In ipython, we use its custom exception handler mechanism
123 124 ip = ipapi.get()
124 125 def_colors = ip.options.colors
125 126 ip.set_custom_exc((bdb.BdbQuit,),BdbQuit_IPython_excepthook)
126 127
127 128 if colors is None:
128 129 colors = def_colors
129 130 self.debugger = Pdb(colors)
130 131
131 132 def __call__(self):
132 133 """Starts an interactive debugger at the point where called.
133 134
134 135 This is similar to the pdb.set_trace() function from the std lib, but
135 136 using IPython's enhanced debugger."""
136 137
137 138 self.debugger.set_trace(sys._getframe().f_back)
138 139
139 140 def decorate_fn_with_doc(new_fn, old_fn, additional_text=""):
140 141 """Make new_fn have old_fn's doc string. This is particularly useful
141 142 for the do_... commands that hook into the help system.
142 143 Adapted from from a comp.lang.python posting
143 144 by Duncan Booth."""
144 145 def wrapper(*args, **kw):
145 146 return new_fn(*args, **kw)
146 147 if old_fn.__doc__:
147 148 wrapper.__doc__ = old_fn.__doc__ + additional_text
148 149 return wrapper
149 150
150 151 def _file_lines(fname):
151 152 """Return the contents of a named file as a list of lines.
152 153
153 154 This function never raises an IOError exception: if the file can't be
154 155 read, it simply returns an empty list."""
155 156
156 157 try:
157 158 outfile = open(fname)
158 159 except IOError:
159 160 return []
160 161 else:
161 162 out = outfile.readlines()
162 163 outfile.close()
163 164 return out
164 165
165 166 class Pdb(OldPdb):
166 167 """Modified Pdb class, does not load readline."""
167 168
168 169 if sys.version[:3] >= '2.5' or has_pydb:
169 170 def __init__(self,color_scheme='NoColor',completekey=None,
170 171 stdin=None, stdout=None):
171 172
172 173 # Parent constructor:
173 174 if has_pydb and completekey is None:
174 175 OldPdb.__init__(self,stdin=stdin,stdout=Term.cout)
175 176 else:
176 177 OldPdb.__init__(self,completekey,stdin,stdout)
177 178
178 179 self.prompt = prompt # The default prompt is '(Pdb)'
179 180
180 181 # IPython changes...
181 182 self.is_pydb = has_pydb
182 183
183 184 if self.is_pydb:
184 185
185 186 # iplib.py's ipalias seems to want pdb's checkline
186 187 # which located in pydb.fn
187 188 import pydb.fns
188 189 self.checkline = lambda filename, lineno: \
189 190 pydb.fns.checkline(self, filename, lineno)
190 191
191 192 self.curframe = None
192 193 self.do_restart = self.new_do_restart
193 194
194 195 self.old_all_completions = __IPYTHON__.Completer.all_completions
195 196 __IPYTHON__.Completer.all_completions=self.all_completions
196 197
197 198 self.do_list = decorate_fn_with_doc(self.list_command_pydb,
198 199 OldPdb.do_list)
199 200 self.do_l = self.do_list
200 201 self.do_frame = decorate_fn_with_doc(self.new_do_frame,
201 202 OldPdb.do_frame)
202 203
203 204 self.aliases = {}
204 205
205 206 # Create color table: we copy the default one from the traceback
206 207 # module and add a few attributes needed for debugging
207 208 self.color_scheme_table = exception_colors()
208 209
209 210 # shorthands
210 C = ColorANSI.TermColors
211 C = coloransi.TermColors
211 212 cst = self.color_scheme_table
212 213
213 214 cst['NoColor'].colors.breakpoint_enabled = C.NoColor
214 215 cst['NoColor'].colors.breakpoint_disabled = C.NoColor
215 216
216 217 cst['Linux'].colors.breakpoint_enabled = C.LightRed
217 218 cst['Linux'].colors.breakpoint_disabled = C.Red
218 219
219 220 cst['LightBG'].colors.breakpoint_enabled = C.LightRed
220 221 cst['LightBG'].colors.breakpoint_disabled = C.Red
221 222
222 223 self.set_colors(color_scheme)
223 224
224 225 # Add a python parser so we can syntax highlight source while
225 226 # debugging.
226 227 self.parser = PyColorize.Parser()
227 228
228 229
229 230 else:
230 231 # Ugly hack: for Python 2.3-2.4, we can't call the parent constructor,
231 232 # because it binds readline and breaks tab-completion. This means we
232 233 # have to COPY the constructor here.
233 234 def __init__(self,color_scheme='NoColor'):
234 235 bdb.Bdb.__init__(self)
235 236 cmd.Cmd.__init__(self,completekey=None) # don't load readline
236 237 self.prompt = 'ipdb> ' # The default prompt is '(Pdb)'
237 238 self.aliases = {}
238 239
239 240 # These two lines are part of the py2.4 constructor, let's put them
240 241 # unconditionally here as they won't cause any problems in 2.3.
241 242 self.mainpyfile = ''
242 243 self._wait_for_mainpyfile = 0
243 244
244 245 # Read $HOME/.pdbrc and ./.pdbrc
245 246 try:
246 247 self.rcLines = _file_lines(os.path.join(os.environ['HOME'],
247 248 ".pdbrc"))
248 249 except KeyError:
249 250 self.rcLines = []
250 251 self.rcLines.extend(_file_lines(".pdbrc"))
251 252
252 253 # Create color table: we copy the default one from the traceback
253 254 # module and add a few attributes needed for debugging
254 255 self.color_scheme_table = exception_colors()
255 256
256 257 # shorthands
257 C = ColorANSI.TermColors
258 C = coloransi.TermColors
258 259 cst = self.color_scheme_table
259 260
260 261 cst['NoColor'].colors.breakpoint_enabled = C.NoColor
261 262 cst['NoColor'].colors.breakpoint_disabled = C.NoColor
262 263
263 264 cst['Linux'].colors.breakpoint_enabled = C.LightRed
264 265 cst['Linux'].colors.breakpoint_disabled = C.Red
265 266
266 267 cst['LightBG'].colors.breakpoint_enabled = C.LightRed
267 268 cst['LightBG'].colors.breakpoint_disabled = C.Red
268 269
269 270 self.set_colors(color_scheme)
270 271
271 272 # Add a python parser so we can syntax highlight source while
272 273 # debugging.
273 274 self.parser = PyColorize.Parser()
274 275
275 276 def set_colors(self, scheme):
276 277 """Shorthand access to the color table scheme selector method."""
277 278 self.color_scheme_table.set_active_scheme(scheme)
278 279
279 280 def interaction(self, frame, traceback):
280 281 __IPYTHON__.set_completer_frame(frame)
281 282 OldPdb.interaction(self, frame, traceback)
282 283
283 284 def new_do_up(self, arg):
284 285 OldPdb.do_up(self, arg)
285 286 __IPYTHON__.set_completer_frame(self.curframe)
286 287 do_u = do_up = decorate_fn_with_doc(new_do_up, OldPdb.do_up)
287 288
288 289 def new_do_down(self, arg):
289 290 OldPdb.do_down(self, arg)
290 291 __IPYTHON__.set_completer_frame(self.curframe)
291 292
292 293 do_d = do_down = decorate_fn_with_doc(new_do_down, OldPdb.do_down)
293 294
294 295 def new_do_frame(self, arg):
295 296 OldPdb.do_frame(self, arg)
296 297 __IPYTHON__.set_completer_frame(self.curframe)
297 298
298 299 def new_do_quit(self, arg):
299 300
300 301 if hasattr(self, 'old_all_completions'):
301 302 __IPYTHON__.Completer.all_completions=self.old_all_completions
302 303
303 304
304 305 return OldPdb.do_quit(self, arg)
305 306
306 307 do_q = do_quit = decorate_fn_with_doc(new_do_quit, OldPdb.do_quit)
307 308
308 309 def new_do_restart(self, arg):
309 310 """Restart command. In the context of ipython this is exactly the same
310 311 thing as 'quit'."""
311 312 self.msg("Restart doesn't make sense here. Using 'quit' instead.")
312 313 return self.do_quit(arg)
313 314
314 315 def postloop(self):
315 316 __IPYTHON__.set_completer_frame(None)
316 317
317 318 def print_stack_trace(self):
318 319 try:
319 320 for frame_lineno in self.stack:
320 321 self.print_stack_entry(frame_lineno, context = 5)
321 322 except KeyboardInterrupt:
322 323 pass
323 324
324 325 def print_stack_entry(self,frame_lineno,prompt_prefix='\n-> ',
325 326 context = 3):
326 327 #frame, lineno = frame_lineno
327 328 print >>Term.cout, self.format_stack_entry(frame_lineno, '', context)
328 329
329 330 # vds: >>
330 331 frame, lineno = frame_lineno
331 332 filename = frame.f_code.co_filename
332 333 __IPYTHON__.hooks.synchronize_with_editor(filename, lineno, 0)
333 334 # vds: <<
334 335
335 336 def format_stack_entry(self, frame_lineno, lprefix=': ', context = 3):
336 337 import linecache, repr
337 338
338 339 ret = []
339 340
340 341 Colors = self.color_scheme_table.active_colors
341 342 ColorsNormal = Colors.Normal
342 343 tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal)
343 344 tpl_call = '%s%%s%s%%s%s' % (Colors.vName, Colors.valEm, ColorsNormal)
344 345 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
345 346 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line,
346 347 ColorsNormal)
347 348
348 349 frame, lineno = frame_lineno
349 350
350 351 return_value = ''
351 352 if '__return__' in frame.f_locals:
352 353 rv = frame.f_locals['__return__']
353 354 #return_value += '->'
354 355 return_value += repr.repr(rv) + '\n'
355 356 ret.append(return_value)
356 357
357 358 #s = filename + '(' + `lineno` + ')'
358 359 filename = self.canonic(frame.f_code.co_filename)
359 360 link = tpl_link % filename
360 361
361 362 if frame.f_code.co_name:
362 363 func = frame.f_code.co_name
363 364 else:
364 365 func = "<lambda>"
365 366
366 367 call = ''
367 368 if func != '?':
368 369 if '__args__' in frame.f_locals:
369 370 args = repr.repr(frame.f_locals['__args__'])
370 371 else:
371 372 args = '()'
372 373 call = tpl_call % (func, args)
373 374
374 375 # The level info should be generated in the same format pdb uses, to
375 376 # avoid breaking the pdbtrack functionality of python-mode in *emacs.
376 377 if frame is self.curframe:
377 378 ret.append('> ')
378 379 else:
379 380 ret.append(' ')
380 381 ret.append('%s(%s)%s\n' % (link,lineno,call))
381 382
382 383 start = lineno - 1 - context//2
383 384 lines = linecache.getlines(filename)
384 385 start = max(start, 0)
385 386 start = min(start, len(lines) - context)
386 387 lines = lines[start : start + context]
387 388
388 389 for i,line in enumerate(lines):
389 390 show_arrow = (start + 1 + i == lineno)
390 391 linetpl = (frame is self.curframe or show_arrow) \
391 392 and tpl_line_em \
392 393 or tpl_line
393 394 ret.append(self.__format_line(linetpl, filename,
394 395 start + 1 + i, line,
395 396 arrow = show_arrow) )
396 397
397 398 return ''.join(ret)
398 399
399 400 def __format_line(self, tpl_line, filename, lineno, line, arrow = False):
400 401 bp_mark = ""
401 402 bp_mark_color = ""
402 403
403 404 scheme = self.color_scheme_table.active_scheme_name
404 405 new_line, err = self.parser.format2(line, 'str', scheme)
405 406 if not err: line = new_line
406 407
407 408 bp = None
408 409 if lineno in self.get_file_breaks(filename):
409 410 bps = self.get_breaks(filename, lineno)
410 411 bp = bps[-1]
411 412
412 413 if bp:
413 414 Colors = self.color_scheme_table.active_colors
414 415 bp_mark = str(bp.number)
415 416 bp_mark_color = Colors.breakpoint_enabled
416 417 if not bp.enabled:
417 418 bp_mark_color = Colors.breakpoint_disabled
418 419
419 420 numbers_width = 7
420 421 if arrow:
421 422 # This is the line with the error
422 423 pad = numbers_width - len(str(lineno)) - len(bp_mark)
423 424 if pad >= 3:
424 425 marker = '-'*(pad-3) + '-> '
425 426 elif pad == 2:
426 427 marker = '> '
427 428 elif pad == 1:
428 429 marker = '>'
429 430 else:
430 431 marker = ''
431 432 num = '%s%s' % (marker, str(lineno))
432 433 line = tpl_line % (bp_mark_color + bp_mark, num, line)
433 434 else:
434 435 num = '%*s' % (numbers_width - len(bp_mark), str(lineno))
435 436 line = tpl_line % (bp_mark_color + bp_mark, num, line)
436 437
437 438 return line
438 439
439 440 def list_command_pydb(self, arg):
440 441 """List command to use if we have a newer pydb installed"""
441 442 filename, first, last = OldPdb.parse_list_cmd(self, arg)
442 443 if filename is not None:
443 444 self.print_list_lines(filename, first, last)
444 445
445 446 def print_list_lines(self, filename, first, last):
446 447 """The printing (as opposed to the parsing part of a 'list'
447 448 command."""
448 449 try:
449 450 Colors = self.color_scheme_table.active_colors
450 451 ColorsNormal = Colors.Normal
451 452 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
452 453 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal)
453 454 src = []
454 455 for lineno in range(first, last+1):
455 456 line = linecache.getline(filename, lineno)
456 457 if not line:
457 458 break
458 459
459 460 if lineno == self.curframe.f_lineno:
460 461 line = self.__format_line(tpl_line_em, filename, lineno, line, arrow = True)
461 462 else:
462 463 line = self.__format_line(tpl_line, filename, lineno, line, arrow = False)
463 464
464 465 src.append(line)
465 466 self.lineno = lineno
466 467
467 468 print >>Term.cout, ''.join(src)
468 469
469 470 except KeyboardInterrupt:
470 471 pass
471 472
472 473 def do_list(self, arg):
473 474 self.lastcmd = 'list'
474 475 last = None
475 476 if arg:
476 477 try:
477 478 x = eval(arg, {}, {})
478 479 if type(x) == type(()):
479 480 first, last = x
480 481 first = int(first)
481 482 last = int(last)
482 483 if last < first:
483 484 # Assume it's a count
484 485 last = first + last
485 486 else:
486 487 first = max(1, int(x) - 5)
487 488 except:
488 489 print '*** Error in argument:', `arg`
489 490 return
490 491 elif self.lineno is None:
491 492 first = max(1, self.curframe.f_lineno - 5)
492 493 else:
493 494 first = self.lineno + 1
494 495 if last is None:
495 496 last = first + 10
496 497 self.print_list_lines(self.curframe.f_code.co_filename, first, last)
497 498
498 499 # vds: >>
499 500 lineno = first
500 501 filename = self.curframe.f_code.co_filename
501 502 __IPYTHON__.hooks.synchronize_with_editor(filename, lineno, 0)
502 503 # vds: <<
503 504
504 505 do_l = do_list
505 506
506 507 def do_pdef(self, arg):
507 508 """The debugger interface to magic_pdef"""
508 509 namespaces = [('Locals', self.curframe.f_locals),
509 510 ('Globals', self.curframe.f_globals)]
510 511 __IPYTHON__.magic_pdef(arg, namespaces=namespaces)
511 512
512 513 def do_pdoc(self, arg):
513 514 """The debugger interface to magic_pdoc"""
514 515 namespaces = [('Locals', self.curframe.f_locals),
515 516 ('Globals', self.curframe.f_globals)]
516 517 __IPYTHON__.magic_pdoc(arg, namespaces=namespaces)
517 518
518 519 def do_pinfo(self, arg):
519 520 """The debugger equivalant of ?obj"""
520 521 namespaces = [('Locals', self.curframe.f_locals),
521 522 ('Globals', self.curframe.f_globals)]
522 523 __IPYTHON__.magic_pinfo("pinfo %s" % arg, namespaces=namespaces)
@@ -1,607 +1,607 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tools for inspecting Python objects.
3 3
4 4 Uses syntax highlighting for presenting the various information elements.
5 5
6 6 Similar in spirit to the inspect module, but all calls take a name argument to
7 7 reference the name under which an object is being read.
8 8 """
9 9
10 10 #*****************************************************************************
11 11 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
12 12 #
13 13 # Distributed under the terms of the BSD License. The full license is in
14 14 # the file COPYING, distributed as part of this software.
15 15 #*****************************************************************************
16 16
17 17 __all__ = ['Inspector','InspectColors']
18 18
19 19 # stdlib modules
20 20 import __builtin__
21 21 import StringIO
22 22 import inspect
23 23 import linecache
24 24 import os
25 25 import string
26 26 import sys
27 27 import types
28 28
29 29 # IPython's own
30 30 from IPython import PyColorize
31 31 from IPython.genutils import page,indent,Term
32 32 from IPython.Itpl import itpl
33 33 from IPython.wildcard import list_namespace
34 from IPython.ColorANSI import *
34 from IPython.utils.coloransi import *
35 35
36 36 #****************************************************************************
37 37 # HACK!!! This is a crude fix for bugs in python 2.3's inspect module. We
38 38 # simply monkeypatch inspect with code copied from python 2.4.
39 39 if sys.version_info[:2] == (2,3):
40 40 from inspect import ismodule, getabsfile, modulesbyfile
41 41 def getmodule(object):
42 42 """Return the module an object was defined in, or None if not found."""
43 43 if ismodule(object):
44 44 return object
45 45 if hasattr(object, '__module__'):
46 46 return sys.modules.get(object.__module__)
47 47 try:
48 48 file = getabsfile(object)
49 49 except TypeError:
50 50 return None
51 51 if file in modulesbyfile:
52 52 return sys.modules.get(modulesbyfile[file])
53 53 for module in sys.modules.values():
54 54 if hasattr(module, '__file__'):
55 55 modulesbyfile[
56 56 os.path.realpath(
57 57 getabsfile(module))] = module.__name__
58 58 if file in modulesbyfile:
59 59 return sys.modules.get(modulesbyfile[file])
60 60 main = sys.modules['__main__']
61 61 if not hasattr(object, '__name__'):
62 62 return None
63 63 if hasattr(main, object.__name__):
64 64 mainobject = getattr(main, object.__name__)
65 65 if mainobject is object:
66 66 return main
67 67 builtin = sys.modules['__builtin__']
68 68 if hasattr(builtin, object.__name__):
69 69 builtinobject = getattr(builtin, object.__name__)
70 70 if builtinobject is object:
71 71 return builtin
72 72
73 73 inspect.getmodule = getmodule
74 74
75 75 #****************************************************************************
76 76 # Builtin color schemes
77 77
78 78 Colors = TermColors # just a shorthand
79 79
80 80 # Build a few color schemes
81 81 NoColor = ColorScheme(
82 82 'NoColor',{
83 83 'header' : Colors.NoColor,
84 84 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
85 85 } )
86 86
87 87 LinuxColors = ColorScheme(
88 88 'Linux',{
89 89 'header' : Colors.LightRed,
90 90 'normal' : Colors.Normal # color off (usu. Colors.Normal)
91 91 } )
92 92
93 93 LightBGColors = ColorScheme(
94 94 'LightBG',{
95 95 'header' : Colors.Red,
96 96 'normal' : Colors.Normal # color off (usu. Colors.Normal)
97 97 } )
98 98
99 99 # Build table of color schemes (needed by the parser)
100 100 InspectColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
101 101 'Linux')
102 102
103 103 #****************************************************************************
104 104 # Auxiliary functions
105 105 def getdoc(obj):
106 106 """Stable wrapper around inspect.getdoc.
107 107
108 108 This can't crash because of attribute problems.
109 109
110 110 It also attempts to call a getdoc() method on the given object. This
111 111 allows objects which provide their docstrings via non-standard mechanisms
112 112 (like Pyro proxies) to still be inspected by ipython's ? system."""
113 113
114 114 ds = None # default return value
115 115 try:
116 116 ds = inspect.getdoc(obj)
117 117 except:
118 118 # Harden against an inspect failure, which can occur with
119 119 # SWIG-wrapped extensions.
120 120 pass
121 121 # Allow objects to offer customized documentation via a getdoc method:
122 122 try:
123 123 ds2 = obj.getdoc()
124 124 except:
125 125 pass
126 126 else:
127 127 # if we get extra info, we add it to the normal docstring.
128 128 if ds is None:
129 129 ds = ds2
130 130 else:
131 131 ds = '%s\n%s' % (ds,ds2)
132 132 return ds
133 133
134 134
135 135 def getsource(obj,is_binary=False):
136 136 """Wrapper around inspect.getsource.
137 137
138 138 This can be modified by other projects to provide customized source
139 139 extraction.
140 140
141 141 Inputs:
142 142
143 143 - obj: an object whose source code we will attempt to extract.
144 144
145 145 Optional inputs:
146 146
147 147 - is_binary: whether the object is known to come from a binary source.
148 148 This implementation will skip returning any output for binary objects, but
149 149 custom extractors may know how to meaningfully process them."""
150 150
151 151 if is_binary:
152 152 return None
153 153 else:
154 154 try:
155 155 src = inspect.getsource(obj)
156 156 except TypeError:
157 157 if hasattr(obj,'__class__'):
158 158 src = inspect.getsource(obj.__class__)
159 159 return src
160 160
161 161 def getargspec(obj):
162 162 """Get the names and default values of a function's arguments.
163 163
164 164 A tuple of four things is returned: (args, varargs, varkw, defaults).
165 165 'args' is a list of the argument names (it may contain nested lists).
166 166 'varargs' and 'varkw' are the names of the * and ** arguments or None.
167 167 'defaults' is an n-tuple of the default values of the last n arguments.
168 168
169 169 Modified version of inspect.getargspec from the Python Standard
170 170 Library."""
171 171
172 172 if inspect.isfunction(obj):
173 173 func_obj = obj
174 174 elif inspect.ismethod(obj):
175 175 func_obj = obj.im_func
176 176 else:
177 177 raise TypeError, 'arg is not a Python function'
178 178 args, varargs, varkw = inspect.getargs(func_obj.func_code)
179 179 return args, varargs, varkw, func_obj.func_defaults
180 180
181 181 #****************************************************************************
182 182 # Class definitions
183 183
184 184 class myStringIO(StringIO.StringIO):
185 185 """Adds a writeln method to normal StringIO."""
186 186 def writeln(self,*arg,**kw):
187 187 """Does a write() and then a write('\n')"""
188 188 self.write(*arg,**kw)
189 189 self.write('\n')
190 190
191 191
192 192 class Inspector:
193 193 def __init__(self,color_table,code_color_table,scheme,
194 194 str_detail_level=0):
195 195 self.color_table = color_table
196 196 self.parser = PyColorize.Parser(code_color_table,out='str')
197 197 self.format = self.parser.format
198 198 self.str_detail_level = str_detail_level
199 199 self.set_active_scheme(scheme)
200 200
201 201 def __getdef(self,obj,oname=''):
202 202 """Return the definition header for any callable object.
203 203
204 204 If any exception is generated, None is returned instead and the
205 205 exception is suppressed."""
206 206
207 207 try:
208 208 return oname + inspect.formatargspec(*getargspec(obj))
209 209 except:
210 210 return None
211 211
212 212 def __head(self,h):
213 213 """Return a header string with proper colors."""
214 214 return '%s%s%s' % (self.color_table.active_colors.header,h,
215 215 self.color_table.active_colors.normal)
216 216
217 217 def set_active_scheme(self,scheme):
218 218 self.color_table.set_active_scheme(scheme)
219 219 self.parser.color_table.set_active_scheme(scheme)
220 220
221 221 def noinfo(self,msg,oname):
222 222 """Generic message when no information is found."""
223 223 print 'No %s found' % msg,
224 224 if oname:
225 225 print 'for %s' % oname
226 226 else:
227 227 print
228 228
229 229 def pdef(self,obj,oname=''):
230 230 """Print the definition header for any callable object.
231 231
232 232 If the object is a class, print the constructor information."""
233 233
234 234 if not callable(obj):
235 235 print 'Object is not callable.'
236 236 return
237 237
238 238 header = ''
239 239
240 240 if inspect.isclass(obj):
241 241 header = self.__head('Class constructor information:\n')
242 242 obj = obj.__init__
243 243 elif type(obj) is types.InstanceType:
244 244 obj = obj.__call__
245 245
246 246 output = self.__getdef(obj,oname)
247 247 if output is None:
248 248 self.noinfo('definition header',oname)
249 249 else:
250 250 print >>Term.cout, header,self.format(output),
251 251
252 252 def pdoc(self,obj,oname='',formatter = None):
253 253 """Print the docstring for any object.
254 254
255 255 Optional:
256 256 -formatter: a function to run the docstring through for specially
257 257 formatted docstrings."""
258 258
259 259 head = self.__head # so that itpl can find it even if private
260 260 ds = getdoc(obj)
261 261 if formatter:
262 262 ds = formatter(ds)
263 263 if inspect.isclass(obj):
264 264 init_ds = getdoc(obj.__init__)
265 265 output = itpl('$head("Class Docstring:")\n'
266 266 '$indent(ds)\n'
267 267 '$head("Constructor Docstring"):\n'
268 268 '$indent(init_ds)')
269 269 elif (type(obj) is types.InstanceType or isinstance(obj,object)) \
270 270 and hasattr(obj,'__call__'):
271 271 call_ds = getdoc(obj.__call__)
272 272 if call_ds:
273 273 output = itpl('$head("Class Docstring:")\n$indent(ds)\n'
274 274 '$head("Calling Docstring:")\n$indent(call_ds)')
275 275 else:
276 276 output = ds
277 277 else:
278 278 output = ds
279 279 if output is None:
280 280 self.noinfo('documentation',oname)
281 281 return
282 282 page(output)
283 283
284 284 def psource(self,obj,oname=''):
285 285 """Print the source code for an object."""
286 286
287 287 # Flush the source cache because inspect can return out-of-date source
288 288 linecache.checkcache()
289 289 try:
290 290 src = getsource(obj)
291 291 except:
292 292 self.noinfo('source',oname)
293 293 else:
294 294 page(self.format(src))
295 295
296 296 def pfile(self,obj,oname=''):
297 297 """Show the whole file where an object was defined."""
298 298
299 299 try:
300 300 try:
301 301 lineno = inspect.getsourcelines(obj)[1]
302 302 except TypeError:
303 303 # For instances, try the class object like getsource() does
304 304 if hasattr(obj,'__class__'):
305 305 lineno = inspect.getsourcelines(obj.__class__)[1]
306 306 # Adjust the inspected object so getabsfile() below works
307 307 obj = obj.__class__
308 308 except:
309 309 self.noinfo('file',oname)
310 310 return
311 311
312 312 # We only reach this point if object was successfully queried
313 313
314 314 # run contents of file through pager starting at line
315 315 # where the object is defined
316 316 ofile = inspect.getabsfile(obj)
317 317
318 318 if (ofile.endswith('.so') or ofile.endswith('.dll')):
319 319 print 'File %r is binary, not printing.' % ofile
320 320 elif not os.path.isfile(ofile):
321 321 print 'File %r does not exist, not printing.' % ofile
322 322 else:
323 323 # Print only text files, not extension binaries. Note that
324 324 # getsourcelines returns lineno with 1-offset and page() uses
325 325 # 0-offset, so we must adjust.
326 326 page(self.format(open(ofile).read()),lineno-1)
327 327
328 328 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
329 329 """Show detailed information about an object.
330 330
331 331 Optional arguments:
332 332
333 333 - oname: name of the variable pointing to the object.
334 334
335 335 - formatter: special formatter for docstrings (see pdoc)
336 336
337 337 - info: a structure with some information fields which may have been
338 338 precomputed already.
339 339
340 340 - detail_level: if set to 1, more information is given.
341 341 """
342 342
343 343 obj_type = type(obj)
344 344
345 345 header = self.__head
346 346 if info is None:
347 347 ismagic = 0
348 348 isalias = 0
349 349 ospace = ''
350 350 else:
351 351 ismagic = info.ismagic
352 352 isalias = info.isalias
353 353 ospace = info.namespace
354 354 # Get docstring, special-casing aliases:
355 355 if isalias:
356 356 if not callable(obj):
357 357 try:
358 358 ds = "Alias to the system command:\n %s" % obj[1]
359 359 except:
360 360 ds = "Alias: " + str(obj)
361 361 else:
362 362 ds = "Alias to " + str(obj)
363 363 if obj.__doc__:
364 364 ds += "\nDocstring:\n" + obj.__doc__
365 365 else:
366 366 ds = getdoc(obj)
367 367 if ds is None:
368 368 ds = '<no docstring>'
369 369 if formatter is not None:
370 370 ds = formatter(ds)
371 371
372 372 # store output in a list which gets joined with \n at the end.
373 373 out = myStringIO()
374 374
375 375 string_max = 200 # max size of strings to show (snipped if longer)
376 376 shalf = int((string_max -5)/2)
377 377
378 378 if ismagic:
379 379 obj_type_name = 'Magic function'
380 380 elif isalias:
381 381 obj_type_name = 'System alias'
382 382 else:
383 383 obj_type_name = obj_type.__name__
384 384 out.writeln(header('Type:\t\t')+obj_type_name)
385 385
386 386 try:
387 387 bclass = obj.__class__
388 388 out.writeln(header('Base Class:\t')+str(bclass))
389 389 except: pass
390 390
391 391 # String form, but snip if too long in ? form (full in ??)
392 392 if detail_level >= self.str_detail_level:
393 393 try:
394 394 ostr = str(obj)
395 395 str_head = 'String Form:'
396 396 if not detail_level and len(ostr)>string_max:
397 397 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
398 398 ostr = ("\n" + " " * len(str_head.expandtabs())).\
399 399 join(map(string.strip,ostr.split("\n")))
400 400 if ostr.find('\n') > -1:
401 401 # Print multi-line strings starting at the next line.
402 402 str_sep = '\n'
403 403 else:
404 404 str_sep = '\t'
405 405 out.writeln("%s%s%s" % (header(str_head),str_sep,ostr))
406 406 except:
407 407 pass
408 408
409 409 if ospace:
410 410 out.writeln(header('Namespace:\t')+ospace)
411 411
412 412 # Length (for strings and lists)
413 413 try:
414 414 length = str(len(obj))
415 415 out.writeln(header('Length:\t\t')+length)
416 416 except: pass
417 417
418 418 # Filename where object was defined
419 419 binary_file = False
420 420 try:
421 421 try:
422 422 fname = inspect.getabsfile(obj)
423 423 except TypeError:
424 424 # For an instance, the file that matters is where its class was
425 425 # declared.
426 426 if hasattr(obj,'__class__'):
427 427 fname = inspect.getabsfile(obj.__class__)
428 428 if fname.endswith('<string>'):
429 429 fname = 'Dynamically generated function. No source code available.'
430 430 if (fname.endswith('.so') or fname.endswith('.dll')):
431 431 binary_file = True
432 432 out.writeln(header('File:\t\t')+fname)
433 433 except:
434 434 # if anything goes wrong, we don't want to show source, so it's as
435 435 # if the file was binary
436 436 binary_file = True
437 437
438 438 # reconstruct the function definition and print it:
439 439 defln = self.__getdef(obj,oname)
440 440 if defln:
441 441 out.write(header('Definition:\t')+self.format(defln))
442 442
443 443 # Docstrings only in detail 0 mode, since source contains them (we
444 444 # avoid repetitions). If source fails, we add them back, see below.
445 445 if ds and detail_level == 0:
446 446 out.writeln(header('Docstring:\n') + indent(ds))
447 447
448 448 # Original source code for any callable
449 449 if detail_level:
450 450 # Flush the source cache because inspect can return out-of-date
451 451 # source
452 452 linecache.checkcache()
453 453 source_success = False
454 454 try:
455 455 try:
456 456 src = getsource(obj,binary_file)
457 457 except TypeError:
458 458 if hasattr(obj,'__class__'):
459 459 src = getsource(obj.__class__,binary_file)
460 460 if src is not None:
461 461 source = self.format(src)
462 462 out.write(header('Source:\n')+source.rstrip())
463 463 source_success = True
464 464 except Exception, msg:
465 465 pass
466 466
467 467 if ds and not source_success:
468 468 out.writeln(header('Docstring [source file open failed]:\n')
469 469 + indent(ds))
470 470
471 471 # Constructor docstring for classes
472 472 if inspect.isclass(obj):
473 473 # reconstruct the function definition and print it:
474 474 try:
475 475 obj_init = obj.__init__
476 476 except AttributeError:
477 477 init_def = init_ds = None
478 478 else:
479 479 init_def = self.__getdef(obj_init,oname)
480 480 init_ds = getdoc(obj_init)
481 481 # Skip Python's auto-generated docstrings
482 482 if init_ds and \
483 483 init_ds.startswith('x.__init__(...) initializes'):
484 484 init_ds = None
485 485
486 486 if init_def or init_ds:
487 487 out.writeln(header('\nConstructor information:'))
488 488 if init_def:
489 489 out.write(header('Definition:\t')+ self.format(init_def))
490 490 if init_ds:
491 491 out.writeln(header('Docstring:\n') + indent(init_ds))
492 492 # and class docstring for instances:
493 493 elif obj_type is types.InstanceType or \
494 494 isinstance(obj,object):
495 495
496 496 # First, check whether the instance docstring is identical to the
497 497 # class one, and print it separately if they don't coincide. In
498 498 # most cases they will, but it's nice to print all the info for
499 499 # objects which use instance-customized docstrings.
500 500 if ds:
501 501 try:
502 502 cls = getattr(obj,'__class__')
503 503 except:
504 504 class_ds = None
505 505 else:
506 506 class_ds = getdoc(cls)
507 507 # Skip Python's auto-generated docstrings
508 508 if class_ds and \
509 509 (class_ds.startswith('function(code, globals[,') or \
510 510 class_ds.startswith('instancemethod(function, instance,') or \
511 511 class_ds.startswith('module(name[,') ):
512 512 class_ds = None
513 513 if class_ds and ds != class_ds:
514 514 out.writeln(header('Class Docstring:\n') +
515 515 indent(class_ds))
516 516
517 517 # Next, try to show constructor docstrings
518 518 try:
519 519 init_ds = getdoc(obj.__init__)
520 520 # Skip Python's auto-generated docstrings
521 521 if init_ds and \
522 522 init_ds.startswith('x.__init__(...) initializes'):
523 523 init_ds = None
524 524 except AttributeError:
525 525 init_ds = None
526 526 if init_ds:
527 527 out.writeln(header('Constructor Docstring:\n') +
528 528 indent(init_ds))
529 529
530 530 # Call form docstring for callable instances
531 531 if hasattr(obj,'__call__'):
532 532 #out.writeln(header('Callable:\t')+'Yes')
533 533 call_def = self.__getdef(obj.__call__,oname)
534 534 #if call_def is None:
535 535 # out.writeln(header('Call def:\t')+
536 536 # 'Calling definition not available.')
537 537 if call_def is not None:
538 538 out.writeln(header('Call def:\t')+self.format(call_def))
539 539 call_ds = getdoc(obj.__call__)
540 540 # Skip Python's auto-generated docstrings
541 541 if call_ds and call_ds.startswith('x.__call__(...) <==> x(...)'):
542 542 call_ds = None
543 543 if call_ds:
544 544 out.writeln(header('Call docstring:\n') + indent(call_ds))
545 545
546 546 # Finally send to printer/pager
547 547 output = out.getvalue()
548 548 if output:
549 549 page(output)
550 550 # end pinfo
551 551
552 552 def psearch(self,pattern,ns_table,ns_search=[],
553 553 ignore_case=False,show_all=False):
554 554 """Search namespaces with wildcards for objects.
555 555
556 556 Arguments:
557 557
558 558 - pattern: string containing shell-like wildcards to use in namespace
559 559 searches and optionally a type specification to narrow the search to
560 560 objects of that type.
561 561
562 562 - ns_table: dict of name->namespaces for search.
563 563
564 564 Optional arguments:
565 565
566 566 - ns_search: list of namespace names to include in search.
567 567
568 568 - ignore_case(False): make the search case-insensitive.
569 569
570 570 - show_all(False): show all names, including those starting with
571 571 underscores.
572 572 """
573 573 #print 'ps pattern:<%r>' % pattern # dbg
574 574
575 575 # defaults
576 576 type_pattern = 'all'
577 577 filter = ''
578 578
579 579 cmds = pattern.split()
580 580 len_cmds = len(cmds)
581 581 if len_cmds == 1:
582 582 # Only filter pattern given
583 583 filter = cmds[0]
584 584 elif len_cmds == 2:
585 585 # Both filter and type specified
586 586 filter,type_pattern = cmds
587 587 else:
588 588 raise ValueError('invalid argument string for psearch: <%s>' %
589 589 pattern)
590 590
591 591 # filter search namespaces
592 592 for name in ns_search:
593 593 if name not in ns_table:
594 594 raise ValueError('invalid namespace <%s>. Valid names: %s' %
595 595 (name,ns_table.keys()))
596 596
597 597 #print 'type_pattern:',type_pattern # dbg
598 598 search_result = []
599 599 for ns_name in ns_search:
600 600 ns = ns_table[ns_name]
601 601 tmp_res = list(list_namespace(ns,type_pattern,filter,
602 602 ignore_case=ignore_case,
603 603 show_all=show_all))
604 604 search_result.extend(tmp_res)
605 605 search_result.sort()
606 606
607 607 page('\n'.join(search_result))
@@ -1,626 +1,626 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Classes for handling input/output prompts.
4 4 """
5 5
6 6 #*****************************************************************************
7 7 # Copyright (C) 2008-2009 The IPython Development Team
8 8 # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.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 #****************************************************************************
15 15 # Required modules
16 16 import __builtin__
17 17 import os
18 18 import socket
19 19 import sys
20 20 import time
21 21
22 22 # IPython's own
23 from IPython import ColorANSI
23 from IPython.utils import coloransi
24 24 from IPython import Release
25 25 from IPython.external.Itpl import ItplNS
26 26 from IPython.ipapi import TryNext
27 27 from IPython.ipstruct import Struct
28 28 from IPython.macro import Macro
29 29
30 30 from IPython.genutils import *
31 31
32 32 #****************************************************************************
33 33 #Color schemes for Prompts.
34 34
35 PromptColors = ColorANSI.ColorSchemeTable()
36 InputColors = ColorANSI.InputTermColors # just a shorthand
37 Colors = ColorANSI.TermColors # just a shorthand
35 PromptColors = coloransi.ColorSchemeTable()
36 InputColors = coloransi.InputTermColors # just a shorthand
37 Colors = coloransi.TermColors # just a shorthand
38 38
39 PromptColors.add_scheme(ColorANSI.ColorScheme(
39 PromptColors.add_scheme(coloransi.ColorScheme(
40 40 'NoColor',
41 41 in_prompt = InputColors.NoColor, # Input prompt
42 42 in_number = InputColors.NoColor, # Input prompt number
43 43 in_prompt2 = InputColors.NoColor, # Continuation prompt
44 44 in_normal = InputColors.NoColor, # color off (usu. Colors.Normal)
45 45
46 46 out_prompt = Colors.NoColor, # Output prompt
47 47 out_number = Colors.NoColor, # Output prompt number
48 48
49 49 normal = Colors.NoColor # color off (usu. Colors.Normal)
50 50 ))
51 51
52 52 # make some schemes as instances so we can copy them for modification easily:
53 __PColLinux = ColorANSI.ColorScheme(
53 __PColLinux = coloransi.ColorScheme(
54 54 'Linux',
55 55 in_prompt = InputColors.Green,
56 56 in_number = InputColors.LightGreen,
57 57 in_prompt2 = InputColors.Green,
58 58 in_normal = InputColors.Normal, # color off (usu. Colors.Normal)
59 59
60 60 out_prompt = Colors.Red,
61 61 out_number = Colors.LightRed,
62 62
63 63 normal = Colors.Normal
64 64 )
65 65 # Don't forget to enter it into the table!
66 66 PromptColors.add_scheme(__PColLinux)
67 67
68 68 # Slightly modified Linux for light backgrounds
69 69 __PColLightBG = __PColLinux.copy('LightBG')
70 70
71 71 __PColLightBG.colors.update(
72 72 in_prompt = InputColors.Blue,
73 73 in_number = InputColors.LightBlue,
74 74 in_prompt2 = InputColors.Blue
75 75 )
76 76 PromptColors.add_scheme(__PColLightBG)
77 77
78 78 del Colors,InputColors
79 79
80 80 #-----------------------------------------------------------------------------
81 81 def multiple_replace(dict, text):
82 82 """ Replace in 'text' all occurences of any key in the given
83 83 dictionary by its corresponding value. Returns the new string."""
84 84
85 85 # Function by Xavier Defrang, originally found at:
86 86 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81330
87 87
88 88 # Create a regular expression from the dictionary keys
89 89 regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))
90 90 # For each match, look-up corresponding value in dictionary
91 91 return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text)
92 92
93 93 #-----------------------------------------------------------------------------
94 94 # Special characters that can be used in prompt templates, mainly bash-like
95 95
96 96 # If $HOME isn't defined (Windows), make it an absurd string so that it can
97 97 # never be expanded out into '~'. Basically anything which can never be a
98 98 # reasonable directory name will do, we just want the $HOME -> '~' operation
99 99 # to become a no-op. We pre-compute $HOME here so it's not done on every
100 100 # prompt call.
101 101
102 102 # FIXME:
103 103
104 104 # - This should be turned into a class which does proper namespace management,
105 105 # since the prompt specials need to be evaluated in a certain namespace.
106 106 # Currently it's just globals, which need to be managed manually by code
107 107 # below.
108 108
109 109 # - I also need to split up the color schemes from the prompt specials
110 110 # somehow. I don't have a clean design for that quite yet.
111 111
112 112 HOME = os.environ.get("HOME","//////:::::ZZZZZ,,,~~~")
113 113
114 114 # We precompute a few more strings here for the prompt_specials, which are
115 115 # fixed once ipython starts. This reduces the runtime overhead of computing
116 116 # prompt strings.
117 117 USER = os.environ.get("USER")
118 118 HOSTNAME = socket.gethostname()
119 119 HOSTNAME_SHORT = HOSTNAME.split(".")[0]
120 120 ROOT_SYMBOL = "$#"[os.name=='nt' or os.getuid()==0]
121 121
122 122 prompt_specials_color = {
123 123 # Prompt/history count
124 124 '%n' : '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
125 125 r'\#': '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
126 126 # Just the prompt counter number, WITHOUT any coloring wrappers, so users
127 127 # can get numbers displayed in whatever color they want.
128 128 r'\N': '${self.cache.prompt_count}',
129 129
130 130 # Prompt/history count, with the actual digits replaced by dots. Used
131 131 # mainly in continuation prompts (prompt_in2)
132 132 #r'\D': '${"."*len(str(self.cache.prompt_count))}',
133 133 # More robust form of the above expression, that uses __builtins__
134 134 r'\D': '${"."*__builtins__.len(__builtins__.str(self.cache.prompt_count))}',
135 135
136 136 # Current working directory
137 137 r'\w': '${os.getcwd()}',
138 138 # Current time
139 139 r'\t' : '${time.strftime("%H:%M:%S")}',
140 140 # Basename of current working directory.
141 141 # (use os.sep to make this portable across OSes)
142 142 r'\W' : '${os.getcwd().split("%s")[-1]}' % os.sep,
143 143 # These X<N> are an extension to the normal bash prompts. They return
144 144 # N terms of the path, after replacing $HOME with '~'
145 145 r'\X0': '${os.getcwd().replace("%s","~")}' % HOME,
146 146 r'\X1': '${self.cwd_filt(1)}',
147 147 r'\X2': '${self.cwd_filt(2)}',
148 148 r'\X3': '${self.cwd_filt(3)}',
149 149 r'\X4': '${self.cwd_filt(4)}',
150 150 r'\X5': '${self.cwd_filt(5)}',
151 151 # Y<N> are similar to X<N>, but they show '~' if it's the directory
152 152 # N+1 in the list. Somewhat like %cN in tcsh.
153 153 r'\Y0': '${self.cwd_filt2(0)}',
154 154 r'\Y1': '${self.cwd_filt2(1)}',
155 155 r'\Y2': '${self.cwd_filt2(2)}',
156 156 r'\Y3': '${self.cwd_filt2(3)}',
157 157 r'\Y4': '${self.cwd_filt2(4)}',
158 158 r'\Y5': '${self.cwd_filt2(5)}',
159 159 # Hostname up to first .
160 160 r'\h': HOSTNAME_SHORT,
161 161 # Full hostname
162 162 r'\H': HOSTNAME,
163 163 # Username of current user
164 164 r'\u': USER,
165 165 # Escaped '\'
166 166 '\\\\': '\\',
167 167 # Newline
168 168 r'\n': '\n',
169 169 # Carriage return
170 170 r'\r': '\r',
171 171 # Release version
172 172 r'\v': Release.version,
173 173 # Root symbol ($ or #)
174 174 r'\$': ROOT_SYMBOL,
175 175 }
176 176
177 177 # A copy of the prompt_specials dictionary but with all color escapes removed,
178 178 # so we can correctly compute the prompt length for the auto_rewrite method.
179 179 prompt_specials_nocolor = prompt_specials_color.copy()
180 180 prompt_specials_nocolor['%n'] = '${self.cache.prompt_count}'
181 181 prompt_specials_nocolor[r'\#'] = '${self.cache.prompt_count}'
182 182
183 183 # Add in all the InputTermColors color escapes as valid prompt characters.
184 184 # They all get added as \\C_COLORNAME, so that we don't have any conflicts
185 185 # with a color name which may begin with a letter used by any other of the
186 186 # allowed specials. This of course means that \\C will never be allowed for
187 187 # anything else.
188 input_colors = ColorANSI.InputTermColors
188 input_colors = coloransi.InputTermColors
189 189 for _color in dir(input_colors):
190 190 if _color[0] != '_':
191 191 c_name = r'\C_'+_color
192 192 prompt_specials_color[c_name] = getattr(input_colors,_color)
193 193 prompt_specials_nocolor[c_name] = ''
194 194
195 195 # we default to no color for safety. Note that prompt_specials is a global
196 196 # variable used by all prompt objects.
197 197 prompt_specials = prompt_specials_nocolor
198 198
199 199 #-----------------------------------------------------------------------------
200 200 def str_safe(arg):
201 201 """Convert to a string, without ever raising an exception.
202 202
203 203 If str(arg) fails, <ERROR: ... > is returned, where ... is the exception
204 204 error message."""
205 205
206 206 try:
207 207 out = str(arg)
208 208 except UnicodeError:
209 209 try:
210 210 out = arg.encode('utf_8','replace')
211 211 except Exception,msg:
212 212 # let's keep this little duplication here, so that the most common
213 213 # case doesn't suffer from a double try wrapping.
214 214 out = '<ERROR: %s>' % msg
215 215 except Exception,msg:
216 216 out = '<ERROR: %s>' % msg
217 217 return out
218 218
219 219 class BasePrompt(object):
220 220 """Interactive prompt similar to Mathematica's."""
221 221
222 222 def _get_p_template(self):
223 223 return self._p_template
224 224
225 225 def _set_p_template(self,val):
226 226 self._p_template = val
227 227 self.set_p_str()
228 228
229 229 p_template = property(_get_p_template,_set_p_template,
230 230 doc='Template for prompt string creation')
231 231
232 232 def __init__(self,cache,sep,prompt,pad_left=False):
233 233
234 234 # Hack: we access information about the primary prompt through the
235 235 # cache argument. We need this, because we want the secondary prompt
236 236 # to be aligned with the primary one. Color table info is also shared
237 237 # by all prompt classes through the cache. Nice OO spaghetti code!
238 238 self.cache = cache
239 239 self.sep = sep
240 240
241 241 # regexp to count the number of spaces at the end of a prompt
242 242 # expression, useful for prompt auto-rewriting
243 243 self.rspace = re.compile(r'(\s*)$')
244 244 # Flag to left-pad prompt strings to match the length of the primary
245 245 # prompt
246 246 self.pad_left = pad_left
247 247
248 248 # Set template to create each actual prompt (where numbers change).
249 249 # Use a property
250 250 self.p_template = prompt
251 251 self.set_p_str()
252 252
253 253 def set_p_str(self):
254 254 """ Set the interpolating prompt strings.
255 255
256 256 This must be called every time the color settings change, because the
257 257 prompt_specials global may have changed."""
258 258
259 259 import os,time # needed in locals for prompt string handling
260 260 loc = locals()
261 261 try:
262 262 self.p_str = ItplNS('%s%s%s' %
263 263 ('${self.sep}${self.col_p}',
264 264 multiple_replace(prompt_specials, self.p_template),
265 265 '${self.col_norm}'),self.cache.user_ns,loc)
266 266
267 267 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
268 268 self.p_template),
269 269 self.cache.user_ns,loc)
270 270 except:
271 271 print "Illegal prompt template (check $ usage!):",self.p_template
272 272 self.p_str = self.p_template
273 273 self.p_str_nocolor = self.p_template
274 274
275 275 def write(self,msg): # dbg
276 276 sys.stdout.write(msg)
277 277 return ''
278 278
279 279 def __str__(self):
280 280 """Return a string form of the prompt.
281 281
282 282 This for is useful for continuation and output prompts, since it is
283 283 left-padded to match lengths with the primary one (if the
284 284 self.pad_left attribute is set)."""
285 285
286 286 out_str = str_safe(self.p_str)
287 287 if self.pad_left:
288 288 # We must find the amount of padding required to match lengths,
289 289 # taking the color escapes (which are invisible on-screen) into
290 290 # account.
291 291 esc_pad = len(out_str) - len(str_safe(self.p_str_nocolor))
292 292 format = '%%%ss' % (len(str(self.cache.last_prompt))+esc_pad)
293 293 return format % out_str
294 294 else:
295 295 return out_str
296 296
297 297 # these path filters are put in as methods so that we can control the
298 298 # namespace where the prompt strings get evaluated
299 299 def cwd_filt(self,depth):
300 300 """Return the last depth elements of the current working directory.
301 301
302 302 $HOME is always replaced with '~'.
303 303 If depth==0, the full path is returned."""
304 304
305 305 cwd = os.getcwd().replace(HOME,"~")
306 306 out = os.sep.join(cwd.split(os.sep)[-depth:])
307 307 if out:
308 308 return out
309 309 else:
310 310 return os.sep
311 311
312 312 def cwd_filt2(self,depth):
313 313 """Return the last depth elements of the current working directory.
314 314
315 315 $HOME is always replaced with '~'.
316 316 If depth==0, the full path is returned."""
317 317
318 318 full_cwd = os.getcwd()
319 319 cwd = full_cwd.replace(HOME,"~").split(os.sep)
320 320 if '~' in cwd and len(cwd) == depth+1:
321 321 depth += 1
322 322 drivepart = ''
323 323 if sys.platform == 'win32' and len(cwd) > depth:
324 324 drivepart = os.path.splitdrive(full_cwd)[0]
325 325 out = drivepart + '/'.join(cwd[-depth:])
326 326
327 327 if out:
328 328 return out
329 329 else:
330 330 return os.sep
331 331
332 332 def __nonzero__(self):
333 333 """Implement boolean behavior.
334 334
335 335 Checks whether the p_str attribute is non-empty"""
336 336
337 337 return bool(self.p_template)
338 338
339 339 class Prompt1(BasePrompt):
340 340 """Input interactive prompt similar to Mathematica's."""
341 341
342 342 def __init__(self,cache,sep='\n',prompt='In [\\#]: ',pad_left=True):
343 343 BasePrompt.__init__(self,cache,sep,prompt,pad_left)
344 344
345 345 def set_colors(self):
346 346 self.set_p_str()
347 347 Colors = self.cache.color_table.active_colors # shorthand
348 348 self.col_p = Colors.in_prompt
349 349 self.col_num = Colors.in_number
350 350 self.col_norm = Colors.in_normal
351 351 # We need a non-input version of these escapes for the '--->'
352 352 # auto-call prompts used in the auto_rewrite() method.
353 353 self.col_p_ni = self.col_p.replace('\001','').replace('\002','')
354 354 self.col_norm_ni = Colors.normal
355 355
356 356 def __str__(self):
357 357 self.cache.prompt_count += 1
358 358 self.cache.last_prompt = str_safe(self.p_str_nocolor).split('\n')[-1]
359 359 return str_safe(self.p_str)
360 360
361 361 def auto_rewrite(self):
362 362 """Print a string of the form '--->' which lines up with the previous
363 363 input string. Useful for systems which re-write the user input when
364 364 handling automatically special syntaxes."""
365 365
366 366 curr = str(self.cache.last_prompt)
367 367 nrspaces = len(self.rspace.search(curr).group())
368 368 return '%s%s>%s%s' % (self.col_p_ni,'-'*(len(curr)-nrspaces-1),
369 369 ' '*nrspaces,self.col_norm_ni)
370 370
371 371 class PromptOut(BasePrompt):
372 372 """Output interactive prompt similar to Mathematica's."""
373 373
374 374 def __init__(self,cache,sep='',prompt='Out[\\#]: ',pad_left=True):
375 375 BasePrompt.__init__(self,cache,sep,prompt,pad_left)
376 376 if not self.p_template:
377 377 self.__str__ = lambda: ''
378 378
379 379 def set_colors(self):
380 380 self.set_p_str()
381 381 Colors = self.cache.color_table.active_colors # shorthand
382 382 self.col_p = Colors.out_prompt
383 383 self.col_num = Colors.out_number
384 384 self.col_norm = Colors.normal
385 385
386 386 class Prompt2(BasePrompt):
387 387 """Interactive continuation prompt."""
388 388
389 389 def __init__(self,cache,prompt=' .\\D.: ',pad_left=True):
390 390 self.cache = cache
391 391 self.p_template = prompt
392 392 self.pad_left = pad_left
393 393 self.set_p_str()
394 394
395 395 def set_p_str(self):
396 396 import os,time # needed in locals for prompt string handling
397 397 loc = locals()
398 398 self.p_str = ItplNS('%s%s%s' %
399 399 ('${self.col_p2}',
400 400 multiple_replace(prompt_specials, self.p_template),
401 401 '$self.col_norm'),
402 402 self.cache.user_ns,loc)
403 403 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
404 404 self.p_template),
405 405 self.cache.user_ns,loc)
406 406
407 407 def set_colors(self):
408 408 self.set_p_str()
409 409 Colors = self.cache.color_table.active_colors
410 410 self.col_p2 = Colors.in_prompt2
411 411 self.col_norm = Colors.in_normal
412 412 # FIXME (2004-06-16) HACK: prevent crashes for users who haven't
413 413 # updated their prompt_in2 definitions. Remove eventually.
414 414 self.col_p = Colors.out_prompt
415 415 self.col_num = Colors.out_number
416 416
417 417
418 418 #-----------------------------------------------------------------------------
419 419 class CachedOutput:
420 420 """Class for printing output from calculations while keeping a cache of
421 421 reults. It dynamically creates global variables prefixed with _ which
422 422 contain these results.
423 423
424 424 Meant to be used as a sys.displayhook replacement, providing numbered
425 425 prompts and cache services.
426 426
427 427 Initialize with initial and final values for cache counter (this defines
428 428 the maximum size of the cache."""
429 429
430 430 def __init__(self,shell,cache_size,Pprint,
431 431 colors='NoColor',input_sep='\n',
432 432 output_sep='\n',output_sep2='',
433 433 ps1 = None, ps2 = None,ps_out = None,pad_left=True):
434 434
435 435 cache_size_min = 3
436 436 if cache_size <= 0:
437 437 self.do_full_cache = 0
438 438 cache_size = 0
439 439 elif cache_size < cache_size_min:
440 440 self.do_full_cache = 0
441 441 cache_size = 0
442 442 warn('caching was disabled (min value for cache size is %s).' %
443 443 cache_size_min,level=3)
444 444 else:
445 445 self.do_full_cache = 1
446 446
447 447 self.cache_size = cache_size
448 448 self.input_sep = input_sep
449 449
450 450 # we need a reference to the user-level namespace
451 451 self.shell = shell
452 452 self.user_ns = shell.user_ns
453 453 # and to the user's input
454 454 self.input_hist = shell.input_hist
455 455 # and to the user's logger, for logging output
456 456 self.logger = shell.logger
457 457
458 458 # Set input prompt strings and colors
459 459 if cache_size == 0:
460 460 if ps1.find('%n') > -1 or ps1.find(r'\#') > -1 \
461 461 or ps1.find(r'\N') > -1:
462 462 ps1 = '>>> '
463 463 if ps2.find('%n') > -1 or ps2.find(r'\#') > -1 \
464 464 or ps2.find(r'\N') > -1:
465 465 ps2 = '... '
466 466 self.ps1_str = self._set_prompt_str(ps1,'In [\\#]: ','>>> ')
467 467 self.ps2_str = self._set_prompt_str(ps2,' .\\D.: ','... ')
468 468 self.ps_out_str = self._set_prompt_str(ps_out,'Out[\\#]: ','')
469 469
470 470 self.color_table = PromptColors
471 471 self.prompt1 = Prompt1(self,sep=input_sep,prompt=self.ps1_str,
472 472 pad_left=pad_left)
473 473 self.prompt2 = Prompt2(self,prompt=self.ps2_str,pad_left=pad_left)
474 474 self.prompt_out = PromptOut(self,sep='',prompt=self.ps_out_str,
475 475 pad_left=pad_left)
476 476 self.set_colors(colors)
477 477
478 478 # other more normal stuff
479 479 # b/c each call to the In[] prompt raises it by 1, even the first.
480 480 self.prompt_count = 0
481 481 # Store the last prompt string each time, we need it for aligning
482 482 # continuation and auto-rewrite prompts
483 483 self.last_prompt = ''
484 484 self.Pprint = Pprint
485 485 self.output_sep = output_sep
486 486 self.output_sep2 = output_sep2
487 487 self._,self.__,self.___ = '','',''
488 488 self.pprint_types = map(type,[(),[],{}])
489 489
490 490 # these are deliberately global:
491 491 to_user_ns = {'_':self._,'__':self.__,'___':self.___}
492 492 self.user_ns.update(to_user_ns)
493 493
494 494 def _set_prompt_str(self,p_str,cache_def,no_cache_def):
495 495 if p_str is None:
496 496 if self.do_full_cache:
497 497 return cache_def
498 498 else:
499 499 return no_cache_def
500 500 else:
501 501 return p_str
502 502
503 503 def set_colors(self,colors):
504 504 """Set the active color scheme and configure colors for the three
505 505 prompt subsystems."""
506 506
507 507 # FIXME: the prompt_specials global should be gobbled inside this
508 508 # class instead. Do it when cleaning up the whole 3-prompt system.
509 509 global prompt_specials
510 510 if colors.lower()=='nocolor':
511 511 prompt_specials = prompt_specials_nocolor
512 512 else:
513 513 prompt_specials = prompt_specials_color
514 514
515 515 self.color_table.set_active_scheme(colors)
516 516 self.prompt1.set_colors()
517 517 self.prompt2.set_colors()
518 518 self.prompt_out.set_colors()
519 519
520 520 def __call__(self,arg=None):
521 521 """Printing with history cache management.
522 522
523 523 This is invoked everytime the interpreter needs to print, and is
524 524 activated by setting the variable sys.displayhook to it."""
525 525
526 526 # If something injected a '_' variable in __builtin__, delete
527 527 # ipython's automatic one so we don't clobber that. gettext() in
528 528 # particular uses _, so we need to stay away from it.
529 529 if '_' in __builtin__.__dict__:
530 530 try:
531 531 del self.user_ns['_']
532 532 except KeyError:
533 533 pass
534 534 if arg is not None:
535 535 cout_write = Term.cout.write # fast lookup
536 536 # first handle the cache and counters
537 537
538 538 # do not print output if input ends in ';'
539 539 try:
540 540 if self.input_hist[self.prompt_count].endswith(';\n'):
541 541 return
542 542 except IndexError:
543 543 # some uses of ipshellembed may fail here
544 544 pass
545 545 # don't use print, puts an extra space
546 546 cout_write(self.output_sep)
547 547 outprompt = self.shell.hooks.generate_output_prompt()
548 548 if self.do_full_cache:
549 549 cout_write(outprompt)
550 550
551 551 # and now call a possibly user-defined print mechanism
552 552 manipulated_val = self.display(arg)
553 553
554 554 # user display hooks can change the variable to be stored in
555 555 # output history
556 556
557 557 if manipulated_val is not None:
558 558 arg = manipulated_val
559 559
560 560 # avoid recursive reference when displaying _oh/Out
561 561 if arg is not self.user_ns['_oh']:
562 562 self.update(arg)
563 563
564 564 if self.logger.log_output:
565 565 self.logger.log_write(repr(arg),'output')
566 566 cout_write(self.output_sep2)
567 567 Term.cout.flush()
568 568
569 569 def _display(self,arg):
570 570 """Default printer method, uses pprint.
571 571
572 572 Do ip.set_hook("result_display", my_displayhook) for custom result
573 573 display, e.g. when your own objects need special formatting.
574 574 """
575 575 try:
576 576 return IPython.generics.result_display(arg)
577 577 except TryNext:
578 578 return self.shell.hooks.result_display(arg)
579 579
580 580 # Assign the default display method:
581 581 display = _display
582 582
583 583 def update(self,arg):
584 584 #print '***cache_count', self.cache_count # dbg
585 585 if len(self.user_ns['_oh']) >= self.cache_size and self.do_full_cache:
586 586 warn('Output cache limit (currently '+
587 587 `self.cache_size`+' entries) hit.\n'
588 588 'Flushing cache and resetting history counter...\n'
589 589 'The only history variables available will be _,__,___ and _1\n'
590 590 'with the current result.')
591 591
592 592 self.flush()
593 593 # Don't overwrite '_' and friends if '_' is in __builtin__ (otherwise
594 594 # we cause buggy behavior for things like gettext).
595 595 if '_' not in __builtin__.__dict__:
596 596 self.___ = self.__
597 597 self.__ = self._
598 598 self._ = arg
599 599 self.user_ns.update({'_':self._,'__':self.__,'___':self.___})
600 600
601 601 # hackish access to top-level namespace to create _1,_2... dynamically
602 602 to_main = {}
603 603 if self.do_full_cache:
604 604 new_result = '_'+`self.prompt_count`
605 605 to_main[new_result] = arg
606 606 self.user_ns.update(to_main)
607 607 self.user_ns['_oh'][self.prompt_count] = arg
608 608
609 609 def flush(self):
610 610 if not self.do_full_cache:
611 611 raise ValueError,"You shouldn't have reached the cache flush "\
612 612 "if full caching is not enabled!"
613 613 # delete auto-generated vars from global namespace
614 614
615 615 for n in range(1,self.prompt_count + 1):
616 616 key = '_'+`n`
617 617 try:
618 618 del self.user_ns[key]
619 619 except: pass
620 620 self.user_ns['_oh'].clear()
621 621
622 622 if '_' not in __builtin__.__dict__:
623 623 self.user_ns.update({'_':None,'__':None, '___':None})
624 624 import gc
625 625 gc.collect() # xxx needed?
626 626
@@ -1,300 +1,299 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Class and program to colorize python source code for ANSI terminals.
4 4
5 5 Based on an HTML code highlighter by Jurgen Hermann found at:
6 6 http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52298
7 7
8 8 Modifications by Fernando Perez (fperez@colorado.edu).
9 9
10 10 Information on the original HTML highlighter follows:
11 11
12 12 MoinMoin - Python Source Parser
13 13
14 14 Title: Colorize Python source using the built-in tokenizer
15 15
16 16 Submitter: Jurgen Hermann
17 17 Last Updated:2001/04/06
18 18
19 19 Version no:1.2
20 20
21 21 Description:
22 22
23 23 This code is part of MoinMoin (http://moin.sourceforge.net/) and converts
24 24 Python source code to HTML markup, rendering comments, keywords,
25 25 operators, numeric and string literals in different colors.
26 26
27 27 It shows how to use the built-in keyword, token and tokenize modules to
28 28 scan Python source code and re-emit it with no changes to its original
29 29 formatting (which is the hard part).
30 30 """
31 31
32 32 __all__ = ['ANSICodeColors','Parser']
33 33
34 34 _scheme_default = 'Linux'
35 35
36 36 # Imports
37 37 import cStringIO
38 38 import keyword
39 39 import os
40 40 import optparse
41 import string
42 41 import sys
43 42 import token
44 43 import tokenize
45 44
46 from IPython.ColorANSI import *
45 from IPython.utils.coloransi import *
47 46
48 47 #############################################################################
49 48 ### Python Source Parser (does Hilighting)
50 49 #############################################################################
51 50
52 51 _KEYWORD = token.NT_OFFSET + 1
53 52 _TEXT = token.NT_OFFSET + 2
54 53
55 54 #****************************************************************************
56 55 # Builtin color schemes
57 56
58 57 Colors = TermColors # just a shorthand
59 58
60 59 # Build a few color schemes
61 60 NoColor = ColorScheme(
62 61 'NoColor',{
63 62 token.NUMBER : Colors.NoColor,
64 63 token.OP : Colors.NoColor,
65 64 token.STRING : Colors.NoColor,
66 65 tokenize.COMMENT : Colors.NoColor,
67 66 token.NAME : Colors.NoColor,
68 67 token.ERRORTOKEN : Colors.NoColor,
69 68
70 69 _KEYWORD : Colors.NoColor,
71 70 _TEXT : Colors.NoColor,
72 71
73 72 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
74 73 } )
75 74
76 75 LinuxColors = ColorScheme(
77 76 'Linux',{
78 77 token.NUMBER : Colors.LightCyan,
79 78 token.OP : Colors.Yellow,
80 79 token.STRING : Colors.LightBlue,
81 80 tokenize.COMMENT : Colors.LightRed,
82 81 token.NAME : Colors.White,
83 82 token.ERRORTOKEN : Colors.Red,
84 83
85 84 _KEYWORD : Colors.LightGreen,
86 85 _TEXT : Colors.Yellow,
87 86
88 87 'normal' : Colors.Normal # color off (usu. Colors.Normal)
89 88 } )
90 89
91 90 LightBGColors = ColorScheme(
92 91 'LightBG',{
93 92 token.NUMBER : Colors.Cyan,
94 93 token.OP : Colors.Blue,
95 94 token.STRING : Colors.Blue,
96 95 tokenize.COMMENT : Colors.Red,
97 96 token.NAME : Colors.Black,
98 97 token.ERRORTOKEN : Colors.Red,
99 98
100 99 _KEYWORD : Colors.Green,
101 100 _TEXT : Colors.Blue,
102 101
103 102 'normal' : Colors.Normal # color off (usu. Colors.Normal)
104 103 } )
105 104
106 105 # Build table of color schemes (needed by the parser)
107 106 ANSICodeColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
108 107 _scheme_default)
109 108
110 109 class Parser:
111 110 """ Format colored Python source.
112 111 """
113 112
114 113 def __init__(self, color_table=None,out = sys.stdout):
115 114 """ Create a parser with a specified color table and output channel.
116 115
117 116 Call format() to process code.
118 117 """
119 118 self.color_table = color_table and color_table or ANSICodeColors
120 119 self.out = out
121 120
122 121 def format(self, raw, out = None, scheme = ''):
123 122 return self.format2(raw, out, scheme)[0]
124 123
125 124 def format2(self, raw, out = None, scheme = ''):
126 125 """ Parse and send the colored source.
127 126
128 127 If out and scheme are not specified, the defaults (given to
129 128 constructor) are used.
130 129
131 130 out should be a file-type object. Optionally, out can be given as the
132 131 string 'str' and the parser will automatically return the output in a
133 132 string."""
134 133
135 134 string_output = 0
136 135 if out == 'str' or self.out == 'str' or \
137 136 isinstance(self.out,cStringIO.OutputType):
138 137 # XXX - I don't really like this state handling logic, but at this
139 138 # point I don't want to make major changes, so adding the
140 139 # isinstance() check is the simplest I can do to ensure correct
141 140 # behavior.
142 141 out_old = self.out
143 142 self.out = cStringIO.StringIO()
144 143 string_output = 1
145 144 elif out is not None:
146 145 self.out = out
147 146
148 147 # Fast return of the unmodified input for NoColor scheme
149 148 if scheme == 'NoColor':
150 149 error = False
151 150 self.out.write(raw)
152 151 if string_output:
153 152 return raw,error
154 153 else:
155 154 return None,error
156 155
157 156 # local shorthands
158 157 colors = self.color_table[scheme].colors
159 158 self.colors = colors # put in object so __call__ sees it
160 159
161 160 # Remove trailing whitespace and normalize tabs
162 161 self.raw = raw.expandtabs().rstrip()
163 162
164 163 # store line offsets in self.lines
165 164 self.lines = [0, 0]
166 165 pos = 0
167 166 raw_find = self.raw.find
168 167 lines_append = self.lines.append
169 168 while 1:
170 169 pos = raw_find('\n', pos) + 1
171 170 if not pos: break
172 171 lines_append(pos)
173 172 lines_append(len(self.raw))
174 173
175 174 # parse the source and write it
176 175 self.pos = 0
177 176 text = cStringIO.StringIO(self.raw)
178 177
179 178 error = False
180 179 try:
181 180 tokenize.tokenize(text.readline, self)
182 181 except tokenize.TokenError, ex:
183 182 msg = ex[0]
184 183 line = ex[1][0]
185 184 self.out.write("%s\n\n*** ERROR: %s%s%s\n" %
186 185 (colors[token.ERRORTOKEN],
187 186 msg, self.raw[self.lines[line]:],
188 187 colors.normal)
189 188 )
190 189 error = True
191 190 self.out.write(colors.normal+'\n')
192 191 if string_output:
193 192 output = self.out.getvalue()
194 193 self.out = out_old
195 194 return (output, error)
196 195 return (None, error)
197 196
198 197 def __call__(self, toktype, toktext, (srow,scol), (erow,ecol), line):
199 198 """ Token handler, with syntax highlighting."""
200 199
201 200 # local shorthands
202 201 colors = self.colors
203 202 owrite = self.out.write
204 203
205 204 # line separator, so this works across platforms
206 205 linesep = os.linesep
207 206
208 207 # calculate new positions
209 208 oldpos = self.pos
210 209 newpos = self.lines[srow] + scol
211 210 self.pos = newpos + len(toktext)
212 211
213 212 # handle newlines
214 213 if toktype in [token.NEWLINE, tokenize.NL]:
215 214 owrite(linesep)
216 215 return
217 216
218 217 # send the original whitespace, if needed
219 218 if newpos > oldpos:
220 219 owrite(self.raw[oldpos:newpos])
221 220
222 221 # skip indenting tokens
223 222 if toktype in [token.INDENT, token.DEDENT]:
224 223 self.pos = newpos
225 224 return
226 225
227 226 # map token type to a color group
228 227 if token.LPAR <= toktype and toktype <= token.OP:
229 228 toktype = token.OP
230 229 elif toktype == token.NAME and keyword.iskeyword(toktext):
231 230 toktype = _KEYWORD
232 231 color = colors.get(toktype, colors[_TEXT])
233 232
234 233 #print '<%s>' % toktext, # dbg
235 234
236 235 # Triple quoted strings must be handled carefully so that backtracking
237 236 # in pagers works correctly. We need color terminators on _each_ line.
238 237 if linesep in toktext:
239 238 toktext = toktext.replace(linesep, '%s%s%s' %
240 239 (colors.normal,linesep,color))
241 240
242 241 # send text
243 242 owrite('%s%s%s' % (color,toktext,colors.normal))
244 243
245 244 def main(argv=None):
246 245 """Run as a command-line script: colorize a python file or stdin using ANSI
247 246 color escapes and print to stdout.
248 247
249 248 Inputs:
250 249
251 250 - argv(None): a list of strings like sys.argv[1:] giving the command-line
252 251 arguments. If None, use sys.argv[1:].
253 252 """
254 253
255 254 usage_msg = """%prog [options] [filename]
256 255
257 256 Colorize a python file or stdin using ANSI color escapes and print to stdout.
258 257 If no filename is given, or if filename is -, read standard input."""
259 258
260 259 parser = optparse.OptionParser(usage=usage_msg)
261 260 newopt = parser.add_option
262 261 newopt('-s','--scheme',metavar='NAME',dest='scheme_name',action='store',
263 262 choices=['Linux','LightBG','NoColor'],default=_scheme_default,
264 263 help="give the color scheme to use. Currently only 'Linux'\
265 264 (default) and 'LightBG' and 'NoColor' are implemented (give without\
266 265 quotes)")
267 266
268 267 opts,args = parser.parse_args(argv)
269 268
270 269 if len(args) > 1:
271 270 parser.error("you must give at most one filename.")
272 271
273 272 if len(args) == 0:
274 273 fname = '-' # no filename given; setup to read from stdin
275 274 else:
276 275 fname = args[0]
277 276
278 277 if fname == '-':
279 278 stream = sys.stdin
280 279 else:
281 280 stream = file(fname)
282 281
283 282 parser = Parser()
284 283
285 284 # we need nested try blocks because pre-2.5 python doesn't support unified
286 285 # try-except-finally
287 286 try:
288 287 try:
289 288 # write colorized version to stdout
290 289 parser.format(stream.read(),scheme=opts.scheme_name)
291 290 except IOError,msg:
292 291 # if user reads through a pager and quits, don't print traceback
293 292 if msg.args != (32,'Broken pipe'):
294 293 raise
295 294 finally:
296 295 if stream is not sys.stdin:
297 296 stream.close() # in case a non-handled exception happened above
298 297
299 298 if __name__ == "__main__":
300 299 main()
1 NO CONTENT: modified file
@@ -1,137 +1,137 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Color schemes for exception handling code in IPython.
4 4 """
5 5
6 6 #*****************************************************************************
7 7 # Copyright (C) 2005-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 # Required modules
15 from IPython.ColorANSI import ColorSchemeTable, TermColors, ColorScheme
15 from IPython.utils.coloransi import ColorSchemeTable, TermColors, ColorScheme
16 16
17 17 def exception_colors():
18 18 """Return a color table with fields for exception reporting.
19 19
20 20 The table is an instance of ColorSchemeTable with schemes added for
21 21 'Linux', 'LightBG' and 'NoColor' and fields for exception handling filled
22 22 in.
23 23
24 24 Examples:
25 25
26 26 >>> ec = exception_colors()
27 27 >>> ec.active_scheme_name
28 28 ''
29 29 >>> print ec.active_colors
30 30 None
31 31
32 32 Now we activate a color scheme:
33 33 >>> ec.set_active_scheme('NoColor')
34 34 >>> ec.active_scheme_name
35 35 'NoColor'
36 36 >>> ec.active_colors.keys()
37 37 ['em', 'caret', '__allownew', 'name', 'val', 'vName', 'Normal', 'normalEm',
38 38 'filename', 'linenoEm', 'excName', 'lineno', 'valEm', 'filenameEm',
39 39 'nameEm', 'line', 'topline']
40 40 """
41 41
42 42 ex_colors = ColorSchemeTable()
43 43
44 44 # Populate it with color schemes
45 45 C = TermColors # shorthand and local lookup
46 46 ex_colors.add_scheme(ColorScheme(
47 47 'NoColor',
48 48 # The color to be used for the top line
49 49 topline = C.NoColor,
50 50
51 51 # The colors to be used in the traceback
52 52 filename = C.NoColor,
53 53 lineno = C.NoColor,
54 54 name = C.NoColor,
55 55 vName = C.NoColor,
56 56 val = C.NoColor,
57 57 em = C.NoColor,
58 58
59 59 # Emphasized colors for the last frame of the traceback
60 60 normalEm = C.NoColor,
61 61 filenameEm = C.NoColor,
62 62 linenoEm = C.NoColor,
63 63 nameEm = C.NoColor,
64 64 valEm = C.NoColor,
65 65
66 66 # Colors for printing the exception
67 67 excName = C.NoColor,
68 68 line = C.NoColor,
69 69 caret = C.NoColor,
70 70 Normal = C.NoColor
71 71 ))
72 72
73 73 # make some schemes as instances so we can copy them for modification easily
74 74 ex_colors.add_scheme(ColorScheme(
75 75 'Linux',
76 76 # The color to be used for the top line
77 77 topline = C.LightRed,
78 78
79 79 # The colors to be used in the traceback
80 80 filename = C.Green,
81 81 lineno = C.Green,
82 82 name = C.Purple,
83 83 vName = C.Cyan,
84 84 val = C.Green,
85 85 em = C.LightCyan,
86 86
87 87 # Emphasized colors for the last frame of the traceback
88 88 normalEm = C.LightCyan,
89 89 filenameEm = C.LightGreen,
90 90 linenoEm = C.LightGreen,
91 91 nameEm = C.LightPurple,
92 92 valEm = C.LightBlue,
93 93
94 94 # Colors for printing the exception
95 95 excName = C.LightRed,
96 96 line = C.Yellow,
97 97 caret = C.White,
98 98 Normal = C.Normal
99 99 ))
100 100
101 101 # For light backgrounds, swap dark/light colors
102 102 ex_colors.add_scheme(ColorScheme(
103 103 'LightBG',
104 104 # The color to be used for the top line
105 105 topline = C.Red,
106 106
107 107 # The colors to be used in the traceback
108 108 filename = C.LightGreen,
109 109 lineno = C.LightGreen,
110 110 name = C.LightPurple,
111 111 vName = C.Cyan,
112 112 val = C.LightGreen,
113 113 em = C.Cyan,
114 114
115 115 # Emphasized colors for the last frame of the traceback
116 116 normalEm = C.Cyan,
117 117 filenameEm = C.Green,
118 118 linenoEm = C.Green,
119 119 nameEm = C.Purple,
120 120 valEm = C.Blue,
121 121
122 122 # Colors for printing the exception
123 123 excName = C.Red,
124 124 #line = C.Brown, # brown often is displayed as yellow
125 125 line = C.Red,
126 126 caret = C.Normal,
127 127 Normal = C.Normal,
128 128 ))
129 129
130 130 return ex_colors
131 131
132 132
133 133 # For backwards compatibility, keep around a single global object. Note that
134 134 # this should NOT be used, the factory function should be used instead, since
135 135 # these objects are stateful and it's very easy to get strange bugs if any code
136 136 # modifies the module-level object's state.
137 137 ExceptionColors = exception_colors()
@@ -1,625 +1,625 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 # XXX: Maybe one day we should factor this code with ColorANSI. Right now
109 # ColorANSI is hard to reuse and makes our code more complex.
108 # XXX: Maybe one day we should factor this code with coloransi. Right now
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 450 if event.KeyCode == ord('L') and event.ControlDown() :
451 451 self.scroll_to_bottom()
452 452 elif event.KeyCode == ord('K') and event.ControlDown() :
453 453 self.input_buffer = ''
454 454 elif event.KeyCode == ord('A') and event.ControlDown() :
455 455 self.GotoPos(self.GetLength())
456 456 self.SetSelectionStart(self.current_prompt_pos)
457 457 self.SetSelectionEnd(self.GetCurrentPos())
458 458 catched = True
459 459 elif event.KeyCode == ord('E') and event.ControlDown() :
460 460 self.GotoPos(self.GetLength())
461 461 catched = True
462 462 elif event.KeyCode == wx.WXK_PAGEUP:
463 463 self.ScrollPages(-1)
464 464 elif event.KeyCode == wx.WXK_PAGEDOWN:
465 465 self.ScrollPages(1)
466 466 elif event.KeyCode == wx.WXK_HOME:
467 467 self.GotoPos(self.GetLength())
468 468 elif event.KeyCode == wx.WXK_END:
469 469 self.GotoPos(self.GetLength())
470 470 elif event.KeyCode == wx.WXK_UP and event.ShiftDown():
471 471 self.ScrollLines(-1)
472 472 elif event.KeyCode == wx.WXK_DOWN and event.ShiftDown():
473 473 self.ScrollLines(1)
474 474 else:
475 475 catched = False
476 476
477 477 if self.AutoCompActive():
478 478 event.Skip()
479 479 else:
480 480 if event.KeyCode in (13, wx.WXK_NUMPAD_ENTER) and \
481 481 event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN,
482 482 wx.MOD_SHIFT):
483 483 catched = True
484 484 if not self.enter_catched:
485 485 self.CallTipCancel()
486 486 if event.Modifiers == wx.MOD_SHIFT:
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 496 elif event.KeyCode == wx.WXK_HOME:
497 497 if event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN):
498 498 self.GotoPos(self.current_prompt_pos)
499 499 catched = True
500 500
501 501 elif event.Modifiers == wx.MOD_SHIFT:
502 502 # FIXME: This behavior is not ideal: if the selection
503 503 # is already started, it will jump.
504 504 self.SetSelectionStart(self.current_prompt_pos)
505 505 self.SetSelectionEnd(self.GetCurrentPos())
506 506 catched = True
507 507
508 508 elif event.KeyCode == wx.WXK_UP:
509 509 if self.GetCurrentLine() > self.current_prompt_line:
510 510 if self.GetCurrentLine() == self.current_prompt_line + 1 \
511 511 and self.GetColumn(self.GetCurrentPos()) < \
512 512 self.GetColumn(self.current_prompt_pos):
513 513 self.GotoPos(self.current_prompt_pos)
514 514 else:
515 515 event.Skip()
516 516 catched = True
517 517
518 518 elif event.KeyCode in (wx.WXK_LEFT, wx.WXK_BACK):
519 519 if not self._keep_cursor_in_buffer(self.GetCurrentPos() - 1):
520 520 event.Skip()
521 521 catched = True
522 522
523 523 elif event.KeyCode == wx.WXK_RIGHT:
524 524 if not self._keep_cursor_in_buffer(self.GetCurrentPos() + 1):
525 525 event.Skip()
526 526 catched = True
527 527
528 528
529 529 elif event.KeyCode == wx.WXK_DELETE:
530 530 if not self._keep_cursor_in_buffer(self.GetCurrentPos() - 1):
531 531 event.Skip()
532 532 catched = True
533 533
534 534 if skip and not catched:
535 535 # Put the cursor back in the edit region
536 536 if not self._keep_cursor_in_buffer():
537 537 if not (self.GetCurrentPos() == self.GetLength()
538 538 and event.KeyCode == wx.WXK_DELETE):
539 539 event.Skip()
540 540 catched = True
541 541
542 542 return catched
543 543
544 544
545 545 def _on_key_up(self, event, skip=True):
546 546 """ If cursor is outside the editing region, put it back.
547 547 """
548 548 if skip:
549 549 event.Skip()
550 550 self._keep_cursor_in_buffer()
551 551
552 552
553 553 # XXX: I need to avoid the problem of having an empty glass;
554 554 def _keep_cursor_in_buffer(self, pos=None):
555 555 """ Checks if the cursor is where it is allowed to be. If not,
556 556 put it back.
557 557
558 558 Returns
559 559 -------
560 560 cursor_moved: Boolean
561 561 whether or not the cursor was moved by this routine.
562 562
563 563 Notes
564 564 ------
565 565 WARNING: This does proper checks only for horizontal
566 566 movements.
567 567 """
568 568 if pos is None:
569 569 current_pos = self.GetCurrentPos()
570 570 else:
571 571 current_pos = pos
572 572 if current_pos < self.current_prompt_pos:
573 573 self.GotoPos(self.current_prompt_pos)
574 574 return True
575 575 line_num = self.LineFromPosition(current_pos)
576 576 if not current_pos > self.GetLength():
577 577 line_pos = self.GetColumn(current_pos)
578 578 else:
579 579 line_pos = self.GetColumn(self.GetLength())
580 580 line = self.GetLine(line_num)
581 581 # Jump the continuation prompt
582 582 continuation_prompt = self.continuation_prompt()
583 583 if ( line.startswith(continuation_prompt)
584 584 and line_pos < len(continuation_prompt)):
585 585 if line_pos < 2:
586 586 # We are at the beginning of the line, trying to move
587 587 # forward: jump forward.
588 588 self.GotoPos(current_pos + 1 +
589 589 len(continuation_prompt) - line_pos)
590 590 else:
591 591 # Jump back up
592 592 self.GotoPos(self.GetLineEndPosition(line_num-1))
593 593 return True
594 594 elif ( current_pos > self.GetLineEndPosition(line_num)
595 595 and not current_pos == self.GetLength()):
596 596 # Jump to next line
597 597 self.GotoPos(current_pos + 1 +
598 598 len(continuation_prompt))
599 599 return True
600 600
601 601 # We re-allow enter event processing
602 602 self.enter_catched = False
603 603 return False
604 604
605 605
606 606 if __name__ == '__main__':
607 607 # Some simple code to test the console widget.
608 608 class MainWindow(wx.Frame):
609 609 def __init__(self, parent, id, title):
610 610 wx.Frame.__init__(self, parent, id, title, size=(300, 250))
611 611 self._sizer = wx.BoxSizer(wx.VERTICAL)
612 612 self.console_widget = ConsoleWidget(self)
613 613 self._sizer.Add(self.console_widget, 1, wx.EXPAND)
614 614 self.SetSizer(self._sizer)
615 615 self.SetAutoLayout(1)
616 616 self.Show(True)
617 617
618 618 app = wx.PySimpleApp()
619 619 w = MainWindow(None, wx.ID_ANY, 'ConsoleWidget')
620 620 w.SetSize((780, 460))
621 621 w.Show()
622 622
623 623 app.MainLoop()
624 624
625 625
@@ -1,2870 +1,2862 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 import cPickle as pickle
35 34 import codeop
36 35 import exceptions
37 36 import glob
38 import inspect
39 37 import keyword
40 38 import new
41 39 import os
42 import pydoc
43 40 import re
44 41 import shutil
45 42 import string
46 43 import sys
47 44 import tempfile
48 import traceback
49 import types
50 from pprint import pprint, pformat
51 45
52 46 # IPython's own modules
53 47 #import IPython
54 48 from IPython import Debugger,OInspect,PyColorize,ultraTB
55 from IPython.ColorANSI import ColorScheme,ColorSchemeTable # too long names
56 49 from IPython.Extensions import pickleshare
57 50 from IPython.FakeModule import FakeModule, init_fakemod_dict
58 from IPython.Itpl import Itpl,itpl,printpl,ItplNS,itplns
51 from IPython.Itpl import ItplNS
59 52 from IPython.Logger import Logger
60 53 from IPython.Magic import Magic
61 54 from IPython.Prompts import CachedOutput
62 55 from IPython.ipstruct import Struct
63 56 from IPython.background_jobs import BackgroundJobManager
64 from IPython.usage import cmd_line_usage,interactive_usage
65 57 from IPython.genutils import *
66 58 from IPython.strdispatch import StrDispatch
67 59 import IPython.ipapi
68 60 import IPython.history
69 61 import IPython.prefilter as prefilter
70 62 import IPython.shadowns
71 63 # Globals
72 64
73 65 # store the builtin raw_input globally, and use this always, in case user code
74 66 # overwrites it (like wx.py.PyShell does)
75 67 raw_input_original = raw_input
76 68
77 69 # compiled regexps for autoindent management
78 70 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
79 71
80 72
81 73 #****************************************************************************
82 74 # Some utility function definitions
83 75
84 76 ini_spaces_re = re.compile(r'^(\s+)')
85 77
86 78 def num_ini_spaces(strng):
87 79 """Return the number of initial spaces in a string"""
88 80
89 81 ini_spaces = ini_spaces_re.match(strng)
90 82 if ini_spaces:
91 83 return ini_spaces.end()
92 84 else:
93 85 return 0
94 86
95 87 def softspace(file, newvalue):
96 88 """Copied from code.py, to remove the dependency"""
97 89
98 90 oldvalue = 0
99 91 try:
100 92 oldvalue = file.softspace
101 93 except AttributeError:
102 94 pass
103 95 try:
104 96 file.softspace = newvalue
105 97 except (AttributeError, TypeError):
106 98 # "attribute-less object" or "read-only attributes"
107 99 pass
108 100 return oldvalue
109 101
110 102
111 103 def user_setup(ipythondir,rc_suffix,mode='install',interactive=True):
112 104 """Install or upgrade the user configuration directory.
113 105
114 106 Can be called when running for the first time or to upgrade the user's
115 107 .ipython/ directory.
116 108
117 109 Parameters
118 110 ----------
119 111 ipythondir : path
120 112 The directory to be used for installation/upgrade. In 'install' mode,
121 113 if this path already exists, the function exits immediately.
122 114
123 115 rc_suffix : str
124 116 Extension for the config files. On *nix platforms it is typically the
125 117 empty string, while Windows normally uses '.ini'.
126 118
127 119 mode : str, optional
128 120 Valid modes are 'install' and 'upgrade'.
129 121
130 122 interactive : bool, optional
131 123 If False, do not wait for user input on any errors. Normally after
132 124 printing its status information, this function waits for the user to
133 125 hit Return before proceeding. This is because the default use case is
134 126 when first installing the IPython configuration, so we want the user to
135 127 acknowledge the initial message, which contains some useful
136 128 information.
137 129 """
138 130
139 131 # For automatic use, deactivate all i/o
140 132 if interactive:
141 133 def wait():
142 134 try:
143 135 raw_input("Please press <RETURN> to start IPython.")
144 136 except EOFError:
145 137 print >> Term.cout
146 138 print '*'*70
147 139
148 140 def printf(s):
149 141 print s
150 142 else:
151 143 wait = lambda : None
152 144 printf = lambda s : None
153 145
154 146 # Install mode should be re-entrant: if the install dir already exists,
155 147 # bail out cleanly.
156 148 # XXX. This is too hasty to return. We need to check to make sure that
157 149 # all the expected config files and directories are actually there. We
158 150 # currently have a failure mode if someone deletes a needed config file
159 151 # but still has the ipythondir.
160 152 if mode == 'install' and os.path.isdir(ipythondir):
161 153 return
162 154
163 155 cwd = os.getcwd() # remember where we started
164 156 glb = glob.glob
165 157
166 158 printf('*'*70)
167 159 if mode == 'install':
168 160 printf(
169 161 """Welcome to IPython. I will try to create a personal configuration directory
170 162 where you can customize many aspects of IPython's functionality in:\n""")
171 163 else:
172 164 printf('I am going to upgrade your configuration in:')
173 165
174 166 printf(ipythondir)
175 167
176 168 rcdirend = os.path.join('IPython','UserConfig')
177 169 cfg = lambda d: os.path.join(d,rcdirend)
178 170 try:
179 171 rcdir = filter(os.path.isdir,map(cfg,sys.path))[0]
180 172 printf("Initializing from configuration: %s" % rcdir)
181 173 except IndexError:
182 174 warning = """
183 175 Installation error. IPython's directory was not found.
184 176
185 177 Check the following:
186 178
187 179 The ipython/IPython directory should be in a directory belonging to your
188 180 PYTHONPATH environment variable (that is, it should be in a directory
189 181 belonging to sys.path). You can copy it explicitly there or just link to it.
190 182
191 183 IPython will create a minimal default configuration for you.
192 184
193 185 """
194 186 warn(warning)
195 187 wait()
196 188
197 189 if sys.platform =='win32':
198 190 inif = 'ipythonrc.ini'
199 191 else:
200 192 inif = 'ipythonrc'
201 193 minimal_setup = {'ipy_user_conf.py' : 'import ipy_defaults',
202 194 inif : '# intentionally left blank' }
203 195 os.makedirs(ipythondir, mode = 0777)
204 196 for f, cont in minimal_setup.items():
205 197 # In 2.5, this can be more cleanly done using 'with'
206 198 fobj = file(ipythondir + '/' + f,'w')
207 199 fobj.write(cont)
208 200 fobj.close()
209 201
210 202 return
211 203
212 204 if mode == 'install':
213 205 try:
214 206 shutil.copytree(rcdir,ipythondir)
215 207 os.chdir(ipythondir)
216 208 rc_files = glb("ipythonrc*")
217 209 for rc_file in rc_files:
218 210 os.rename(rc_file,rc_file+rc_suffix)
219 211 except:
220 212 warning = """
221 213
222 214 There was a problem with the installation:
223 215 %s
224 216 Try to correct it or contact the developers if you think it's a bug.
225 217 IPython will proceed with builtin defaults.""" % sys.exc_info()[1]
226 218 warn(warning)
227 219 wait()
228 220 return
229 221
230 222 elif mode == 'upgrade':
231 223 try:
232 224 os.chdir(ipythondir)
233 225 except:
234 226 printf("""
235 227 Can not upgrade: changing to directory %s failed. Details:
236 228 %s
237 229 """ % (ipythondir,sys.exc_info()[1]) )
238 230 wait()
239 231 return
240 232 else:
241 233 sources = glb(os.path.join(rcdir,'[A-Za-z]*'))
242 234 for new_full_path in sources:
243 235 new_filename = os.path.basename(new_full_path)
244 236 if new_filename.startswith('ipythonrc'):
245 237 new_filename = new_filename + rc_suffix
246 238 # The config directory should only contain files, skip any
247 239 # directories which may be there (like CVS)
248 240 if os.path.isdir(new_full_path):
249 241 continue
250 242 if os.path.exists(new_filename):
251 243 old_file = new_filename+'.old'
252 244 if os.path.exists(old_file):
253 245 os.remove(old_file)
254 246 os.rename(new_filename,old_file)
255 247 shutil.copy(new_full_path,new_filename)
256 248 else:
257 249 raise ValueError('unrecognized mode for install: %r' % mode)
258 250
259 251 # Fix line-endings to those native to each platform in the config
260 252 # directory.
261 253 try:
262 254 os.chdir(ipythondir)
263 255 except:
264 256 printf("""
265 257 Problem: changing to directory %s failed.
266 258 Details:
267 259 %s
268 260
269 261 Some configuration files may have incorrect line endings. This should not
270 262 cause any problems during execution. """ % (ipythondir,sys.exc_info()[1]) )
271 263 wait()
272 264 else:
273 265 for fname in glb('ipythonrc*'):
274 266 try:
275 267 native_line_ends(fname,backup=0)
276 268 except IOError:
277 269 pass
278 270
279 271 if mode == 'install':
280 272 printf("""
281 273 Successful installation!
282 274
283 275 Please read the sections 'Initial Configuration' and 'Quick Tips' in the
284 276 IPython manual (there are both HTML and PDF versions supplied with the
285 277 distribution) to make sure that your system environment is properly configured
286 278 to take advantage of IPython's features.
287 279
288 280 Important note: the configuration system has changed! The old system is
289 281 still in place, but its setting may be partly overridden by the settings in
290 282 "~/.ipython/ipy_user_conf.py" config file. Please take a look at the file
291 283 if some of the new settings bother you.
292 284
293 285 """)
294 286 else:
295 287 printf("""
296 288 Successful upgrade!
297 289
298 290 All files in your directory:
299 291 %(ipythondir)s
300 292 which would have been overwritten by the upgrade were backed up with a .old
301 293 extension. If you had made particular customizations in those files you may
302 294 want to merge them back into the new files.""" % locals() )
303 295 wait()
304 296 os.chdir(cwd)
305 297
306 298 #****************************************************************************
307 299 # Local use exceptions
308 300 class SpaceInInput(exceptions.Exception): pass
309 301
310 302
311 303 #****************************************************************************
312 304 # Local use classes
313 305 class Bunch: pass
314 306
315 307 class Undefined: pass
316 308
317 309 class Quitter(object):
318 310 """Simple class to handle exit, similar to Python 2.5's.
319 311
320 312 It handles exiting in an ipython-safe manner, which the one in Python 2.5
321 313 doesn't do (obviously, since it doesn't know about ipython)."""
322 314
323 315 def __init__(self,shell,name):
324 316 self.shell = shell
325 317 self.name = name
326 318
327 319 def __repr__(self):
328 320 return 'Type %s() to exit.' % self.name
329 321 __str__ = __repr__
330 322
331 323 def __call__(self):
332 324 self.shell.exit()
333 325
334 326 class InputList(list):
335 327 """Class to store user input.
336 328
337 329 It's basically a list, but slices return a string instead of a list, thus
338 330 allowing things like (assuming 'In' is an instance):
339 331
340 332 exec In[4:7]
341 333
342 334 or
343 335
344 336 exec In[5:9] + In[14] + In[21:25]"""
345 337
346 338 def __getslice__(self,i,j):
347 339 return ''.join(list.__getslice__(self,i,j))
348 340
349 341 class SyntaxTB(ultraTB.ListTB):
350 342 """Extension which holds some state: the last exception value"""
351 343
352 344 def __init__(self,color_scheme = 'NoColor'):
353 345 ultraTB.ListTB.__init__(self,color_scheme)
354 346 self.last_syntax_error = None
355 347
356 348 def __call__(self, etype, value, elist):
357 349 self.last_syntax_error = value
358 350 ultraTB.ListTB.__call__(self,etype,value,elist)
359 351
360 352 def clear_err_state(self):
361 353 """Return the current error state and clear it"""
362 354 e = self.last_syntax_error
363 355 self.last_syntax_error = None
364 356 return e
365 357
366 358 #****************************************************************************
367 359 # Main IPython class
368 360
369 361 # FIXME: the Magic class is a mixin for now, and will unfortunately remain so
370 362 # until a full rewrite is made. I've cleaned all cross-class uses of
371 363 # attributes and methods, but too much user code out there relies on the
372 364 # equlity %foo == __IP.magic_foo, so I can't actually remove the mixin usage.
373 365 #
374 366 # But at least now, all the pieces have been separated and we could, in
375 367 # principle, stop using the mixin. This will ease the transition to the
376 368 # chainsaw branch.
377 369
378 370 # For reference, the following is the list of 'self.foo' uses in the Magic
379 371 # class as of 2005-12-28. These are names we CAN'T use in the main ipython
380 372 # class, to prevent clashes.
381 373
382 374 # ['self.__class__', 'self.__dict__', 'self._inspect', 'self._ofind',
383 375 # 'self.arg_err', 'self.extract_input', 'self.format_', 'self.lsmagic',
384 376 # 'self.magic_', 'self.options_table', 'self.parse', 'self.shell',
385 377 # 'self.value']
386 378
387 379 class InteractiveShell(object,Magic):
388 380 """An enhanced console for Python."""
389 381
390 382 # class attribute to indicate whether the class supports threads or not.
391 383 # Subclasses with thread support should override this as needed.
392 384 isthreaded = False
393 385
394 386 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
395 387 user_ns=None,user_global_ns=None,banner2='',
396 388 custom_exceptions=((),None),embedded=False):
397 389
398 390 # log system
399 391 self.logger = Logger(self,logfname='ipython_log.py',logmode='rotate')
400 392
401 393 # Job manager (for jobs run as background threads)
402 394 self.jobs = BackgroundJobManager()
403 395
404 396 # Store the actual shell's name
405 397 self.name = name
406 398 self.more = False
407 399
408 400 # We need to know whether the instance is meant for embedding, since
409 401 # global/local namespaces need to be handled differently in that case
410 402 self.embedded = embedded
411 403 if embedded:
412 404 # Control variable so users can, from within the embedded instance,
413 405 # permanently deactivate it.
414 406 self.embedded_active = True
415 407
416 408 # command compiler
417 409 self.compile = codeop.CommandCompiler()
418 410
419 411 # User input buffer
420 412 self.buffer = []
421 413
422 414 # Default name given in compilation of code
423 415 self.filename = '<ipython console>'
424 416
425 417 # Install our own quitter instead of the builtins. For python2.3-2.4,
426 418 # this brings in behavior like 2.5, and for 2.5 it's identical.
427 419 __builtin__.exit = Quitter(self,'exit')
428 420 __builtin__.quit = Quitter(self,'quit')
429 421
430 422 # Make an empty namespace, which extension writers can rely on both
431 423 # existing and NEVER being used by ipython itself. This gives them a
432 424 # convenient location for storing additional information and state
433 425 # their extensions may require, without fear of collisions with other
434 426 # ipython names that may develop later.
435 427 self.meta = Struct()
436 428
437 429 # Create the namespace where the user will operate. user_ns is
438 430 # normally the only one used, and it is passed to the exec calls as
439 431 # the locals argument. But we do carry a user_global_ns namespace
440 432 # given as the exec 'globals' argument, This is useful in embedding
441 433 # situations where the ipython shell opens in a context where the
442 434 # distinction between locals and globals is meaningful. For
443 435 # non-embedded contexts, it is just the same object as the user_ns dict.
444 436
445 437 # FIXME. For some strange reason, __builtins__ is showing up at user
446 438 # level as a dict instead of a module. This is a manual fix, but I
447 439 # should really track down where the problem is coming from. Alex
448 440 # Schmolck reported this problem first.
449 441
450 442 # A useful post by Alex Martelli on this topic:
451 443 # Re: inconsistent value from __builtins__
452 444 # Von: Alex Martelli <aleaxit@yahoo.com>
453 445 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
454 446 # Gruppen: comp.lang.python
455 447
456 448 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
457 449 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
458 450 # > <type 'dict'>
459 451 # > >>> print type(__builtins__)
460 452 # > <type 'module'>
461 453 # > Is this difference in return value intentional?
462 454
463 455 # Well, it's documented that '__builtins__' can be either a dictionary
464 456 # or a module, and it's been that way for a long time. Whether it's
465 457 # intentional (or sensible), I don't know. In any case, the idea is
466 458 # that if you need to access the built-in namespace directly, you
467 459 # should start with "import __builtin__" (note, no 's') which will
468 460 # definitely give you a module. Yeah, it's somewhat confusing:-(.
469 461
470 462 # These routines return properly built dicts as needed by the rest of
471 463 # the code, and can also be used by extension writers to generate
472 464 # properly initialized namespaces.
473 465 user_ns, user_global_ns = IPython.ipapi.make_user_namespaces(user_ns,
474 466 user_global_ns)
475 467
476 468 # Assign namespaces
477 469 # This is the namespace where all normal user variables live
478 470 self.user_ns = user_ns
479 471 self.user_global_ns = user_global_ns
480 472
481 473 # An auxiliary namespace that checks what parts of the user_ns were
482 474 # loaded at startup, so we can list later only variables defined in
483 475 # actual interactive use. Since it is always a subset of user_ns, it
484 476 # doesn't need to be seaparately tracked in the ns_table
485 477 self.user_config_ns = {}
486 478
487 479 # A namespace to keep track of internal data structures to prevent
488 480 # them from cluttering user-visible stuff. Will be updated later
489 481 self.internal_ns = {}
490 482
491 483 # Namespace of system aliases. Each entry in the alias
492 484 # table must be a 2-tuple of the form (N,name), where N is the number
493 485 # of positional arguments of the alias.
494 486 self.alias_table = {}
495 487
496 488 # Now that FakeModule produces a real module, we've run into a nasty
497 489 # problem: after script execution (via %run), the module where the user
498 490 # code ran is deleted. Now that this object is a true module (needed
499 491 # so docetst and other tools work correctly), the Python module
500 492 # teardown mechanism runs over it, and sets to None every variable
501 493 # present in that module. Top-level references to objects from the
502 494 # script survive, because the user_ns is updated with them. However,
503 495 # calling functions defined in the script that use other things from
504 496 # the script will fail, because the function's closure had references
505 497 # to the original objects, which are now all None. So we must protect
506 498 # these modules from deletion by keeping a cache.
507 499 #
508 500 # To avoid keeping stale modules around (we only need the one from the
509 501 # last run), we use a dict keyed with the full path to the script, so
510 502 # only the last version of the module is held in the cache. Note,
511 503 # however, that we must cache the module *namespace contents* (their
512 504 # __dict__). Because if we try to cache the actual modules, old ones
513 505 # (uncached) could be destroyed while still holding references (such as
514 506 # those held by GUI objects that tend to be long-lived)>
515 507 #
516 508 # The %reset command will flush this cache. See the cache_main_mod()
517 509 # and clear_main_mod_cache() methods for details on use.
518 510
519 511 # This is the cache used for 'main' namespaces
520 512 self._main_ns_cache = {}
521 513 # And this is the single instance of FakeModule whose __dict__ we keep
522 514 # copying and clearing for reuse on each %run
523 515 self._user_main_module = FakeModule()
524 516
525 517 # A table holding all the namespaces IPython deals with, so that
526 518 # introspection facilities can search easily.
527 519 self.ns_table = {'user':user_ns,
528 520 'user_global':user_global_ns,
529 521 'alias':self.alias_table,
530 522 'internal':self.internal_ns,
531 523 'builtin':__builtin__.__dict__
532 524 }
533 525
534 526 # Similarly, track all namespaces where references can be held and that
535 527 # we can safely clear (so it can NOT include builtin). This one can be
536 528 # a simple list.
537 529 self.ns_refs_table = [ user_ns, user_global_ns, self.user_config_ns,
538 530 self.alias_table, self.internal_ns,
539 531 self._main_ns_cache ]
540 532
541 533 # We need to insert into sys.modules something that looks like a
542 534 # module but which accesses the IPython namespace, for shelve and
543 535 # pickle to work interactively. Normally they rely on getting
544 536 # everything out of __main__, but for embedding purposes each IPython
545 537 # instance has its own private namespace, so we can't go shoving
546 538 # everything into __main__.
547 539
548 540 # note, however, that we should only do this for non-embedded
549 541 # ipythons, which really mimic the __main__.__dict__ with their own
550 542 # namespace. Embedded instances, on the other hand, should not do
551 543 # this because they need to manage the user local/global namespaces
552 544 # only, but they live within a 'normal' __main__ (meaning, they
553 545 # shouldn't overtake the execution environment of the script they're
554 546 # embedded in).
555 547
556 548 if not embedded:
557 549 try:
558 550 main_name = self.user_ns['__name__']
559 551 except KeyError:
560 552 raise KeyError,'user_ns dictionary MUST have a "__name__" key'
561 553 else:
562 554 #print "pickle hack in place" # dbg
563 555 #print 'main_name:',main_name # dbg
564 556 sys.modules[main_name] = FakeModule(self.user_ns)
565 557
566 558 # List of input with multi-line handling.
567 559 self.input_hist = InputList()
568 560 # This one will hold the 'raw' input history, without any
569 561 # pre-processing. This will allow users to retrieve the input just as
570 562 # it was exactly typed in by the user, with %hist -r.
571 563 self.input_hist_raw = InputList()
572 564
573 565 # list of visited directories
574 566 try:
575 567 self.dir_hist = [os.getcwd()]
576 568 except OSError:
577 569 self.dir_hist = []
578 570
579 571 # dict of output history
580 572 self.output_hist = {}
581 573
582 574 # Get system encoding at startup time. Certain terminals (like Emacs
583 575 # under Win32 have it set to None, and we need to have a known valid
584 576 # encoding to use in the raw_input() method
585 577 try:
586 578 self.stdin_encoding = sys.stdin.encoding or 'ascii'
587 579 except AttributeError:
588 580 self.stdin_encoding = 'ascii'
589 581
590 582 # dict of things NOT to alias (keywords, builtins and some magics)
591 583 no_alias = {}
592 584 no_alias_magics = ['cd','popd','pushd','dhist','alias','unalias']
593 585 for key in keyword.kwlist + no_alias_magics:
594 586 no_alias[key] = 1
595 587 no_alias.update(__builtin__.__dict__)
596 588 self.no_alias = no_alias
597 589
598 590 # Object variable to store code object waiting execution. This is
599 591 # used mainly by the multithreaded shells, but it can come in handy in
600 592 # other situations. No need to use a Queue here, since it's a single
601 593 # item which gets cleared once run.
602 594 self.code_to_run = None
603 595
604 596 # escapes for automatic behavior on the command line
605 597 self.ESC_SHELL = '!'
606 598 self.ESC_SH_CAP = '!!'
607 599 self.ESC_HELP = '?'
608 600 self.ESC_MAGIC = '%'
609 601 self.ESC_QUOTE = ','
610 602 self.ESC_QUOTE2 = ';'
611 603 self.ESC_PAREN = '/'
612 604
613 605 # And their associated handlers
614 606 self.esc_handlers = {self.ESC_PAREN : self.handle_auto,
615 607 self.ESC_QUOTE : self.handle_auto,
616 608 self.ESC_QUOTE2 : self.handle_auto,
617 609 self.ESC_MAGIC : self.handle_magic,
618 610 self.ESC_HELP : self.handle_help,
619 611 self.ESC_SHELL : self.handle_shell_escape,
620 612 self.ESC_SH_CAP : self.handle_shell_escape,
621 613 }
622 614
623 615 # class initializations
624 616 Magic.__init__(self,self)
625 617
626 618 # Python source parser/formatter for syntax highlighting
627 619 pyformat = PyColorize.Parser().format
628 620 self.pycolorize = lambda src: pyformat(src,'str',self.rc['colors'])
629 621
630 622 # hooks holds pointers used for user-side customizations
631 623 self.hooks = Struct()
632 624
633 625 self.strdispatchers = {}
634 626
635 627 # Set all default hooks, defined in the IPython.hooks module.
636 628 hooks = IPython.hooks
637 629 for hook_name in hooks.__all__:
638 630 # default hooks have priority 100, i.e. low; user hooks should have
639 631 # 0-100 priority
640 632 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
641 633 #print "bound hook",hook_name
642 634
643 635 # Flag to mark unconditional exit
644 636 self.exit_now = False
645 637
646 638 self.usage_min = """\
647 639 An enhanced console for Python.
648 640 Some of its features are:
649 641 - Readline support if the readline library is present.
650 642 - Tab completion in the local namespace.
651 643 - Logging of input, see command-line options.
652 644 - System shell escape via ! , eg !ls.
653 645 - Magic commands, starting with a % (like %ls, %pwd, %cd, etc.)
654 646 - Keeps track of locally defined variables via %who, %whos.
655 647 - Show object information with a ? eg ?x or x? (use ?? for more info).
656 648 """
657 649 if usage: self.usage = usage
658 650 else: self.usage = self.usage_min
659 651
660 652 # Storage
661 653 self.rc = rc # This will hold all configuration information
662 654 self.pager = 'less'
663 655 # temporary files used for various purposes. Deleted at exit.
664 656 self.tempfiles = []
665 657
666 658 # Keep track of readline usage (later set by init_readline)
667 659 self.has_readline = False
668 660
669 661 # template for logfile headers. It gets resolved at runtime by the
670 662 # logstart method.
671 663 self.loghead_tpl = \
672 664 """#log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE ***
673 665 #log# DO NOT CHANGE THIS LINE OR THE TWO BELOW
674 666 #log# opts = %s
675 667 #log# args = %s
676 668 #log# It is safe to make manual edits below here.
677 669 #log#-----------------------------------------------------------------------
678 670 """
679 671 # for pushd/popd management
680 672 try:
681 673 self.home_dir = get_home_dir()
682 674 except HomeDirError,msg:
683 675 fatal(msg)
684 676
685 677 self.dir_stack = []
686 678
687 679 # Functions to call the underlying shell.
688 680
689 681 # The first is similar to os.system, but it doesn't return a value,
690 682 # and it allows interpolation of variables in the user's namespace.
691 683 self.system = lambda cmd: \
692 684 self.hooks.shell_hook(self.var_expand(cmd,depth=2))
693 685
694 686 # These are for getoutput and getoutputerror:
695 687 self.getoutput = lambda cmd: \
696 688 getoutput(self.var_expand(cmd,depth=2),
697 689 header=self.rc.system_header,
698 690 verbose=self.rc.system_verbose)
699 691
700 692 self.getoutputerror = lambda cmd: \
701 693 getoutputerror(self.var_expand(cmd,depth=2),
702 694 header=self.rc.system_header,
703 695 verbose=self.rc.system_verbose)
704 696
705 697
706 698 # keep track of where we started running (mainly for crash post-mortem)
707 699 self.starting_dir = os.getcwd()
708 700
709 701 # Various switches which can be set
710 702 self.CACHELENGTH = 5000 # this is cheap, it's just text
711 703 self.BANNER = "Python %(version)s on %(platform)s\n" % sys.__dict__
712 704 self.banner2 = banner2
713 705
714 706 # TraceBack handlers:
715 707
716 708 # Syntax error handler.
717 709 self.SyntaxTB = SyntaxTB(color_scheme='NoColor')
718 710
719 711 # The interactive one is initialized with an offset, meaning we always
720 712 # want to remove the topmost item in the traceback, which is our own
721 713 # internal code. Valid modes: ['Plain','Context','Verbose']
722 714 self.InteractiveTB = ultraTB.AutoFormattedTB(mode = 'Plain',
723 715 color_scheme='NoColor',
724 716 tb_offset = 1)
725 717
726 718 # IPython itself shouldn't crash. This will produce a detailed
727 719 # post-mortem if it does. But we only install the crash handler for
728 720 # non-threaded shells, the threaded ones use a normal verbose reporter
729 721 # and lose the crash handler. This is because exceptions in the main
730 722 # thread (such as in GUI code) propagate directly to sys.excepthook,
731 723 # and there's no point in printing crash dumps for every user exception.
732 724 if self.isthreaded:
733 725 ipCrashHandler = ultraTB.FormattedTB()
734 726 else:
735 727 from IPython import CrashHandler
736 728 ipCrashHandler = CrashHandler.IPythonCrashHandler(self)
737 729 self.set_crash_handler(ipCrashHandler)
738 730
739 731 # and add any custom exception handlers the user may have specified
740 732 self.set_custom_exc(*custom_exceptions)
741 733
742 734 # indentation management
743 735 self.autoindent = False
744 736 self.indent_current_nsp = 0
745 737
746 738 # Make some aliases automatically
747 739 # Prepare list of shell aliases to auto-define
748 740 if os.name == 'posix':
749 741 auto_alias = ('mkdir mkdir', 'rmdir rmdir',
750 742 'mv mv -i','rm rm -i','cp cp -i',
751 743 'cat cat','less less','clear clear',
752 744 # a better ls
753 745 'ls ls -F',
754 746 # long ls
755 747 'll ls -lF')
756 748 # Extra ls aliases with color, which need special treatment on BSD
757 749 # variants
758 750 ls_extra = ( # color ls
759 751 'lc ls -F -o --color',
760 752 # ls normal files only
761 753 'lf ls -F -o --color %l | grep ^-',
762 754 # ls symbolic links
763 755 'lk ls -F -o --color %l | grep ^l',
764 756 # directories or links to directories,
765 757 'ldir ls -F -o --color %l | grep /$',
766 758 # things which are executable
767 759 'lx ls -F -o --color %l | grep ^-..x',
768 760 )
769 761 # The BSDs don't ship GNU ls, so they don't understand the
770 762 # --color switch out of the box
771 763 if 'bsd' in sys.platform:
772 764 ls_extra = ( # ls normal files only
773 765 'lf ls -lF | grep ^-',
774 766 # ls symbolic links
775 767 'lk ls -lF | grep ^l',
776 768 # directories or links to directories,
777 769 'ldir ls -lF | grep /$',
778 770 # things which are executable
779 771 'lx ls -lF | grep ^-..x',
780 772 )
781 773 auto_alias = auto_alias + ls_extra
782 774 elif os.name in ['nt','dos']:
783 775 auto_alias = ('ls dir /on',
784 776 'ddir dir /ad /on', 'ldir dir /ad /on',
785 777 'mkdir mkdir','rmdir rmdir','echo echo',
786 778 'ren ren','cls cls','copy copy')
787 779 else:
788 780 auto_alias = ()
789 781 self.auto_alias = [s.split(None,1) for s in auto_alias]
790 782
791 783 # Produce a public API instance
792 784 self.api = IPython.ipapi.IPApi(self)
793 785
794 786 # Initialize all user-visible namespaces
795 787 self.init_namespaces()
796 788
797 789 # Call the actual (public) initializer
798 790 self.init_auto_alias()
799 791
800 792 # track which builtins we add, so we can clean up later
801 793 self.builtins_added = {}
802 794 # This method will add the necessary builtins for operation, but
803 795 # tracking what it did via the builtins_added dict.
804 796
805 797 #TODO: remove this, redundant
806 798 self.add_builtins()
807 799 # end __init__
808 800
809 801 def var_expand(self,cmd,depth=0):
810 802 """Expand python variables in a string.
811 803
812 804 The depth argument indicates how many frames above the caller should
813 805 be walked to look for the local namespace where to expand variables.
814 806
815 807 The global namespace for expansion is always the user's interactive
816 808 namespace.
817 809 """
818 810
819 811 return str(ItplNS(cmd,
820 812 self.user_ns, # globals
821 813 # Skip our own frame in searching for locals:
822 814 sys._getframe(depth+1).f_locals # locals
823 815 ))
824 816
825 817 def pre_config_initialization(self):
826 818 """Pre-configuration init method
827 819
828 820 This is called before the configuration files are processed to
829 821 prepare the services the config files might need.
830 822
831 823 self.rc already has reasonable default values at this point.
832 824 """
833 825 rc = self.rc
834 826 try:
835 827 self.db = pickleshare.PickleShareDB(rc.ipythondir + "/db")
836 828 except exceptions.UnicodeDecodeError:
837 829 print "Your ipythondir can't be decoded to unicode!"
838 830 print "Please set HOME environment variable to something that"
839 831 print r"only has ASCII characters, e.g. c:\home"
840 832 print "Now it is",rc.ipythondir
841 833 sys.exit()
842 834 self.shadowhist = IPython.history.ShadowHist(self.db)
843 835
844 836 def post_config_initialization(self):
845 837 """Post configuration init method
846 838
847 839 This is called after the configuration files have been processed to
848 840 'finalize' the initialization."""
849 841
850 842 rc = self.rc
851 843
852 844 # Object inspector
853 845 self.inspector = OInspect.Inspector(OInspect.InspectColors,
854 846 PyColorize.ANSICodeColors,
855 847 'NoColor',
856 848 rc.object_info_string_level)
857 849
858 850 self.rl_next_input = None
859 851 self.rl_do_indent = False
860 852 # Load readline proper
861 853 if rc.readline:
862 854 self.init_readline()
863 855
864 856 # local shortcut, this is used a LOT
865 857 self.log = self.logger.log
866 858
867 859 # Initialize cache, set in/out prompts and printing system
868 860 self.outputcache = CachedOutput(self,
869 861 rc.cache_size,
870 862 rc.pprint,
871 863 input_sep = rc.separate_in,
872 864 output_sep = rc.separate_out,
873 865 output_sep2 = rc.separate_out2,
874 866 ps1 = rc.prompt_in1,
875 867 ps2 = rc.prompt_in2,
876 868 ps_out = rc.prompt_out,
877 869 pad_left = rc.prompts_pad_left)
878 870
879 871 # user may have over-ridden the default print hook:
880 872 try:
881 873 self.outputcache.__class__.display = self.hooks.display
882 874 except AttributeError:
883 875 pass
884 876
885 877 # I don't like assigning globally to sys, because it means when
886 878 # embedding instances, each embedded instance overrides the previous
887 879 # choice. But sys.displayhook seems to be called internally by exec,
888 880 # so I don't see a way around it. We first save the original and then
889 881 # overwrite it.
890 882 self.sys_displayhook = sys.displayhook
891 883 sys.displayhook = self.outputcache
892 884
893 885 # Do a proper resetting of doctest, including the necessary displayhook
894 886 # monkeypatching
895 887 try:
896 888 doctest_reload()
897 889 except ImportError:
898 890 warn("doctest module does not exist.")
899 891
900 892 # Set user colors (don't do it in the constructor above so that it
901 893 # doesn't crash if colors option is invalid)
902 894 self.magic_colors(rc.colors)
903 895
904 896 # Set calling of pdb on exceptions
905 897 self.call_pdb = rc.pdb
906 898
907 899 # Load user aliases
908 900 for alias in rc.alias:
909 901 self.magic_alias(alias)
910 902
911 903 self.hooks.late_startup_hook()
912 904
913 905 for cmd in self.rc.autoexec:
914 906 #print "autoexec>",cmd #dbg
915 907 self.api.runlines(cmd)
916 908
917 909 batchrun = False
918 910 for batchfile in [path(arg) for arg in self.rc.args
919 911 if arg.lower().endswith('.ipy')]:
920 912 if not batchfile.isfile():
921 913 print "No such batch file:", batchfile
922 914 continue
923 915 self.api.runlines(batchfile.text())
924 916 batchrun = True
925 917 # without -i option, exit after running the batch file
926 918 if batchrun and not self.rc.interact:
927 919 self.ask_exit()
928 920
929 921 def init_namespaces(self):
930 922 """Initialize all user-visible namespaces to their minimum defaults.
931 923
932 924 Certain history lists are also initialized here, as they effectively
933 925 act as user namespaces.
934 926
935 927 Note
936 928 ----
937 929 All data structures here are only filled in, they are NOT reset by this
938 930 method. If they were not empty before, data will simply be added to
939 931 therm.
940 932 """
941 933 # The user namespace MUST have a pointer to the shell itself.
942 934 self.user_ns[self.name] = self
943 935
944 936 # Store the public api instance
945 937 self.user_ns['_ip'] = self.api
946 938
947 939 # make global variables for user access to the histories
948 940 self.user_ns['_ih'] = self.input_hist
949 941 self.user_ns['_oh'] = self.output_hist
950 942 self.user_ns['_dh'] = self.dir_hist
951 943
952 944 # user aliases to input and output histories
953 945 self.user_ns['In'] = self.input_hist
954 946 self.user_ns['Out'] = self.output_hist
955 947
956 948 self.user_ns['_sh'] = IPython.shadowns
957 949
958 950 # Fill the history zero entry, user counter starts at 1
959 951 self.input_hist.append('\n')
960 952 self.input_hist_raw.append('\n')
961 953
962 954 def add_builtins(self):
963 955 """Store ipython references into the builtin namespace.
964 956
965 957 Some parts of ipython operate via builtins injected here, which hold a
966 958 reference to IPython itself."""
967 959
968 960 # TODO: deprecate all of these, they are unsafe
969 961 builtins_new = dict(__IPYTHON__ = self,
970 962 ip_set_hook = self.set_hook,
971 963 jobs = self.jobs,
972 964 ipmagic = wrap_deprecated(self.ipmagic,'_ip.magic()'),
973 965 ipalias = wrap_deprecated(self.ipalias),
974 966 ipsystem = wrap_deprecated(self.ipsystem,'_ip.system()'),
975 967 #_ip = self.api
976 968 )
977 969 for biname,bival in builtins_new.items():
978 970 try:
979 971 # store the orignal value so we can restore it
980 972 self.builtins_added[biname] = __builtin__.__dict__[biname]
981 973 except KeyError:
982 974 # or mark that it wasn't defined, and we'll just delete it at
983 975 # cleanup
984 976 self.builtins_added[biname] = Undefined
985 977 __builtin__.__dict__[biname] = bival
986 978
987 979 # Keep in the builtins a flag for when IPython is active. We set it
988 980 # with setdefault so that multiple nested IPythons don't clobber one
989 981 # another. Each will increase its value by one upon being activated,
990 982 # which also gives us a way to determine the nesting level.
991 983 __builtin__.__dict__.setdefault('__IPYTHON__active',0)
992 984
993 985 def clean_builtins(self):
994 986 """Remove any builtins which might have been added by add_builtins, or
995 987 restore overwritten ones to their previous values."""
996 988 for biname,bival in self.builtins_added.items():
997 989 if bival is Undefined:
998 990 del __builtin__.__dict__[biname]
999 991 else:
1000 992 __builtin__.__dict__[biname] = bival
1001 993 self.builtins_added.clear()
1002 994
1003 995 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
1004 996 """set_hook(name,hook) -> sets an internal IPython hook.
1005 997
1006 998 IPython exposes some of its internal API as user-modifiable hooks. By
1007 999 adding your function to one of these hooks, you can modify IPython's
1008 1000 behavior to call at runtime your own routines."""
1009 1001
1010 1002 # At some point in the future, this should validate the hook before it
1011 1003 # accepts it. Probably at least check that the hook takes the number
1012 1004 # of args it's supposed to.
1013 1005
1014 1006 f = new.instancemethod(hook,self,self.__class__)
1015 1007
1016 1008 # check if the hook is for strdispatcher first
1017 1009 if str_key is not None:
1018 1010 sdp = self.strdispatchers.get(name, StrDispatch())
1019 1011 sdp.add_s(str_key, f, priority )
1020 1012 self.strdispatchers[name] = sdp
1021 1013 return
1022 1014 if re_key is not None:
1023 1015 sdp = self.strdispatchers.get(name, StrDispatch())
1024 1016 sdp.add_re(re.compile(re_key), f, priority )
1025 1017 self.strdispatchers[name] = sdp
1026 1018 return
1027 1019
1028 1020 dp = getattr(self.hooks, name, None)
1029 1021 if name not in IPython.hooks.__all__:
1030 1022 print "Warning! Hook '%s' is not one of %s" % (name, IPython.hooks.__all__ )
1031 1023 if not dp:
1032 1024 dp = IPython.hooks.CommandChainDispatcher()
1033 1025
1034 1026 try:
1035 1027 dp.add(f,priority)
1036 1028 except AttributeError:
1037 1029 # it was not commandchain, plain old func - replace
1038 1030 dp = f
1039 1031
1040 1032 setattr(self.hooks,name, dp)
1041 1033
1042 1034
1043 1035 #setattr(self.hooks,name,new.instancemethod(hook,self,self.__class__))
1044 1036
1045 1037 def set_crash_handler(self,crashHandler):
1046 1038 """Set the IPython crash handler.
1047 1039
1048 1040 This must be a callable with a signature suitable for use as
1049 1041 sys.excepthook."""
1050 1042
1051 1043 # Install the given crash handler as the Python exception hook
1052 1044 sys.excepthook = crashHandler
1053 1045
1054 1046 # The instance will store a pointer to this, so that runtime code
1055 1047 # (such as magics) can access it. This is because during the
1056 1048 # read-eval loop, it gets temporarily overwritten (to deal with GUI
1057 1049 # frameworks).
1058 1050 self.sys_excepthook = sys.excepthook
1059 1051
1060 1052
1061 1053 def set_custom_exc(self,exc_tuple,handler):
1062 1054 """set_custom_exc(exc_tuple,handler)
1063 1055
1064 1056 Set a custom exception handler, which will be called if any of the
1065 1057 exceptions in exc_tuple occur in the mainloop (specifically, in the
1066 1058 runcode() method.
1067 1059
1068 1060 Inputs:
1069 1061
1070 1062 - exc_tuple: a *tuple* of valid exceptions to call the defined
1071 1063 handler for. It is very important that you use a tuple, and NOT A
1072 1064 LIST here, because of the way Python's except statement works. If
1073 1065 you only want to trap a single exception, use a singleton tuple:
1074 1066
1075 1067 exc_tuple == (MyCustomException,)
1076 1068
1077 1069 - handler: this must be defined as a function with the following
1078 1070 basic interface: def my_handler(self,etype,value,tb).
1079 1071
1080 1072 This will be made into an instance method (via new.instancemethod)
1081 1073 of IPython itself, and it will be called if any of the exceptions
1082 1074 listed in the exc_tuple are caught. If the handler is None, an
1083 1075 internal basic one is used, which just prints basic info.
1084 1076
1085 1077 WARNING: by putting in your own exception handler into IPython's main
1086 1078 execution loop, you run a very good chance of nasty crashes. This
1087 1079 facility should only be used if you really know what you are doing."""
1088 1080
1089 1081 assert type(exc_tuple)==type(()) , \
1090 1082 "The custom exceptions must be given AS A TUPLE."
1091 1083
1092 1084 def dummy_handler(self,etype,value,tb):
1093 1085 print '*** Simple custom exception handler ***'
1094 1086 print 'Exception type :',etype
1095 1087 print 'Exception value:',value
1096 1088 print 'Traceback :',tb
1097 1089 print 'Source code :','\n'.join(self.buffer)
1098 1090
1099 1091 if handler is None: handler = dummy_handler
1100 1092
1101 1093 self.CustomTB = new.instancemethod(handler,self,self.__class__)
1102 1094 self.custom_exceptions = exc_tuple
1103 1095
1104 1096 def set_custom_completer(self,completer,pos=0):
1105 1097 """set_custom_completer(completer,pos=0)
1106 1098
1107 1099 Adds a new custom completer function.
1108 1100
1109 1101 The position argument (defaults to 0) is the index in the completers
1110 1102 list where you want the completer to be inserted."""
1111 1103
1112 1104 newcomp = new.instancemethod(completer,self.Completer,
1113 1105 self.Completer.__class__)
1114 1106 self.Completer.matchers.insert(pos,newcomp)
1115 1107
1116 1108 def set_completer(self):
1117 1109 """reset readline's completer to be our own."""
1118 1110 self.readline.set_completer(self.Completer.complete)
1119 1111
1120 1112 def _get_call_pdb(self):
1121 1113 return self._call_pdb
1122 1114
1123 1115 def _set_call_pdb(self,val):
1124 1116
1125 1117 if val not in (0,1,False,True):
1126 1118 raise ValueError,'new call_pdb value must be boolean'
1127 1119
1128 1120 # store value in instance
1129 1121 self._call_pdb = val
1130 1122
1131 1123 # notify the actual exception handlers
1132 1124 self.InteractiveTB.call_pdb = val
1133 1125 if self.isthreaded:
1134 1126 try:
1135 1127 self.sys_excepthook.call_pdb = val
1136 1128 except:
1137 1129 warn('Failed to activate pdb for threaded exception handler')
1138 1130
1139 1131 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
1140 1132 'Control auto-activation of pdb at exceptions')
1141 1133
1142 1134 # These special functions get installed in the builtin namespace, to
1143 1135 # provide programmatic (pure python) access to magics, aliases and system
1144 1136 # calls. This is important for logging, user scripting, and more.
1145 1137
1146 1138 # We are basically exposing, via normal python functions, the three
1147 1139 # mechanisms in which ipython offers special call modes (magics for
1148 1140 # internal control, aliases for direct system access via pre-selected
1149 1141 # names, and !cmd for calling arbitrary system commands).
1150 1142
1151 1143 def ipmagic(self,arg_s):
1152 1144 """Call a magic function by name.
1153 1145
1154 1146 Input: a string containing the name of the magic function to call and any
1155 1147 additional arguments to be passed to the magic.
1156 1148
1157 1149 ipmagic('name -opt foo bar') is equivalent to typing at the ipython
1158 1150 prompt:
1159 1151
1160 1152 In[1]: %name -opt foo bar
1161 1153
1162 1154 To call a magic without arguments, simply use ipmagic('name').
1163 1155
1164 1156 This provides a proper Python function to call IPython's magics in any
1165 1157 valid Python code you can type at the interpreter, including loops and
1166 1158 compound statements. It is added by IPython to the Python builtin
1167 1159 namespace upon initialization."""
1168 1160
1169 1161 args = arg_s.split(' ',1)
1170 1162 magic_name = args[0]
1171 1163 magic_name = magic_name.lstrip(self.ESC_MAGIC)
1172 1164
1173 1165 try:
1174 1166 magic_args = args[1]
1175 1167 except IndexError:
1176 1168 magic_args = ''
1177 1169 fn = getattr(self,'magic_'+magic_name,None)
1178 1170 if fn is None:
1179 1171 error("Magic function `%s` not found." % magic_name)
1180 1172 else:
1181 1173 magic_args = self.var_expand(magic_args,1)
1182 1174 return fn(magic_args)
1183 1175
1184 1176 def ipalias(self,arg_s):
1185 1177 """Call an alias by name.
1186 1178
1187 1179 Input: a string containing the name of the alias to call and any
1188 1180 additional arguments to be passed to the magic.
1189 1181
1190 1182 ipalias('name -opt foo bar') is equivalent to typing at the ipython
1191 1183 prompt:
1192 1184
1193 1185 In[1]: name -opt foo bar
1194 1186
1195 1187 To call an alias without arguments, simply use ipalias('name').
1196 1188
1197 1189 This provides a proper Python function to call IPython's aliases in any
1198 1190 valid Python code you can type at the interpreter, including loops and
1199 1191 compound statements. It is added by IPython to the Python builtin
1200 1192 namespace upon initialization."""
1201 1193
1202 1194 args = arg_s.split(' ',1)
1203 1195 alias_name = args[0]
1204 1196 try:
1205 1197 alias_args = args[1]
1206 1198 except IndexError:
1207 1199 alias_args = ''
1208 1200 if alias_name in self.alias_table:
1209 1201 self.call_alias(alias_name,alias_args)
1210 1202 else:
1211 1203 error("Alias `%s` not found." % alias_name)
1212 1204
1213 1205 def ipsystem(self,arg_s):
1214 1206 """Make a system call, using IPython."""
1215 1207
1216 1208 self.system(arg_s)
1217 1209
1218 1210 def complete(self,text):
1219 1211 """Return a sorted list of all possible completions on text.
1220 1212
1221 1213 Inputs:
1222 1214
1223 1215 - text: a string of text to be completed on.
1224 1216
1225 1217 This is a wrapper around the completion mechanism, similar to what
1226 1218 readline does at the command line when the TAB key is hit. By
1227 1219 exposing it as a method, it can be used by other non-readline
1228 1220 environments (such as GUIs) for text completion.
1229 1221
1230 1222 Simple usage example:
1231 1223
1232 1224 In [7]: x = 'hello'
1233 1225
1234 1226 In [8]: x
1235 1227 Out[8]: 'hello'
1236 1228
1237 1229 In [9]: print x
1238 1230 hello
1239 1231
1240 1232 In [10]: _ip.IP.complete('x.l')
1241 1233 Out[10]: ['x.ljust', 'x.lower', 'x.lstrip']
1242 1234 """
1243 1235
1244 1236 complete = self.Completer.complete
1245 1237 state = 0
1246 1238 # use a dict so we get unique keys, since ipyhton's multiple
1247 1239 # completers can return duplicates. When we make 2.4 a requirement,
1248 1240 # start using sets instead, which are faster.
1249 1241 comps = {}
1250 1242 while True:
1251 1243 newcomp = complete(text,state,line_buffer=text)
1252 1244 if newcomp is None:
1253 1245 break
1254 1246 comps[newcomp] = 1
1255 1247 state += 1
1256 1248 outcomps = comps.keys()
1257 1249 outcomps.sort()
1258 1250 #print "T:",text,"OC:",outcomps # dbg
1259 1251 #print "vars:",self.user_ns.keys()
1260 1252 return outcomps
1261 1253
1262 1254 def set_completer_frame(self, frame=None):
1263 1255 if frame:
1264 1256 self.Completer.namespace = frame.f_locals
1265 1257 self.Completer.global_namespace = frame.f_globals
1266 1258 else:
1267 1259 self.Completer.namespace = self.user_ns
1268 1260 self.Completer.global_namespace = self.user_global_ns
1269 1261
1270 1262 def init_auto_alias(self):
1271 1263 """Define some aliases automatically.
1272 1264
1273 1265 These are ALL parameter-less aliases"""
1274 1266
1275 1267 for alias,cmd in self.auto_alias:
1276 1268 self.getapi().defalias(alias,cmd)
1277 1269
1278 1270
1279 1271 def alias_table_validate(self,verbose=0):
1280 1272 """Update information about the alias table.
1281 1273
1282 1274 In particular, make sure no Python keywords/builtins are in it."""
1283 1275
1284 1276 no_alias = self.no_alias
1285 1277 for k in self.alias_table.keys():
1286 1278 if k in no_alias:
1287 1279 del self.alias_table[k]
1288 1280 if verbose:
1289 1281 print ("Deleting alias <%s>, it's a Python "
1290 1282 "keyword or builtin." % k)
1291 1283
1292 1284 def set_autoindent(self,value=None):
1293 1285 """Set the autoindent flag, checking for readline support.
1294 1286
1295 1287 If called with no arguments, it acts as a toggle."""
1296 1288
1297 1289 if not self.has_readline:
1298 1290 if os.name == 'posix':
1299 1291 warn("The auto-indent feature requires the readline library")
1300 1292 self.autoindent = 0
1301 1293 return
1302 1294 if value is None:
1303 1295 self.autoindent = not self.autoindent
1304 1296 else:
1305 1297 self.autoindent = value
1306 1298
1307 1299 def rc_set_toggle(self,rc_field,value=None):
1308 1300 """Set or toggle a field in IPython's rc config. structure.
1309 1301
1310 1302 If called with no arguments, it acts as a toggle.
1311 1303
1312 1304 If called with a non-existent field, the resulting AttributeError
1313 1305 exception will propagate out."""
1314 1306
1315 1307 rc_val = getattr(self.rc,rc_field)
1316 1308 if value is None:
1317 1309 value = not rc_val
1318 1310 setattr(self.rc,rc_field,value)
1319 1311
1320 1312 def user_setup(self,ipythondir,rc_suffix,mode='install'):
1321 1313 """Install the user configuration directory.
1322 1314
1323 1315 Note
1324 1316 ----
1325 1317 DEPRECATED: use the top-level user_setup() function instead.
1326 1318 """
1327 1319 return user_setup(ipythondir,rc_suffix,mode)
1328 1320
1329 1321 def atexit_operations(self):
1330 1322 """This will be executed at the time of exit.
1331 1323
1332 1324 Saving of persistent data should be performed here. """
1333 1325
1334 1326 #print '*** IPython exit cleanup ***' # dbg
1335 1327 # input history
1336 1328 self.savehist()
1337 1329
1338 1330 # Cleanup all tempfiles left around
1339 1331 for tfile in self.tempfiles:
1340 1332 try:
1341 1333 os.unlink(tfile)
1342 1334 except OSError:
1343 1335 pass
1344 1336
1345 1337 # Clear all user namespaces to release all references cleanly.
1346 1338 self.reset()
1347 1339
1348 1340 # Run user hooks
1349 1341 self.hooks.shutdown_hook()
1350 1342
1351 1343 def reset(self):
1352 1344 """Clear all internal namespaces.
1353 1345
1354 1346 Note that this is much more aggressive than %reset, since it clears
1355 1347 fully all namespaces, as well as all input/output lists.
1356 1348 """
1357 1349 for ns in self.ns_refs_table:
1358 1350 ns.clear()
1359 1351
1360 1352 # Clear input and output histories
1361 1353 self.input_hist[:] = []
1362 1354 self.input_hist_raw[:] = []
1363 1355 self.output_hist.clear()
1364 1356 # Restore the user namespaces to minimal usability
1365 1357 self.init_namespaces()
1366 1358
1367 1359 def savehist(self):
1368 1360 """Save input history to a file (via readline library)."""
1369 1361
1370 1362 if not self.has_readline:
1371 1363 return
1372 1364
1373 1365 try:
1374 1366 self.readline.write_history_file(self.histfile)
1375 1367 except:
1376 1368 print 'Unable to save IPython command history to file: ' + \
1377 1369 `self.histfile`
1378 1370
1379 1371 def reloadhist(self):
1380 1372 """Reload the input history from disk file."""
1381 1373
1382 1374 if self.has_readline:
1383 1375 try:
1384 1376 self.readline.clear_history()
1385 1377 self.readline.read_history_file(self.shell.histfile)
1386 1378 except AttributeError:
1387 1379 pass
1388 1380
1389 1381
1390 1382 def history_saving_wrapper(self, func):
1391 1383 """ Wrap func for readline history saving
1392 1384
1393 1385 Convert func into callable that saves & restores
1394 1386 history around the call """
1395 1387
1396 1388 if not self.has_readline:
1397 1389 return func
1398 1390
1399 1391 def wrapper():
1400 1392 self.savehist()
1401 1393 try:
1402 1394 func()
1403 1395 finally:
1404 1396 readline.read_history_file(self.histfile)
1405 1397 return wrapper
1406 1398
1407 1399 def pre_readline(self):
1408 1400 """readline hook to be used at the start of each line.
1409 1401
1410 1402 Currently it handles auto-indent only."""
1411 1403
1412 1404 #debugx('self.indent_current_nsp','pre_readline:')
1413 1405
1414 1406 if self.rl_do_indent:
1415 1407 self.readline.insert_text(self.indent_current_str())
1416 1408 if self.rl_next_input is not None:
1417 1409 self.readline.insert_text(self.rl_next_input)
1418 1410 self.rl_next_input = None
1419 1411
1420 1412 def init_readline(self):
1421 1413 """Command history completion/saving/reloading."""
1422 1414
1423 1415
1424 1416 import IPython.rlineimpl as readline
1425 1417
1426 1418 if not readline.have_readline:
1427 1419 self.has_readline = 0
1428 1420 self.readline = None
1429 1421 # no point in bugging windows users with this every time:
1430 1422 warn('Readline services not available on this platform.')
1431 1423 else:
1432 1424 sys.modules['readline'] = readline
1433 1425 import atexit
1434 1426 from IPython.completer import IPCompleter
1435 1427 self.Completer = IPCompleter(self,
1436 1428 self.user_ns,
1437 1429 self.user_global_ns,
1438 1430 self.rc.readline_omit__names,
1439 1431 self.alias_table)
1440 1432 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1441 1433 self.strdispatchers['complete_command'] = sdisp
1442 1434 self.Completer.custom_completers = sdisp
1443 1435 # Platform-specific configuration
1444 1436 if os.name == 'nt':
1445 1437 self.readline_startup_hook = readline.set_pre_input_hook
1446 1438 else:
1447 1439 self.readline_startup_hook = readline.set_startup_hook
1448 1440
1449 1441 # Load user's initrc file (readline config)
1450 1442 # Or if libedit is used, load editrc.
1451 1443 inputrc_name = os.environ.get('INPUTRC')
1452 1444 if inputrc_name is None:
1453 1445 home_dir = get_home_dir()
1454 1446 if home_dir is not None:
1455 1447 inputrc_name = '.inputrc'
1456 1448 if readline.uses_libedit:
1457 1449 inputrc_name = '.editrc'
1458 1450 inputrc_name = os.path.join(home_dir, inputrc_name)
1459 1451 if os.path.isfile(inputrc_name):
1460 1452 try:
1461 1453 readline.read_init_file(inputrc_name)
1462 1454 except:
1463 1455 warn('Problems reading readline initialization file <%s>'
1464 1456 % inputrc_name)
1465 1457
1466 1458 self.has_readline = 1
1467 1459 self.readline = readline
1468 1460 # save this in sys so embedded copies can restore it properly
1469 1461 sys.ipcompleter = self.Completer.complete
1470 1462 self.set_completer()
1471 1463
1472 1464 # Configure readline according to user's prefs
1473 1465 # This is only done if GNU readline is being used. If libedit
1474 1466 # is being used (as on Leopard) the readline config is
1475 1467 # not run as the syntax for libedit is different.
1476 1468 if not readline.uses_libedit:
1477 1469 for rlcommand in self.rc.readline_parse_and_bind:
1478 1470 #print "loading rl:",rlcommand # dbg
1479 1471 readline.parse_and_bind(rlcommand)
1480 1472
1481 1473 # Remove some chars from the delimiters list. If we encounter
1482 1474 # unicode chars, discard them.
1483 1475 delims = readline.get_completer_delims().encode("ascii", "ignore")
1484 1476 delims = delims.translate(string._idmap,
1485 1477 self.rc.readline_remove_delims)
1486 1478 readline.set_completer_delims(delims)
1487 1479 # otherwise we end up with a monster history after a while:
1488 1480 readline.set_history_length(1000)
1489 1481 try:
1490 1482 #print '*** Reading readline history' # dbg
1491 1483 readline.read_history_file(self.histfile)
1492 1484 except IOError:
1493 1485 pass # It doesn't exist yet.
1494 1486
1495 1487 atexit.register(self.atexit_operations)
1496 1488 del atexit
1497 1489
1498 1490 # Configure auto-indent for all platforms
1499 1491 self.set_autoindent(self.rc.autoindent)
1500 1492
1501 1493 def ask_yes_no(self,prompt,default=True):
1502 1494 if self.rc.quiet:
1503 1495 return True
1504 1496 return ask_yes_no(prompt,default)
1505 1497
1506 1498 def new_main_mod(self,ns=None):
1507 1499 """Return a new 'main' module object for user code execution.
1508 1500 """
1509 1501 main_mod = self._user_main_module
1510 1502 init_fakemod_dict(main_mod,ns)
1511 1503 return main_mod
1512 1504
1513 1505 def cache_main_mod(self,ns,fname):
1514 1506 """Cache a main module's namespace.
1515 1507
1516 1508 When scripts are executed via %run, we must keep a reference to the
1517 1509 namespace of their __main__ module (a FakeModule instance) around so
1518 1510 that Python doesn't clear it, rendering objects defined therein
1519 1511 useless.
1520 1512
1521 1513 This method keeps said reference in a private dict, keyed by the
1522 1514 absolute path of the module object (which corresponds to the script
1523 1515 path). This way, for multiple executions of the same script we only
1524 1516 keep one copy of the namespace (the last one), thus preventing memory
1525 1517 leaks from old references while allowing the objects from the last
1526 1518 execution to be accessible.
1527 1519
1528 1520 Note: we can not allow the actual FakeModule instances to be deleted,
1529 1521 because of how Python tears down modules (it hard-sets all their
1530 1522 references to None without regard for reference counts). This method
1531 1523 must therefore make a *copy* of the given namespace, to allow the
1532 1524 original module's __dict__ to be cleared and reused.
1533 1525
1534 1526
1535 1527 Parameters
1536 1528 ----------
1537 1529 ns : a namespace (a dict, typically)
1538 1530
1539 1531 fname : str
1540 1532 Filename associated with the namespace.
1541 1533
1542 1534 Examples
1543 1535 --------
1544 1536
1545 1537 In [10]: import IPython
1546 1538
1547 1539 In [11]: _ip.IP.cache_main_mod(IPython.__dict__,IPython.__file__)
1548 1540
1549 1541 In [12]: IPython.__file__ in _ip.IP._main_ns_cache
1550 1542 Out[12]: True
1551 1543 """
1552 1544 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
1553 1545
1554 1546 def clear_main_mod_cache(self):
1555 1547 """Clear the cache of main modules.
1556 1548
1557 1549 Mainly for use by utilities like %reset.
1558 1550
1559 1551 Examples
1560 1552 --------
1561 1553
1562 1554 In [15]: import IPython
1563 1555
1564 1556 In [16]: _ip.IP.cache_main_mod(IPython.__dict__,IPython.__file__)
1565 1557
1566 1558 In [17]: len(_ip.IP._main_ns_cache) > 0
1567 1559 Out[17]: True
1568 1560
1569 1561 In [18]: _ip.IP.clear_main_mod_cache()
1570 1562
1571 1563 In [19]: len(_ip.IP._main_ns_cache) == 0
1572 1564 Out[19]: True
1573 1565 """
1574 1566 self._main_ns_cache.clear()
1575 1567
1576 1568 def _should_recompile(self,e):
1577 1569 """Utility routine for edit_syntax_error"""
1578 1570
1579 1571 if e.filename in ('<ipython console>','<input>','<string>',
1580 1572 '<console>','<BackgroundJob compilation>',
1581 1573 None):
1582 1574
1583 1575 return False
1584 1576 try:
1585 1577 if (self.rc.autoedit_syntax and
1586 1578 not self.ask_yes_no('Return to editor to correct syntax error? '
1587 1579 '[Y/n] ','y')):
1588 1580 return False
1589 1581 except EOFError:
1590 1582 return False
1591 1583
1592 1584 def int0(x):
1593 1585 try:
1594 1586 return int(x)
1595 1587 except TypeError:
1596 1588 return 0
1597 1589 # always pass integer line and offset values to editor hook
1598 1590 try:
1599 1591 self.hooks.fix_error_editor(e.filename,
1600 1592 int0(e.lineno),int0(e.offset),e.msg)
1601 1593 except IPython.ipapi.TryNext:
1602 1594 warn('Could not open editor')
1603 1595 return False
1604 1596 return True
1605 1597
1606 1598 def edit_syntax_error(self):
1607 1599 """The bottom half of the syntax error handler called in the main loop.
1608 1600
1609 1601 Loop until syntax error is fixed or user cancels.
1610 1602 """
1611 1603
1612 1604 while self.SyntaxTB.last_syntax_error:
1613 1605 # copy and clear last_syntax_error
1614 1606 err = self.SyntaxTB.clear_err_state()
1615 1607 if not self._should_recompile(err):
1616 1608 return
1617 1609 try:
1618 1610 # may set last_syntax_error again if a SyntaxError is raised
1619 1611 self.safe_execfile(err.filename,self.user_ns)
1620 1612 except:
1621 1613 self.showtraceback()
1622 1614 else:
1623 1615 try:
1624 1616 f = file(err.filename)
1625 1617 try:
1626 1618 sys.displayhook(f.read())
1627 1619 finally:
1628 1620 f.close()
1629 1621 except:
1630 1622 self.showtraceback()
1631 1623
1632 1624 def showsyntaxerror(self, filename=None):
1633 1625 """Display the syntax error that just occurred.
1634 1626
1635 1627 This doesn't display a stack trace because there isn't one.
1636 1628
1637 1629 If a filename is given, it is stuffed in the exception instead
1638 1630 of what was there before (because Python's parser always uses
1639 1631 "<string>" when reading from a string).
1640 1632 """
1641 1633 etype, value, last_traceback = sys.exc_info()
1642 1634
1643 1635 # See note about these variables in showtraceback() below
1644 1636 sys.last_type = etype
1645 1637 sys.last_value = value
1646 1638 sys.last_traceback = last_traceback
1647 1639
1648 1640 if filename and etype is SyntaxError:
1649 1641 # Work hard to stuff the correct filename in the exception
1650 1642 try:
1651 1643 msg, (dummy_filename, lineno, offset, line) = value
1652 1644 except:
1653 1645 # Not the format we expect; leave it alone
1654 1646 pass
1655 1647 else:
1656 1648 # Stuff in the right filename
1657 1649 try:
1658 1650 # Assume SyntaxError is a class exception
1659 1651 value = SyntaxError(msg, (filename, lineno, offset, line))
1660 1652 except:
1661 1653 # If that failed, assume SyntaxError is a string
1662 1654 value = msg, (filename, lineno, offset, line)
1663 1655 self.SyntaxTB(etype,value,[])
1664 1656
1665 1657 def debugger(self,force=False):
1666 1658 """Call the pydb/pdb debugger.
1667 1659
1668 1660 Keywords:
1669 1661
1670 1662 - force(False): by default, this routine checks the instance call_pdb
1671 1663 flag and does not actually invoke the debugger if the flag is false.
1672 1664 The 'force' option forces the debugger to activate even if the flag
1673 1665 is false.
1674 1666 """
1675 1667
1676 1668 if not (force or self.call_pdb):
1677 1669 return
1678 1670
1679 1671 if not hasattr(sys,'last_traceback'):
1680 1672 error('No traceback has been produced, nothing to debug.')
1681 1673 return
1682 1674
1683 1675 # use pydb if available
1684 1676 if Debugger.has_pydb:
1685 1677 from pydb import pm
1686 1678 else:
1687 1679 # fallback to our internal debugger
1688 1680 pm = lambda : self.InteractiveTB.debugger(force=True)
1689 1681 self.history_saving_wrapper(pm)()
1690 1682
1691 1683 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None):
1692 1684 """Display the exception that just occurred.
1693 1685
1694 1686 If nothing is known about the exception, this is the method which
1695 1687 should be used throughout the code for presenting user tracebacks,
1696 1688 rather than directly invoking the InteractiveTB object.
1697 1689
1698 1690 A specific showsyntaxerror() also exists, but this method can take
1699 1691 care of calling it if needed, so unless you are explicitly catching a
1700 1692 SyntaxError exception, don't try to analyze the stack manually and
1701 1693 simply call this method."""
1702 1694
1703 1695
1704 1696 # Though this won't be called by syntax errors in the input line,
1705 1697 # there may be SyntaxError cases whith imported code.
1706 1698
1707 1699 try:
1708 1700 if exc_tuple is None:
1709 1701 etype, value, tb = sys.exc_info()
1710 1702 else:
1711 1703 etype, value, tb = exc_tuple
1712 1704
1713 1705 if etype is SyntaxError:
1714 1706 self.showsyntaxerror(filename)
1715 1707 elif etype is IPython.ipapi.UsageError:
1716 1708 print "UsageError:", value
1717 1709 else:
1718 1710 # WARNING: these variables are somewhat deprecated and not
1719 1711 # necessarily safe to use in a threaded environment, but tools
1720 1712 # like pdb depend on their existence, so let's set them. If we
1721 1713 # find problems in the field, we'll need to revisit their use.
1722 1714 sys.last_type = etype
1723 1715 sys.last_value = value
1724 1716 sys.last_traceback = tb
1725 1717
1726 1718 if etype in self.custom_exceptions:
1727 1719 self.CustomTB(etype,value,tb)
1728 1720 else:
1729 1721 self.InteractiveTB(etype,value,tb,tb_offset=tb_offset)
1730 1722 if self.InteractiveTB.call_pdb and self.has_readline:
1731 1723 # pdb mucks up readline, fix it back
1732 1724 self.set_completer()
1733 1725 except KeyboardInterrupt:
1734 1726 self.write("\nKeyboardInterrupt\n")
1735 1727
1736 1728 def mainloop(self,banner=None):
1737 1729 """Creates the local namespace and starts the mainloop.
1738 1730
1739 1731 If an optional banner argument is given, it will override the
1740 1732 internally created default banner."""
1741 1733
1742 1734 if self.rc.c: # Emulate Python's -c option
1743 1735 self.exec_init_cmd()
1744 1736 if banner is None:
1745 1737 if not self.rc.banner:
1746 1738 banner = ''
1747 1739 # banner is string? Use it directly!
1748 1740 elif isinstance(self.rc.banner,basestring):
1749 1741 banner = self.rc.banner
1750 1742 else:
1751 1743 banner = self.BANNER+self.banner2
1752 1744
1753 1745 # if you run stuff with -c <cmd>, raw hist is not updated
1754 1746 # ensure that it's in sync
1755 1747 if len(self.input_hist) != len (self.input_hist_raw):
1756 1748 self.input_hist_raw = InputList(self.input_hist)
1757 1749
1758 1750 while 1:
1759 1751 try:
1760 1752 self.interact(banner)
1761 1753 #self.interact_with_readline()
1762 1754
1763 1755 # XXX for testing of a readline-decoupled repl loop, call
1764 1756 # interact_with_readline above
1765 1757
1766 1758 break
1767 1759 except KeyboardInterrupt:
1768 1760 # this should not be necessary, but KeyboardInterrupt
1769 1761 # handling seems rather unpredictable...
1770 1762 self.write("\nKeyboardInterrupt in interact()\n")
1771 1763
1772 1764 def exec_init_cmd(self):
1773 1765 """Execute a command given at the command line.
1774 1766
1775 1767 This emulates Python's -c option."""
1776 1768
1777 1769 #sys.argv = ['-c']
1778 1770 self.push(self.prefilter(self.rc.c, False))
1779 1771 if not self.rc.interact:
1780 1772 self.ask_exit()
1781 1773
1782 1774 def embed_mainloop(self,header='',local_ns=None,global_ns=None,stack_depth=0):
1783 1775 """Embeds IPython into a running python program.
1784 1776
1785 1777 Input:
1786 1778
1787 1779 - header: An optional header message can be specified.
1788 1780
1789 1781 - local_ns, global_ns: working namespaces. If given as None, the
1790 1782 IPython-initialized one is updated with __main__.__dict__, so that
1791 1783 program variables become visible but user-specific configuration
1792 1784 remains possible.
1793 1785
1794 1786 - stack_depth: specifies how many levels in the stack to go to
1795 1787 looking for namespaces (when local_ns and global_ns are None). This
1796 1788 allows an intermediate caller to make sure that this function gets
1797 1789 the namespace from the intended level in the stack. By default (0)
1798 1790 it will get its locals and globals from the immediate caller.
1799 1791
1800 1792 Warning: it's possible to use this in a program which is being run by
1801 1793 IPython itself (via %run), but some funny things will happen (a few
1802 1794 globals get overwritten). In the future this will be cleaned up, as
1803 1795 there is no fundamental reason why it can't work perfectly."""
1804 1796
1805 1797 # Get locals and globals from caller
1806 1798 if local_ns is None or global_ns is None:
1807 1799 call_frame = sys._getframe(stack_depth).f_back
1808 1800
1809 1801 if local_ns is None:
1810 1802 local_ns = call_frame.f_locals
1811 1803 if global_ns is None:
1812 1804 global_ns = call_frame.f_globals
1813 1805
1814 1806 # Update namespaces and fire up interpreter
1815 1807
1816 1808 # The global one is easy, we can just throw it in
1817 1809 self.user_global_ns = global_ns
1818 1810
1819 1811 # but the user/local one is tricky: ipython needs it to store internal
1820 1812 # data, but we also need the locals. We'll copy locals in the user
1821 1813 # one, but will track what got copied so we can delete them at exit.
1822 1814 # This is so that a later embedded call doesn't see locals from a
1823 1815 # previous call (which most likely existed in a separate scope).
1824 1816 local_varnames = local_ns.keys()
1825 1817 self.user_ns.update(local_ns)
1826 1818 #self.user_ns['local_ns'] = local_ns # dbg
1827 1819
1828 1820 # Patch for global embedding to make sure that things don't overwrite
1829 1821 # user globals accidentally. Thanks to Richard <rxe@renre-europe.com>
1830 1822 # FIXME. Test this a bit more carefully (the if.. is new)
1831 1823 if local_ns is None and global_ns is None:
1832 1824 self.user_global_ns.update(__main__.__dict__)
1833 1825
1834 1826 # make sure the tab-completer has the correct frame information, so it
1835 1827 # actually completes using the frame's locals/globals
1836 1828 self.set_completer_frame()
1837 1829
1838 1830 # before activating the interactive mode, we need to make sure that
1839 1831 # all names in the builtin namespace needed by ipython point to
1840 1832 # ourselves, and not to other instances.
1841 1833 self.add_builtins()
1842 1834
1843 1835 self.interact(header)
1844 1836
1845 1837 # now, purge out the user namespace from anything we might have added
1846 1838 # from the caller's local namespace
1847 1839 delvar = self.user_ns.pop
1848 1840 for var in local_varnames:
1849 1841 delvar(var,None)
1850 1842 # and clean builtins we may have overridden
1851 1843 self.clean_builtins()
1852 1844
1853 1845 def interact_prompt(self):
1854 1846 """ Print the prompt (in read-eval-print loop)
1855 1847
1856 1848 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1857 1849 used in standard IPython flow.
1858 1850 """
1859 1851 if self.more:
1860 1852 try:
1861 1853 prompt = self.hooks.generate_prompt(True)
1862 1854 except:
1863 1855 self.showtraceback()
1864 1856 if self.autoindent:
1865 1857 self.rl_do_indent = True
1866 1858
1867 1859 else:
1868 1860 try:
1869 1861 prompt = self.hooks.generate_prompt(False)
1870 1862 except:
1871 1863 self.showtraceback()
1872 1864 self.write(prompt)
1873 1865
1874 1866 def interact_handle_input(self,line):
1875 1867 """ Handle the input line (in read-eval-print loop)
1876 1868
1877 1869 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1878 1870 used in standard IPython flow.
1879 1871 """
1880 1872 if line.lstrip() == line:
1881 1873 self.shadowhist.add(line.strip())
1882 1874 lineout = self.prefilter(line,self.more)
1883 1875
1884 1876 if line.strip():
1885 1877 if self.more:
1886 1878 self.input_hist_raw[-1] += '%s\n' % line
1887 1879 else:
1888 1880 self.input_hist_raw.append('%s\n' % line)
1889 1881
1890 1882
1891 1883 self.more = self.push(lineout)
1892 1884 if (self.SyntaxTB.last_syntax_error and
1893 1885 self.rc.autoedit_syntax):
1894 1886 self.edit_syntax_error()
1895 1887
1896 1888 def interact_with_readline(self):
1897 1889 """ Demo of using interact_handle_input, interact_prompt
1898 1890
1899 1891 This is the main read-eval-print loop. If you need to implement your own (e.g. for GUI),
1900 1892 it should work like this.
1901 1893 """
1902 1894 self.readline_startup_hook(self.pre_readline)
1903 1895 while not self.exit_now:
1904 1896 self.interact_prompt()
1905 1897 if self.more:
1906 1898 self.rl_do_indent = True
1907 1899 else:
1908 1900 self.rl_do_indent = False
1909 1901 line = raw_input_original().decode(self.stdin_encoding)
1910 1902 self.interact_handle_input(line)
1911 1903
1912 1904
1913 1905 def interact(self, banner=None):
1914 1906 """Closely emulate the interactive Python console.
1915 1907
1916 1908 The optional banner argument specify the banner to print
1917 1909 before the first interaction; by default it prints a banner
1918 1910 similar to the one printed by the real Python interpreter,
1919 1911 followed by the current class name in parentheses (so as not
1920 1912 to confuse this with the real interpreter -- since it's so
1921 1913 close!).
1922 1914
1923 1915 """
1924 1916
1925 1917 if self.exit_now:
1926 1918 # batch run -> do not interact
1927 1919 return
1928 1920 cprt = 'Type "copyright", "credits" or "license" for more information.'
1929 1921 if banner is None:
1930 1922 self.write("Python %s on %s\n%s\n(%s)\n" %
1931 1923 (sys.version, sys.platform, cprt,
1932 1924 self.__class__.__name__))
1933 1925 else:
1934 1926 self.write(banner)
1935 1927
1936 1928 more = 0
1937 1929
1938 1930 # Mark activity in the builtins
1939 1931 __builtin__.__dict__['__IPYTHON__active'] += 1
1940 1932
1941 1933 if self.has_readline:
1942 1934 self.readline_startup_hook(self.pre_readline)
1943 1935 # exit_now is set by a call to %Exit or %Quit, through the
1944 1936 # ask_exit callback.
1945 1937
1946 1938 while not self.exit_now:
1947 1939 self.hooks.pre_prompt_hook()
1948 1940 if more:
1949 1941 try:
1950 1942 prompt = self.hooks.generate_prompt(True)
1951 1943 except:
1952 1944 self.showtraceback()
1953 1945 if self.autoindent:
1954 1946 self.rl_do_indent = True
1955 1947
1956 1948 else:
1957 1949 try:
1958 1950 prompt = self.hooks.generate_prompt(False)
1959 1951 except:
1960 1952 self.showtraceback()
1961 1953 try:
1962 1954 line = self.raw_input(prompt,more)
1963 1955 if self.exit_now:
1964 1956 # quick exit on sys.std[in|out] close
1965 1957 break
1966 1958 if self.autoindent:
1967 1959 self.rl_do_indent = False
1968 1960
1969 1961 except KeyboardInterrupt:
1970 1962 #double-guard against keyboardinterrupts during kbdint handling
1971 1963 try:
1972 1964 self.write('\nKeyboardInterrupt\n')
1973 1965 self.resetbuffer()
1974 1966 # keep cache in sync with the prompt counter:
1975 1967 self.outputcache.prompt_count -= 1
1976 1968
1977 1969 if self.autoindent:
1978 1970 self.indent_current_nsp = 0
1979 1971 more = 0
1980 1972 except KeyboardInterrupt:
1981 1973 pass
1982 1974 except EOFError:
1983 1975 if self.autoindent:
1984 1976 self.rl_do_indent = False
1985 1977 self.readline_startup_hook(None)
1986 1978 self.write('\n')
1987 1979 self.exit()
1988 1980 except bdb.BdbQuit:
1989 1981 warn('The Python debugger has exited with a BdbQuit exception.\n'
1990 1982 'Because of how pdb handles the stack, it is impossible\n'
1991 1983 'for IPython to properly format this particular exception.\n'
1992 1984 'IPython will resume normal operation.')
1993 1985 except:
1994 1986 # exceptions here are VERY RARE, but they can be triggered
1995 1987 # asynchronously by signal handlers, for example.
1996 1988 self.showtraceback()
1997 1989 else:
1998 1990 more = self.push(line)
1999 1991 if (self.SyntaxTB.last_syntax_error and
2000 1992 self.rc.autoedit_syntax):
2001 1993 self.edit_syntax_error()
2002 1994
2003 1995 # We are off again...
2004 1996 __builtin__.__dict__['__IPYTHON__active'] -= 1
2005 1997
2006 1998 def excepthook(self, etype, value, tb):
2007 1999 """One more defense for GUI apps that call sys.excepthook.
2008 2000
2009 2001 GUI frameworks like wxPython trap exceptions and call
2010 2002 sys.excepthook themselves. I guess this is a feature that
2011 2003 enables them to keep running after exceptions that would
2012 2004 otherwise kill their mainloop. This is a bother for IPython
2013 2005 which excepts to catch all of the program exceptions with a try:
2014 2006 except: statement.
2015 2007
2016 2008 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
2017 2009 any app directly invokes sys.excepthook, it will look to the user like
2018 2010 IPython crashed. In order to work around this, we can disable the
2019 2011 CrashHandler and replace it with this excepthook instead, which prints a
2020 2012 regular traceback using our InteractiveTB. In this fashion, apps which
2021 2013 call sys.excepthook will generate a regular-looking exception from
2022 2014 IPython, and the CrashHandler will only be triggered by real IPython
2023 2015 crashes.
2024 2016
2025 2017 This hook should be used sparingly, only in places which are not likely
2026 2018 to be true IPython errors.
2027 2019 """
2028 2020 self.showtraceback((etype,value,tb),tb_offset=0)
2029 2021
2030 2022 def expand_aliases(self,fn,rest):
2031 2023 """ Expand multiple levels of aliases:
2032 2024
2033 2025 if:
2034 2026
2035 2027 alias foo bar /tmp
2036 2028 alias baz foo
2037 2029
2038 2030 then:
2039 2031
2040 2032 baz huhhahhei -> bar /tmp huhhahhei
2041 2033
2042 2034 """
2043 2035 line = fn + " " + rest
2044 2036
2045 2037 done = set()
2046 2038 while 1:
2047 2039 pre,fn,rest = prefilter.splitUserInput(line,
2048 2040 prefilter.shell_line_split)
2049 2041 if fn in self.alias_table:
2050 2042 if fn in done:
2051 2043 warn("Cyclic alias definition, repeated '%s'" % fn)
2052 2044 return ""
2053 2045 done.add(fn)
2054 2046
2055 2047 l2 = self.transform_alias(fn,rest)
2056 2048 # dir -> dir
2057 2049 # print "alias",line, "->",l2 #dbg
2058 2050 if l2 == line:
2059 2051 break
2060 2052 # ls -> ls -F should not recurse forever
2061 2053 if l2.split(None,1)[0] == line.split(None,1)[0]:
2062 2054 line = l2
2063 2055 break
2064 2056
2065 2057 line=l2
2066 2058
2067 2059
2068 2060 # print "al expand to",line #dbg
2069 2061 else:
2070 2062 break
2071 2063
2072 2064 return line
2073 2065
2074 2066 def transform_alias(self, alias,rest=''):
2075 2067 """ Transform alias to system command string.
2076 2068 """
2077 2069 trg = self.alias_table[alias]
2078 2070
2079 2071 nargs,cmd = trg
2080 2072 # print trg #dbg
2081 2073 if ' ' in cmd and os.path.isfile(cmd):
2082 2074 cmd = '"%s"' % cmd
2083 2075
2084 2076 # Expand the %l special to be the user's input line
2085 2077 if cmd.find('%l') >= 0:
2086 2078 cmd = cmd.replace('%l',rest)
2087 2079 rest = ''
2088 2080 if nargs==0:
2089 2081 # Simple, argument-less aliases
2090 2082 cmd = '%s %s' % (cmd,rest)
2091 2083 else:
2092 2084 # Handle aliases with positional arguments
2093 2085 args = rest.split(None,nargs)
2094 2086 if len(args)< nargs:
2095 2087 error('Alias <%s> requires %s arguments, %s given.' %
2096 2088 (alias,nargs,len(args)))
2097 2089 return None
2098 2090 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
2099 2091 # Now call the macro, evaluating in the user's namespace
2100 2092 #print 'new command: <%r>' % cmd # dbg
2101 2093 return cmd
2102 2094
2103 2095 def call_alias(self,alias,rest=''):
2104 2096 """Call an alias given its name and the rest of the line.
2105 2097
2106 2098 This is only used to provide backwards compatibility for users of
2107 2099 ipalias(), use of which is not recommended for anymore."""
2108 2100
2109 2101 # Now call the macro, evaluating in the user's namespace
2110 2102 cmd = self.transform_alias(alias, rest)
2111 2103 try:
2112 2104 self.system(cmd)
2113 2105 except:
2114 2106 self.showtraceback()
2115 2107
2116 2108 def indent_current_str(self):
2117 2109 """return the current level of indentation as a string"""
2118 2110 return self.indent_current_nsp * ' '
2119 2111
2120 2112 def autoindent_update(self,line):
2121 2113 """Keep track of the indent level."""
2122 2114
2123 2115 #debugx('line')
2124 2116 #debugx('self.indent_current_nsp')
2125 2117 if self.autoindent:
2126 2118 if line:
2127 2119 inisp = num_ini_spaces(line)
2128 2120 if inisp < self.indent_current_nsp:
2129 2121 self.indent_current_nsp = inisp
2130 2122
2131 2123 if line[-1] == ':':
2132 2124 self.indent_current_nsp += 4
2133 2125 elif dedent_re.match(line):
2134 2126 self.indent_current_nsp -= 4
2135 2127 else:
2136 2128 self.indent_current_nsp = 0
2137 2129
2138 2130 def runlines(self,lines):
2139 2131 """Run a string of one or more lines of source.
2140 2132
2141 2133 This method is capable of running a string containing multiple source
2142 2134 lines, as if they had been entered at the IPython prompt. Since it
2143 2135 exposes IPython's processing machinery, the given strings can contain
2144 2136 magic calls (%magic), special shell access (!cmd), etc."""
2145 2137
2146 2138 # We must start with a clean buffer, in case this is run from an
2147 2139 # interactive IPython session (via a magic, for example).
2148 2140 self.resetbuffer()
2149 2141 lines = lines.split('\n')
2150 2142 more = 0
2151 2143
2152 2144 for line in lines:
2153 2145 # skip blank lines so we don't mess up the prompt counter, but do
2154 2146 # NOT skip even a blank line if we are in a code block (more is
2155 2147 # true)
2156 2148
2157 2149 if line or more:
2158 2150 # push to raw history, so hist line numbers stay in sync
2159 2151 self.input_hist_raw.append("# " + line + "\n")
2160 2152 more = self.push(self.prefilter(line,more))
2161 2153 # IPython's runsource returns None if there was an error
2162 2154 # compiling the code. This allows us to stop processing right
2163 2155 # away, so the user gets the error message at the right place.
2164 2156 if more is None:
2165 2157 break
2166 2158 else:
2167 2159 self.input_hist_raw.append("\n")
2168 2160 # final newline in case the input didn't have it, so that the code
2169 2161 # actually does get executed
2170 2162 if more:
2171 2163 self.push('\n')
2172 2164
2173 2165 def runsource(self, source, filename='<input>', symbol='single'):
2174 2166 """Compile and run some source in the interpreter.
2175 2167
2176 2168 Arguments are as for compile_command().
2177 2169
2178 2170 One several things can happen:
2179 2171
2180 2172 1) The input is incorrect; compile_command() raised an
2181 2173 exception (SyntaxError or OverflowError). A syntax traceback
2182 2174 will be printed by calling the showsyntaxerror() method.
2183 2175
2184 2176 2) The input is incomplete, and more input is required;
2185 2177 compile_command() returned None. Nothing happens.
2186 2178
2187 2179 3) The input is complete; compile_command() returned a code
2188 2180 object. The code is executed by calling self.runcode() (which
2189 2181 also handles run-time exceptions, except for SystemExit).
2190 2182
2191 2183 The return value is:
2192 2184
2193 2185 - True in case 2
2194 2186
2195 2187 - False in the other cases, unless an exception is raised, where
2196 2188 None is returned instead. This can be used by external callers to
2197 2189 know whether to continue feeding input or not.
2198 2190
2199 2191 The return value can be used to decide whether to use sys.ps1 or
2200 2192 sys.ps2 to prompt the next line."""
2201 2193
2202 2194 # if the source code has leading blanks, add 'if 1:\n' to it
2203 2195 # this allows execution of indented pasted code. It is tempting
2204 2196 # to add '\n' at the end of source to run commands like ' a=1'
2205 2197 # directly, but this fails for more complicated scenarios
2206 2198 source=source.encode(self.stdin_encoding)
2207 2199 if source[:1] in [' ', '\t']:
2208 2200 source = 'if 1:\n%s' % source
2209 2201
2210 2202 try:
2211 2203 code = self.compile(source,filename,symbol)
2212 2204 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
2213 2205 # Case 1
2214 2206 self.showsyntaxerror(filename)
2215 2207 return None
2216 2208
2217 2209 if code is None:
2218 2210 # Case 2
2219 2211 return True
2220 2212
2221 2213 # Case 3
2222 2214 # We store the code object so that threaded shells and
2223 2215 # custom exception handlers can access all this info if needed.
2224 2216 # The source corresponding to this can be obtained from the
2225 2217 # buffer attribute as '\n'.join(self.buffer).
2226 2218 self.code_to_run = code
2227 2219 # now actually execute the code object
2228 2220 if self.runcode(code) == 0:
2229 2221 return False
2230 2222 else:
2231 2223 return None
2232 2224
2233 2225 def runcode(self,code_obj):
2234 2226 """Execute a code object.
2235 2227
2236 2228 When an exception occurs, self.showtraceback() is called to display a
2237 2229 traceback.
2238 2230
2239 2231 Return value: a flag indicating whether the code to be run completed
2240 2232 successfully:
2241 2233
2242 2234 - 0: successful execution.
2243 2235 - 1: an error occurred.
2244 2236 """
2245 2237
2246 2238 # Set our own excepthook in case the user code tries to call it
2247 2239 # directly, so that the IPython crash handler doesn't get triggered
2248 2240 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2249 2241
2250 2242 # we save the original sys.excepthook in the instance, in case config
2251 2243 # code (such as magics) needs access to it.
2252 2244 self.sys_excepthook = old_excepthook
2253 2245 outflag = 1 # happens in more places, so it's easier as default
2254 2246 try:
2255 2247 try:
2256 2248 self.hooks.pre_runcode_hook()
2257 2249 exec code_obj in self.user_global_ns, self.user_ns
2258 2250 finally:
2259 2251 # Reset our crash handler in place
2260 2252 sys.excepthook = old_excepthook
2261 2253 except SystemExit:
2262 2254 self.resetbuffer()
2263 2255 self.showtraceback()
2264 2256 warn("Type %exit or %quit to exit IPython "
2265 2257 "(%Exit or %Quit do so unconditionally).",level=1)
2266 2258 except self.custom_exceptions:
2267 2259 etype,value,tb = sys.exc_info()
2268 2260 self.CustomTB(etype,value,tb)
2269 2261 except:
2270 2262 self.showtraceback()
2271 2263 else:
2272 2264 outflag = 0
2273 2265 if softspace(sys.stdout, 0):
2274 2266 print
2275 2267 # Flush out code object which has been run (and source)
2276 2268 self.code_to_run = None
2277 2269 return outflag
2278 2270
2279 2271 def push(self, line):
2280 2272 """Push a line to the interpreter.
2281 2273
2282 2274 The line should not have a trailing newline; it may have
2283 2275 internal newlines. The line is appended to a buffer and the
2284 2276 interpreter's runsource() method is called with the
2285 2277 concatenated contents of the buffer as source. If this
2286 2278 indicates that the command was executed or invalid, the buffer
2287 2279 is reset; otherwise, the command is incomplete, and the buffer
2288 2280 is left as it was after the line was appended. The return
2289 2281 value is 1 if more input is required, 0 if the line was dealt
2290 2282 with in some way (this is the same as runsource()).
2291 2283 """
2292 2284
2293 2285 # autoindent management should be done here, and not in the
2294 2286 # interactive loop, since that one is only seen by keyboard input. We
2295 2287 # need this done correctly even for code run via runlines (which uses
2296 2288 # push).
2297 2289
2298 2290 #print 'push line: <%s>' % line # dbg
2299 2291 for subline in line.splitlines():
2300 2292 self.autoindent_update(subline)
2301 2293 self.buffer.append(line)
2302 2294 more = self.runsource('\n'.join(self.buffer), self.filename)
2303 2295 if not more:
2304 2296 self.resetbuffer()
2305 2297 return more
2306 2298
2307 2299 def split_user_input(self, line):
2308 2300 # This is really a hold-over to support ipapi and some extensions
2309 2301 return prefilter.splitUserInput(line)
2310 2302
2311 2303 def resetbuffer(self):
2312 2304 """Reset the input buffer."""
2313 2305 self.buffer[:] = []
2314 2306
2315 2307 def raw_input(self,prompt='',continue_prompt=False):
2316 2308 """Write a prompt and read a line.
2317 2309
2318 2310 The returned line does not include the trailing newline.
2319 2311 When the user enters the EOF key sequence, EOFError is raised.
2320 2312
2321 2313 Optional inputs:
2322 2314
2323 2315 - prompt(''): a string to be printed to prompt the user.
2324 2316
2325 2317 - continue_prompt(False): whether this line is the first one or a
2326 2318 continuation in a sequence of inputs.
2327 2319 """
2328 2320
2329 2321 # Code run by the user may have modified the readline completer state.
2330 2322 # We must ensure that our completer is back in place.
2331 2323 if self.has_readline:
2332 2324 self.set_completer()
2333 2325
2334 2326 try:
2335 2327 line = raw_input_original(prompt).decode(self.stdin_encoding)
2336 2328 except ValueError:
2337 2329 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
2338 2330 " or sys.stdout.close()!\nExiting IPython!")
2339 2331 self.ask_exit()
2340 2332 return ""
2341 2333
2342 2334 # Try to be reasonably smart about not re-indenting pasted input more
2343 2335 # than necessary. We do this by trimming out the auto-indent initial
2344 2336 # spaces, if the user's actual input started itself with whitespace.
2345 2337 #debugx('self.buffer[-1]')
2346 2338
2347 2339 if self.autoindent:
2348 2340 if num_ini_spaces(line) > self.indent_current_nsp:
2349 2341 line = line[self.indent_current_nsp:]
2350 2342 self.indent_current_nsp = 0
2351 2343
2352 2344 # store the unfiltered input before the user has any chance to modify
2353 2345 # it.
2354 2346 if line.strip():
2355 2347 if continue_prompt:
2356 2348 self.input_hist_raw[-1] += '%s\n' % line
2357 2349 if self.has_readline: # and some config option is set?
2358 2350 try:
2359 2351 histlen = self.readline.get_current_history_length()
2360 2352 if histlen > 1:
2361 2353 newhist = self.input_hist_raw[-1].rstrip()
2362 2354 self.readline.remove_history_item(histlen-1)
2363 2355 self.readline.replace_history_item(histlen-2,
2364 2356 newhist.encode(self.stdin_encoding))
2365 2357 except AttributeError:
2366 2358 pass # re{move,place}_history_item are new in 2.4.
2367 2359 else:
2368 2360 self.input_hist_raw.append('%s\n' % line)
2369 2361 # only entries starting at first column go to shadow history
2370 2362 if line.lstrip() == line:
2371 2363 self.shadowhist.add(line.strip())
2372 2364 elif not continue_prompt:
2373 2365 self.input_hist_raw.append('\n')
2374 2366 try:
2375 2367 lineout = self.prefilter(line,continue_prompt)
2376 2368 except:
2377 2369 # blanket except, in case a user-defined prefilter crashes, so it
2378 2370 # can't take all of ipython with it.
2379 2371 self.showtraceback()
2380 2372 return ''
2381 2373 else:
2382 2374 return lineout
2383 2375
2384 2376 def _prefilter(self, line, continue_prompt):
2385 2377 """Calls different preprocessors, depending on the form of line."""
2386 2378
2387 2379 # All handlers *must* return a value, even if it's blank ('').
2388 2380
2389 2381 # Lines are NOT logged here. Handlers should process the line as
2390 2382 # needed, update the cache AND log it (so that the input cache array
2391 2383 # stays synced).
2392 2384
2393 2385 #.....................................................................
2394 2386 # Code begins
2395 2387
2396 2388 #if line.startswith('%crash'): raise RuntimeError,'Crash now!' # dbg
2397 2389
2398 2390 # save the line away in case we crash, so the post-mortem handler can
2399 2391 # record it
2400 2392 self._last_input_line = line
2401 2393
2402 2394 #print '***line: <%s>' % line # dbg
2403 2395
2404 2396 if not line:
2405 2397 # Return immediately on purely empty lines, so that if the user
2406 2398 # previously typed some whitespace that started a continuation
2407 2399 # prompt, he can break out of that loop with just an empty line.
2408 2400 # This is how the default python prompt works.
2409 2401
2410 2402 # Only return if the accumulated input buffer was just whitespace!
2411 2403 if ''.join(self.buffer).isspace():
2412 2404 self.buffer[:] = []
2413 2405 return ''
2414 2406
2415 2407 line_info = prefilter.LineInfo(line, continue_prompt)
2416 2408
2417 2409 # the input history needs to track even empty lines
2418 2410 stripped = line.strip()
2419 2411
2420 2412 if not stripped:
2421 2413 if not continue_prompt:
2422 2414 self.outputcache.prompt_count -= 1
2423 2415 return self.handle_normal(line_info)
2424 2416
2425 2417 # print '***cont',continue_prompt # dbg
2426 2418 # special handlers are only allowed for single line statements
2427 2419 if continue_prompt and not self.rc.multi_line_specials:
2428 2420 return self.handle_normal(line_info)
2429 2421
2430 2422
2431 2423 # See whether any pre-existing handler can take care of it
2432 2424 rewritten = self.hooks.input_prefilter(stripped)
2433 2425 if rewritten != stripped: # ok, some prefilter did something
2434 2426 rewritten = line_info.pre + rewritten # add indentation
2435 2427 return self.handle_normal(prefilter.LineInfo(rewritten,
2436 2428 continue_prompt))
2437 2429
2438 2430 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
2439 2431
2440 2432 return prefilter.prefilter(line_info, self)
2441 2433
2442 2434
2443 2435 def _prefilter_dumb(self, line, continue_prompt):
2444 2436 """simple prefilter function, for debugging"""
2445 2437 return self.handle_normal(line,continue_prompt)
2446 2438
2447 2439
2448 2440 def multiline_prefilter(self, line, continue_prompt):
2449 2441 """ Run _prefilter for each line of input
2450 2442
2451 2443 Covers cases where there are multiple lines in the user entry,
2452 2444 which is the case when the user goes back to a multiline history
2453 2445 entry and presses enter.
2454 2446
2455 2447 """
2456 2448 out = []
2457 2449 for l in line.rstrip('\n').split('\n'):
2458 2450 out.append(self._prefilter(l, continue_prompt))
2459 2451 return '\n'.join(out)
2460 2452
2461 2453 # Set the default prefilter() function (this can be user-overridden)
2462 2454 prefilter = multiline_prefilter
2463 2455
2464 2456 def handle_normal(self,line_info):
2465 2457 """Handle normal input lines. Use as a template for handlers."""
2466 2458
2467 2459 # With autoindent on, we need some way to exit the input loop, and I
2468 2460 # don't want to force the user to have to backspace all the way to
2469 2461 # clear the line. The rule will be in this case, that either two
2470 2462 # lines of pure whitespace in a row, or a line of pure whitespace but
2471 2463 # of a size different to the indent level, will exit the input loop.
2472 2464 line = line_info.line
2473 2465 continue_prompt = line_info.continue_prompt
2474 2466
2475 2467 if (continue_prompt and self.autoindent and line.isspace() and
2476 2468 (0 < abs(len(line) - self.indent_current_nsp) <= 2 or
2477 2469 (self.buffer[-1]).isspace() )):
2478 2470 line = ''
2479 2471
2480 2472 self.log(line,line,continue_prompt)
2481 2473 return line
2482 2474
2483 2475 def handle_alias(self,line_info):
2484 2476 """Handle alias input lines. """
2485 2477 tgt = self.alias_table[line_info.iFun]
2486 2478 # print "=>",tgt #dbg
2487 2479 if callable(tgt):
2488 2480 if '$' in line_info.line:
2489 2481 call_meth = '(_ip, _ip.itpl(%s))'
2490 2482 else:
2491 2483 call_meth = '(_ip,%s)'
2492 2484 line_out = ("%s_sh.%s" + call_meth) % (line_info.preWhitespace,
2493 2485 line_info.iFun,
2494 2486 make_quoted_expr(line_info.line))
2495 2487 else:
2496 2488 transformed = self.expand_aliases(line_info.iFun,line_info.theRest)
2497 2489
2498 2490 # pre is needed, because it carries the leading whitespace. Otherwise
2499 2491 # aliases won't work in indented sections.
2500 2492 line_out = '%s_ip.system(%s)' % (line_info.preWhitespace,
2501 2493 make_quoted_expr( transformed ))
2502 2494
2503 2495 self.log(line_info.line,line_out,line_info.continue_prompt)
2504 2496 #print 'line out:',line_out # dbg
2505 2497 return line_out
2506 2498
2507 2499 def handle_shell_escape(self, line_info):
2508 2500 """Execute the line in a shell, empty return value"""
2509 2501 #print 'line in :', `line` # dbg
2510 2502 line = line_info.line
2511 2503 if line.lstrip().startswith('!!'):
2512 2504 # rewrite LineInfo's line, iFun and theRest to properly hold the
2513 2505 # call to %sx and the actual command to be executed, so
2514 2506 # handle_magic can work correctly. Note that this works even if
2515 2507 # the line is indented, so it handles multi_line_specials
2516 2508 # properly.
2517 2509 new_rest = line.lstrip()[2:]
2518 2510 line_info.line = '%ssx %s' % (self.ESC_MAGIC,new_rest)
2519 2511 line_info.iFun = 'sx'
2520 2512 line_info.theRest = new_rest
2521 2513 return self.handle_magic(line_info)
2522 2514 else:
2523 2515 cmd = line.lstrip().lstrip('!')
2524 2516 line_out = '%s_ip.system(%s)' % (line_info.preWhitespace,
2525 2517 make_quoted_expr(cmd))
2526 2518 # update cache/log and return
2527 2519 self.log(line,line_out,line_info.continue_prompt)
2528 2520 return line_out
2529 2521
2530 2522 def handle_magic(self, line_info):
2531 2523 """Execute magic functions."""
2532 2524 iFun = line_info.iFun
2533 2525 theRest = line_info.theRest
2534 2526 cmd = '%s_ip.magic(%s)' % (line_info.preWhitespace,
2535 2527 make_quoted_expr(iFun + " " + theRest))
2536 2528 self.log(line_info.line,cmd,line_info.continue_prompt)
2537 2529 #print 'in handle_magic, cmd=<%s>' % cmd # dbg
2538 2530 return cmd
2539 2531
2540 2532 def handle_auto(self, line_info):
2541 2533 """Hande lines which can be auto-executed, quoting if requested."""
2542 2534
2543 2535 line = line_info.line
2544 2536 iFun = line_info.iFun
2545 2537 theRest = line_info.theRest
2546 2538 pre = line_info.pre
2547 2539 continue_prompt = line_info.continue_prompt
2548 2540 obj = line_info.ofind(self)['obj']
2549 2541
2550 2542 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
2551 2543
2552 2544 # This should only be active for single-line input!
2553 2545 if continue_prompt:
2554 2546 self.log(line,line,continue_prompt)
2555 2547 return line
2556 2548
2557 2549 force_auto = isinstance(obj, IPython.ipapi.IPyAutocall)
2558 2550 auto_rewrite = True
2559 2551
2560 2552 if pre == self.ESC_QUOTE:
2561 2553 # Auto-quote splitting on whitespace
2562 2554 newcmd = '%s("%s")' % (iFun,'", "'.join(theRest.split()) )
2563 2555 elif pre == self.ESC_QUOTE2:
2564 2556 # Auto-quote whole string
2565 2557 newcmd = '%s("%s")' % (iFun,theRest)
2566 2558 elif pre == self.ESC_PAREN:
2567 2559 newcmd = '%s(%s)' % (iFun,",".join(theRest.split()))
2568 2560 else:
2569 2561 # Auto-paren.
2570 2562 # We only apply it to argument-less calls if the autocall
2571 2563 # parameter is set to 2. We only need to check that autocall is <
2572 2564 # 2, since this function isn't called unless it's at least 1.
2573 2565 if not theRest and (self.rc.autocall < 2) and not force_auto:
2574 2566 newcmd = '%s %s' % (iFun,theRest)
2575 2567 auto_rewrite = False
2576 2568 else:
2577 2569 if not force_auto and theRest.startswith('['):
2578 2570 if hasattr(obj,'__getitem__'):
2579 2571 # Don't autocall in this case: item access for an object
2580 2572 # which is BOTH callable and implements __getitem__.
2581 2573 newcmd = '%s %s' % (iFun,theRest)
2582 2574 auto_rewrite = False
2583 2575 else:
2584 2576 # if the object doesn't support [] access, go ahead and
2585 2577 # autocall
2586 2578 newcmd = '%s(%s)' % (iFun.rstrip(),theRest)
2587 2579 elif theRest.endswith(';'):
2588 2580 newcmd = '%s(%s);' % (iFun.rstrip(),theRest[:-1])
2589 2581 else:
2590 2582 newcmd = '%s(%s)' % (iFun.rstrip(), theRest)
2591 2583
2592 2584 if auto_rewrite:
2593 2585 rw = self.outputcache.prompt1.auto_rewrite() + newcmd
2594 2586
2595 2587 try:
2596 2588 # plain ascii works better w/ pyreadline, on some machines, so
2597 2589 # we use it and only print uncolored rewrite if we have unicode
2598 2590 rw = str(rw)
2599 2591 print >>Term.cout, rw
2600 2592 except UnicodeEncodeError:
2601 2593 print "-------------->" + newcmd
2602 2594
2603 2595 # log what is now valid Python, not the actual user input (without the
2604 2596 # final newline)
2605 2597 self.log(line,newcmd,continue_prompt)
2606 2598 return newcmd
2607 2599
2608 2600 def handle_help(self, line_info):
2609 2601 """Try to get some help for the object.
2610 2602
2611 2603 obj? or ?obj -> basic information.
2612 2604 obj?? or ??obj -> more details.
2613 2605 """
2614 2606
2615 2607 line = line_info.line
2616 2608 # We need to make sure that we don't process lines which would be
2617 2609 # otherwise valid python, such as "x=1 # what?"
2618 2610 try:
2619 2611 codeop.compile_command(line)
2620 2612 except SyntaxError:
2621 2613 # We should only handle as help stuff which is NOT valid syntax
2622 2614 if line[0]==self.ESC_HELP:
2623 2615 line = line[1:]
2624 2616 elif line[-1]==self.ESC_HELP:
2625 2617 line = line[:-1]
2626 2618 self.log(line,'#?'+line,line_info.continue_prompt)
2627 2619 if line:
2628 2620 #print 'line:<%r>' % line # dbg
2629 2621 self.magic_pinfo(line)
2630 2622 else:
2631 2623 page(self.usage,screen_lines=self.rc.screen_length)
2632 2624 return '' # Empty string is needed here!
2633 2625 except:
2634 2626 # Pass any other exceptions through to the normal handler
2635 2627 return self.handle_normal(line_info)
2636 2628 else:
2637 2629 # If the code compiles ok, we should handle it normally
2638 2630 return self.handle_normal(line_info)
2639 2631
2640 2632 def getapi(self):
2641 2633 """ Get an IPApi object for this shell instance
2642 2634
2643 2635 Getting an IPApi object is always preferable to accessing the shell
2644 2636 directly, but this holds true especially for extensions.
2645 2637
2646 2638 It should always be possible to implement an extension with IPApi
2647 2639 alone. If not, contact maintainer to request an addition.
2648 2640
2649 2641 """
2650 2642 return self.api
2651 2643
2652 2644 def handle_emacs(self, line_info):
2653 2645 """Handle input lines marked by python-mode."""
2654 2646
2655 2647 # Currently, nothing is done. Later more functionality can be added
2656 2648 # here if needed.
2657 2649
2658 2650 # The input cache shouldn't be updated
2659 2651 return line_info.line
2660 2652
2661 2653
2662 2654 def mktempfile(self,data=None):
2663 2655 """Make a new tempfile and return its filename.
2664 2656
2665 2657 This makes a call to tempfile.mktemp, but it registers the created
2666 2658 filename internally so ipython cleans it up at exit time.
2667 2659
2668 2660 Optional inputs:
2669 2661
2670 2662 - data(None): if data is given, it gets written out to the temp file
2671 2663 immediately, and the file is closed again."""
2672 2664
2673 2665 filename = tempfile.mktemp('.py','ipython_edit_')
2674 2666 self.tempfiles.append(filename)
2675 2667
2676 2668 if data:
2677 2669 tmp_file = open(filename,'w')
2678 2670 tmp_file.write(data)
2679 2671 tmp_file.close()
2680 2672 return filename
2681 2673
2682 2674 def write(self,data):
2683 2675 """Write a string to the default output"""
2684 2676 Term.cout.write(data)
2685 2677
2686 2678 def write_err(self,data):
2687 2679 """Write a string to the default error output"""
2688 2680 Term.cerr.write(data)
2689 2681
2690 2682 def ask_exit(self):
2691 2683 """ Call for exiting. Can be overiden and used as a callback. """
2692 2684 self.exit_now = True
2693 2685
2694 2686 def exit(self):
2695 2687 """Handle interactive exit.
2696 2688
2697 2689 This method calls the ask_exit callback."""
2698 2690
2699 2691 if self.rc.confirm_exit:
2700 2692 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
2701 2693 self.ask_exit()
2702 2694 else:
2703 2695 self.ask_exit()
2704 2696
2705 2697 def safe_execfile(self,fname,*where,**kw):
2706 2698 """A safe version of the builtin execfile().
2707 2699
2708 2700 This version will never throw an exception, and knows how to handle
2709 2701 ipython logs as well.
2710 2702
2711 2703 :Parameters:
2712 2704 fname : string
2713 2705 Name of the file to be executed.
2714 2706
2715 2707 where : tuple
2716 2708 One or two namespaces, passed to execfile() as (globals,locals).
2717 2709 If only one is given, it is passed as both.
2718 2710
2719 2711 :Keywords:
2720 2712 islog : boolean (False)
2721 2713
2722 2714 quiet : boolean (True)
2723 2715
2724 2716 exit_ignore : boolean (False)
2725 2717 """
2726 2718
2727 2719 def syspath_cleanup():
2728 2720 """Internal cleanup routine for sys.path."""
2729 2721 if add_dname:
2730 2722 try:
2731 2723 sys.path.remove(dname)
2732 2724 except ValueError:
2733 2725 # For some reason the user has already removed it, ignore.
2734 2726 pass
2735 2727
2736 2728 fname = os.path.expanduser(fname)
2737 2729
2738 2730 # Find things also in current directory. This is needed to mimic the
2739 2731 # behavior of running a script from the system command line, where
2740 2732 # Python inserts the script's directory into sys.path
2741 2733 dname = os.path.dirname(os.path.abspath(fname))
2742 2734 add_dname = False
2743 2735 if dname not in sys.path:
2744 2736 sys.path.insert(0,dname)
2745 2737 add_dname = True
2746 2738
2747 2739 try:
2748 2740 xfile = open(fname)
2749 2741 except:
2750 2742 print >> Term.cerr, \
2751 2743 'Could not open file <%s> for safe execution.' % fname
2752 2744 syspath_cleanup()
2753 2745 return None
2754 2746
2755 2747 kw.setdefault('islog',0)
2756 2748 kw.setdefault('quiet',1)
2757 2749 kw.setdefault('exit_ignore',0)
2758 2750
2759 2751 first = xfile.readline()
2760 2752 loghead = str(self.loghead_tpl).split('\n',1)[0].strip()
2761 2753 xfile.close()
2762 2754 # line by line execution
2763 2755 if first.startswith(loghead) or kw['islog']:
2764 2756 print 'Loading log file <%s> one line at a time...' % fname
2765 2757 if kw['quiet']:
2766 2758 stdout_save = sys.stdout
2767 2759 sys.stdout = StringIO.StringIO()
2768 2760 try:
2769 2761 globs,locs = where[0:2]
2770 2762 except:
2771 2763 try:
2772 2764 globs = locs = where[0]
2773 2765 except:
2774 2766 globs = locs = globals()
2775 2767 badblocks = []
2776 2768
2777 2769 # we also need to identify indented blocks of code when replaying
2778 2770 # logs and put them together before passing them to an exec
2779 2771 # statement. This takes a bit of regexp and look-ahead work in the
2780 2772 # file. It's easiest if we swallow the whole thing in memory
2781 2773 # first, and manually walk through the lines list moving the
2782 2774 # counter ourselves.
2783 2775 indent_re = re.compile('\s+\S')
2784 2776 xfile = open(fname)
2785 2777 filelines = xfile.readlines()
2786 2778 xfile.close()
2787 2779 nlines = len(filelines)
2788 2780 lnum = 0
2789 2781 while lnum < nlines:
2790 2782 line = filelines[lnum]
2791 2783 lnum += 1
2792 2784 # don't re-insert logger status info into cache
2793 2785 if line.startswith('#log#'):
2794 2786 continue
2795 2787 else:
2796 2788 # build a block of code (maybe a single line) for execution
2797 2789 block = line
2798 2790 try:
2799 2791 next = filelines[lnum] # lnum has already incremented
2800 2792 except:
2801 2793 next = None
2802 2794 while next and indent_re.match(next):
2803 2795 block += next
2804 2796 lnum += 1
2805 2797 try:
2806 2798 next = filelines[lnum]
2807 2799 except:
2808 2800 next = None
2809 2801 # now execute the block of one or more lines
2810 2802 try:
2811 2803 exec block in globs,locs
2812 2804 except SystemExit:
2813 2805 pass
2814 2806 except:
2815 2807 badblocks.append(block.rstrip())
2816 2808 if kw['quiet']: # restore stdout
2817 2809 sys.stdout.close()
2818 2810 sys.stdout = stdout_save
2819 2811 print 'Finished replaying log file <%s>' % fname
2820 2812 if badblocks:
2821 2813 print >> sys.stderr, ('\nThe following lines/blocks in file '
2822 2814 '<%s> reported errors:' % fname)
2823 2815
2824 2816 for badline in badblocks:
2825 2817 print >> sys.stderr, badline
2826 2818 else: # regular file execution
2827 2819 try:
2828 2820 if sys.platform == 'win32' and sys.version_info < (2,5,1):
2829 2821 # Work around a bug in Python for Windows. The bug was
2830 2822 # fixed in in Python 2.5 r54159 and 54158, but that's still
2831 2823 # SVN Python as of March/07. For details, see:
2832 2824 # http://projects.scipy.org/ipython/ipython/ticket/123
2833 2825 try:
2834 2826 globs,locs = where[0:2]
2835 2827 except:
2836 2828 try:
2837 2829 globs = locs = where[0]
2838 2830 except:
2839 2831 globs = locs = globals()
2840 2832 exec file(fname) in globs,locs
2841 2833 else:
2842 2834 execfile(fname,*where)
2843 2835 except SyntaxError:
2844 2836 self.showsyntaxerror()
2845 2837 warn('Failure executing file: <%s>' % fname)
2846 2838 except SystemExit,status:
2847 2839 # Code that correctly sets the exit status flag to success (0)
2848 2840 # shouldn't be bothered with a traceback. Note that a plain
2849 2841 # sys.exit() does NOT set the message to 0 (it's empty) so that
2850 2842 # will still get a traceback. Note that the structure of the
2851 2843 # SystemExit exception changed between Python 2.4 and 2.5, so
2852 2844 # the checks must be done in a version-dependent way.
2853 2845 show = False
2854 2846
2855 2847 if sys.version_info[:2] > (2,5):
2856 2848 if status.message!=0 and not kw['exit_ignore']:
2857 2849 show = True
2858 2850 else:
2859 2851 if status.code and not kw['exit_ignore']:
2860 2852 show = True
2861 2853 if show:
2862 2854 self.showtraceback()
2863 2855 warn('Failure executing file: <%s>' % fname)
2864 2856 except:
2865 2857 self.showtraceback()
2866 2858 warn('Failure executing file: <%s>' % fname)
2867 2859
2868 2860 syspath_cleanup()
2869 2861
2870 2862 #************************* end of file <iplib.py> *****************************
@@ -1,588 +1,584 b''
1 1 # encoding: utf-8
2 2 """Classes for handling input/output prompts.
3 3
4 4 Authors
5 5 -------
6 6 - Fernando Perez <Fernando.Perez@berkeley.edu>
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 # Required modules
23 23 import __builtin__
24 import os
25 24 import socket
26 25 import sys
27 import time
28 26
29 27 # IPython's own
30 28 from IPython.external.Itpl import ItplNS
31 from macro import Macro
32 29
33 from IPython import ColorANSI
30 from IPython.utils import coloransi
34 31 from IPython import Release
35 32 from IPython.ipapi import TryNext
36 from IPython.ipstruct import Struct
37 33 from IPython.genutils import *
38 34
39 35 #****************************************************************************
40 36 #Color schemes for Prompts.
41 37
42 PromptColors = ColorANSI.ColorSchemeTable()
43 InputColors = ColorANSI.InputTermColors # just a shorthand
44 Colors = ColorANSI.TermColors # just a shorthand
38 PromptColors = coloransi.ColorSchemeTable()
39 InputColors = coloransi.InputTermColors # just a shorthand
40 Colors = coloransi.TermColors # just a shorthand
45 41
46 42
47 __PColNoColor = ColorANSI.ColorScheme(
43 __PColNoColor = coloransi.ColorScheme(
48 44 'NoColor',
49 45 in_prompt = InputColors.NoColor, # Input prompt
50 46 in_number = InputColors.NoColor, # Input prompt number
51 47 in_prompt2 = InputColors.NoColor, # Continuation prompt
52 48 in_normal = InputColors.NoColor, # color off (usu. Colors.Normal)
53 49
54 50 out_prompt = Colors.NoColor, # Output prompt
55 51 out_number = Colors.NoColor, # Output prompt number
56 52
57 53 normal = Colors.NoColor # color off (usu. Colors.Normal)
58 54 )
59 55
60 56 PromptColors.add_scheme(__PColNoColor)
61 57
62 58 # make some schemes as instances so we can copy them for modification easily:
63 59 __PColLinux = __PColNoColor.copy('Linux')
64 60 # Don't forget to enter it into the table!
65 61 PromptColors.add_scheme(__PColLinux)
66 62 __PColLightBG = __PColLinux.copy('LightBG')
67 63 PromptColors.add_scheme(__PColLightBG)
68 64
69 65 del Colors,InputColors
70 66
71 67 #-----------------------------------------------------------------------------
72 68 def multiple_replace(dict, text):
73 69 """ Replace in 'text' all occurences of any key in the given
74 70 dictionary by its corresponding value. Returns the new string."""
75 71
76 72 # Function by Xavier Defrang, originally found at:
77 73 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81330
78 74
79 75 # Create a regular expression from the dictionary keys
80 76 regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))
81 77 # For each match, look-up corresponding value in dictionary
82 78 return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text)
83 79
84 80 #-----------------------------------------------------------------------------
85 81 # Special characters that can be used in prompt templates, mainly bash-like
86 82
87 83 # If $HOME isn't defined (Windows), make it an absurd string so that it can
88 84 # never be expanded out into '~'. Basically anything which can never be a
89 85 # reasonable directory name will do, we just want the $HOME -> '~' operation
90 86 # to become a no-op. We pre-compute $HOME here so it's not done on every
91 87 # prompt call.
92 88
93 89 # FIXME:
94 90
95 91 # - This should be turned into a class which does proper namespace management,
96 92 # since the prompt specials need to be evaluated in a certain namespace.
97 93 # Currently it's just globals, which need to be managed manually by code
98 94 # below.
99 95
100 96 # - I also need to split up the color schemes from the prompt specials
101 97 # somehow. I don't have a clean design for that quite yet.
102 98
103 99 HOME = os.environ.get("HOME","//////:::::ZZZZZ,,,~~~")
104 100
105 101 # We precompute a few more strings here for the prompt_specials, which are
106 102 # fixed once ipython starts. This reduces the runtime overhead of computing
107 103 # prompt strings.
108 104 USER = os.environ.get("USER")
109 105 HOSTNAME = socket.gethostname()
110 106 HOSTNAME_SHORT = HOSTNAME.split(".")[0]
111 107 ROOT_SYMBOL = "$#"[os.name=='nt' or os.getuid()==0]
112 108
113 109 prompt_specials_color = {
114 110 # Prompt/history count
115 111 '%n' : '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
116 112 r'\#': '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
117 113 # Just the prompt counter number, WITHOUT any coloring wrappers, so users
118 114 # can get numbers displayed in whatever color they want.
119 115 r'\N': '${self.cache.prompt_count}',
120 116 # Prompt/history count, with the actual digits replaced by dots. Used
121 117 # mainly in continuation prompts (prompt_in2)
122 118 r'\D': '${"."*len(str(self.cache.prompt_count))}',
123 119 # Current working directory
124 120 r'\w': '${os.getcwd()}',
125 121 # Current time
126 122 r'\t' : '${time.strftime("%H:%M:%S")}',
127 123 # Basename of current working directory.
128 124 # (use os.sep to make this portable across OSes)
129 125 r'\W' : '${os.getcwd().split("%s")[-1]}' % os.sep,
130 126 # These X<N> are an extension to the normal bash prompts. They return
131 127 # N terms of the path, after replacing $HOME with '~'
132 128 r'\X0': '${os.getcwd().replace("%s","~")}' % HOME,
133 129 r'\X1': '${self.cwd_filt(1)}',
134 130 r'\X2': '${self.cwd_filt(2)}',
135 131 r'\X3': '${self.cwd_filt(3)}',
136 132 r'\X4': '${self.cwd_filt(4)}',
137 133 r'\X5': '${self.cwd_filt(5)}',
138 134 # Y<N> are similar to X<N>, but they show '~' if it's the directory
139 135 # N+1 in the list. Somewhat like %cN in tcsh.
140 136 r'\Y0': '${self.cwd_filt2(0)}',
141 137 r'\Y1': '${self.cwd_filt2(1)}',
142 138 r'\Y2': '${self.cwd_filt2(2)}',
143 139 r'\Y3': '${self.cwd_filt2(3)}',
144 140 r'\Y4': '${self.cwd_filt2(4)}',
145 141 r'\Y5': '${self.cwd_filt2(5)}',
146 142 # Hostname up to first .
147 143 r'\h': HOSTNAME_SHORT,
148 144 # Full hostname
149 145 r'\H': HOSTNAME,
150 146 # Username of current user
151 147 r'\u': USER,
152 148 # Escaped '\'
153 149 '\\\\': '\\',
154 150 # Newline
155 151 r'\n': '\n',
156 152 # Carriage return
157 153 r'\r': '\r',
158 154 # Release version
159 155 r'\v': Release.version,
160 156 # Root symbol ($ or #)
161 157 r'\$': ROOT_SYMBOL,
162 158 }
163 159
164 160 # A copy of the prompt_specials dictionary but with all color escapes removed,
165 161 # so we can correctly compute the prompt length for the auto_rewrite method.
166 162 prompt_specials_nocolor = prompt_specials_color.copy()
167 163 prompt_specials_nocolor['%n'] = '${self.cache.prompt_count}'
168 164 prompt_specials_nocolor[r'\#'] = '${self.cache.prompt_count}'
169 165
170 166 # Add in all the InputTermColors color escapes as valid prompt characters.
171 167 # They all get added as \\C_COLORNAME, so that we don't have any conflicts
172 168 # with a color name which may begin with a letter used by any other of the
173 169 # allowed specials. This of course means that \\C will never be allowed for
174 170 # anything else.
175 input_colors = ColorANSI.InputTermColors
171 input_colors = coloransi.InputTermColors
176 172 for _color in dir(input_colors):
177 173 if _color[0] != '_':
178 174 c_name = r'\C_'+_color
179 175 prompt_specials_color[c_name] = getattr(input_colors,_color)
180 176 prompt_specials_nocolor[c_name] = ''
181 177
182 178 # we default to no color for safety. Note that prompt_specials is a global
183 179 # variable used by all prompt objects.
184 180 prompt_specials = prompt_specials_nocolor
185 181
186 182 #-----------------------------------------------------------------------------
187 183 def str_safe(arg):
188 184 """Convert to a string, without ever raising an exception.
189 185
190 186 If str(arg) fails, <ERROR: ... > is returned, where ... is the exception
191 187 error message."""
192 188
193 189 try:
194 190 out = str(arg)
195 191 except UnicodeError:
196 192 try:
197 193 out = arg.encode('utf_8','replace')
198 194 except Exception,msg:
199 195 # let's keep this little duplication here, so that the most common
200 196 # case doesn't suffer from a double try wrapping.
201 197 out = '<ERROR: %s>' % msg
202 198 except Exception,msg:
203 199 out = '<ERROR: %s>' % msg
204 200 return out
205 201
206 202 class BasePrompt(object):
207 203 """Interactive prompt similar to Mathematica's."""
208 204
209 205 def _get_p_template(self):
210 206 return self._p_template
211 207
212 208 def _set_p_template(self,val):
213 209 self._p_template = val
214 210 self.set_p_str()
215 211
216 212 p_template = property(_get_p_template,_set_p_template,
217 213 doc='Template for prompt string creation')
218 214
219 215 def __init__(self,cache,sep,prompt,pad_left=False):
220 216
221 217 # Hack: we access information about the primary prompt through the
222 218 # cache argument. We need this, because we want the secondary prompt
223 219 # to be aligned with the primary one. Color table info is also shared
224 220 # by all prompt classes through the cache. Nice OO spaghetti code!
225 221 self.cache = cache
226 222 self.sep = sep
227 223
228 224 # regexp to count the number of spaces at the end of a prompt
229 225 # expression, useful for prompt auto-rewriting
230 226 self.rspace = re.compile(r'(\s*)$')
231 227 # Flag to left-pad prompt strings to match the length of the primary
232 228 # prompt
233 229 self.pad_left = pad_left
234 230
235 231 # Set template to create each actual prompt (where numbers change).
236 232 # Use a property
237 233 self.p_template = prompt
238 234 self.set_p_str()
239 235
240 236 def set_p_str(self):
241 237 """ Set the interpolating prompt strings.
242 238
243 239 This must be called every time the color settings change, because the
244 240 prompt_specials global may have changed."""
245 241
246 242 import os,time # needed in locals for prompt string handling
247 243 loc = locals()
248 244 self.p_str = ItplNS('%s%s%s' %
249 245 ('${self.sep}${self.col_p}',
250 246 multiple_replace(prompt_specials, self.p_template),
251 247 '${self.col_norm}'),self.cache.user_ns,loc)
252 248
253 249 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
254 250 self.p_template),
255 251 self.cache.user_ns,loc)
256 252
257 253 def write(self,msg): # dbg
258 254 sys.stdout.write(msg)
259 255 return ''
260 256
261 257 def __str__(self):
262 258 """Return a string form of the prompt.
263 259
264 260 This for is useful for continuation and output prompts, since it is
265 261 left-padded to match lengths with the primary one (if the
266 262 self.pad_left attribute is set)."""
267 263
268 264 out_str = str_safe(self.p_str)
269 265 if self.pad_left:
270 266 # We must find the amount of padding required to match lengths,
271 267 # taking the color escapes (which are invisible on-screen) into
272 268 # account.
273 269 esc_pad = len(out_str) - len(str_safe(self.p_str_nocolor))
274 270 format = '%%%ss' % (len(str(self.cache.last_prompt))+esc_pad)
275 271 return format % out_str
276 272 else:
277 273 return out_str
278 274
279 275 # these path filters are put in as methods so that we can control the
280 276 # namespace where the prompt strings get evaluated
281 277 def cwd_filt(self,depth):
282 278 """Return the last depth elements of the current working directory.
283 279
284 280 $HOME is always replaced with '~'.
285 281 If depth==0, the full path is returned."""
286 282
287 283 cwd = os.getcwd().replace(HOME,"~")
288 284 out = os.sep.join(cwd.split(os.sep)[-depth:])
289 285 if out:
290 286 return out
291 287 else:
292 288 return os.sep
293 289
294 290 def cwd_filt2(self,depth):
295 291 """Return the last depth elements of the current working directory.
296 292
297 293 $HOME is always replaced with '~'.
298 294 If depth==0, the full path is returned."""
299 295
300 296 cwd = os.getcwd().replace(HOME,"~").split(os.sep)
301 297 if '~' in cwd and len(cwd) == depth+1:
302 298 depth += 1
303 299 out = os.sep.join(cwd[-depth:])
304 300 if out:
305 301 return out
306 302 else:
307 303 return os.sep
308 304
309 305 class Prompt1(BasePrompt):
310 306 """Input interactive prompt similar to Mathematica's."""
311 307
312 308 def __init__(self,cache,sep='\n',prompt='In [\\#]: ',pad_left=True):
313 309 BasePrompt.__init__(self,cache,sep,prompt,pad_left)
314 310
315 311 def set_colors(self):
316 312 self.set_p_str()
317 313 Colors = self.cache.color_table.active_colors # shorthand
318 314 self.col_p = Colors.in_prompt
319 315 self.col_num = Colors.in_number
320 316 self.col_norm = Colors.in_normal
321 317 # We need a non-input version of these escapes for the '--->'
322 318 # auto-call prompts used in the auto_rewrite() method.
323 319 self.col_p_ni = self.col_p.replace('\001','').replace('\002','')
324 320 self.col_norm_ni = Colors.normal
325 321
326 322 def __str__(self):
327 323 self.cache.prompt_count += 1
328 324 self.cache.last_prompt = str_safe(self.p_str_nocolor).split('\n')[-1]
329 325 return str_safe(self.p_str)
330 326
331 327 def auto_rewrite(self):
332 328 """Print a string of the form '--->' which lines up with the previous
333 329 input string. Useful for systems which re-write the user input when
334 330 handling automatically special syntaxes."""
335 331
336 332 curr = str(self.cache.last_prompt)
337 333 nrspaces = len(self.rspace.search(curr).group())
338 334 return '%s%s>%s%s' % (self.col_p_ni,'-'*(len(curr)-nrspaces-1),
339 335 ' '*nrspaces,self.col_norm_ni)
340 336
341 337 class PromptOut(BasePrompt):
342 338 """Output interactive prompt similar to Mathematica's."""
343 339
344 340 def __init__(self,cache,sep='',prompt='Out[\\#]: ',pad_left=True):
345 341 BasePrompt.__init__(self,cache,sep,prompt,pad_left)
346 342 if not self.p_template:
347 343 self.__str__ = lambda: ''
348 344
349 345 def set_colors(self):
350 346 self.set_p_str()
351 347 Colors = self.cache.color_table.active_colors # shorthand
352 348 self.col_p = Colors.out_prompt
353 349 self.col_num = Colors.out_number
354 350 self.col_norm = Colors.normal
355 351
356 352 class Prompt2(BasePrompt):
357 353 """Interactive continuation prompt."""
358 354
359 355 def __init__(self,cache,prompt=' .\\D.: ',pad_left=True):
360 356 self.cache = cache
361 357 self.p_template = prompt
362 358 self.pad_left = pad_left
363 359 self.set_p_str()
364 360
365 361 def set_p_str(self):
366 362 import os,time # needed in locals for prompt string handling
367 363 loc = locals()
368 364 self.p_str = ItplNS('%s%s%s' %
369 365 ('${self.col_p2}',
370 366 multiple_replace(prompt_specials, self.p_template),
371 367 '$self.col_norm'),
372 368 self.cache.user_ns,loc)
373 369 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
374 370 self.p_template),
375 371 self.cache.user_ns,loc)
376 372
377 373 def set_colors(self):
378 374 self.set_p_str()
379 375 Colors = self.cache.color_table.active_colors
380 376 self.col_p2 = Colors.in_prompt2
381 377 self.col_norm = Colors.in_normal
382 378 # FIXME (2004-06-16) HACK: prevent crashes for users who haven't
383 379 # updated their prompt_in2 definitions. Remove eventually.
384 380 self.col_p = Colors.out_prompt
385 381 self.col_num = Colors.out_number
386 382
387 383
388 384 #-----------------------------------------------------------------------------
389 385 class CachedOutput:
390 386 """Class for printing output from calculations while keeping a cache of
391 387 reults. It dynamically creates global variables prefixed with _ which
392 388 contain these results.
393 389
394 390 Meant to be used as a sys.displayhook replacement, providing numbered
395 391 prompts and cache services.
396 392
397 393 Initialize with initial and final values for cache counter (this defines
398 394 the maximum size of the cache."""
399 395
400 396 def __init__(self,shell,cache_size,Pprint,
401 397 colors='NoColor',input_sep='\n',
402 398 output_sep='\n',output_sep2='',
403 399 ps1 = None, ps2 = None,ps_out = None,pad_left=True):
404 400
405 401 cache_size_min = 3
406 402 if cache_size <= 0:
407 403 self.do_full_cache = 0
408 404 cache_size = 0
409 405 elif cache_size < cache_size_min:
410 406 self.do_full_cache = 0
411 407 cache_size = 0
412 408 warn('caching was disabled (min value for cache size is %s).' %
413 409 cache_size_min,level=3)
414 410 else:
415 411 self.do_full_cache = 1
416 412
417 413 self.cache_size = cache_size
418 414 self.input_sep = input_sep
419 415
420 416 # we need a reference to the user-level namespace
421 417 self.shell = shell
422 418 self.user_ns = shell.user_ns
423 419 # and to the user's input
424 420 self.input_hist = shell.history.input_cache
425 421
426 422 # Set input prompt strings and colors
427 423 if cache_size == 0:
428 424 if ps1.find('%n') > -1 or ps1.find(r'\#') > -1 \
429 425 or ps1.find(r'\N') > -1:
430 426 ps1 = '>>> '
431 427 if ps2.find('%n') > -1 or ps2.find(r'\#') > -1 \
432 428 or ps2.find(r'\N') > -1:
433 429 ps2 = '... '
434 430 self.ps1_str = self._set_prompt_str(ps1,'In [\\#]: ','>>> ')
435 431 self.ps2_str = self._set_prompt_str(ps2,' .\\D.: ','... ')
436 432 self.ps_out_str = self._set_prompt_str(ps_out,'Out[\\#]: ','')
437 433
438 434 self.color_table = PromptColors
439 435 self.prompt1 = Prompt1(self,sep=input_sep,prompt=self.ps1_str,
440 436 pad_left=pad_left)
441 437 self.prompt2 = Prompt2(self,prompt=self.ps2_str,pad_left=pad_left)
442 438 self.prompt_out = PromptOut(self,sep='',prompt=self.ps_out_str,
443 439 pad_left=pad_left)
444 440 self.set_colors(colors)
445 441
446 442 # other more normal stuff
447 443 # b/c each call to the In[] prompt raises it by 1, even the first.
448 444 self.prompt_count = 0
449 445 # Store the last prompt string each time, we need it for aligning
450 446 # continuation and auto-rewrite prompts
451 447 self.last_prompt = ''
452 448 self.Pprint = Pprint
453 449 self.output_sep = output_sep
454 450 self.output_sep2 = output_sep2
455 451 self._,self.__,self.___ = '','',''
456 452 self.pprint_types = map(type,[(),[],{}])
457 453
458 454 # these are deliberately global:
459 455 to_user_ns = {'_':self._,'__':self.__,'___':self.___}
460 456 self.user_ns.update(to_user_ns)
461 457
462 458 def _set_prompt_str(self,p_str,cache_def,no_cache_def):
463 459 if p_str is None:
464 460 if self.do_full_cache:
465 461 return cache_def
466 462 else:
467 463 return no_cache_def
468 464 else:
469 465 return p_str
470 466
471 467 def set_colors(self,colors):
472 468 """Set the active color scheme and configure colors for the three
473 469 prompt subsystems."""
474 470
475 471 # FIXME: the prompt_specials global should be gobbled inside this
476 472 # class instead. Do it when cleaning up the whole 3-prompt system.
477 473 global prompt_specials
478 474 if colors.lower()=='nocolor':
479 475 prompt_specials = prompt_specials_nocolor
480 476 else:
481 477 prompt_specials = prompt_specials_color
482 478
483 479 self.color_table.set_active_scheme(colors)
484 480 self.prompt1.set_colors()
485 481 self.prompt2.set_colors()
486 482 self.prompt_out.set_colors()
487 483
488 484 def __call__(self,arg=None):
489 485 """Printing with history cache management.
490 486
491 487 This is invoked everytime the interpreter needs to print, and is
492 488 activated by setting the variable sys.displayhook to it."""
493 489
494 490 # If something injected a '_' variable in __builtin__, delete
495 491 # ipython's automatic one so we don't clobber that. gettext() in
496 492 # particular uses _, so we need to stay away from it.
497 493 if '_' in __builtin__.__dict__:
498 494 try:
499 495 del self.user_ns['_']
500 496 except KeyError:
501 497 pass
502 498 if arg is not None:
503 499 cout_write = Term.cout.write # fast lookup
504 500 # first handle the cache and counters
505 501
506 502 # do not print output if input ends in ';'
507 503 if self.input_hist[self.prompt_count].endswith(';\n'):
508 504 return
509 505 # don't use print, puts an extra space
510 506 cout_write(self.output_sep)
511 507 outprompt = self.shell.hooks.generate_output_prompt()
512 508 if self.do_full_cache:
513 509 cout_write(outprompt)
514 510
515 511 # and now call a possibly user-defined print mechanism
516 512 manipulated_val = self.display(arg)
517 513
518 514 # user display hooks can change the variable to be stored in
519 515 # output history
520 516
521 517 if manipulated_val is not None:
522 518 arg = manipulated_val
523 519
524 520 # avoid recursive reference when displaying _oh/Out
525 521 if arg is not self.user_ns['_oh']:
526 522 self.update(arg)
527 523
528 524 cout_write(self.output_sep2)
529 525 Term.cout.flush()
530 526
531 527 def _display(self,arg):
532 528 """Default printer method, uses pprint.
533 529
534 530 Do ip.set_hook("result_display", my_displayhook) for custom result
535 531 display, e.g. when your own objects need special formatting.
536 532 """
537 533 try:
538 534 return IPython.generics.result_display(arg)
539 535 except TryNext:
540 536 return self.shell.hooks.result_display(arg)
541 537
542 538 # Assign the default display method:
543 539 display = _display
544 540
545 541 def update(self,arg):
546 542 #print '***cache_count', self.cache_count # dbg
547 543 if len(self.user_ns['_oh']) >= self.cache_size and self.do_full_cache:
548 544 warn('Output cache limit (currently '+
549 545 `self.cache_size`+' entries) hit.\n'
550 546 'Flushing cache and resetting history counter...\n'
551 547 'The only history variables available will be _,__,___ and _1\n'
552 548 'with the current result.')
553 549
554 550 self.flush()
555 551 # Don't overwrite '_' and friends if '_' is in __builtin__ (otherwise
556 552 # we cause buggy behavior for things like gettext).
557 553 if '_' not in __builtin__.__dict__:
558 554 self.___ = self.__
559 555 self.__ = self._
560 556 self._ = arg
561 557 self.user_ns.update({'_':self._,'__':self.__,'___':self.___})
562 558
563 559 # hackish access to top-level namespace to create _1,_2... dynamically
564 560 to_main = {}
565 561 if self.do_full_cache:
566 562 new_result = '_'+`self.prompt_count`
567 563 to_main[new_result] = arg
568 564 self.user_ns.update(to_main)
569 565 self.user_ns['_oh'][self.prompt_count] = arg
570 566
571 567 def flush(self):
572 568 if not self.do_full_cache:
573 569 raise ValueError,"You shouldn't have reached the cache flush "\
574 570 "if full caching is not enabled!"
575 571 # delete auto-generated vars from global namespace
576 572
577 573 for n in range(1,self.prompt_count + 1):
578 574 key = '_'+`n`
579 575 try:
580 576 del self.user_ns[key]
581 577 except: pass
582 578 self.user_ns['_oh'].clear()
583 579
584 580 if '_' not in __builtin__.__dict__:
585 581 self.user_ns.update({'_':None,'__':None, '___':None})
586 582 import gc
587 583 gc.collect() # xxx needed?
588 584
@@ -1,965 +1,960 b''
1 1 # encoding: utf-8
2 2 # -*- test-case-name: IPython.kernel.test.test_multiengineclient -*-
3 3
4 4 """General Classes for IMultiEngine clients."""
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 in
12 12 # the file COPYING, distributed as part of this software.
13 13 #-------------------------------------------------------------------------------
14 14
15 15 #-------------------------------------------------------------------------------
16 16 # Imports
17 17 #-------------------------------------------------------------------------------
18 18
19 19 import sys
20 import cPickle as pickle
21 from types import FunctionType
22 20 import linecache
23 21 import warnings
24 22
25 from twisted.internet import reactor
26 from twisted.python import components, log
23 from twisted.python import components
27 24 from twisted.python.failure import Failure
28 25 from zope.interface import Interface, implements, Attribute
29 26
30 from IPython.ColorANSI import TermColors
27 from IPython.utils.coloransi import TermColors
31 28
32 29 from IPython.kernel.twistedutil import blockingCallFromThread
33 30 from IPython.kernel import error
34 31 from IPython.kernel.parallelfunction import ParallelFunction
35 32 from IPython.kernel.mapper import (
36 33 MultiEngineMapper,
37 34 IMultiEngineMapperFactory,
38 35 IMapper
39 36 )
40 from IPython.kernel import map as Map
41 from IPython.kernel import multiengine as me
42 from IPython.kernel.multiengine import (IFullMultiEngine,
43 IFullSynchronousMultiEngine)
37
38 from IPython.kernel.multiengine import IFullSynchronousMultiEngine
44 39
45 40
46 41 #-------------------------------------------------------------------------------
47 42 # Pending Result things
48 43 #-------------------------------------------------------------------------------
49 44
50 45 class IPendingResult(Interface):
51 46 """A representation of a result that is pending.
52 47
53 48 This class is similar to Twisted's `Deferred` object, but is designed to be
54 49 used in a synchronous context.
55 50 """
56 51
57 52 result_id=Attribute("ID of the deferred on the other side")
58 53 client=Attribute("A client that I came from")
59 54 r=Attribute("An attribute that is a property that calls and returns get_result")
60 55
61 56 def get_result(default=None, block=True):
62 57 """
63 58 Get a result that is pending.
64 59
65 60 :Parameters:
66 61 default
67 62 The value to return if the result is not ready.
68 63 block : boolean
69 64 Should I block for the result.
70 65
71 66 :Returns: The actual result or the default value.
72 67 """
73 68
74 69 def add_callback(f, *args, **kwargs):
75 70 """
76 71 Add a callback that is called with the result.
77 72
78 73 If the original result is foo, adding a callback will cause
79 74 f(foo, *args, **kwargs) to be returned instead. If multiple
80 75 callbacks are registered, they are chained together: the result of
81 76 one is passed to the next and so on.
82 77
83 78 Unlike Twisted's Deferred object, there is no errback chain. Thus
84 79 any exception raised will not be caught and handled. User must
85 80 catch these by hand when calling `get_result`.
86 81 """
87 82
88 83
89 84 class PendingResult(object):
90 85 """A representation of a result that is not yet ready.
91 86
92 87 A user should not create a `PendingResult` instance by hand.
93 88
94 89 Methods
95 90 =======
96 91
97 92 * `get_result`
98 93 * `add_callback`
99 94
100 95 Properties
101 96 ==========
102 97 * `r`
103 98 """
104 99
105 100 def __init__(self, client, result_id):
106 101 """Create a PendingResult with a result_id and a client instance.
107 102
108 103 The client should implement `_getPendingResult(result_id, block)`.
109 104 """
110 105 self.client = client
111 106 self.result_id = result_id
112 107 self.called = False
113 108 self.raised = False
114 109 self.callbacks = []
115 110
116 111 def get_result(self, default=None, block=True):
117 112 """Get a result that is pending.
118 113
119 114 This method will connect to an IMultiEngine adapted controller
120 115 and see if the result is ready. If the action triggers an exception
121 116 raise it and record it. This method records the result/exception once it is
122 117 retrieved. Calling `get_result` again will get this cached result or will
123 118 re-raise the exception. The .r attribute is a property that calls
124 119 `get_result` with block=True.
125 120
126 121 :Parameters:
127 122 default
128 123 The value to return if the result is not ready.
129 124 block : boolean
130 125 Should I block for the result.
131 126
132 127 :Returns: The actual result or the default value.
133 128 """
134 129
135 130 if self.called:
136 131 if self.raised:
137 132 raise self.result[0], self.result[1], self.result[2]
138 133 else:
139 134 return self.result
140 135 try:
141 136 result = self.client.get_pending_deferred(self.result_id, block)
142 137 except error.ResultNotCompleted:
143 138 return default
144 139 except:
145 140 # Reraise other error, but first record them so they can be reraised
146 141 # later if .r or get_result is called again.
147 142 self.result = sys.exc_info()
148 143 self.called = True
149 144 self.raised = True
150 145 raise
151 146 else:
152 147 for cb in self.callbacks:
153 148 result = cb[0](result, *cb[1], **cb[2])
154 149 self.result = result
155 150 self.called = True
156 151 return result
157 152
158 153 def add_callback(self, f, *args, **kwargs):
159 154 """Add a callback that is called with the result.
160 155
161 156 If the original result is result, adding a callback will cause
162 157 f(result, *args, **kwargs) to be returned instead. If multiple
163 158 callbacks are registered, they are chained together: the result of
164 159 one is passed to the next and so on.
165 160
166 161 Unlike Twisted's Deferred object, there is no errback chain. Thus
167 162 any exception raised will not be caught and handled. User must
168 163 catch these by hand when calling `get_result`.
169 164 """
170 165 assert callable(f)
171 166 self.callbacks.append((f, args, kwargs))
172 167
173 168 def __cmp__(self, other):
174 169 if self.result_id < other.result_id:
175 170 return -1
176 171 else:
177 172 return 1
178 173
179 174 def _get_r(self):
180 175 return self.get_result(block=True)
181 176
182 177 r = property(_get_r)
183 178 """This property is a shortcut to a `get_result(block=True)`."""
184 179
185 180
186 181 #-------------------------------------------------------------------------------
187 182 # Pretty printing wrappers for certain lists
188 183 #-------------------------------------------------------------------------------
189 184
190 185 class ResultList(list):
191 186 """A subclass of list that pretty prints the output of `execute`/`get_result`."""
192 187
193 188 def __repr__(self):
194 189 output = []
195 190 # These colored prompts were not working on Windows
196 191 if sys.platform == 'win32':
197 192 blue = normal = red = green = ''
198 193 else:
199 194 blue = TermColors.Blue
200 195 normal = TermColors.Normal
201 196 red = TermColors.Red
202 197 green = TermColors.Green
203 198 output.append("<Results List>\n")
204 199 for cmd in self:
205 200 if isinstance(cmd, Failure):
206 201 output.append(cmd)
207 202 else:
208 203 target = cmd.get('id',None)
209 204 cmd_num = cmd.get('number',None)
210 205 cmd_stdin = cmd.get('input',{}).get('translated','No Input')
211 206 cmd_stdout = cmd.get('stdout', None)
212 207 cmd_stderr = cmd.get('stderr', None)
213 208 output.append("%s[%i]%s In [%i]:%s %s\n" % \
214 209 (green, target,
215 210 blue, cmd_num, normal, cmd_stdin))
216 211 if cmd_stdout:
217 212 output.append("%s[%i]%s Out[%i]:%s %s\n" % \
218 213 (green, target,
219 214 red, cmd_num, normal, cmd_stdout))
220 215 if cmd_stderr:
221 216 output.append("%s[%i]%s Err[%i]:\n%s %s" % \
222 217 (green, target,
223 218 red, cmd_num, normal, cmd_stderr))
224 219 return ''.join(output)
225 220
226 221
227 222 def wrapResultList(result):
228 223 """A function that wraps the output of `execute`/`get_result` -> `ResultList`."""
229 224 if len(result) == 0:
230 225 result = [result]
231 226 return ResultList(result)
232 227
233 228
234 229 class QueueStatusList(list):
235 230 """A subclass of list that pretty prints the output of `queue_status`."""
236 231
237 232 def __repr__(self):
238 233 output = []
239 234 output.append("<Queue Status List>\n")
240 235 for e in self:
241 236 output.append("Engine: %s\n" % repr(e[0]))
242 237 output.append(" Pending: %s\n" % repr(e[1]['pending']))
243 238 for q in e[1]['queue']:
244 239 output.append(" Command: %s\n" % repr(q))
245 240 return ''.join(output)
246 241
247 242
248 243 #-------------------------------------------------------------------------------
249 244 # InteractiveMultiEngineClient
250 245 #-------------------------------------------------------------------------------
251 246
252 247 class InteractiveMultiEngineClient(object):
253 248 """A mixin class that add a few methods to a multiengine client.
254 249
255 250 The methods in this mixin class are designed for interactive usage.
256 251 """
257 252
258 253 def activate(self):
259 254 """Make this `MultiEngineClient` active for parallel magic commands.
260 255
261 256 IPython has a magic command syntax to work with `MultiEngineClient` objects.
262 257 In a given IPython session there is a single active one. While
263 258 there can be many `MultiEngineClient` created and used by the user,
264 259 there is only one active one. The active `MultiEngineClient` is used whenever
265 260 the magic commands %px and %autopx are used.
266 261
267 262 The activate() method is called on a given `MultiEngineClient` to make it
268 263 active. Once this has been done, the magic commands can be used.
269 264 """
270 265
271 266 try:
272 267 __IPYTHON__.activeController = self
273 268 except NameError:
274 269 print "The IPython Controller magics only work within IPython."
275 270
276 271 def __setitem__(self, key, value):
277 272 """Add a dictionary interface for pushing/pulling.
278 273
279 274 This functions as a shorthand for `push`.
280 275
281 276 :Parameters:
282 277 key : str
283 278 What to call the remote object.
284 279 value : object
285 280 The local Python object to push.
286 281 """
287 282 targets, block = self._findTargetsAndBlock()
288 283 return self.push({key:value}, targets=targets, block=block)
289 284
290 285 def __getitem__(self, key):
291 286 """Add a dictionary interface for pushing/pulling.
292 287
293 288 This functions as a shorthand to `pull`.
294 289
295 290 :Parameters:
296 291 - `key`: A string representing the key.
297 292 """
298 293 if isinstance(key, str):
299 294 targets, block = self._findTargetsAndBlock()
300 295 return self.pull(key, targets=targets, block=block)
301 296 else:
302 297 raise TypeError("__getitem__ only takes strs")
303 298
304 299 def __len__(self):
305 300 """Return the number of available engines."""
306 301 return len(self.get_ids())
307 302
308 303 #---------------------------------------------------------------------------
309 304 # Make this a context manager for with
310 305 #---------------------------------------------------------------------------
311 306
312 307 def findsource_file(self,f):
313 308 linecache.checkcache()
314 s = findsource(f.f_code)
309 s = findsource(f.f_code) # findsource is not defined!
315 310 lnum = f.f_lineno
316 311 wsource = s[0][f.f_lineno:]
317 312 return strip_whitespace(wsource)
318 313
319 314 def findsource_ipython(self,f):
320 315 from IPython import ipapi
321 316 self.ip = ipapi.get()
322 317 wsource = [l+'\n' for l in
323 318 self.ip.IP.input_hist_raw[-1].splitlines()[1:]]
324 319 return strip_whitespace(wsource)
325 320
326 321 def __enter__(self):
327 322 f = sys._getframe(1)
328 323 local_ns = f.f_locals
329 324 global_ns = f.f_globals
330 325 if f.f_code.co_filename == '<ipython console>':
331 326 s = self.findsource_ipython(f)
332 327 else:
333 328 s = self.findsource_file(f)
334 329
335 330 self._with_context_result = self.execute(s)
336 331
337 332 def __exit__ (self, etype, value, tb):
338 333 if issubclass(etype,error.StopLocalExecution):
339 334 return True
340 335
341 336
342 337 def remote():
343 338 m = 'Special exception to stop local execution of parallel code.'
344 339 raise error.StopLocalExecution(m)
345 340
346 341 def strip_whitespace(source):
347 342 # Expand tabs to avoid any confusion.
348 343 wsource = [l.expandtabs(4) for l in source]
349 344 # Detect the indentation level
350 345 done = False
351 346 for line in wsource:
352 347 if line.isspace():
353 348 continue
354 349 for col,char in enumerate(line):
355 350 if char != ' ':
356 351 done = True
357 352 break
358 353 if done:
359 354 break
360 355 # Now we know how much leading space there is in the code. Next, we
361 356 # extract up to the first line that has less indentation.
362 357 # WARNINGS: we skip comments that may be misindented, but we do NOT yet
363 358 # detect triple quoted strings that may have flush left text.
364 359 for lno,line in enumerate(wsource):
365 360 lead = line[:col]
366 361 if lead.isspace():
367 362 continue
368 363 else:
369 364 if not lead.lstrip().startswith('#'):
370 365 break
371 366 # The real 'with' source is up to lno
372 367 src_lines = [l[col:] for l in wsource[:lno+1]]
373 368
374 369 # Finally, check that the source's first non-comment line begins with the
375 370 # special call 'remote()'
376 371 for nline,line in enumerate(src_lines):
377 372 if line.isspace() or line.startswith('#'):
378 373 continue
379 374 if 'remote()' in line:
380 375 break
381 376 else:
382 377 raise ValueError('remote() call missing at the start of code')
383 378 src = ''.join(src_lines[nline+1:])
384 379 #print 'SRC:\n<<<<<<<>>>>>>>\n%s<<<<<>>>>>>' % src # dbg
385 380 return src
386 381
387 382
388 383 #-------------------------------------------------------------------------------
389 384 # The top-level MultiEngine client adaptor
390 385 #-------------------------------------------------------------------------------
391 386
392 387
393 388 _prop_warn = """\
394 389
395 390 We are currently refactoring the task dependency system. This might
396 391 involve the removal of this method and other methods related to engine
397 392 properties. Please see the docstrings for IPython.kernel.TaskRejectError
398 393 for more information."""
399 394
400 395
401 396 class IFullBlockingMultiEngineClient(Interface):
402 397 pass
403 398
404 399
405 400 class FullBlockingMultiEngineClient(InteractiveMultiEngineClient):
406 401 """
407 402 A blocking client to the `IMultiEngine` controller interface.
408 403
409 404 This class allows users to use a set of engines for a parallel
410 405 computation through the `IMultiEngine` interface. In this interface,
411 406 each engine has a specific id (an int) that is used to refer to the
412 407 engine, run code on it, etc.
413 408 """
414 409
415 410 implements(
416 411 IFullBlockingMultiEngineClient,
417 412 IMultiEngineMapperFactory,
418 413 IMapper
419 414 )
420 415
421 416 def __init__(self, smultiengine):
422 417 self.smultiengine = smultiengine
423 418 self.block = True
424 419 self.targets = 'all'
425 420
426 421 def _findBlock(self, block=None):
427 422 if block is None:
428 423 return self.block
429 424 else:
430 425 if block in (True, False):
431 426 return block
432 427 else:
433 428 raise ValueError("block must be True or False")
434 429
435 430 def _findTargets(self, targets=None):
436 431 if targets is None:
437 432 return self.targets
438 433 else:
439 434 if not isinstance(targets, (str,list,tuple,int)):
440 435 raise ValueError("targets must be a str, list, tuple or int")
441 436 return targets
442 437
443 438 def _findTargetsAndBlock(self, targets=None, block=None):
444 439 return self._findTargets(targets), self._findBlock(block)
445 440
446 441 def _blockFromThread(self, function, *args, **kwargs):
447 442 block = kwargs.get('block', None)
448 443 if block is None:
449 444 raise error.MissingBlockArgument("'block' keyword argument is missing")
450 445 result = blockingCallFromThread(function, *args, **kwargs)
451 446 if not block:
452 447 result = PendingResult(self, result)
453 448 return result
454 449
455 450 def get_pending_deferred(self, deferredID, block):
456 451 return blockingCallFromThread(self.smultiengine.get_pending_deferred, deferredID, block)
457 452
458 453 def barrier(self, pendingResults):
459 454 """Synchronize a set of `PendingResults`.
460 455
461 456 This method is a synchronization primitive that waits for a set of
462 457 `PendingResult` objects to complete. More specifically, barier does
463 458 the following.
464 459
465 460 * The `PendingResult`s are sorted by result_id.
466 461 * The `get_result` method is called for each `PendingResult` sequentially
467 462 with block=True.
468 463 * If a `PendingResult` gets a result that is an exception, it is
469 464 trapped and can be re-raised later by calling `get_result` again.
470 465 * The `PendingResult`s are flushed from the controller.
471 466
472 467 After barrier has been called on a `PendingResult`, its results can
473 468 be retrieved by calling `get_result` again or accesing the `r` attribute
474 469 of the instance.
475 470 """
476 471
477 472 # Convert to list for sorting and check class type
478 473 prList = list(pendingResults)
479 474 for pr in prList:
480 475 if not isinstance(pr, PendingResult):
481 476 raise error.NotAPendingResult("Objects passed to barrier must be PendingResult instances")
482 477
483 478 # Sort the PendingResults so they are in order
484 479 prList.sort()
485 480 # Block on each PendingResult object
486 481 for pr in prList:
487 482 try:
488 483 result = pr.get_result(block=True)
489 484 except Exception:
490 485 pass
491 486
492 487 def flush(self):
493 488 """
494 489 Clear all pending deferreds/results from the controller.
495 490
496 491 For each `PendingResult` that is created by this client, the controller
497 492 holds on to the result for that `PendingResult`. This can be a problem
498 493 if there are a large number of `PendingResult` objects that are created.
499 494
500 495 Once the result of the `PendingResult` has been retrieved, the result
501 496 is removed from the controller, but if a user doesn't get a result (
502 497 they just ignore the `PendingResult`) the result is kept forever on the
503 498 controller. This method allows the user to clear out all un-retrieved
504 499 results on the controller.
505 500 """
506 501 r = blockingCallFromThread(self.smultiengine.clear_pending_deferreds)
507 502 return r
508 503
509 504 clear_pending_results = flush
510 505
511 506 #---------------------------------------------------------------------------
512 507 # IEngineMultiplexer related methods
513 508 #---------------------------------------------------------------------------
514 509
515 510 def execute(self, lines, targets=None, block=None):
516 511 """
517 512 Execute code on a set of engines.
518 513
519 514 :Parameters:
520 515 lines : str
521 516 The Python code to execute as a string
522 517 targets : id or list of ids
523 518 The engine to use for the execution
524 519 block : boolean
525 520 If False, this method will return the actual result. If False,
526 521 a `PendingResult` is returned which can be used to get the result
527 522 at a later time.
528 523 """
529 524 targets, block = self._findTargetsAndBlock(targets, block)
530 525 result = blockingCallFromThread(self.smultiengine.execute, lines,
531 526 targets=targets, block=block)
532 527 if block:
533 528 result = ResultList(result)
534 529 else:
535 530 result = PendingResult(self, result)
536 531 result.add_callback(wrapResultList)
537 532 return result
538 533
539 534 def push(self, namespace, targets=None, block=None):
540 535 """
541 536 Push a dictionary of keys and values to engines namespace.
542 537
543 538 Each engine has a persistent namespace. This method is used to push
544 539 Python objects into that namespace.
545 540
546 541 The objects in the namespace must be pickleable.
547 542
548 543 :Parameters:
549 544 namespace : dict
550 545 A dict that contains Python objects to be injected into
551 546 the engine persistent namespace.
552 547 targets : id or list of ids
553 548 The engine to use for the execution
554 549 block : boolean
555 550 If False, this method will return the actual result. If False,
556 551 a `PendingResult` is returned which can be used to get the result
557 552 at a later time.
558 553 """
559 554 targets, block = self._findTargetsAndBlock(targets, block)
560 555 return self._blockFromThread(self.smultiengine.push, namespace,
561 556 targets=targets, block=block)
562 557
563 558 def pull(self, keys, targets=None, block=None):
564 559 """
565 560 Pull Python objects by key out of engines namespaces.
566 561
567 562 :Parameters:
568 563 keys : str or list of str
569 564 The names of the variables to be pulled
570 565 targets : id or list of ids
571 566 The engine to use for the execution
572 567 block : boolean
573 568 If False, this method will return the actual result. If False,
574 569 a `PendingResult` is returned which can be used to get the result
575 570 at a later time.
576 571 """
577 572 targets, block = self._findTargetsAndBlock(targets, block)
578 573 return self._blockFromThread(self.smultiengine.pull, keys, targets=targets, block=block)
579 574
580 575 def push_function(self, namespace, targets=None, block=None):
581 576 """
582 577 Push a Python function to an engine.
583 578
584 579 This method is used to push a Python function to an engine. This
585 580 method can then be used in code on the engines. Closures are not supported.
586 581
587 582 :Parameters:
588 583 namespace : dict
589 584 A dict whose values are the functions to be pushed. The keys give
590 585 that names that the function will appear as in the engines
591 586 namespace.
592 587 targets : id or list of ids
593 588 The engine to use for the execution
594 589 block : boolean
595 590 If False, this method will return the actual result. If False,
596 591 a `PendingResult` is returned which can be used to get the result
597 592 at a later time.
598 593 """
599 594 targets, block = self._findTargetsAndBlock(targets, block)
600 595 return self._blockFromThread(self.smultiengine.push_function, namespace, targets=targets, block=block)
601 596
602 597 def pull_function(self, keys, targets=None, block=None):
603 598 """
604 599 Pull a Python function from an engine.
605 600
606 601 This method is used to pull a Python function from an engine.
607 602 Closures are not supported.
608 603
609 604 :Parameters:
610 605 keys : str or list of str
611 606 The names of the functions to be pulled
612 607 targets : id or list of ids
613 608 The engine to use for the execution
614 609 block : boolean
615 610 If False, this method will return the actual result. If False,
616 611 a `PendingResult` is returned which can be used to get the result
617 612 at a later time.
618 613 """
619 614 targets, block = self._findTargetsAndBlock(targets, block)
620 615 return self._blockFromThread(self.smultiengine.pull_function, keys, targets=targets, block=block)
621 616
622 617 def push_serialized(self, namespace, targets=None, block=None):
623 618 targets, block = self._findTargetsAndBlock(targets, block)
624 619 return self._blockFromThread(self.smultiengine.push_serialized, namespace, targets=targets, block=block)
625 620
626 621 def pull_serialized(self, keys, targets=None, block=None):
627 622 targets, block = self._findTargetsAndBlock(targets, block)
628 623 return self._blockFromThread(self.smultiengine.pull_serialized, keys, targets=targets, block=block)
629 624
630 625 def get_result(self, i=None, targets=None, block=None):
631 626 """
632 627 Get a previous result.
633 628
634 629 When code is executed in an engine, a dict is created and returned. This
635 630 method retrieves that dict for previous commands.
636 631
637 632 :Parameters:
638 633 i : int
639 634 The number of the result to get
640 635 targets : id or list of ids
641 636 The engine to use for the execution
642 637 block : boolean
643 638 If False, this method will return the actual result. If False,
644 639 a `PendingResult` is returned which can be used to get the result
645 640 at a later time.
646 641 """
647 642 targets, block = self._findTargetsAndBlock(targets, block)
648 643 result = blockingCallFromThread(self.smultiengine.get_result, i, targets=targets, block=block)
649 644 if block:
650 645 result = ResultList(result)
651 646 else:
652 647 result = PendingResult(self, result)
653 648 result.add_callback(wrapResultList)
654 649 return result
655 650
656 651 def reset(self, targets=None, block=None):
657 652 """
658 653 Reset an engine.
659 654
660 655 This method clears out the namespace of an engine.
661 656
662 657 :Parameters:
663 658 targets : id or list of ids
664 659 The engine to use for the execution
665 660 block : boolean
666 661 If False, this method will return the actual result. If False,
667 662 a `PendingResult` is returned which can be used to get the result
668 663 at a later time.
669 664 """
670 665 targets, block = self._findTargetsAndBlock(targets, block)
671 666 return self._blockFromThread(self.smultiengine.reset, targets=targets, block=block)
672 667
673 668 def keys(self, targets=None, block=None):
674 669 """
675 670 Get a list of all the variables in an engine's namespace.
676 671
677 672 :Parameters:
678 673 targets : id or list of ids
679 674 The engine to use for the execution
680 675 block : boolean
681 676 If False, this method will return the actual result. If False,
682 677 a `PendingResult` is returned which can be used to get the result
683 678 at a later time.
684 679 """
685 680 targets, block = self._findTargetsAndBlock(targets, block)
686 681 return self._blockFromThread(self.smultiengine.keys, targets=targets, block=block)
687 682
688 683 def kill(self, controller=False, targets=None, block=None):
689 684 """
690 685 Kill the engines and controller.
691 686
692 687 This method is used to stop the engine and controller by calling
693 688 `reactor.stop`.
694 689
695 690 :Parameters:
696 691 controller : boolean
697 692 If True, kill the engines and controller. If False, just the
698 693 engines
699 694 targets : id or list of ids
700 695 The engine to use for the execution
701 696 block : boolean
702 697 If False, this method will return the actual result. If False,
703 698 a `PendingResult` is returned which can be used to get the result
704 699 at a later time.
705 700 """
706 701 targets, block = self._findTargetsAndBlock(targets, block)
707 702 return self._blockFromThread(self.smultiengine.kill, controller, targets=targets, block=block)
708 703
709 704 def clear_queue(self, targets=None, block=None):
710 705 """
711 706 Clear out the controller's queue for an engine.
712 707
713 708 The controller maintains a queue for each engine. This clear it out.
714 709
715 710 :Parameters:
716 711 targets : id or list of ids
717 712 The engine to use for the execution
718 713 block : boolean
719 714 If False, this method will return the actual result. If False,
720 715 a `PendingResult` is returned which can be used to get the result
721 716 at a later time.
722 717 """
723 718 targets, block = self._findTargetsAndBlock(targets, block)
724 719 return self._blockFromThread(self.smultiengine.clear_queue, targets=targets, block=block)
725 720
726 721 def queue_status(self, targets=None, block=None):
727 722 """
728 723 Get the status of an engines queue.
729 724
730 725 :Parameters:
731 726 targets : id or list of ids
732 727 The engine to use for the execution
733 728 block : boolean
734 729 If False, this method will return the actual result. If False,
735 730 a `PendingResult` is returned which can be used to get the result
736 731 at a later time.
737 732 """
738 733 targets, block = self._findTargetsAndBlock(targets, block)
739 734 return self._blockFromThread(self.smultiengine.queue_status, targets=targets, block=block)
740 735
741 736 def set_properties(self, properties, targets=None, block=None):
742 737 warnings.warn(_prop_warn)
743 738 targets, block = self._findTargetsAndBlock(targets, block)
744 739 return self._blockFromThread(self.smultiengine.set_properties, properties, targets=targets, block=block)
745 740
746 741 def get_properties(self, keys=None, targets=None, block=None):
747 742 warnings.warn(_prop_warn)
748 743 targets, block = self._findTargetsAndBlock(targets, block)
749 744 return self._blockFromThread(self.smultiengine.get_properties, keys, targets=targets, block=block)
750 745
751 746 def has_properties(self, keys, targets=None, block=None):
752 747 warnings.warn(_prop_warn)
753 748 targets, block = self._findTargetsAndBlock(targets, block)
754 749 return self._blockFromThread(self.smultiengine.has_properties, keys, targets=targets, block=block)
755 750
756 751 def del_properties(self, keys, targets=None, block=None):
757 752 warnings.warn(_prop_warn)
758 753 targets, block = self._findTargetsAndBlock(targets, block)
759 754 return self._blockFromThread(self.smultiengine.del_properties, keys, targets=targets, block=block)
760 755
761 756 def clear_properties(self, targets=None, block=None):
762 757 warnings.warn(_prop_warn)
763 758 targets, block = self._findTargetsAndBlock(targets, block)
764 759 return self._blockFromThread(self.smultiengine.clear_properties, targets=targets, block=block)
765 760
766 761 #---------------------------------------------------------------------------
767 762 # IMultiEngine related methods
768 763 #---------------------------------------------------------------------------
769 764
770 765 def get_ids(self):
771 766 """
772 767 Returns the ids of currently registered engines.
773 768 """
774 769 result = blockingCallFromThread(self.smultiengine.get_ids)
775 770 return result
776 771
777 772 #---------------------------------------------------------------------------
778 773 # IMultiEngineCoordinator
779 774 #---------------------------------------------------------------------------
780 775
781 776 def scatter(self, key, seq, dist='b', flatten=False, targets=None, block=None):
782 777 """
783 778 Partition a Python sequence and send the partitions to a set of engines.
784 779 """
785 780 targets, block = self._findTargetsAndBlock(targets, block)
786 781 return self._blockFromThread(self.smultiengine.scatter, key, seq,
787 782 dist, flatten, targets=targets, block=block)
788 783
789 784 def gather(self, key, dist='b', targets=None, block=None):
790 785 """
791 786 Gather a partitioned sequence on a set of engines as a single local seq.
792 787 """
793 788 targets, block = self._findTargetsAndBlock(targets, block)
794 789 return self._blockFromThread(self.smultiengine.gather, key, dist,
795 790 targets=targets, block=block)
796 791
797 792 def raw_map(self, func, seq, dist='b', targets=None, block=None):
798 793 """
799 794 A parallelized version of Python's builtin map.
800 795
801 796 This has a slightly different syntax than the builtin `map`.
802 797 This is needed because we need to have keyword arguments and thus
803 798 can't use *args to capture all the sequences. Instead, they must
804 799 be passed in a list or tuple.
805 800
806 801 raw_map(func, seqs) -> map(func, seqs[0], seqs[1], ...)
807 802
808 803 Most users will want to use parallel functions or the `mapper`
809 804 and `map` methods for an API that follows that of the builtin
810 805 `map`.
811 806 """
812 807 targets, block = self._findTargetsAndBlock(targets, block)
813 808 return self._blockFromThread(self.smultiengine.raw_map, func, seq,
814 809 dist, targets=targets, block=block)
815 810
816 811 def map(self, func, *sequences):
817 812 """
818 813 A parallel version of Python's builtin `map` function.
819 814
820 815 This method applies a function to sequences of arguments. It
821 816 follows the same syntax as the builtin `map`.
822 817
823 818 This method creates a mapper objects by calling `self.mapper` with
824 819 no arguments and then uses that mapper to do the mapping. See
825 820 the documentation of `mapper` for more details.
826 821 """
827 822 return self.mapper().map(func, *sequences)
828 823
829 824 def mapper(self, dist='b', targets='all', block=None):
830 825 """
831 826 Create a mapper object that has a `map` method.
832 827
833 828 This method returns an object that implements the `IMapper`
834 829 interface. This method is a factory that is used to control how
835 830 the map happens.
836 831
837 832 :Parameters:
838 833 dist : str
839 834 What decomposition to use, 'b' is the only one supported
840 835 currently
841 836 targets : str, int, sequence of ints
842 837 Which engines to use for the map
843 838 block : boolean
844 839 Should calls to `map` block or not
845 840 """
846 841 return MultiEngineMapper(self, dist, targets, block)
847 842
848 843 def parallel(self, dist='b', targets=None, block=None):
849 844 """
850 845 A decorator that turns a function into a parallel function.
851 846
852 847 This can be used as:
853 848
854 849 @parallel()
855 850 def f(x, y)
856 851 ...
857 852
858 853 f(range(10), range(10))
859 854
860 855 This causes f(0,0), f(1,1), ... to be called in parallel.
861 856
862 857 :Parameters:
863 858 dist : str
864 859 What decomposition to use, 'b' is the only one supported
865 860 currently
866 861 targets : str, int, sequence of ints
867 862 Which engines to use for the map
868 863 block : boolean
869 864 Should calls to `map` block or not
870 865 """
871 866 targets, block = self._findTargetsAndBlock(targets, block)
872 867 mapper = self.mapper(dist, targets, block)
873 868 pf = ParallelFunction(mapper)
874 869 return pf
875 870
876 871 #---------------------------------------------------------------------------
877 872 # IMultiEngineExtras
878 873 #---------------------------------------------------------------------------
879 874
880 875 def zip_pull(self, keys, targets=None, block=None):
881 876 targets, block = self._findTargetsAndBlock(targets, block)
882 877 return self._blockFromThread(self.smultiengine.zip_pull, keys,
883 878 targets=targets, block=block)
884 879
885 880 def run(self, filename, targets=None, block=None):
886 881 """
887 882 Run a Python code in a file on the engines.
888 883
889 884 :Parameters:
890 885 filename : str
891 886 The name of the local file to run
892 887 targets : id or list of ids
893 888 The engine to use for the execution
894 889 block : boolean
895 890 If False, this method will return the actual result. If False,
896 891 a `PendingResult` is returned which can be used to get the result
897 892 at a later time.
898 893 """
899 894 targets, block = self._findTargetsAndBlock(targets, block)
900 895 return self._blockFromThread(self.smultiengine.run, filename,
901 896 targets=targets, block=block)
902 897
903 898 def benchmark(self, push_size=10000):
904 899 """
905 900 Run performance benchmarks for the current IPython cluster.
906 901
907 902 This method tests both the latency of sending command and data to the
908 903 engines as well as the throughput of sending large objects to the
909 904 engines using push. The latency is measured by having one or more
910 905 engines execute the command 'pass'. The throughput is measure by
911 906 sending an NumPy array of size `push_size` to one or more engines.
912 907
913 908 These benchmarks will vary widely on different hardware and networks
914 909 and thus can be used to get an idea of the performance characteristics
915 910 of a particular configuration of an IPython controller and engines.
916 911
917 912 This function is not testable within our current testing framework.
918 913 """
919 914 import timeit, __builtin__
920 915 __builtin__._mec_self = self
921 916 benchmarks = {}
922 917 repeat = 3
923 918 count = 10
924 919
925 920 timer = timeit.Timer('_mec_self.execute("pass",0)')
926 921 result = 1000*min(timer.repeat(repeat,count))/count
927 922 benchmarks['single_engine_latency'] = (result,'msec')
928 923
929 924 timer = timeit.Timer('_mec_self.execute("pass")')
930 925 result = 1000*min(timer.repeat(repeat,count))/count
931 926 benchmarks['all_engine_latency'] = (result,'msec')
932 927
933 928 try:
934 929 import numpy as np
935 930 except:
936 931 pass
937 932 else:
938 933 timer = timeit.Timer(
939 934 "_mec_self.push(d)",
940 935 "import numpy as np; d = dict(a=np.zeros(%r,dtype='float64'))" % push_size
941 936 )
942 937 result = min(timer.repeat(repeat,count))/count
943 938 benchmarks['all_engine_push'] = (1e-6*push_size*8/result, 'MB/sec')
944 939
945 940 try:
946 941 import numpy as np
947 942 except:
948 943 pass
949 944 else:
950 945 timer = timeit.Timer(
951 946 "_mec_self.push(d,0)",
952 947 "import numpy as np; d = dict(a=np.zeros(%r,dtype='float64'))" % push_size
953 948 )
954 949 result = min(timer.repeat(repeat,count))/count
955 950 benchmarks['single_engine_push'] = (1e-6*push_size*8/result, 'MB/sec')
956 951
957 952 return benchmarks
958 953
959 954
960 955 components.registerAdapter(FullBlockingMultiEngineClient,
961 956 IFullSynchronousMultiEngine, IFullBlockingMultiEngineClient)
962 957
963 958
964 959
965 960
@@ -1,300 +1,300 b''
1 1 # -*- coding: utf-8 -*-
2 2 """IPython Test Suite Runner.
3 3
4 4 This module provides a main entry point to a user script to test IPython
5 5 itself from the command line. There are two ways of running this script:
6 6
7 7 1. With the syntax `iptest all`. This runs our entire test suite by
8 8 calling this script (with different arguments) or trial recursively. This
9 9 causes modules and package to be tested in different processes, using nose
10 10 or trial where appropriate.
11 11 2. With the regular nose syntax, like `iptest -vvs IPython`. In this form
12 12 the script simply calls nose, but with special command line flags and
13 13 plugins loaded.
14 14
15 15 For now, this script requires that both nose and twisted are installed. This
16 16 will change in the future.
17 17 """
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Module imports
21 21 #-----------------------------------------------------------------------------
22 22
23 23 import os
24 24 import os.path as path
25 25 import sys
26 26 import subprocess
27 27 import time
28 28 import warnings
29 29
30 30 import nose.plugins.builtin
31 31 from nose.core import TestProgram
32 32
33 33 from IPython.platutils import find_cmd
34 34 from IPython.testing.plugin.ipdoctest import IPythonDoctest
35 35
36 36 pjoin = path.join
37 37
38 38 #-----------------------------------------------------------------------------
39 39 # Logic for skipping doctests
40 40 #-----------------------------------------------------------------------------
41 41
42 42 def test_for(mod):
43 43 """Test to see if mod is importable."""
44 44 try:
45 45 __import__(mod)
46 46 except ImportError:
47 47 return False
48 48 else:
49 49 return True
50 50
51 51 have_curses = test_for('_curses')
52 52 have_wx = test_for('wx')
53 53 have_zi = test_for('zope.interface')
54 54 have_twisted = test_for('twisted')
55 55 have_foolscap = test_for('foolscap')
56 56 have_objc = test_for('objc')
57 57 have_pexpect = test_for('pexpect')
58 58
59 59 # For the IPythonDoctest plugin, we need to exclude certain patterns that cause
60 60 # testing problems. We should strive to minimize the number of skipped
61 61 # modules, since this means untested code. As the testing machinery
62 62 # solidifies, this list should eventually become empty.
63 63 EXCLUDE = [pjoin('IPython', 'external'),
64 64 pjoin('IPython', 'frontend', 'process', 'winprocess.py'),
65 65 pjoin('IPython_doctest_plugin'),
66 66 pjoin('IPython', 'Gnuplot'),
67 67 pjoin('IPython', 'Extensions', 'ipy_'),
68 68 pjoin('IPython', 'Extensions', 'clearcmd'),
69 69 pjoin('IPython', 'Extensions', 'PhysicalQInteractive'),
70 70 pjoin('IPython', 'Extensions', 'scitedirector'),
71 71 pjoin('IPython', 'Extensions', 'numeric_formats'),
72 72 pjoin('IPython', 'testing', 'attic'),
73 73 pjoin('IPython', 'testing', 'tutils'),
74 74 pjoin('IPython', 'testing', 'tools'),
75 75 pjoin('IPython', 'testing', 'mkdoctests')
76 76 ]
77 77
78 78 if not have_wx:
79 79 EXCLUDE.append(pjoin('IPython', 'Extensions', 'igrid'))
80 80 EXCLUDE.append(pjoin('IPython', 'gui'))
81 81 EXCLUDE.append(pjoin('IPython', 'frontend', 'wx'))
82 82
83 83 if not have_objc:
84 84 EXCLUDE.append(pjoin('IPython', 'frontend', 'cocoa'))
85 85
86 86 if not have_curses:
87 87 EXCLUDE.append(pjoin('IPython', 'Extensions', 'ibrowse'))
88 88
89 89 if not sys.platform == 'win32':
90 90 EXCLUDE.append(pjoin('IPython', 'platutils_win32'))
91 91
92 92 # These have to be skipped on win32 because the use echo, rm, cd, etc.
93 93 # See ticket https://bugs.launchpad.net/bugs/366982
94 94 if sys.platform == 'win32':
95 95 EXCLUDE.append(pjoin('IPython', 'testing', 'plugin', 'test_exampleip'))
96 96 EXCLUDE.append(pjoin('IPython', 'testing', 'plugin', 'dtexample'))
97 97
98 98 if not os.name == 'posix':
99 99 EXCLUDE.append(pjoin('IPython', 'platutils_posix'))
100 100
101 101 if not have_pexpect:
102 102 EXCLUDE.append(pjoin('IPython', 'irunner'))
103 103
104 104 # This is needed for the reg-exp to match on win32 in the ipdoctest plugin.
105 105 if sys.platform == 'win32':
106 106 EXCLUDE = [s.replace('\\','\\\\') for s in EXCLUDE]
107 107
108 108
109 109 #-----------------------------------------------------------------------------
110 110 # Functions and classes
111 111 #-----------------------------------------------------------------------------
112 112
113 113 def run_iptest():
114 114 """Run the IPython test suite using nose.
115 115
116 116 This function is called when this script is **not** called with the form
117 117 `iptest all`. It simply calls nose with appropriate command line flags
118 118 and accepts all of the standard nose arguments.
119 119 """
120 120
121 121 warnings.filterwarnings('ignore',
122 122 'This will be removed soon. Use IPython.testing.util instead')
123 123
124 124 argv = sys.argv + [
125 125 # Loading ipdoctest causes problems with Twisted.
126 126 # I am removing this as a temporary fix to get the
127 127 # test suite back into working shape. Our nose
128 128 # plugin needs to be gone through with a fine
129 129 # toothed comb to find what is causing the problem.
130 130 '--with-ipdoctest',
131 131 '--ipdoctest-tests','--ipdoctest-extension=txt',
132 132 '--detailed-errors',
133 133
134 134 # We add --exe because of setuptools' imbecility (it
135 135 # blindly does chmod +x on ALL files). Nose does the
136 136 # right thing and it tries to avoid executables,
137 137 # setuptools unfortunately forces our hand here. This
138 138 # has been discussed on the distutils list and the
139 139 # setuptools devs refuse to fix this problem!
140 140 '--exe',
141 141 ]
142 142
143 143 # Detect if any tests were required by explicitly calling an IPython
144 144 # submodule or giving a specific path
145 145 has_tests = False
146 146 for arg in sys.argv:
147 147 if 'IPython' in arg or arg.endswith('.py') or \
148 148 (':' in arg and '.py' in arg):
149 149 has_tests = True
150 150 break
151 151
152 152 # If nothing was specifically requested, test full IPython
153 153 if not has_tests:
154 154 argv.append('IPython')
155 155
156 156 # Construct list of plugins, omitting the existing doctest plugin, which
157 157 # ours replaces (and extends).
158 158 plugins = [IPythonDoctest(EXCLUDE)]
159 159 for p in nose.plugins.builtin.plugins:
160 160 plug = p()
161 161 if plug.name == 'doctest':
162 162 continue
163 163
164 164 #print '*** adding plugin:',plug.name # dbg
165 165 plugins.append(plug)
166 166
167 167 TestProgram(argv=argv,plugins=plugins)
168 168
169 169
170 170 class IPTester(object):
171 171 """Call that calls iptest or trial in a subprocess.
172 172 """
173 173 def __init__(self,runner='iptest',params=None):
174 174 """ """
175 175 if runner == 'iptest':
176 176 self.runner = ['iptest','-v']
177 177 else:
178 178 self.runner = [find_cmd('trial')]
179 179 if params is None:
180 180 params = []
181 181 if isinstance(params,str):
182 182 params = [params]
183 183 self.params = params
184 184
185 185 # Assemble call
186 186 self.call_args = self.runner+self.params
187 187
188 188 def run(self):
189 189 """Run the stored commands"""
190 190 return subprocess.call(self.call_args)
191 191
192 192
193 193 def make_runners():
194 194 """Define the modules and packages that need to be tested.
195 195 """
196 196
197 197 # This omits additional top-level modules that should not be doctested.
198 198 # XXX: Shell.py is also ommited because of a bug in the skip_doctest
199 199 # decorator. See ticket https://bugs.launchpad.net/bugs/366209
200 200 top_mod = \
201 ['background_jobs.py', 'ColorANSI.py', 'completer.py', 'ConfigLoader.py',
201 ['background_jobs.py', 'coloransi.py', 'completer.py', 'ConfigLoader.py',
202 202 'CrashHandler.py', 'Debugger.py', 'deep_reload.py', 'demo.py',
203 203 'DPyGetOpt.py', 'dtutils.py', 'excolors.py', 'FakeModule.py',
204 204 'generics.py', 'genutils.py', 'history.py', 'hooks.py', 'ipapi.py',
205 205 'iplib.py', 'ipmaker.py', 'ipstruct.py', 'Itpl.py',
206 206 'Logger.py', 'macro.py', 'Magic.py', 'OInspect.py',
207 207 'OutputTrap.py', 'platutils.py', 'prefilter.py', 'Prompts.py',
208 208 'PyColorize.py', 'Release.py', 'rlineimpl.py', 'shadowns.py',
209 209 'shellglobals.py', 'strdispatch.py', 'twshell.py',
210 210 'ultraTB.py', 'upgrade_dir.py', 'usage.py', 'wildcard.py',
211 211 # See note above for why this is skipped
212 212 # 'Shell.py',
213 213 'winconsole.py']
214 214
215 215 if have_pexpect:
216 216 top_mod.append('irunner.py')
217 217
218 218 if sys.platform == 'win32':
219 219 top_mod.append('platutils_win32.py')
220 220 elif os.name == 'posix':
221 221 top_mod.append('platutils_posix.py')
222 222 else:
223 223 top_mod.append('platutils_dummy.py')
224 224
225 225 # These are tested by nose, so skip IPython.kernel
226 226 top_pack = ['config','Extensions','frontend',
227 227 'testing','tests','tools','UserConfig']
228 228
229 229 if have_wx:
230 230 top_pack.append('gui')
231 231
232 232 modules = ['IPython.%s' % m[:-3] for m in top_mod ]
233 233 packages = ['IPython.%s' % m for m in top_pack ]
234 234
235 235 # Make runners
236 236 runners = dict(zip(top_pack, [IPTester(params=v) for v in packages]))
237 237
238 238 # Test IPython.kernel using trial if twisted is installed
239 239 if have_zi and have_twisted and have_foolscap:
240 240 runners['trial'] = IPTester('trial',['IPython'])
241 241
242 242 runners['modules'] = IPTester(params=modules)
243 243
244 244 return runners
245 245
246 246
247 247 def run_iptestall():
248 248 """Run the entire IPython test suite by calling nose and trial.
249 249
250 250 This function constructs :class:`IPTester` instances for all IPython
251 251 modules and package and then runs each of them. This causes the modules
252 252 and packages of IPython to be tested each in their own subprocess using
253 253 nose or twisted.trial appropriately.
254 254 """
255 255 runners = make_runners()
256 256 # Run all test runners, tracking execution time
257 257 failed = {}
258 258 t_start = time.time()
259 259 for name,runner in runners.iteritems():
260 260 print '*'*77
261 261 print 'IPython test set:',name
262 262 res = runner.run()
263 263 if res:
264 264 failed[name] = res
265 265 t_end = time.time()
266 266 t_tests = t_end - t_start
267 267 nrunners = len(runners)
268 268 nfail = len(failed)
269 269 # summarize results
270 270 print
271 271 print '*'*77
272 272 print 'Ran %s test sets in %.3fs' % (nrunners, t_tests)
273 273 print
274 274 if not failed:
275 275 print 'OK'
276 276 else:
277 277 # If anything went wrong, point out what command to rerun manually to
278 278 # see the actual errors and individual summary
279 279 print 'ERROR - %s out of %s test sets failed.' % (nfail, nrunners)
280 280 for name in failed:
281 281 failed_runner = runners[name]
282 282 print '-'*40
283 283 print 'Runner failed:',name
284 284 print 'You may wish to rerun this one individually, with:'
285 285 print ' '.join(failed_runner.call_args)
286 286 print
287 287
288 288
289 289 def main():
290 290 if len(sys.argv) == 1:
291 291 run_iptestall()
292 292 else:
293 293 if sys.argv[1] == 'all':
294 294 run_iptestall()
295 295 else:
296 296 run_iptest()
297 297
298 298
299 299 if __name__ == '__main__':
300 300 main() No newline at end of file
1 NO CONTENT: file renamed from IPython/ColorANSI.py to IPython/utils/coloransi.py
@@ -1,228 +1,239 b''
1 1 =============================
2 2 IPython module reorganization
3 3 =============================
4 4
5 5 Currently, IPython has many top-level modules that serve many different purposes.
6 6 The lack of organization make it very difficult for developers to work on IPython
7 7 and understand its design. This document contains notes about how we will reorganize
8 8 the modules into sub-packages.
9 9
10 10 .. warning::
11 11
12 12 This effort will possibly break third party packages that use IPython as
13 13 a library or hack on the IPython internals.
14 14
15 15 .. warning::
16 16
17 17 This effort will result in the removal from IPython of certain modules
18 18 that are not used anymore, don't currently work, are unmaintained, etc.
19 19
20 20
21 21 Current subpackges
22 22 ==================
23 23
24 24 IPython currently has the following sub-packages:
25 25
26 26 * :mod:`IPython.config`
27 27
28 28 * :mod:`IPython.Extensions`
29 29
30 30 * :mod:`IPython.external`
31 31
32 32 * :mod:`IPython.frontend`
33 33
34 34 * :mod:`IPython.gui`
35 35
36 36 * :mod:`IPython.kernel`
37 37
38 38 * :mod:`IPython.testing`
39 39
40 40 * :mod:`IPython.tests`
41 41
42 42 * :mod:`IPython.tools`
43 43
44 44 * :mod:`IPython.UserConfig`
45 45
46 46 New Subpackages to be created
47 47 =============================
48 48
49 49 We propose to create the following new sub-packages:
50 50
51 51 * :mod:`IPython.core`. This sub-package will contain the core of the IPython
52 52 interpreter, but none of its extended capabilities.
53 53
54 54 * :mod:`IPython.lib`. IPython has many extended capabilities that are not part
55 55 of the IPython core. These things will go here. Any better names than
56 56 :mod:`IPython.lib`?
57 57
58 58 * :mod:`IPython.utils`. This sub-package will contain anything that might
59 59 eventually be found in the Python standard library, like things in
60 60 :mod:`genutils`. Each sub-module in this sub-package should contain
61 61 functions and classes that serve a single purpose.
62 62
63 63 * :mod:`IPython.deathrow`. This is for code that is untested and/or rotting
64 64 and needs to be removed from IPython. Eventually all this code will either
65 65 i) be revived by someone willing to maintain it with tests and docs and
66 66 re-included into IPython or 2) be removed from IPython proper, but put into
67 67 a separate top-level (not IPython) package that we keep around. No new code
68 68 will be allowed here.
69 69
70 70 * :mod:`IPython.quarantine`. This is for code that doesn't meet IPython's
71 71 standards, but that we plan on keeping. To be moved out of this sub-package
72 72 a module needs to have a maintainer, tests and documentation.
73 73
74 Prodecure
75 =========
76
77 1. Move the file to its new location with its new name.
78 2. Rename all import statements to reflect the change.
79 3. Run PyFlakes on each changes module.
80 3. Add tests/test_imports.py to test it.
81
82 Need to modify iptests to properly skip modules that are no longer top
83 level modules.
84
74 85 Where things will be moved
75 86 ==========================
76 87
77 88 * :file:`ColorANSI.py`. Move to :file:`IPython/core/coloransi.py`. Maybe move to
78 89 :mod:`IPython.lib` or :mod:`IPython.python`?
79 90
80 91 * :file:`ConfigLoader.py`. Move to :file:`IPython/config/configloader.py`.
81 92
82 93 * :file:`CrashHandler.py`. Move to :file:`IPython/core/crashhandler`.
83 94
84 95 * :file:`DPyGetOpt.py`. Move to :mod:`IPython.sandbox` and replace with newer options parser.
85 96
86 97 * :file:`Debugger.py`. Move to :file:`IPython/core/debugger.py`.
87 98
88 99 * :file:`Extensions`. This needs to be gone through separately. Minimally,
89 100 the package should be renamed to :file:`extensions`.
90 101
91 102 * :file:`FakeModule.py`. Move to :file:`IPython/core/fakemodule.py`.
92 103
93 104 * :file:`Gnuplot2.py`. Move to :file:`IPython.sandbox`.
94 105
95 106 * :file:`GnuplotInteractive.py`. Move to :file:`IPython.sandbox`.
96 107
97 108 * :file:`GnuplotRuntime.py`. Move to :file:`IPython.sandbox`.
98 109
99 110 * :file:`Itpl.py`. Remove. Version already in :file:`IPython.external`.
100 111
101 112 * :file:`Logger.py`. Move to :file:`IPython/core/logger.py`.
102 113
103 114 * :file:`Magic.py`. Move to :file:`IPython/core/magic.py`.
104 115
105 116 * :file:`OInspect.py`. Move to :file:`IPython/core/oinspect.py`.
106 117
107 118 * :file:`OutputTrap.py`. Move to :file:`IPython/core/outputtrap.py`.
108 119
109 120 * :file:`Prompts.py`. Move to :file:`IPython/core/prompts.py` or
110 121 :file:`IPython/frontend/prompts.py`.
111 122
112 123 * :file:`PyColorize.py`. Replace with pygments? If not, move to
113 124 :file:`IPython/core/pycolorize.py`. Maybe move to :mod:`IPython.lib` or
114 125 :mod:`IPython.python`?
115 126
116 127 * :file:`Release.py`. Move to ??? or remove?
117 128
118 129 * :file:`Shell.py`. Move to :file:`IPython.core.shell.py` or
119 130 :file:`IPython/frontend/shell.py`.
120 131
121 132 * :file:`UserConfig`. Move to a subdirectory of :file:`IPython.config`.
122 133
123 134 * :file:`background_jobs.py`. Move to :file:`IPython/lib/backgroundjobs.py`.
124 135
125 136 * :file:`completer.py`. Move to :file:`IPython/core/completer.py`.
126 137
127 138 * :file:`config`. Good where it is!
128 139
129 140 * :file:`deep_reload.py`. Move to :file:`IPython/lib/deepreload.py`.
130 141
131 142 * :file:`demo.py`. Move to :file:`IPython/lib/demo.py`.
132 143
133 144 * :file:`dtutils.py`. Remove or move to :file:`IPython.testing` or
134 145 :file:`IPython.lib`.
135 146
136 147 * :file:`excolors.py`. Move to :file:`IPython.core` or :file:`IPython.config`.
137 148 Maybe move to :mod:`IPython.lib` or :mod:`IPython.python`?
138 149
139 150 * :file:`external`. Good where it is!
140 151
141 152 * :file:`frontend`. Good where it is!
142 153
143 154 * :file:`generics.py`. Move to :file:`IPython.python`.
144 155
145 156 * :file:`genutils.py`. Move to :file:`IPython.python` and break up into different
146 157 modules.
147 158
148 159 * :file:`gui`. Eventually this should be moved to a subdir of
149 160 :file:`IPython.frontend`.
150 161
151 162 * :file:`history.py`. Move to :file:`IPython.core`.
152 163
153 164 * :file:`hooks.py`. Move to :file:`IPython.core`.
154 165
155 166 * :file:`ipapi.py`. Move to :file:`IPython.core`.
156 167
157 168 * :file:`iplib.py`. Move to :file:`IPython.core`.
158 169
159 170 * :file:`ipmaker.py`: Move to :file:`IPython.core`.
160 171
161 172 * :file:`ipstruct.py`. Move to :file:`IPython.python`.
162 173
163 174 * :file:`irunner.py`. Move to :file:`IPython.scripts`.
164 175
165 176 * :file:`kernel`. Good where it is.
166 177
167 178 * :file:`macro.py`. Move to :file:`IPython.core`.
168 179
169 180 * :file:`numutils.py`. Move to :file:`IPython.sandbox`.
170 181
171 182 * :file:`platutils.py`. Move to :file:`IPython.python`.
172 183
173 184 * :file:`platutils_dummy.py`. Move to :file:`IPython.python`.
174 185
175 186 * :file:`platutils_posix.py`. Move to :file:`IPython.python`.
176 187
177 188 * :file:`platutils_win32.py`. Move to :file:`IPython.python`.
178 189
179 190 * :file:`prefilter.py`: Move to :file:`IPython.core`.
180 191
181 192 * :file:`rlineimpl.py`. Move to :file:`IPython.core`.
182 193
183 194 * :file:`shadowns.py`. Move to :file:`IPython.core`.
184 195
185 196 * :file:`shellglobals.py`. Move to :file:`IPython.core`.
186 197
187 198 * :file:`strdispatch.py`. Move to :file:`IPython.python`.
188 199
189 200 * :file:`testing`. Good where it is.
190 201
191 202 * :file:`tests`. Good where it is.
192 203
193 204 * :file:`tools`. Things in here need to be looked at and moved elsewhere like
194 205 :file:`IPython.python`.
195 206
196 207 * :file:`twshell.py`. Move to :file:`IPython.sandbox`.
197 208
198 209 * :file:`ultraTB.py`. Move to :file:`IPython/core/ultratb.py`.
199 210
200 211 * :file:`upgrade_dir.py`. Move to :file:`IPython/python/upgradedir.py`.
201 212
202 213 * :file:`usage.py`. Move to :file:`IPython.core`.
203 214
204 215 * :file:`wildcard.py`. Move to :file:`IPython.python` or :file:`IPython.core`.
205 216
206 217 * :file:`winconsole.py`. Move to :file:`IPython.lib`.
207 218
208 219 Other things
209 220 ============
210 221
211 222 When these files are moved around, a number of other things will happen at the same time:
212 223
213 224 1. Test files will be created for each module in IPython. Minimally, all
214 225 modules will be imported as a part of the test. This will serve as a
215 226 test of the module reorganization. These tests will be put into new
216 227 :file:`tests` subdirectories that each package will have.
217 228
218 229 2. PyFlakes and other code checkers will be run to look for problems.
219 230
220 231 3. Modules will be renamed to comply with PEP 8 naming conventions: all
221 232 lowercase and no special characters like ``-`` or ``_``.
222 233
223 234 4. Existing tests will be moved to the appropriate :file:`tests`
224 235 subdirectories.
225 236
226 237
227 238
228 239
General Comments 0
You need to be logged in to leave comments. Login now