##// END OF EJS Templates
Merge branch 'fp-newkernel' into newkernel
Fernando Perez -
r2859:6b93afaa merge
parent child Browse files
Show More
@@ -1,722 +1,795 b''
1 """Word completion for IPython.
1 """Word completion for IPython.
2
2
3 This module is a fork of the rlcompleter module in the Python standard
3 This module is a fork of the rlcompleter module in the Python standard
4 library. The original enhancements made to rlcompleter have been sent
4 library. The original enhancements made to rlcompleter have been sent
5 upstream and were accepted as of Python 2.3, but we need a lot more
5 upstream and were accepted as of Python 2.3, but we need a lot more
6 functionality specific to IPython, so this module will continue to live as an
6 functionality specific to IPython, so this module will continue to live as an
7 IPython-specific utility.
7 IPython-specific utility.
8
8
9 Original rlcompleter documentation:
9 Original rlcompleter documentation:
10
10
11 This requires the latest extension to the readline module (the
11 This requires the latest extension to the readline module (the
12 completes keywords, built-ins and globals in __main__; when completing
12 completes keywords, built-ins and globals in __main__; when completing
13 NAME.NAME..., it evaluates (!) the expression up to the last dot and
13 NAME.NAME..., it evaluates (!) the expression up to the last dot and
14 completes its attributes.
14 completes its attributes.
15
15
16 It's very cool to do "import string" type "string.", hit the
16 It's very cool to do "import string" type "string.", hit the
17 completion key (twice), and see the list of names defined by the
17 completion key (twice), and see the list of names defined by the
18 string module!
18 string module!
19
19
20 Tip: to use the tab key as the completion key, call
20 Tip: to use the tab key as the completion key, call
21
21
22 readline.parse_and_bind("tab: complete")
22 readline.parse_and_bind("tab: complete")
23
23
24 Notes:
24 Notes:
25
25
26 - Exceptions raised by the completer function are *ignored* (and
26 - Exceptions raised by the completer function are *ignored* (and
27 generally cause the completion to fail). This is a feature -- since
27 generally cause the completion to fail). This is a feature -- since
28 readline sets the tty device in raw (or cbreak) mode, printing a
28 readline sets the tty device in raw (or cbreak) mode, printing a
29 traceback wouldn't work well without some complicated hoopla to save,
29 traceback wouldn't work well without some complicated hoopla to save,
30 reset and restore the tty state.
30 reset and restore the tty state.
31
31
32 - The evaluation of the NAME.NAME... form may cause arbitrary
32 - The evaluation of the NAME.NAME... form may cause arbitrary
33 application defined code to be executed if an object with a
33 application defined code to be executed if an object with a
34 __getattr__ hook is found. Since it is the responsibility of the
34 __getattr__ hook is found. Since it is the responsibility of the
35 application (or the user) to enable this feature, I consider this an
35 application (or the user) to enable this feature, I consider this an
36 acceptable risk. More complicated expressions (e.g. function calls or
36 acceptable risk. More complicated expressions (e.g. function calls or
37 indexing operations) are *not* evaluated.
37 indexing operations) are *not* evaluated.
38
38
39 - GNU readline is also used by the built-in functions input() and
39 - GNU readline is also used by the built-in functions input() and
40 raw_input(), and thus these also benefit/suffer from the completer
40 raw_input(), and thus these also benefit/suffer from the completer
41 features. Clearly an interactive application can benefit by
41 features. Clearly an interactive application can benefit by
42 specifying its own completer function and using raw_input() for all
42 specifying its own completer function and using raw_input() for all
43 its input.
43 its input.
44
44
45 - When the original stdin is not a tty device, GNU readline is never
45 - When the original stdin is not a tty device, GNU readline is never
46 used, and this module (and the readline module) are silently inactive.
46 used, and this module (and the readline module) are silently inactive.
47 """
47 """
48
48
49 #*****************************************************************************
49 #*****************************************************************************
50 #
50 #
51 # Since this file is essentially a minimally modified copy of the rlcompleter
51 # Since this file is essentially a minimally modified copy of the rlcompleter
52 # module which is part of the standard Python distribution, I assume that the
52 # module which is part of the standard Python distribution, I assume that the
53 # proper procedure is to maintain its copyright as belonging to the Python
53 # proper procedure is to maintain its copyright as belonging to the Python
54 # Software Foundation (in addition to my own, for all new code).
54 # Software Foundation (in addition to my own, for all new code).
55 #
55 #
56 # Copyright (C) 2008-2010 IPython Development Team
56 # Copyright (C) 2008-2010 IPython Development Team
57 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
57 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
58 # Copyright (C) 2001 Python Software Foundation, www.python.org
58 # Copyright (C) 2001 Python Software Foundation, www.python.org
59 #
59 #
60 # Distributed under the terms of the BSD License. The full license is in
60 # Distributed under the terms of the BSD License. The full license is in
61 # the file COPYING, distributed as part of this software.
61 # the file COPYING, distributed as part of this software.
62 #
62 #
63 #*****************************************************************************
63 #*****************************************************************************
64 from __future__ import print_function
64
65
65 #-----------------------------------------------------------------------------
66 #-----------------------------------------------------------------------------
66 # Imports
67 # Imports
67 #-----------------------------------------------------------------------------
68 #-----------------------------------------------------------------------------
68
69
69 import __builtin__
70 import __builtin__
70 import __main__
71 import __main__
71 import glob
72 import glob
72 import inspect
73 import inspect
73 import itertools
74 import itertools
74 import keyword
75 import keyword
75 import os
76 import os
76 import re
77 import re
77 import shlex
78 import shlex
78 import sys
79 import sys
79
80
80 from IPython.core.error import TryNext
81 from IPython.core.error import TryNext
81 from IPython.core.prefilter import ESC_MAGIC
82 from IPython.core.prefilter import ESC_MAGIC
82 from IPython.utils import generics
83 from IPython.utils import generics, io
83 from IPython.utils.frame import debugx
84 from IPython.utils.frame import debugx
84 from IPython.utils.dir2 import dir2
85 from IPython.utils.dir2 import dir2
85
86
86 #-----------------------------------------------------------------------------
87 #-----------------------------------------------------------------------------
87 # Globals
88 # Globals
88 #-----------------------------------------------------------------------------
89 #-----------------------------------------------------------------------------
89
90
90 # Public API
91 # Public API
91 __all__ = ['Completer','IPCompleter']
92 __all__ = ['Completer','IPCompleter']
92
93
93 if sys.platform == 'win32':
94 if sys.platform == 'win32':
94 PROTECTABLES = ' '
95 PROTECTABLES = ' '
95 else:
96 else:
96 PROTECTABLES = ' ()'
97 PROTECTABLES = ' ()'
97
98
98 #-----------------------------------------------------------------------------
99 #-----------------------------------------------------------------------------
99 # Main functions and classes
100 # Main functions and classes
100 #-----------------------------------------------------------------------------
101 #-----------------------------------------------------------------------------
101
102
102 def protect_filename(s):
103 def protect_filename(s):
103 """Escape a string to protect certain characters."""
104 """Escape a string to protect certain characters."""
104
105
105 return "".join([(ch in PROTECTABLES and '\\' + ch or ch)
106 return "".join([(ch in PROTECTABLES and '\\' + ch or ch)
106 for ch in s])
107 for ch in s])
107
108
108
109
109 def mark_dirs(matches):
110 def mark_dirs(matches):
110 """Mark directories in input list by appending '/' to their names."""
111 """Mark directories in input list by appending '/' to their names."""
111 out = []
112 out = []
112 isdir = os.path.isdir
113 isdir = os.path.isdir
113 for x in matches:
114 for x in matches:
114 if isdir(x):
115 if isdir(x):
115 out.append(x+'/')
116 out.append(x+'/')
116 else:
117 else:
117 out.append(x)
118 out.append(x)
118 return out
119 return out
119
120
120
121
121 def single_dir_expand(matches):
122 def single_dir_expand(matches):
122 "Recursively expand match lists containing a single dir."
123 "Recursively expand match lists containing a single dir."
123
124
124 if len(matches) == 1 and os.path.isdir(matches[0]):
125 if len(matches) == 1 and os.path.isdir(matches[0]):
125 # Takes care of links to directories also. Use '/'
126 # Takes care of links to directories also. Use '/'
126 # explicitly, even under Windows, so that name completions
127 # explicitly, even under Windows, so that name completions
127 # don't end up escaped.
128 # don't end up escaped.
128 d = matches[0]
129 d = matches[0]
129 if d[-1] in ['/','\\']:
130 if d[-1] in ['/','\\']:
130 d = d[:-1]
131 d = d[:-1]
131
132
132 subdirs = os.listdir(d)
133 subdirs = os.listdir(d)
133 if subdirs:
134 if subdirs:
134 matches = [ (d + '/' + p) for p in subdirs]
135 matches = [ (d + '/' + p) for p in subdirs]
135 return single_dir_expand(matches)
136 return single_dir_expand(matches)
136 else:
137 else:
137 return matches
138 return matches
138 else:
139 else:
139 return matches
140 return matches
140
141
141 class Bunch: pass
142
142
143 class Completer:
143 class Bunch(object): pass
144
145
146 class CompletionSplitter(object):
147 """An object to split an input line in a manner similar to readline.
148
149 By having our own implementation, we can expose readline-like completion in
150 a uniform manner to all frontends. This object only needs to be given the
151 line of text to be split and the cursor position on said line, and it
152 returns the 'word' to be completed on at the cursor after splitting the
153 entire line.
154
155 What characters are used as splitting delimiters can be controlled by
156 setting the `delims` attribute (this is a property that internally
157 automatically builds the necessary """
158
159 # Private interface
160
161 # A string of delimiter characters. The default value makes sense for
162 # IPython's most typical usage patterns.
163 _delims = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
164
165 # The expression (a normal string) to be compiled into a regular expression
166 # for actual splitting. We store it as an attribute mostly for ease of
167 # debugging, since this type of code can be so tricky to debug.
168 _delim_expr = None
169
170 # The regular expression that does the actual splitting
171 _delim_re = None
172
173 def __init__(self, delims=None):
174 delims = CompletionSplitter._delims if delims is None else delims
175 self.set_delims(delims)
176
177 def set_delims(self, delims):
178 """Set the delimiters for line splitting."""
179 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
180 self._delim_re = re.compile(expr)
181 self._delims = delims
182 self._delim_expr = expr
183
184 def get_delims(self):
185 """Return the string of delimiter characters."""
186 return self._delims
187
188 def split_line(self, line, cursor_pos=None):
189 """Split a line of text with a cursor at the given position.
190 """
191 l = line if cursor_pos is None else line[:cursor_pos]
192 return self._delim_re.split(l)[-1]
193
194
195 class Completer(object):
144 def __init__(self,namespace=None,global_namespace=None):
196 def __init__(self, namespace=None, global_namespace=None):
145 """Create a new completer for the command line.
197 """Create a new completer for the command line.
146
198
147 Completer([namespace,global_namespace]) -> completer instance.
199 Completer([namespace,global_namespace]) -> completer instance.
148
200
149 If unspecified, the default namespace where completions are performed
201 If unspecified, the default namespace where completions are performed
150 is __main__ (technically, __main__.__dict__). Namespaces should be
202 is __main__ (technically, __main__.__dict__). Namespaces should be
151 given as dictionaries.
203 given as dictionaries.
152
204
153 An optional second namespace can be given. This allows the completer
205 An optional second namespace can be given. This allows the completer
154 to handle cases where both the local and global scopes need to be
206 to handle cases where both the local and global scopes need to be
155 distinguished.
207 distinguished.
156
208
157 Completer instances should be used as the completion mechanism of
209 Completer instances should be used as the completion mechanism of
158 readline via the set_completer() call:
210 readline via the set_completer() call:
159
211
160 readline.set_completer(Completer(my_namespace).complete)
212 readline.set_completer(Completer(my_namespace).complete)
161 """
213 """
162
214
163 # Don't bind to namespace quite yet, but flag whether the user wants a
215 # Don't bind to namespace quite yet, but flag whether the user wants a
164 # specific namespace or to use __main__.__dict__. This will allow us
216 # specific namespace or to use __main__.__dict__. This will allow us
165 # to bind to __main__.__dict__ at completion time, not now.
217 # to bind to __main__.__dict__ at completion time, not now.
166 if namespace is None:
218 if namespace is None:
167 self.use_main_ns = 1
219 self.use_main_ns = 1
168 else:
220 else:
169 self.use_main_ns = 0
221 self.use_main_ns = 0
170 self.namespace = namespace
222 self.namespace = namespace
171
223
172 # The global namespace, if given, can be bound directly
224 # The global namespace, if given, can be bound directly
173 if global_namespace is None:
225 if global_namespace is None:
174 self.global_namespace = {}
226 self.global_namespace = {}
175 else:
227 else:
176 self.global_namespace = global_namespace
228 self.global_namespace = global_namespace
177
229
178 def complete(self, text, state):
230 def complete(self, text, state):
179 """Return the next possible completion for 'text'.
231 """Return the next possible completion for 'text'.
180
232
181 This is called successively with state == 0, 1, 2, ... until it
233 This is called successively with state == 0, 1, 2, ... until it
182 returns None. The completion should begin with 'text'.
234 returns None. The completion should begin with 'text'.
183
235
184 """
236 """
185 if self.use_main_ns:
237 if self.use_main_ns:
186 self.namespace = __main__.__dict__
238 self.namespace = __main__.__dict__
187
239
188 if state == 0:
240 if state == 0:
189 if "." in text:
241 if "." in text:
190 self.matches = self.attr_matches(text)
242 self.matches = self.attr_matches(text)
191 else:
243 else:
192 self.matches = self.global_matches(text)
244 self.matches = self.global_matches(text)
193 try:
245 try:
194 return self.matches[state]
246 return self.matches[state]
195 except IndexError:
247 except IndexError:
196 return None
248 return None
197
249
198 def global_matches(self, text):
250 def global_matches(self, text):
199 """Compute matches when text is a simple name.
251 """Compute matches when text is a simple name.
200
252
201 Return a list of all keywords, built-in functions and names currently
253 Return a list of all keywords, built-in functions and names currently
202 defined in self.namespace or self.global_namespace that match.
254 defined in self.namespace or self.global_namespace that match.
203
255
204 """
256 """
205 #print 'Completer->global_matches, txt=%r' % text # dbg
257 #print 'Completer->global_matches, txt=%r' % text # dbg
206 matches = []
258 matches = []
207 match_append = matches.append
259 match_append = matches.append
208 n = len(text)
260 n = len(text)
209 for lst in [keyword.kwlist,
261 for lst in [keyword.kwlist,
210 __builtin__.__dict__.keys(),
262 __builtin__.__dict__.keys(),
211 self.namespace.keys(),
263 self.namespace.keys(),
212 self.global_namespace.keys()]:
264 self.global_namespace.keys()]:
213 for word in lst:
265 for word in lst:
214 if word[:n] == text and word != "__builtins__":
266 if word[:n] == text and word != "__builtins__":
215 match_append(word)
267 match_append(word)
216 return matches
268 return matches
217
269
218 def attr_matches(self, text):
270 def attr_matches(self, text):
219 """Compute matches when text contains a dot.
271 """Compute matches when text contains a dot.
220
272
221 Assuming the text is of the form NAME.NAME....[NAME], and is
273 Assuming the text is of the form NAME.NAME....[NAME], and is
222 evaluatable in self.namespace or self.global_namespace, it will be
274 evaluatable in self.namespace or self.global_namespace, it will be
223 evaluated and its attributes (as revealed by dir()) are used as
275 evaluated and its attributes (as revealed by dir()) are used as
224 possible completions. (For class instances, class members are are
276 possible completions. (For class instances, class members are are
225 also considered.)
277 also considered.)
226
278
227 WARNING: this can still invoke arbitrary C code, if an object
279 WARNING: this can still invoke arbitrary C code, if an object
228 with a __getattr__ hook is evaluated.
280 with a __getattr__ hook is evaluated.
229
281
230 """
282 """
231
283
232 #print 'Completer->attr_matches, txt=%r' % text # dbg
284 #print 'Completer->attr_matches, txt=%r' % text # dbg
233 # Another option, seems to work great. Catches things like ''.<tab>
285 # Another option, seems to work great. Catches things like ''.<tab>
234 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
286 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
235
287
236 if not m:
288 if not m:
237 return []
289 return []
238
290
239 expr, attr = m.group(1, 3)
291 expr, attr = m.group(1, 3)
240 try:
292 try:
241 obj = eval(expr, self.namespace)
293 obj = eval(expr, self.namespace)
242 except:
294 except:
243 try:
295 try:
244 obj = eval(expr, self.global_namespace)
296 obj = eval(expr, self.global_namespace)
245 except:
297 except:
246 return []
298 return []
247
299
248 words = dir2(obj)
300 words = dir2(obj)
249
301
250 try:
302 try:
251 words = generics.complete_object(obj, words)
303 words = generics.complete_object(obj, words)
252 except TryNext:
304 except TryNext:
253 pass
305 pass
254 # Build match list to return
306 # Build match list to return
255 n = len(attr)
307 n = len(attr)
256 res = ["%s.%s" % (expr, w) for w in words if w[:n] == attr ]
308 res = ["%s.%s" % (expr, w) for w in words if w[:n] == attr ]
257 return res
309 return res
258
310
259
311
260 class IPCompleter(Completer):
312 class IPCompleter(Completer):
261 """Extension of the completer class with IPython-specific features"""
313 """Extension of the completer class with IPython-specific features"""
262
314
263 def __init__(self, shell, namespace=None, global_namespace=None,
315 def __init__(self, shell, namespace=None, global_namespace=None,
264 omit__names=0, alias_table=None, use_readline=True):
316 omit__names=0, alias_table=None, use_readline=True):
265 """IPCompleter() -> completer
317 """IPCompleter() -> completer
266
318
267 Return a completer object suitable for use by the readline library
319 Return a completer object suitable for use by the readline library
268 via readline.set_completer().
320 via readline.set_completer().
269
321
270 Inputs:
322 Inputs:
271
323
272 - shell: a pointer to the ipython shell itself. This is needed
324 - shell: a pointer to the ipython shell itself. This is needed
273 because this completer knows about magic functions, and those can
325 because this completer knows about magic functions, and those can
274 only be accessed via the ipython instance.
326 only be accessed via the ipython instance.
275
327
276 - namespace: an optional dict where completions are performed.
328 - namespace: an optional dict where completions are performed.
277
329
278 - global_namespace: secondary optional dict for completions, to
330 - global_namespace: secondary optional dict for completions, to
279 handle cases (such as IPython embedded inside functions) where
331 handle cases (such as IPython embedded inside functions) where
280 both Python scopes are visible.
332 both Python scopes are visible.
281
333
282 - The optional omit__names parameter sets the completer to omit the
334 - The optional omit__names parameter sets the completer to omit the
283 'magic' names (__magicname__) for python objects unless the text
335 'magic' names (__magicname__) for python objects unless the text
284 to be completed explicitly starts with one or more underscores.
336 to be completed explicitly starts with one or more underscores.
285
337
286 - If alias_table is supplied, it should be a dictionary of aliases
338 - If alias_table is supplied, it should be a dictionary of aliases
287 to complete.
339 to complete.
288
340
289 use_readline : bool, optional
341 use_readline : bool, optional
290 If true, use the readline library. This completer can still function
342 If true, use the readline library. This completer can still function
291 without readline, though in that case callers must provide some extra
343 without readline, though in that case callers must provide some extra
292 information on each call about the current line."""
344 information on each call about the current line."""
293
345
294 Completer.__init__(self,namespace,global_namespace)
346 Completer.__init__(self, namespace, global_namespace)
295
347
296 self.magic_escape = ESC_MAGIC
348 self.magic_escape = ESC_MAGIC
297
349
350 self.splitter = CompletionSplitter()
351
298 # Readline-dependent code
352 # Readline-dependent code
299 self.use_readline = use_readline
353 self.use_readline = use_readline
300 if use_readline:
354 if use_readline:
301 import IPython.utils.rlineimpl as readline
355 import IPython.utils.rlineimpl as readline
302 self.readline = readline
356 self.readline = readline
303 delims = self.readline.get_completer_delims()
357 delims = self.readline.get_completer_delims()
304 delims = delims.replace(self.magic_escape,'')
358 delims = delims.replace(self.magic_escape,'')
305 self.readline.set_completer_delims(delims)
359 self.readline.set_completer_delims(delims)
306 self.get_line_buffer = self.readline.get_line_buffer
360 self.get_line_buffer = self.readline.get_line_buffer
307 self.get_endidx = self.readline.get_endidx
361 self.get_endidx = self.readline.get_endidx
308 # /end readline-dependent code
362 # /end readline-dependent code
309
363
310 # List where completion matches will be stored
364 # List where completion matches will be stored
311 self.matches = []
365 self.matches = []
312 self.omit__names = omit__names
366 self.omit__names = omit__names
313 self.merge_completions = shell.readline_merge_completions
367 self.merge_completions = shell.readline_merge_completions
314 self.shell = shell.shell
368 self.shell = shell.shell
315 if alias_table is None:
369 if alias_table is None:
316 alias_table = {}
370 alias_table = {}
317 self.alias_table = alias_table
371 self.alias_table = alias_table
318 # Regexp to split filenames with spaces in them
372 # Regexp to split filenames with spaces in them
319 self.space_name_re = re.compile(r'([^\\] )')
373 self.space_name_re = re.compile(r'([^\\] )')
320 # Hold a local ref. to glob.glob for speed
374 # Hold a local ref. to glob.glob for speed
321 self.glob = glob.glob
375 self.glob = glob.glob
322
376
323 # Determine if we are running on 'dumb' terminals, like (X)Emacs
377 # Determine if we are running on 'dumb' terminals, like (X)Emacs
324 # buffers, to avoid completion problems.
378 # buffers, to avoid completion problems.
325 term = os.environ.get('TERM','xterm')
379 term = os.environ.get('TERM','xterm')
326 self.dumb_terminal = term in ['dumb','emacs']
380 self.dumb_terminal = term in ['dumb','emacs']
327
381
328 # Special handling of backslashes needed in win32 platforms
382 # Special handling of backslashes needed in win32 platforms
329 if sys.platform == "win32":
383 if sys.platform == "win32":
330 self.clean_glob = self._clean_glob_win32
384 self.clean_glob = self._clean_glob_win32
331 else:
385 else:
332 self.clean_glob = self._clean_glob
386 self.clean_glob = self._clean_glob
333
387
334 # All active matcher routines for completion
388 # All active matcher routines for completion
335 self.matchers = [self.python_matches,
389 self.matchers = [self.python_matches,
336 self.file_matches,
390 self.file_matches,
337 self.magic_matches,
391 self.magic_matches,
338 self.alias_matches,
392 self.alias_matches,
339 self.python_func_kw_matches,
393 self.python_func_kw_matches,
340 ]
394 ]
341
395
342 # Code contributed by Alex Schmolck, for ipython/emacs integration
396 # Code contributed by Alex Schmolck, for ipython/emacs integration
343 def all_completions(self, text):
397 def all_completions(self, text):
344 """Return all possible completions for the benefit of emacs."""
398 """Return all possible completions for the benefit of emacs."""
345
399
346 completions = []
400 completions = []
347 comp_append = completions.append
401 comp_append = completions.append
348 try:
402 try:
349 for i in xrange(sys.maxint):
403 for i in xrange(sys.maxint):
350 res = self.complete(text, i, text)
404 res = self.complete(text, i, text)
351 if not res:
405 if not res:
352 break
406 break
353 comp_append(res)
407 comp_append(res)
354 #XXX workaround for ``notDefined.<tab>``
408 #XXX workaround for ``notDefined.<tab>``
355 except NameError:
409 except NameError:
356 pass
410 pass
357 return completions
411 return completions
358 # /end Alex Schmolck code.
412 # /end Alex Schmolck code.
359
413
360 def _clean_glob(self,text):
414 def _clean_glob(self,text):
361 return self.glob("%s*" % text)
415 return self.glob("%s*" % text)
362
416
363 def _clean_glob_win32(self,text):
417 def _clean_glob_win32(self,text):
364 return [f.replace("\\","/")
418 return [f.replace("\\","/")
365 for f in self.glob("%s*" % text)]
419 for f in self.glob("%s*" % text)]
366
420
367 def file_matches(self, text):
421 def file_matches(self, text):
368 """Match filenames, expanding ~USER type strings.
422 """Match filenames, expanding ~USER type strings.
369
423
370 Most of the seemingly convoluted logic in this completer is an
424 Most of the seemingly convoluted logic in this completer is an
371 attempt to handle filenames with spaces in them. And yet it's not
425 attempt to handle filenames with spaces in them. And yet it's not
372 quite perfect, because Python's readline doesn't expose all of the
426 quite perfect, because Python's readline doesn't expose all of the
373 GNU readline details needed for this to be done correctly.
427 GNU readline details needed for this to be done correctly.
374
428
375 For a filename with a space in it, the printed completions will be
429 For a filename with a space in it, the printed completions will be
376 only the parts after what's already been typed (instead of the
430 only the parts after what's already been typed (instead of the
377 full completions, as is normally done). I don't think with the
431 full completions, as is normally done). I don't think with the
378 current (as of Python 2.3) Python readline it's possible to do
432 current (as of Python 2.3) Python readline it's possible to do
379 better."""
433 better."""
380
434
381 #print 'Completer->file_matches: <%s>' % text # dbg
435 #print 'Completer->file_matches: <%s>' % text # dbg
382
436
383 # chars that require escaping with backslash - i.e. chars
437 # chars that require escaping with backslash - i.e. chars
384 # that readline treats incorrectly as delimiters, but we
438 # that readline treats incorrectly as delimiters, but we
385 # don't want to treat as delimiters in filename matching
439 # don't want to treat as delimiters in filename matching
386 # when escaped with backslash
440 # when escaped with backslash
387
441
388 if text.startswith('!'):
442 if text.startswith('!'):
389 text = text[1:]
443 text = text[1:]
390 text_prefix = '!'
444 text_prefix = '!'
391 else:
445 else:
392 text_prefix = ''
446 text_prefix = ''
393
447
394 lbuf = self.lbuf
448 lbuf = self.lbuf
395 open_quotes = 0 # track strings with open quotes
449 open_quotes = 0 # track strings with open quotes
396 try:
450 try:
397 lsplit = shlex.split(lbuf)[-1]
451 lsplit = shlex.split(lbuf)[-1]
398 except ValueError:
452 except ValueError:
399 # typically an unmatched ", or backslash without escaped char.
453 # typically an unmatched ", or backslash without escaped char.
400 if lbuf.count('"')==1:
454 if lbuf.count('"')==1:
401 open_quotes = 1
455 open_quotes = 1
402 lsplit = lbuf.split('"')[-1]
456 lsplit = lbuf.split('"')[-1]
403 elif lbuf.count("'")==1:
457 elif lbuf.count("'")==1:
404 open_quotes = 1
458 open_quotes = 1
405 lsplit = lbuf.split("'")[-1]
459 lsplit = lbuf.split("'")[-1]
406 else:
460 else:
407 return []
461 return []
408 except IndexError:
462 except IndexError:
409 # tab pressed on empty line
463 # tab pressed on empty line
410 lsplit = ""
464 lsplit = ""
411
465
412 if lsplit != protect_filename(lsplit):
466 if lsplit != protect_filename(lsplit):
413 # if protectables are found, do matching on the whole escaped
467 # if protectables are found, do matching on the whole escaped
414 # name
468 # name
415 has_protectables = 1
469 has_protectables = 1
416 text0,text = text,lsplit
470 text0,text = text,lsplit
417 else:
471 else:
418 has_protectables = 0
472 has_protectables = 0
419 text = os.path.expanduser(text)
473 text = os.path.expanduser(text)
420
474
421 if text == "":
475 if text == "":
422 return [text_prefix + protect_filename(f) for f in self.glob("*")]
476 return [text_prefix + protect_filename(f) for f in self.glob("*")]
423
477
424 m0 = self.clean_glob(text.replace('\\',''))
478 m0 = self.clean_glob(text.replace('\\',''))
425 if has_protectables:
479 if has_protectables:
426 # If we had protectables, we need to revert our changes to the
480 # If we had protectables, we need to revert our changes to the
427 # beginning of filename so that we don't double-write the part
481 # beginning of filename so that we don't double-write the part
428 # of the filename we have so far
482 # of the filename we have so far
429 len_lsplit = len(lsplit)
483 len_lsplit = len(lsplit)
430 matches = [text_prefix + text0 +
484 matches = [text_prefix + text0 +
431 protect_filename(f[len_lsplit:]) for f in m0]
485 protect_filename(f[len_lsplit:]) for f in m0]
432 else:
486 else:
433 if open_quotes:
487 if open_quotes:
434 # if we have a string with an open quote, we don't need to
488 # if we have a string with an open quote, we don't need to
435 # protect the names at all (and we _shouldn't_, as it
489 # protect the names at all (and we _shouldn't_, as it
436 # would cause bugs when the filesystem call is made).
490 # would cause bugs when the filesystem call is made).
437 matches = m0
491 matches = m0
438 else:
492 else:
439 matches = [text_prefix +
493 matches = [text_prefix +
440 protect_filename(f) for f in m0]
494 protect_filename(f) for f in m0]
441
495
442 #print 'mm',matches # dbg
496 #print 'mm',matches # dbg
443 #return single_dir_expand(matches)
497 #return single_dir_expand(matches)
444 return mark_dirs(matches)
498 return mark_dirs(matches)
445
499
446 def magic_matches(self, text):
500 def magic_matches(self, text):
447 """Match magics"""
501 """Match magics"""
448 #print 'Completer->magic_matches:',text,'lb',self.lbuf # dbg
502 #print 'Completer->magic_matches:',text,'lb',self.lbuf # dbg
449 # Get all shell magics now rather than statically, so magics loaded at
503 # Get all shell magics now rather than statically, so magics loaded at
450 # runtime show up too
504 # runtime show up too
451 magics = self.shell.lsmagic()
505 magics = self.shell.lsmagic()
452 pre = self.magic_escape
506 pre = self.magic_escape
453 baretext = text.lstrip(pre)
507 baretext = text.lstrip(pre)
454 return [ pre+m for m in magics if m.startswith(baretext)]
508 return [ pre+m for m in magics if m.startswith(baretext)]
455
509
456 def alias_matches(self, text):
510 def alias_matches(self, text):
457 """Match internal system aliases"""
511 """Match internal system aliases"""
458 #print 'Completer->alias_matches:',text,'lb',self.lbuf # dbg
512 #print 'Completer->alias_matches:',text,'lb',self.lbuf # dbg
459
513
460 # if we are not in the first 'item', alias matching
514 # if we are not in the first 'item', alias matching
461 # doesn't make sense - unless we are starting with 'sudo' command.
515 # doesn't make sense - unless we are starting with 'sudo' command.
462 if ' ' in self.lbuf.lstrip() and \
516 if ' ' in self.lbuf.lstrip() and \
463 not self.lbuf.lstrip().startswith('sudo'):
517 not self.lbuf.lstrip().startswith('sudo'):
464 return []
518 return []
465 text = os.path.expanduser(text)
519 text = os.path.expanduser(text)
466 aliases = self.alias_table.keys()
520 aliases = self.alias_table.keys()
467 if text == "":
521 if text == "":
468 return aliases
522 return aliases
469 else:
523 else:
470 return [alias for alias in aliases if alias.startswith(text)]
524 return [alias for alias in aliases if alias.startswith(text)]
471
525
472 def python_matches(self,text):
526 def python_matches(self,text):
473 """Match attributes or global python names"""
527 """Match attributes or global python names"""
474
528
475 #print 'Completer->python_matches, txt=%r' % text # dbg
529 #print 'Completer->python_matches, txt=%r' % text # dbg
476 if "." in text:
530 if "." in text:
477 try:
531 try:
478 matches = self.attr_matches(text)
532 matches = self.attr_matches(text)
479 if text.endswith('.') and self.omit__names:
533 if text.endswith('.') and self.omit__names:
480 if self.omit__names == 1:
534 if self.omit__names == 1:
481 # true if txt is _not_ a __ name, false otherwise:
535 # true if txt is _not_ a __ name, false otherwise:
482 no__name = (lambda txt:
536 no__name = (lambda txt:
483 re.match(r'.*\.__.*?__',txt) is None)
537 re.match(r'.*\.__.*?__',txt) is None)
484 else:
538 else:
485 # true if txt is _not_ a _ name, false otherwise:
539 # true if txt is _not_ a _ name, false otherwise:
486 no__name = (lambda txt:
540 no__name = (lambda txt:
487 re.match(r'.*\._.*?',txt) is None)
541 re.match(r'.*\._.*?',txt) is None)
488 matches = filter(no__name, matches)
542 matches = filter(no__name, matches)
489 except NameError:
543 except NameError:
490 # catches <undefined attributes>.<tab>
544 # catches <undefined attributes>.<tab>
491 matches = []
545 matches = []
492 else:
546 else:
493 matches = self.global_matches(text)
547 matches = self.global_matches(text)
494
548
495 return matches
549 return matches
496
550
497 def _default_arguments(self, obj):
551 def _default_arguments(self, obj):
498 """Return the list of default arguments of obj if it is callable,
552 """Return the list of default arguments of obj if it is callable,
499 or empty list otherwise."""
553 or empty list otherwise."""
500
554
501 if not (inspect.isfunction(obj) or inspect.ismethod(obj)):
555 if not (inspect.isfunction(obj) or inspect.ismethod(obj)):
502 # for classes, check for __init__,__new__
556 # for classes, check for __init__,__new__
503 if inspect.isclass(obj):
557 if inspect.isclass(obj):
504 obj = (getattr(obj,'__init__',None) or
558 obj = (getattr(obj,'__init__',None) or
505 getattr(obj,'__new__',None))
559 getattr(obj,'__new__',None))
506 # for all others, check if they are __call__able
560 # for all others, check if they are __call__able
507 elif hasattr(obj, '__call__'):
561 elif hasattr(obj, '__call__'):
508 obj = obj.__call__
562 obj = obj.__call__
509 # XXX: is there a way to handle the builtins ?
563 # XXX: is there a way to handle the builtins ?
510 try:
564 try:
511 args,_,_1,defaults = inspect.getargspec(obj)
565 args,_,_1,defaults = inspect.getargspec(obj)
512 if defaults:
566 if defaults:
513 return args[-len(defaults):]
567 return args[-len(defaults):]
514 except TypeError: pass
568 except TypeError: pass
515 return []
569 return []
516
570
517 def python_func_kw_matches(self,text):
571 def python_func_kw_matches(self,text):
518 """Match named parameters (kwargs) of the last open function"""
572 """Match named parameters (kwargs) of the last open function"""
519
573
520 if "." in text: # a parameter cannot be dotted
574 if "." in text: # a parameter cannot be dotted
521 return []
575 return []
522 try: regexp = self.__funcParamsRegex
576 try: regexp = self.__funcParamsRegex
523 except AttributeError:
577 except AttributeError:
524 regexp = self.__funcParamsRegex = re.compile(r'''
578 regexp = self.__funcParamsRegex = re.compile(r'''
525 '.*?' | # single quoted strings or
579 '.*?' | # single quoted strings or
526 ".*?" | # double quoted strings or
580 ".*?" | # double quoted strings or
527 \w+ | # identifier
581 \w+ | # identifier
528 \S # other characters
582 \S # other characters
529 ''', re.VERBOSE | re.DOTALL)
583 ''', re.VERBOSE | re.DOTALL)
530 # 1. find the nearest identifier that comes before an unclosed
584 # 1. find the nearest identifier that comes before an unclosed
531 # parenthesis e.g. for "foo (1+bar(x), pa", the candidate is "foo"
585 # parenthesis e.g. for "foo (1+bar(x), pa", the candidate is "foo"
532 tokens = regexp.findall(self.get_line_buffer())
586 tokens = regexp.findall(self.get_line_buffer())
533 tokens.reverse()
587 tokens.reverse()
534 iterTokens = iter(tokens); openPar = 0
588 iterTokens = iter(tokens); openPar = 0
535 for token in iterTokens:
589 for token in iterTokens:
536 if token == ')':
590 if token == ')':
537 openPar -= 1
591 openPar -= 1
538 elif token == '(':
592 elif token == '(':
539 openPar += 1
593 openPar += 1
540 if openPar > 0:
594 if openPar > 0:
541 # found the last unclosed parenthesis
595 # found the last unclosed parenthesis
542 break
596 break
543 else:
597 else:
544 return []
598 return []
545 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
599 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
546 ids = []
600 ids = []
547 isId = re.compile(r'\w+$').match
601 isId = re.compile(r'\w+$').match
548 while True:
602 while True:
549 try:
603 try:
550 ids.append(iterTokens.next())
604 ids.append(iterTokens.next())
551 if not isId(ids[-1]):
605 if not isId(ids[-1]):
552 ids.pop(); break
606 ids.pop(); break
553 if not iterTokens.next() == '.':
607 if not iterTokens.next() == '.':
554 break
608 break
555 except StopIteration:
609 except StopIteration:
556 break
610 break
557 # lookup the candidate callable matches either using global_matches
611 # lookup the candidate callable matches either using global_matches
558 # or attr_matches for dotted names
612 # or attr_matches for dotted names
559 if len(ids) == 1:
613 if len(ids) == 1:
560 callableMatches = self.global_matches(ids[0])
614 callableMatches = self.global_matches(ids[0])
561 else:
615 else:
562 callableMatches = self.attr_matches('.'.join(ids[::-1]))
616 callableMatches = self.attr_matches('.'.join(ids[::-1]))
563 argMatches = []
617 argMatches = []
564 for callableMatch in callableMatches:
618 for callableMatch in callableMatches:
565 try:
619 try:
566 namedArgs = self._default_arguments(eval(callableMatch,
620 namedArgs = self._default_arguments(eval(callableMatch,
567 self.namespace))
621 self.namespace))
568 except:
622 except:
569 continue
623 continue
570 for namedArg in namedArgs:
624 for namedArg in namedArgs:
571 if namedArg.startswith(text):
625 if namedArg.startswith(text):
572 argMatches.append("%s=" %namedArg)
626 argMatches.append("%s=" %namedArg)
573 return argMatches
627 return argMatches
574
628
575 def dispatch_custom_completer(self,text):
629 def dispatch_custom_completer(self,text):
576 #print "Custom! '%s' %s" % (text, self.custom_completers) # dbg
630 #print "Custom! '%s' %s" % (text, self.custom_completers) # dbg
577 line = self.full_lbuf
631 line = self.full_lbuf
578 if not line.strip():
632 if not line.strip():
579 return None
633 return None
580
634
581 event = Bunch()
635 event = Bunch()
582 event.line = line
636 event.line = line
583 event.symbol = text
637 event.symbol = text
584 cmd = line.split(None,1)[0]
638 cmd = line.split(None,1)[0]
585 event.command = cmd
639 event.command = cmd
586 #print "\ncustom:{%s]\n" % event # dbg
640 #print "\ncustom:{%s]\n" % event # dbg
587
641
588 # for foo etc, try also to find completer for %foo
642 # for foo etc, try also to find completer for %foo
589 if not cmd.startswith(self.magic_escape):
643 if not cmd.startswith(self.magic_escape):
590 try_magic = self.custom_completers.s_matches(
644 try_magic = self.custom_completers.s_matches(
591 self.magic_escape + cmd)
645 self.magic_escape + cmd)
592 else:
646 else:
593 try_magic = []
647 try_magic = []
594
648
595 for c in itertools.chain(self.custom_completers.s_matches(cmd),
649 for c in itertools.chain(self.custom_completers.s_matches(cmd),
596 try_magic,
650 try_magic,
597 self.custom_completers.flat_matches(self.lbuf)):
651 self.custom_completers.flat_matches(self.lbuf)):
598 #print "try",c # dbg
652 #print "try",c # dbg
599 try:
653 try:
600 res = c(event)
654 res = c(event)
601 # first, try case sensitive match
655 # first, try case sensitive match
602 withcase = [r for r in res if r.startswith(text)]
656 withcase = [r for r in res if r.startswith(text)]
603 if withcase:
657 if withcase:
604 return withcase
658 return withcase
605 # if none, then case insensitive ones are ok too
659 # if none, then case insensitive ones are ok too
606 text_low = text.lower()
660 text_low = text.lower()
607 return [r for r in res if r.lower().startswith(text_low)]
661 return [r for r in res if r.lower().startswith(text_low)]
608 except TryNext:
662 except TryNext:
609 pass
663 pass
610
664
611 return None
665 return None
612
666
613 def complete(self, text, line_buffer, cursor_pos=None):
667 def complete(self, text=None, line_buffer=None, cursor_pos=None):
614 """Return the state-th possible completion for 'text'.
668 """Return the state-th possible completion for 'text'.
615
669
616 This is called successively with state == 0, 1, 2, ... until it
670 This is called successively with state == 0, 1, 2, ... until it
617 returns None. The completion should begin with 'text'.
671 returns None. The completion should begin with 'text'.
618
672
673 Note that both the text and the line_buffer are optional, but at least
674 one of them must be given.
675
619 Parameters
676 Parameters
620 ----------
677 ----------
621 text : string
678 text : string, optional
622 Text to perform the completion on.
679 Text to perform the completion on. If not given, the line buffer
680 is split using the instance's CompletionSplitter object.
623
681
624 line_buffer : string, optional
682 line_buffer : string, optional
625 If not given, the completer attempts to obtain the current line
683 If not given, the completer attempts to obtain the current line
626 buffer via readline. This keyword allows clients which are
684 buffer via readline. This keyword allows clients which are
627 requesting for text completions in non-readline contexts to inform
685 requesting for text completions in non-readline contexts to inform
628 the completer of the entire text.
686 the completer of the entire text.
629
687
630 cursor_pos : int, optional
688 cursor_pos : int, optional
631 Index of the cursor in the full line buffer. Should be provided by
689 Index of the cursor in the full line buffer. Should be provided by
632 remote frontends where kernel has no access to frontend state.
690 remote frontends where kernel has no access to frontend state.
633 """
691 """
692 #io.rprint('COMP1 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg
693
694 # if the cursor position isn't given, the only sane assumption we can
695 # make is that it's at the end of the line (the common case)
696 if cursor_pos is None:
697 cursor_pos = len(line_buffer) if text is None else len(text)
698
699 # if text is either None or an empty string, rely on the line buffer
700 if not text:
701 text = self.splitter.split_line(line_buffer, cursor_pos)
702
703 # If no line buffer is given, assume the input text is all there was
704 if line_buffer is None:
705 line_buffer = text
634
706
635 magic_escape = self.magic_escape
707 magic_escape = self.magic_escape
636 self.full_lbuf = line_buffer
708 self.full_lbuf = line_buffer
637 self.lbuf = self.full_lbuf[:cursor_pos]
709 self.lbuf = self.full_lbuf[:cursor_pos]
638
710
639 if text.startswith('~'):
711 if text.startswith('~'):
640 text = os.path.expanduser(text)
712 text = os.path.expanduser(text)
641
713
714 #io.rprint('COMP2 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg
715
642 # Start with a clean slate of completions
716 # Start with a clean slate of completions
643 self.matches[:] = []
717 self.matches[:] = []
644 custom_res = self.dispatch_custom_completer(text)
718 custom_res = self.dispatch_custom_completer(text)
645 if custom_res is not None:
719 if custom_res is not None:
646 # did custom completers produce something?
720 # did custom completers produce something?
647 self.matches = custom_res
721 self.matches = custom_res
648 else:
722 else:
649 # Extend the list of completions with the results of each
723 # Extend the list of completions with the results of each
650 # matcher, so we return results to the user from all
724 # matcher, so we return results to the user from all
651 # namespaces.
725 # namespaces.
652 if self.merge_completions:
726 if self.merge_completions:
653 self.matches = []
727 self.matches = []
654 for matcher in self.matchers:
728 for matcher in self.matchers:
655 self.matches.extend(matcher(text))
729 self.matches.extend(matcher(text))
656 else:
730 else:
657 for matcher in self.matchers:
731 for matcher in self.matchers:
658 self.matches = matcher(text)
732 self.matches = matcher(text)
659 if self.matches:
733 if self.matches:
660 break
734 break
661 # FIXME: we should extend our api to return a dict with completions for
735 # FIXME: we should extend our api to return a dict with completions for
662 # different types of objects. The rlcomplete() method could then
736 # different types of objects. The rlcomplete() method could then
663 # simply collapse the dict into a list for readline, but we'd have
737 # simply collapse the dict into a list for readline, but we'd have
664 # richer completion semantics in other evironments.
738 # richer completion semantics in other evironments.
665 self.matches = sorted(set(self.matches))
739 self.matches = sorted(set(self.matches))
666 #from IPython.utils.io import rprint; rprint(self.matches) # dbg
740 #io.rprint('COMP TEXT, MATCHES: %r, %r' % (text, self.matches)) # dbg
667 return self.matches
741 return text, self.matches
668
742
669 def rlcomplete(self, text, state):
743 def rlcomplete(self, text, state):
670 """Return the state-th possible completion for 'text'.
744 """Return the state-th possible completion for 'text'.
671
745
672 This is called successively with state == 0, 1, 2, ... until it
746 This is called successively with state == 0, 1, 2, ... until it
673 returns None. The completion should begin with 'text'.
747 returns None. The completion should begin with 'text'.
674
748
675 Parameters
749 Parameters
676 ----------
750 ----------
677 text : string
751 text : string
678 Text to perform the completion on.
752 Text to perform the completion on.
679
753
680 state : int
754 state : int
681 Counter used by readline.
755 Counter used by readline.
682
683 """
756 """
684
685 #print "rlcomplete! '%s' %s" % (text, state) # dbg
686
687 if state==0:
757 if state==0:
758
688 self.full_lbuf = line_buffer = self.get_line_buffer()
759 self.full_lbuf = line_buffer = self.get_line_buffer()
689 cursor_pos = self.get_endidx()
760 cursor_pos = self.get_endidx()
690
761
762 #io.rprint("\nRLCOMPLETE: %r %r %r" %
763 # (text, line_buffer, cursor_pos) ) # dbg
764
691 # if there is only a tab on a line with only whitespace, instead of
765 # if there is only a tab on a line with only whitespace, instead of
692 # the mostly useless 'do you want to see all million completions'
766 # the mostly useless 'do you want to see all million completions'
693 # message, just do the right thing and give the user his tab!
767 # message, just do the right thing and give the user his tab!
694 # Incidentally, this enables pasting of tabbed text from an editor
768 # Incidentally, this enables pasting of tabbed text from an editor
695 # (as long as autoindent is off).
769 # (as long as autoindent is off).
696
770
697 # It should be noted that at least pyreadline still shows file
771 # It should be noted that at least pyreadline still shows file
698 # completions - is there a way around it?
772 # completions - is there a way around it?
699
773
700 # don't apply this on 'dumb' terminals, such as emacs buffers, so
774 # don't apply this on 'dumb' terminals, such as emacs buffers, so
701 # we don't interfere with their own tab-completion mechanism.
775 # we don't interfere with their own tab-completion mechanism.
702 if not (self.dumb_terminal or self.full_lbuf.strip()):
776 if not (self.dumb_terminal or line_buffer.strip()):
703 self.readline.insert_text('\t')
777 self.readline.insert_text('\t')
704 sys.stdout.flush()
778 sys.stdout.flush()
705 return None
779 return None
706
780
707 # This method computes the self.matches array
781 # This method computes the self.matches array
708 self.complete(text, line_buffer, cursor_pos)
782 self.complete(text, line_buffer, cursor_pos)
709
783
710 # Debug version, since readline silences all exceptions making it
784 # Debug version, since readline silences all exceptions making it
711 # impossible to debug any problem in the above code
785 # impossible to debug any problem in the above code
712
786
713 ## try:
787 ## try:
714 ## self.complete(text, line_buffer, cursor_pos)
788 ## self.complete(text, line_buffer, cursor_pos)
715 ## except:
789 ## except:
716 ## import traceback; traceback.print_exc()
790 ## import traceback; traceback.print_exc()
717
791
718 try:
792 try:
719 return self.matches[state]
793 return self.matches[state]
720 except IndexError:
794 except IndexError:
721 return None
795 return None
722
@@ -1,2147 +1,2151 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Main IPython class."""
2 """Main IPython class."""
3
3
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
7 # Copyright (C) 2008-2010 The IPython Development Team
7 # Copyright (C) 2008-2010 The IPython Development Team
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 from __future__ import with_statement
17 from __future__ import with_statement
18 from __future__ import absolute_import
18 from __future__ import absolute_import
19
19
20 import __builtin__
20 import __builtin__
21 import abc
21 import abc
22 import codeop
22 import codeop
23 import exceptions
23 import exceptions
24 import new
24 import new
25 import os
25 import os
26 import re
26 import re
27 import string
27 import string
28 import sys
28 import sys
29 import tempfile
29 import tempfile
30 from contextlib import nested
30 from contextlib import nested
31
31
32 from IPython.config.configurable import Configurable
32 from IPython.config.configurable import Configurable
33 from IPython.core import debugger, oinspect
33 from IPython.core import debugger, oinspect
34 from IPython.core import history as ipcorehist
34 from IPython.core import history as ipcorehist
35 from IPython.core import prefilter
35 from IPython.core import prefilter
36 from IPython.core import shadowns
36 from IPython.core import shadowns
37 from IPython.core import ultratb
37 from IPython.core import ultratb
38 from IPython.core.alias import AliasManager
38 from IPython.core.alias import AliasManager
39 from IPython.core.builtin_trap import BuiltinTrap
39 from IPython.core.builtin_trap import BuiltinTrap
40 from IPython.core.display_trap import DisplayTrap
40 from IPython.core.display_trap import DisplayTrap
41 from IPython.core.displayhook import DisplayHook
41 from IPython.core.displayhook import DisplayHook
42 from IPython.core.error import UsageError
42 from IPython.core.error import UsageError
43 from IPython.core.extensions import ExtensionManager
43 from IPython.core.extensions import ExtensionManager
44 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
44 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
45 from IPython.core.inputlist import InputList
45 from IPython.core.inputlist import InputList
46 from IPython.core.logger import Logger
46 from IPython.core.logger import Logger
47 from IPython.core.magic import Magic
47 from IPython.core.magic import Magic
48 from IPython.core.payload import PayloadManager
48 from IPython.core.payload import PayloadManager
49 from IPython.core.plugin import PluginManager
49 from IPython.core.plugin import PluginManager
50 from IPython.core.prefilter import PrefilterManager
50 from IPython.core.prefilter import PrefilterManager
51 from IPython.external.Itpl import ItplNS
51 from IPython.external.Itpl import ItplNS
52 from IPython.utils import PyColorize
52 from IPython.utils import PyColorize
53 from IPython.utils import io
53 from IPython.utils import io
54 from IPython.utils import pickleshare
54 from IPython.utils import pickleshare
55 from IPython.utils.doctestreload import doctest_reload
55 from IPython.utils.doctestreload import doctest_reload
56 from IPython.utils.io import ask_yes_no, rprint
56 from IPython.utils.io import ask_yes_no, rprint
57 from IPython.utils.ipstruct import Struct
57 from IPython.utils.ipstruct import Struct
58 from IPython.utils.path import get_home_dir, get_ipython_dir, HomeDirError
58 from IPython.utils.path import get_home_dir, get_ipython_dir, HomeDirError
59 from IPython.utils.process import getoutput, getoutputerror
59 from IPython.utils.process import getoutput, getoutputerror
60 from IPython.utils.strdispatch import StrDispatch
60 from IPython.utils.strdispatch import StrDispatch
61 from IPython.utils.syspathcontext import prepended_to_syspath
61 from IPython.utils.syspathcontext import prepended_to_syspath
62 from IPython.utils.text import num_ini_spaces
62 from IPython.utils.text import num_ini_spaces
63 from IPython.utils.traitlets import (Int, Str, CBool, CaselessStrEnum, Enum,
63 from IPython.utils.traitlets import (Int, Str, CBool, CaselessStrEnum, Enum,
64 List, Unicode, Instance, Type)
64 List, Unicode, Instance, Type)
65 from IPython.utils.warn import warn, error, fatal
65 from IPython.utils.warn import warn, error, fatal
66 import IPython.core.hooks
66 import IPython.core.hooks
67
67
68 # from IPython.utils import growl
68 # from IPython.utils import growl
69 # growl.start("IPython")
69 # growl.start("IPython")
70
70
71 #-----------------------------------------------------------------------------
71 #-----------------------------------------------------------------------------
72 # Globals
72 # Globals
73 #-----------------------------------------------------------------------------
73 #-----------------------------------------------------------------------------
74
74
75 # compiled regexps for autoindent management
75 # compiled regexps for autoindent management
76 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
76 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
77
77
78 #-----------------------------------------------------------------------------
78 #-----------------------------------------------------------------------------
79 # Utilities
79 # Utilities
80 #-----------------------------------------------------------------------------
80 #-----------------------------------------------------------------------------
81
81
82 # store the builtin raw_input globally, and use this always, in case user code
82 # store the builtin raw_input globally, and use this always, in case user code
83 # overwrites it (like wx.py.PyShell does)
83 # overwrites it (like wx.py.PyShell does)
84 raw_input_original = raw_input
84 raw_input_original = raw_input
85
85
86 def softspace(file, newvalue):
86 def softspace(file, newvalue):
87 """Copied from code.py, to remove the dependency"""
87 """Copied from code.py, to remove the dependency"""
88
88
89 oldvalue = 0
89 oldvalue = 0
90 try:
90 try:
91 oldvalue = file.softspace
91 oldvalue = file.softspace
92 except AttributeError:
92 except AttributeError:
93 pass
93 pass
94 try:
94 try:
95 file.softspace = newvalue
95 file.softspace = newvalue
96 except (AttributeError, TypeError):
96 except (AttributeError, TypeError):
97 # "attribute-less object" or "read-only attributes"
97 # "attribute-less object" or "read-only attributes"
98 pass
98 pass
99 return oldvalue
99 return oldvalue
100
100
101
101
102 def no_op(*a, **kw): pass
102 def no_op(*a, **kw): pass
103
103
104 class SpaceInInput(exceptions.Exception): pass
104 class SpaceInInput(exceptions.Exception): pass
105
105
106 class Bunch: pass
106 class Bunch: pass
107
107
108
108
109 def get_default_colors():
109 def get_default_colors():
110 if sys.platform=='darwin':
110 if sys.platform=='darwin':
111 return "LightBG"
111 return "LightBG"
112 elif os.name=='nt':
112 elif os.name=='nt':
113 return 'Linux'
113 return 'Linux'
114 else:
114 else:
115 return 'Linux'
115 return 'Linux'
116
116
117
117
118 class SeparateStr(Str):
118 class SeparateStr(Str):
119 """A Str subclass to validate separate_in, separate_out, etc.
119 """A Str subclass to validate separate_in, separate_out, etc.
120
120
121 This is a Str based trait that converts '0'->'' and '\\n'->'\n'.
121 This is a Str based trait that converts '0'->'' and '\\n'->'\n'.
122 """
122 """
123
123
124 def validate(self, obj, value):
124 def validate(self, obj, value):
125 if value == '0': value = ''
125 if value == '0': value = ''
126 value = value.replace('\\n','\n')
126 value = value.replace('\\n','\n')
127 return super(SeparateStr, self).validate(obj, value)
127 return super(SeparateStr, self).validate(obj, value)
128
128
129 class MultipleInstanceError(Exception):
129 class MultipleInstanceError(Exception):
130 pass
130 pass
131
131
132
132
133 #-----------------------------------------------------------------------------
133 #-----------------------------------------------------------------------------
134 # Main IPython class
134 # Main IPython class
135 #-----------------------------------------------------------------------------
135 #-----------------------------------------------------------------------------
136
136
137
137
138 class InteractiveShell(Configurable, Magic):
138 class InteractiveShell(Configurable, Magic):
139 """An enhanced, interactive shell for Python."""
139 """An enhanced, interactive shell for Python."""
140
140
141 _instance = None
141 _instance = None
142 autocall = Enum((0,1,2), default_value=1, config=True)
142 autocall = Enum((0,1,2), default_value=1, config=True)
143 # TODO: remove all autoindent logic and put into frontends.
143 # TODO: remove all autoindent logic and put into frontends.
144 # We can't do this yet because even runlines uses the autoindent.
144 # We can't do this yet because even runlines uses the autoindent.
145 autoindent = CBool(True, config=True)
145 autoindent = CBool(True, config=True)
146 automagic = CBool(True, config=True)
146 automagic = CBool(True, config=True)
147 cache_size = Int(1000, config=True)
147 cache_size = Int(1000, config=True)
148 color_info = CBool(True, config=True)
148 color_info = CBool(True, config=True)
149 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
149 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
150 default_value=get_default_colors(), config=True)
150 default_value=get_default_colors(), config=True)
151 debug = CBool(False, config=True)
151 debug = CBool(False, config=True)
152 deep_reload = CBool(False, config=True)
152 deep_reload = CBool(False, config=True)
153 displayhook_class = Type(DisplayHook)
153 displayhook_class = Type(DisplayHook)
154 filename = Str("<ipython console>")
154 filename = Str("<ipython console>")
155 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
155 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
156 logstart = CBool(False, config=True)
156 logstart = CBool(False, config=True)
157 logfile = Str('', config=True)
157 logfile = Str('', config=True)
158 logappend = Str('', config=True)
158 logappend = Str('', config=True)
159 object_info_string_level = Enum((0,1,2), default_value=0,
159 object_info_string_level = Enum((0,1,2), default_value=0,
160 config=True)
160 config=True)
161 pdb = CBool(False, config=True)
161 pdb = CBool(False, config=True)
162 pprint = CBool(True, config=True)
162 pprint = CBool(True, config=True)
163 profile = Str('', config=True)
163 profile = Str('', config=True)
164 prompt_in1 = Str('In [\\#]: ', config=True)
164 prompt_in1 = Str('In [\\#]: ', config=True)
165 prompt_in2 = Str(' .\\D.: ', config=True)
165 prompt_in2 = Str(' .\\D.: ', config=True)
166 prompt_out = Str('Out[\\#]: ', config=True)
166 prompt_out = Str('Out[\\#]: ', config=True)
167 prompts_pad_left = CBool(True, config=True)
167 prompts_pad_left = CBool(True, config=True)
168 quiet = CBool(False, config=True)
168 quiet = CBool(False, config=True)
169
169
170 # The readline stuff will eventually be moved to the terminal subclass
170 # The readline stuff will eventually be moved to the terminal subclass
171 # but for now, we can't do that as readline is welded in everywhere.
171 # but for now, we can't do that as readline is welded in everywhere.
172 readline_use = CBool(True, config=True)
172 readline_use = CBool(True, config=True)
173 readline_merge_completions = CBool(True, config=True)
173 readline_merge_completions = CBool(True, config=True)
174 readline_omit__names = Enum((0,1,2), default_value=0, config=True)
174 readline_omit__names = Enum((0,1,2), default_value=0, config=True)
175 readline_remove_delims = Str('-/~', config=True)
175 readline_remove_delims = Str('-/~', config=True)
176 readline_parse_and_bind = List([
176 readline_parse_and_bind = List([
177 'tab: complete',
177 'tab: complete',
178 '"\C-l": clear-screen',
178 '"\C-l": clear-screen',
179 'set show-all-if-ambiguous on',
179 'set show-all-if-ambiguous on',
180 '"\C-o": tab-insert',
180 '"\C-o": tab-insert',
181 '"\M-i": " "',
181 '"\M-i": " "',
182 '"\M-o": "\d\d\d\d"',
182 '"\M-o": "\d\d\d\d"',
183 '"\M-I": "\d\d\d\d"',
183 '"\M-I": "\d\d\d\d"',
184 '"\C-r": reverse-search-history',
184 '"\C-r": reverse-search-history',
185 '"\C-s": forward-search-history',
185 '"\C-s": forward-search-history',
186 '"\C-p": history-search-backward',
186 '"\C-p": history-search-backward',
187 '"\C-n": history-search-forward',
187 '"\C-n": history-search-forward',
188 '"\e[A": history-search-backward',
188 '"\e[A": history-search-backward',
189 '"\e[B": history-search-forward',
189 '"\e[B": history-search-forward',
190 '"\C-k": kill-line',
190 '"\C-k": kill-line',
191 '"\C-u": unix-line-discard',
191 '"\C-u": unix-line-discard',
192 ], allow_none=False, config=True)
192 ], allow_none=False, config=True)
193
193
194 # TODO: this part of prompt management should be moved to the frontends.
194 # TODO: this part of prompt management should be moved to the frontends.
195 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
195 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
196 separate_in = SeparateStr('\n', config=True)
196 separate_in = SeparateStr('\n', config=True)
197 separate_out = SeparateStr('\n', config=True)
197 separate_out = SeparateStr('\n', config=True)
198 separate_out2 = SeparateStr('\n', config=True)
198 separate_out2 = SeparateStr('\n', config=True)
199 system_header = Str('IPython system call: ', config=True)
199 system_header = Str('IPython system call: ', config=True)
200 system_verbose = CBool(False, config=True)
200 system_verbose = CBool(False, config=True)
201 wildcards_case_sensitive = CBool(True, config=True)
201 wildcards_case_sensitive = CBool(True, config=True)
202 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
202 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
203 default_value='Context', config=True)
203 default_value='Context', config=True)
204
204
205 # Subcomponents of InteractiveShell
205 # Subcomponents of InteractiveShell
206 alias_manager = Instance('IPython.core.alias.AliasManager')
206 alias_manager = Instance('IPython.core.alias.AliasManager')
207 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
207 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
208 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap')
208 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap')
209 display_trap = Instance('IPython.core.display_trap.DisplayTrap')
209 display_trap = Instance('IPython.core.display_trap.DisplayTrap')
210 extension_manager = Instance('IPython.core.extensions.ExtensionManager')
210 extension_manager = Instance('IPython.core.extensions.ExtensionManager')
211 plugin_manager = Instance('IPython.core.plugin.PluginManager')
211 plugin_manager = Instance('IPython.core.plugin.PluginManager')
212 payload_manager = Instance('IPython.core.payload.PayloadManager')
212 payload_manager = Instance('IPython.core.payload.PayloadManager')
213
213
214 def __init__(self, config=None, ipython_dir=None,
214 def __init__(self, config=None, ipython_dir=None,
215 user_ns=None, user_global_ns=None,
215 user_ns=None, user_global_ns=None,
216 custom_exceptions=((),None)):
216 custom_exceptions=((),None)):
217
217
218 # This is where traits with a config_key argument are updated
218 # This is where traits with a config_key argument are updated
219 # from the values on config.
219 # from the values on config.
220 super(InteractiveShell, self).__init__(config=config)
220 super(InteractiveShell, self).__init__(config=config)
221
221
222 # These are relatively independent and stateless
222 # These are relatively independent and stateless
223 self.init_ipython_dir(ipython_dir)
223 self.init_ipython_dir(ipython_dir)
224 self.init_instance_attrs()
224 self.init_instance_attrs()
225
225
226 # Create namespaces (user_ns, user_global_ns, etc.)
226 # Create namespaces (user_ns, user_global_ns, etc.)
227 self.init_create_namespaces(user_ns, user_global_ns)
227 self.init_create_namespaces(user_ns, user_global_ns)
228 # This has to be done after init_create_namespaces because it uses
228 # This has to be done after init_create_namespaces because it uses
229 # something in self.user_ns, but before init_sys_modules, which
229 # something in self.user_ns, but before init_sys_modules, which
230 # is the first thing to modify sys.
230 # is the first thing to modify sys.
231 # TODO: When we override sys.stdout and sys.stderr before this class
231 # TODO: When we override sys.stdout and sys.stderr before this class
232 # is created, we are saving the overridden ones here. Not sure if this
232 # is created, we are saving the overridden ones here. Not sure if this
233 # is what we want to do.
233 # is what we want to do.
234 self.save_sys_module_state()
234 self.save_sys_module_state()
235 self.init_sys_modules()
235 self.init_sys_modules()
236
236
237 self.init_history()
237 self.init_history()
238 self.init_encoding()
238 self.init_encoding()
239 self.init_prefilter()
239 self.init_prefilter()
240
240
241 Magic.__init__(self, self)
241 Magic.__init__(self, self)
242
242
243 self.init_syntax_highlighting()
243 self.init_syntax_highlighting()
244 self.init_hooks()
244 self.init_hooks()
245 self.init_pushd_popd_magic()
245 self.init_pushd_popd_magic()
246 # self.init_traceback_handlers use to be here, but we moved it below
246 # self.init_traceback_handlers use to be here, but we moved it below
247 # because it and init_io have to come after init_readline.
247 # because it and init_io have to come after init_readline.
248 self.init_user_ns()
248 self.init_user_ns()
249 self.init_logger()
249 self.init_logger()
250 self.init_alias()
250 self.init_alias()
251 self.init_builtins()
251 self.init_builtins()
252
252
253 # pre_config_initialization
253 # pre_config_initialization
254 self.init_shadow_hist()
254 self.init_shadow_hist()
255
255
256 # The next section should contain averything that was in ipmaker.
256 # The next section should contain averything that was in ipmaker.
257 self.init_logstart()
257 self.init_logstart()
258
258
259 # The following was in post_config_initialization
259 # The following was in post_config_initialization
260 self.init_inspector()
260 self.init_inspector()
261 # init_readline() must come before init_io(), because init_io uses
261 # init_readline() must come before init_io(), because init_io uses
262 # readline related things.
262 # readline related things.
263 self.init_readline()
263 self.init_readline()
264 # TODO: init_io() needs to happen before init_traceback handlers
264 # TODO: init_io() needs to happen before init_traceback handlers
265 # because the traceback handlers hardcode the stdout/stderr streams.
265 # because the traceback handlers hardcode the stdout/stderr streams.
266 # This logic in in debugger.Pdb and should eventually be changed.
266 # This logic in in debugger.Pdb and should eventually be changed.
267 self.init_io()
267 self.init_io()
268 self.init_traceback_handlers(custom_exceptions)
268 self.init_traceback_handlers(custom_exceptions)
269 self.init_prompts()
269 self.init_prompts()
270 self.init_displayhook()
270 self.init_displayhook()
271 self.init_reload_doctest()
271 self.init_reload_doctest()
272 self.init_magics()
272 self.init_magics()
273 self.init_pdb()
273 self.init_pdb()
274 self.init_extension_manager()
274 self.init_extension_manager()
275 self.init_plugin_manager()
275 self.init_plugin_manager()
276 self.init_payload()
276 self.init_payload()
277 self.hooks.late_startup_hook()
277 self.hooks.late_startup_hook()
278
278
279 @classmethod
279 @classmethod
280 def instance(cls, *args, **kwargs):
280 def instance(cls, *args, **kwargs):
281 """Returns a global InteractiveShell instance."""
281 """Returns a global InteractiveShell instance."""
282 if cls._instance is None:
282 if cls._instance is None:
283 inst = cls(*args, **kwargs)
283 inst = cls(*args, **kwargs)
284 # Now make sure that the instance will also be returned by
284 # Now make sure that the instance will also be returned by
285 # the subclasses instance attribute.
285 # the subclasses instance attribute.
286 for subclass in cls.mro():
286 for subclass in cls.mro():
287 if issubclass(cls, subclass) and issubclass(subclass, InteractiveShell):
287 if issubclass(cls, subclass) and issubclass(subclass, InteractiveShell):
288 subclass._instance = inst
288 subclass._instance = inst
289 else:
289 else:
290 break
290 break
291 if isinstance(cls._instance, cls):
291 if isinstance(cls._instance, cls):
292 return cls._instance
292 return cls._instance
293 else:
293 else:
294 raise MultipleInstanceError(
294 raise MultipleInstanceError(
295 'Multiple incompatible subclass instances of '
295 'Multiple incompatible subclass instances of '
296 'InteractiveShell are being created.'
296 'InteractiveShell are being created.'
297 )
297 )
298
298
299 @classmethod
299 @classmethod
300 def initialized(cls):
300 def initialized(cls):
301 return hasattr(cls, "_instance")
301 return hasattr(cls, "_instance")
302
302
303 def get_ipython(self):
303 def get_ipython(self):
304 """Return the currently running IPython instance."""
304 """Return the currently running IPython instance."""
305 return self
305 return self
306
306
307 #-------------------------------------------------------------------------
307 #-------------------------------------------------------------------------
308 # Trait changed handlers
308 # Trait changed handlers
309 #-------------------------------------------------------------------------
309 #-------------------------------------------------------------------------
310
310
311 def _ipython_dir_changed(self, name, new):
311 def _ipython_dir_changed(self, name, new):
312 if not os.path.isdir(new):
312 if not os.path.isdir(new):
313 os.makedirs(new, mode = 0777)
313 os.makedirs(new, mode = 0777)
314
314
315 def set_autoindent(self,value=None):
315 def set_autoindent(self,value=None):
316 """Set the autoindent flag, checking for readline support.
316 """Set the autoindent flag, checking for readline support.
317
317
318 If called with no arguments, it acts as a toggle."""
318 If called with no arguments, it acts as a toggle."""
319
319
320 if not self.has_readline:
320 if not self.has_readline:
321 if os.name == 'posix':
321 if os.name == 'posix':
322 warn("The auto-indent feature requires the readline library")
322 warn("The auto-indent feature requires the readline library")
323 self.autoindent = 0
323 self.autoindent = 0
324 return
324 return
325 if value is None:
325 if value is None:
326 self.autoindent = not self.autoindent
326 self.autoindent = not self.autoindent
327 else:
327 else:
328 self.autoindent = value
328 self.autoindent = value
329
329
330 #-------------------------------------------------------------------------
330 #-------------------------------------------------------------------------
331 # init_* methods called by __init__
331 # init_* methods called by __init__
332 #-------------------------------------------------------------------------
332 #-------------------------------------------------------------------------
333
333
334 def init_ipython_dir(self, ipython_dir):
334 def init_ipython_dir(self, ipython_dir):
335 if ipython_dir is not None:
335 if ipython_dir is not None:
336 self.ipython_dir = ipython_dir
336 self.ipython_dir = ipython_dir
337 self.config.Global.ipython_dir = self.ipython_dir
337 self.config.Global.ipython_dir = self.ipython_dir
338 return
338 return
339
339
340 if hasattr(self.config.Global, 'ipython_dir'):
340 if hasattr(self.config.Global, 'ipython_dir'):
341 self.ipython_dir = self.config.Global.ipython_dir
341 self.ipython_dir = self.config.Global.ipython_dir
342 else:
342 else:
343 self.ipython_dir = get_ipython_dir()
343 self.ipython_dir = get_ipython_dir()
344
344
345 # All children can just read this
345 # All children can just read this
346 self.config.Global.ipython_dir = self.ipython_dir
346 self.config.Global.ipython_dir = self.ipython_dir
347
347
348 def init_instance_attrs(self):
348 def init_instance_attrs(self):
349 self.more = False
349 self.more = False
350
350
351 # command compiler
351 # command compiler
352 self.compile = codeop.CommandCompiler()
352 self.compile = codeop.CommandCompiler()
353
353
354 # User input buffer
354 # User input buffer
355 self.buffer = []
355 self.buffer = []
356
356
357 # Make an empty namespace, which extension writers can rely on both
357 # Make an empty namespace, which extension writers can rely on both
358 # existing and NEVER being used by ipython itself. This gives them a
358 # existing and NEVER being used by ipython itself. This gives them a
359 # convenient location for storing additional information and state
359 # convenient location for storing additional information and state
360 # their extensions may require, without fear of collisions with other
360 # their extensions may require, without fear of collisions with other
361 # ipython names that may develop later.
361 # ipython names that may develop later.
362 self.meta = Struct()
362 self.meta = Struct()
363
363
364 # Object variable to store code object waiting execution. This is
364 # Object variable to store code object waiting execution. This is
365 # used mainly by the multithreaded shells, but it can come in handy in
365 # used mainly by the multithreaded shells, but it can come in handy in
366 # other situations. No need to use a Queue here, since it's a single
366 # other situations. No need to use a Queue here, since it's a single
367 # item which gets cleared once run.
367 # item which gets cleared once run.
368 self.code_to_run = None
368 self.code_to_run = None
369
369
370 # Temporary files used for various purposes. Deleted at exit.
370 # Temporary files used for various purposes. Deleted at exit.
371 self.tempfiles = []
371 self.tempfiles = []
372
372
373 # Keep track of readline usage (later set by init_readline)
373 # Keep track of readline usage (later set by init_readline)
374 self.has_readline = False
374 self.has_readline = False
375
375
376 # keep track of where we started running (mainly for crash post-mortem)
376 # keep track of where we started running (mainly for crash post-mortem)
377 # This is not being used anywhere currently.
377 # This is not being used anywhere currently.
378 self.starting_dir = os.getcwd()
378 self.starting_dir = os.getcwd()
379
379
380 # Indentation management
380 # Indentation management
381 self.indent_current_nsp = 0
381 self.indent_current_nsp = 0
382
382
383 def init_encoding(self):
383 def init_encoding(self):
384 # Get system encoding at startup time. Certain terminals (like Emacs
384 # Get system encoding at startup time. Certain terminals (like Emacs
385 # under Win32 have it set to None, and we need to have a known valid
385 # under Win32 have it set to None, and we need to have a known valid
386 # encoding to use in the raw_input() method
386 # encoding to use in the raw_input() method
387 try:
387 try:
388 self.stdin_encoding = sys.stdin.encoding or 'ascii'
388 self.stdin_encoding = sys.stdin.encoding or 'ascii'
389 except AttributeError:
389 except AttributeError:
390 self.stdin_encoding = 'ascii'
390 self.stdin_encoding = 'ascii'
391
391
392 def init_syntax_highlighting(self):
392 def init_syntax_highlighting(self):
393 # Python source parser/formatter for syntax highlighting
393 # Python source parser/formatter for syntax highlighting
394 pyformat = PyColorize.Parser().format
394 pyformat = PyColorize.Parser().format
395 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
395 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
396
396
397 def init_pushd_popd_magic(self):
397 def init_pushd_popd_magic(self):
398 # for pushd/popd management
398 # for pushd/popd management
399 try:
399 try:
400 self.home_dir = get_home_dir()
400 self.home_dir = get_home_dir()
401 except HomeDirError, msg:
401 except HomeDirError, msg:
402 fatal(msg)
402 fatal(msg)
403
403
404 self.dir_stack = []
404 self.dir_stack = []
405
405
406 def init_logger(self):
406 def init_logger(self):
407 self.logger = Logger(self, logfname='ipython_log.py', logmode='rotate')
407 self.logger = Logger(self, logfname='ipython_log.py', logmode='rotate')
408 # local shortcut, this is used a LOT
408 # local shortcut, this is used a LOT
409 self.log = self.logger.log
409 self.log = self.logger.log
410
410
411 def init_logstart(self):
411 def init_logstart(self):
412 if self.logappend:
412 if self.logappend:
413 self.magic_logstart(self.logappend + ' append')
413 self.magic_logstart(self.logappend + ' append')
414 elif self.logfile:
414 elif self.logfile:
415 self.magic_logstart(self.logfile)
415 self.magic_logstart(self.logfile)
416 elif self.logstart:
416 elif self.logstart:
417 self.magic_logstart()
417 self.magic_logstart()
418
418
419 def init_builtins(self):
419 def init_builtins(self):
420 self.builtin_trap = BuiltinTrap(shell=self)
420 self.builtin_trap = BuiltinTrap(shell=self)
421
421
422 def init_inspector(self):
422 def init_inspector(self):
423 # Object inspector
423 # Object inspector
424 self.inspector = oinspect.Inspector(oinspect.InspectColors,
424 self.inspector = oinspect.Inspector(oinspect.InspectColors,
425 PyColorize.ANSICodeColors,
425 PyColorize.ANSICodeColors,
426 'NoColor',
426 'NoColor',
427 self.object_info_string_level)
427 self.object_info_string_level)
428
428
429 def init_io(self):
429 def init_io(self):
430 import IPython.utils.io
430 import IPython.utils.io
431 if sys.platform == 'win32' and self.has_readline:
431 if sys.platform == 'win32' and self.has_readline:
432 Term = io.IOTerm(
432 Term = io.IOTerm(
433 cout=self.readline._outputfile,cerr=self.readline._outputfile
433 cout=self.readline._outputfile,cerr=self.readline._outputfile
434 )
434 )
435 else:
435 else:
436 Term = io.IOTerm()
436 Term = io.IOTerm()
437 io.Term = Term
437 io.Term = Term
438
438
439 def init_prompts(self):
439 def init_prompts(self):
440 # TODO: This is a pass for now because the prompts are managed inside
440 # TODO: This is a pass for now because the prompts are managed inside
441 # the DisplayHook. Once there is a separate prompt manager, this
441 # the DisplayHook. Once there is a separate prompt manager, this
442 # will initialize that object and all prompt related information.
442 # will initialize that object and all prompt related information.
443 pass
443 pass
444
444
445 def init_displayhook(self):
445 def init_displayhook(self):
446 # Initialize displayhook, set in/out prompts and printing system
446 # Initialize displayhook, set in/out prompts and printing system
447 self.displayhook = self.displayhook_class(
447 self.displayhook = self.displayhook_class(
448 shell=self,
448 shell=self,
449 cache_size=self.cache_size,
449 cache_size=self.cache_size,
450 input_sep = self.separate_in,
450 input_sep = self.separate_in,
451 output_sep = self.separate_out,
451 output_sep = self.separate_out,
452 output_sep2 = self.separate_out2,
452 output_sep2 = self.separate_out2,
453 ps1 = self.prompt_in1,
453 ps1 = self.prompt_in1,
454 ps2 = self.prompt_in2,
454 ps2 = self.prompt_in2,
455 ps_out = self.prompt_out,
455 ps_out = self.prompt_out,
456 pad_left = self.prompts_pad_left
456 pad_left = self.prompts_pad_left
457 )
457 )
458 # This is a context manager that installs/revmoes the displayhook at
458 # This is a context manager that installs/revmoes the displayhook at
459 # the appropriate time.
459 # the appropriate time.
460 self.display_trap = DisplayTrap(hook=self.displayhook)
460 self.display_trap = DisplayTrap(hook=self.displayhook)
461
461
462 def init_reload_doctest(self):
462 def init_reload_doctest(self):
463 # Do a proper resetting of doctest, including the necessary displayhook
463 # Do a proper resetting of doctest, including the necessary displayhook
464 # monkeypatching
464 # monkeypatching
465 try:
465 try:
466 doctest_reload()
466 doctest_reload()
467 except ImportError:
467 except ImportError:
468 warn("doctest module does not exist.")
468 warn("doctest module does not exist.")
469
469
470 #-------------------------------------------------------------------------
470 #-------------------------------------------------------------------------
471 # Things related to injections into the sys module
471 # Things related to injections into the sys module
472 #-------------------------------------------------------------------------
472 #-------------------------------------------------------------------------
473
473
474 def save_sys_module_state(self):
474 def save_sys_module_state(self):
475 """Save the state of hooks in the sys module.
475 """Save the state of hooks in the sys module.
476
476
477 This has to be called after self.user_ns is created.
477 This has to be called after self.user_ns is created.
478 """
478 """
479 self._orig_sys_module_state = {}
479 self._orig_sys_module_state = {}
480 self._orig_sys_module_state['stdin'] = sys.stdin
480 self._orig_sys_module_state['stdin'] = sys.stdin
481 self._orig_sys_module_state['stdout'] = sys.stdout
481 self._orig_sys_module_state['stdout'] = sys.stdout
482 self._orig_sys_module_state['stderr'] = sys.stderr
482 self._orig_sys_module_state['stderr'] = sys.stderr
483 self._orig_sys_module_state['excepthook'] = sys.excepthook
483 self._orig_sys_module_state['excepthook'] = sys.excepthook
484 try:
484 try:
485 self._orig_sys_modules_main_name = self.user_ns['__name__']
485 self._orig_sys_modules_main_name = self.user_ns['__name__']
486 except KeyError:
486 except KeyError:
487 pass
487 pass
488
488
489 def restore_sys_module_state(self):
489 def restore_sys_module_state(self):
490 """Restore the state of the sys module."""
490 """Restore the state of the sys module."""
491 try:
491 try:
492 for k, v in self._orig_sys_module_state.items():
492 for k, v in self._orig_sys_module_state.items():
493 setattr(sys, k, v)
493 setattr(sys, k, v)
494 except AttributeError:
494 except AttributeError:
495 pass
495 pass
496 try:
496 try:
497 delattr(sys, 'ipcompleter')
497 delattr(sys, 'ipcompleter')
498 except AttributeError:
498 except AttributeError:
499 pass
499 pass
500 # Reset what what done in self.init_sys_modules
500 # Reset what what done in self.init_sys_modules
501 try:
501 try:
502 sys.modules[self.user_ns['__name__']] = self._orig_sys_modules_main_name
502 sys.modules[self.user_ns['__name__']] = self._orig_sys_modules_main_name
503 except (AttributeError, KeyError):
503 except (AttributeError, KeyError):
504 pass
504 pass
505
505
506 #-------------------------------------------------------------------------
506 #-------------------------------------------------------------------------
507 # Things related to hooks
507 # Things related to hooks
508 #-------------------------------------------------------------------------
508 #-------------------------------------------------------------------------
509
509
510 def init_hooks(self):
510 def init_hooks(self):
511 # hooks holds pointers used for user-side customizations
511 # hooks holds pointers used for user-side customizations
512 self.hooks = Struct()
512 self.hooks = Struct()
513
513
514 self.strdispatchers = {}
514 self.strdispatchers = {}
515
515
516 # Set all default hooks, defined in the IPython.hooks module.
516 # Set all default hooks, defined in the IPython.hooks module.
517 hooks = IPython.core.hooks
517 hooks = IPython.core.hooks
518 for hook_name in hooks.__all__:
518 for hook_name in hooks.__all__:
519 # default hooks have priority 100, i.e. low; user hooks should have
519 # default hooks have priority 100, i.e. low; user hooks should have
520 # 0-100 priority
520 # 0-100 priority
521 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
521 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
522
522
523 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
523 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
524 """set_hook(name,hook) -> sets an internal IPython hook.
524 """set_hook(name,hook) -> sets an internal IPython hook.
525
525
526 IPython exposes some of its internal API as user-modifiable hooks. By
526 IPython exposes some of its internal API as user-modifiable hooks. By
527 adding your function to one of these hooks, you can modify IPython's
527 adding your function to one of these hooks, you can modify IPython's
528 behavior to call at runtime your own routines."""
528 behavior to call at runtime your own routines."""
529
529
530 # At some point in the future, this should validate the hook before it
530 # At some point in the future, this should validate the hook before it
531 # accepts it. Probably at least check that the hook takes the number
531 # accepts it. Probably at least check that the hook takes the number
532 # of args it's supposed to.
532 # of args it's supposed to.
533
533
534 f = new.instancemethod(hook,self,self.__class__)
534 f = new.instancemethod(hook,self,self.__class__)
535
535
536 # check if the hook is for strdispatcher first
536 # check if the hook is for strdispatcher first
537 if str_key is not None:
537 if str_key is not None:
538 sdp = self.strdispatchers.get(name, StrDispatch())
538 sdp = self.strdispatchers.get(name, StrDispatch())
539 sdp.add_s(str_key, f, priority )
539 sdp.add_s(str_key, f, priority )
540 self.strdispatchers[name] = sdp
540 self.strdispatchers[name] = sdp
541 return
541 return
542 if re_key is not None:
542 if re_key is not None:
543 sdp = self.strdispatchers.get(name, StrDispatch())
543 sdp = self.strdispatchers.get(name, StrDispatch())
544 sdp.add_re(re.compile(re_key), f, priority )
544 sdp.add_re(re.compile(re_key), f, priority )
545 self.strdispatchers[name] = sdp
545 self.strdispatchers[name] = sdp
546 return
546 return
547
547
548 dp = getattr(self.hooks, name, None)
548 dp = getattr(self.hooks, name, None)
549 if name not in IPython.core.hooks.__all__:
549 if name not in IPython.core.hooks.__all__:
550 print "Warning! Hook '%s' is not one of %s" % (name, IPython.core.hooks.__all__ )
550 print "Warning! Hook '%s' is not one of %s" % (name, IPython.core.hooks.__all__ )
551 if not dp:
551 if not dp:
552 dp = IPython.core.hooks.CommandChainDispatcher()
552 dp = IPython.core.hooks.CommandChainDispatcher()
553
553
554 try:
554 try:
555 dp.add(f,priority)
555 dp.add(f,priority)
556 except AttributeError:
556 except AttributeError:
557 # it was not commandchain, plain old func - replace
557 # it was not commandchain, plain old func - replace
558 dp = f
558 dp = f
559
559
560 setattr(self.hooks,name, dp)
560 setattr(self.hooks,name, dp)
561
561
562 #-------------------------------------------------------------------------
562 #-------------------------------------------------------------------------
563 # Things related to the "main" module
563 # Things related to the "main" module
564 #-------------------------------------------------------------------------
564 #-------------------------------------------------------------------------
565
565
566 def new_main_mod(self,ns=None):
566 def new_main_mod(self,ns=None):
567 """Return a new 'main' module object for user code execution.
567 """Return a new 'main' module object for user code execution.
568 """
568 """
569 main_mod = self._user_main_module
569 main_mod = self._user_main_module
570 init_fakemod_dict(main_mod,ns)
570 init_fakemod_dict(main_mod,ns)
571 return main_mod
571 return main_mod
572
572
573 def cache_main_mod(self,ns,fname):
573 def cache_main_mod(self,ns,fname):
574 """Cache a main module's namespace.
574 """Cache a main module's namespace.
575
575
576 When scripts are executed via %run, we must keep a reference to the
576 When scripts are executed via %run, we must keep a reference to the
577 namespace of their __main__ module (a FakeModule instance) around so
577 namespace of their __main__ module (a FakeModule instance) around so
578 that Python doesn't clear it, rendering objects defined therein
578 that Python doesn't clear it, rendering objects defined therein
579 useless.
579 useless.
580
580
581 This method keeps said reference in a private dict, keyed by the
581 This method keeps said reference in a private dict, keyed by the
582 absolute path of the module object (which corresponds to the script
582 absolute path of the module object (which corresponds to the script
583 path). This way, for multiple executions of the same script we only
583 path). This way, for multiple executions of the same script we only
584 keep one copy of the namespace (the last one), thus preventing memory
584 keep one copy of the namespace (the last one), thus preventing memory
585 leaks from old references while allowing the objects from the last
585 leaks from old references while allowing the objects from the last
586 execution to be accessible.
586 execution to be accessible.
587
587
588 Note: we can not allow the actual FakeModule instances to be deleted,
588 Note: we can not allow the actual FakeModule instances to be deleted,
589 because of how Python tears down modules (it hard-sets all their
589 because of how Python tears down modules (it hard-sets all their
590 references to None without regard for reference counts). This method
590 references to None without regard for reference counts). This method
591 must therefore make a *copy* of the given namespace, to allow the
591 must therefore make a *copy* of the given namespace, to allow the
592 original module's __dict__ to be cleared and reused.
592 original module's __dict__ to be cleared and reused.
593
593
594
594
595 Parameters
595 Parameters
596 ----------
596 ----------
597 ns : a namespace (a dict, typically)
597 ns : a namespace (a dict, typically)
598
598
599 fname : str
599 fname : str
600 Filename associated with the namespace.
600 Filename associated with the namespace.
601
601
602 Examples
602 Examples
603 --------
603 --------
604
604
605 In [10]: import IPython
605 In [10]: import IPython
606
606
607 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
607 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
608
608
609 In [12]: IPython.__file__ in _ip._main_ns_cache
609 In [12]: IPython.__file__ in _ip._main_ns_cache
610 Out[12]: True
610 Out[12]: True
611 """
611 """
612 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
612 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
613
613
614 def clear_main_mod_cache(self):
614 def clear_main_mod_cache(self):
615 """Clear the cache of main modules.
615 """Clear the cache of main modules.
616
616
617 Mainly for use by utilities like %reset.
617 Mainly for use by utilities like %reset.
618
618
619 Examples
619 Examples
620 --------
620 --------
621
621
622 In [15]: import IPython
622 In [15]: import IPython
623
623
624 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
624 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
625
625
626 In [17]: len(_ip._main_ns_cache) > 0
626 In [17]: len(_ip._main_ns_cache) > 0
627 Out[17]: True
627 Out[17]: True
628
628
629 In [18]: _ip.clear_main_mod_cache()
629 In [18]: _ip.clear_main_mod_cache()
630
630
631 In [19]: len(_ip._main_ns_cache) == 0
631 In [19]: len(_ip._main_ns_cache) == 0
632 Out[19]: True
632 Out[19]: True
633 """
633 """
634 self._main_ns_cache.clear()
634 self._main_ns_cache.clear()
635
635
636 #-------------------------------------------------------------------------
636 #-------------------------------------------------------------------------
637 # Things related to debugging
637 # Things related to debugging
638 #-------------------------------------------------------------------------
638 #-------------------------------------------------------------------------
639
639
640 def init_pdb(self):
640 def init_pdb(self):
641 # Set calling of pdb on exceptions
641 # Set calling of pdb on exceptions
642 # self.call_pdb is a property
642 # self.call_pdb is a property
643 self.call_pdb = self.pdb
643 self.call_pdb = self.pdb
644
644
645 def _get_call_pdb(self):
645 def _get_call_pdb(self):
646 return self._call_pdb
646 return self._call_pdb
647
647
648 def _set_call_pdb(self,val):
648 def _set_call_pdb(self,val):
649
649
650 if val not in (0,1,False,True):
650 if val not in (0,1,False,True):
651 raise ValueError,'new call_pdb value must be boolean'
651 raise ValueError,'new call_pdb value must be boolean'
652
652
653 # store value in instance
653 # store value in instance
654 self._call_pdb = val
654 self._call_pdb = val
655
655
656 # notify the actual exception handlers
656 # notify the actual exception handlers
657 self.InteractiveTB.call_pdb = val
657 self.InteractiveTB.call_pdb = val
658
658
659 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
659 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
660 'Control auto-activation of pdb at exceptions')
660 'Control auto-activation of pdb at exceptions')
661
661
662 def debugger(self,force=False):
662 def debugger(self,force=False):
663 """Call the pydb/pdb debugger.
663 """Call the pydb/pdb debugger.
664
664
665 Keywords:
665 Keywords:
666
666
667 - force(False): by default, this routine checks the instance call_pdb
667 - force(False): by default, this routine checks the instance call_pdb
668 flag and does not actually invoke the debugger if the flag is false.
668 flag and does not actually invoke the debugger if the flag is false.
669 The 'force' option forces the debugger to activate even if the flag
669 The 'force' option forces the debugger to activate even if the flag
670 is false.
670 is false.
671 """
671 """
672
672
673 if not (force or self.call_pdb):
673 if not (force or self.call_pdb):
674 return
674 return
675
675
676 if not hasattr(sys,'last_traceback'):
676 if not hasattr(sys,'last_traceback'):
677 error('No traceback has been produced, nothing to debug.')
677 error('No traceback has been produced, nothing to debug.')
678 return
678 return
679
679
680 # use pydb if available
680 # use pydb if available
681 if debugger.has_pydb:
681 if debugger.has_pydb:
682 from pydb import pm
682 from pydb import pm
683 else:
683 else:
684 # fallback to our internal debugger
684 # fallback to our internal debugger
685 pm = lambda : self.InteractiveTB.debugger(force=True)
685 pm = lambda : self.InteractiveTB.debugger(force=True)
686 self.history_saving_wrapper(pm)()
686 self.history_saving_wrapper(pm)()
687
687
688 #-------------------------------------------------------------------------
688 #-------------------------------------------------------------------------
689 # Things related to IPython's various namespaces
689 # Things related to IPython's various namespaces
690 #-------------------------------------------------------------------------
690 #-------------------------------------------------------------------------
691
691
692 def init_create_namespaces(self, user_ns=None, user_global_ns=None):
692 def init_create_namespaces(self, user_ns=None, user_global_ns=None):
693 # Create the namespace where the user will operate. user_ns is
693 # Create the namespace where the user will operate. user_ns is
694 # normally the only one used, and it is passed to the exec calls as
694 # normally the only one used, and it is passed to the exec calls as
695 # the locals argument. But we do carry a user_global_ns namespace
695 # the locals argument. But we do carry a user_global_ns namespace
696 # given as the exec 'globals' argument, This is useful in embedding
696 # given as the exec 'globals' argument, This is useful in embedding
697 # situations where the ipython shell opens in a context where the
697 # situations where the ipython shell opens in a context where the
698 # distinction between locals and globals is meaningful. For
698 # distinction between locals and globals is meaningful. For
699 # non-embedded contexts, it is just the same object as the user_ns dict.
699 # non-embedded contexts, it is just the same object as the user_ns dict.
700
700
701 # FIXME. For some strange reason, __builtins__ is showing up at user
701 # FIXME. For some strange reason, __builtins__ is showing up at user
702 # level as a dict instead of a module. This is a manual fix, but I
702 # level as a dict instead of a module. This is a manual fix, but I
703 # should really track down where the problem is coming from. Alex
703 # should really track down where the problem is coming from. Alex
704 # Schmolck reported this problem first.
704 # Schmolck reported this problem first.
705
705
706 # A useful post by Alex Martelli on this topic:
706 # A useful post by Alex Martelli on this topic:
707 # Re: inconsistent value from __builtins__
707 # Re: inconsistent value from __builtins__
708 # Von: Alex Martelli <aleaxit@yahoo.com>
708 # Von: Alex Martelli <aleaxit@yahoo.com>
709 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
709 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
710 # Gruppen: comp.lang.python
710 # Gruppen: comp.lang.python
711
711
712 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
712 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
713 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
713 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
714 # > <type 'dict'>
714 # > <type 'dict'>
715 # > >>> print type(__builtins__)
715 # > >>> print type(__builtins__)
716 # > <type 'module'>
716 # > <type 'module'>
717 # > Is this difference in return value intentional?
717 # > Is this difference in return value intentional?
718
718
719 # Well, it's documented that '__builtins__' can be either a dictionary
719 # Well, it's documented that '__builtins__' can be either a dictionary
720 # or a module, and it's been that way for a long time. Whether it's
720 # or a module, and it's been that way for a long time. Whether it's
721 # intentional (or sensible), I don't know. In any case, the idea is
721 # intentional (or sensible), I don't know. In any case, the idea is
722 # that if you need to access the built-in namespace directly, you
722 # that if you need to access the built-in namespace directly, you
723 # should start with "import __builtin__" (note, no 's') which will
723 # should start with "import __builtin__" (note, no 's') which will
724 # definitely give you a module. Yeah, it's somewhat confusing:-(.
724 # definitely give you a module. Yeah, it's somewhat confusing:-(.
725
725
726 # These routines return properly built dicts as needed by the rest of
726 # These routines return properly built dicts as needed by the rest of
727 # the code, and can also be used by extension writers to generate
727 # the code, and can also be used by extension writers to generate
728 # properly initialized namespaces.
728 # properly initialized namespaces.
729 user_ns, user_global_ns = self.make_user_namespaces(user_ns, user_global_ns)
729 user_ns, user_global_ns = self.make_user_namespaces(user_ns, user_global_ns)
730
730
731 # Assign namespaces
731 # Assign namespaces
732 # This is the namespace where all normal user variables live
732 # This is the namespace where all normal user variables live
733 self.user_ns = user_ns
733 self.user_ns = user_ns
734 self.user_global_ns = user_global_ns
734 self.user_global_ns = user_global_ns
735
735
736 # An auxiliary namespace that checks what parts of the user_ns were
736 # An auxiliary namespace that checks what parts of the user_ns were
737 # loaded at startup, so we can list later only variables defined in
737 # loaded at startup, so we can list later only variables defined in
738 # actual interactive use. Since it is always a subset of user_ns, it
738 # actual interactive use. Since it is always a subset of user_ns, it
739 # doesn't need to be separately tracked in the ns_table.
739 # doesn't need to be separately tracked in the ns_table.
740 self.user_ns_hidden = {}
740 self.user_ns_hidden = {}
741
741
742 # A namespace to keep track of internal data structures to prevent
742 # A namespace to keep track of internal data structures to prevent
743 # them from cluttering user-visible stuff. Will be updated later
743 # them from cluttering user-visible stuff. Will be updated later
744 self.internal_ns = {}
744 self.internal_ns = {}
745
745
746 # Now that FakeModule produces a real module, we've run into a nasty
746 # Now that FakeModule produces a real module, we've run into a nasty
747 # problem: after script execution (via %run), the module where the user
747 # problem: after script execution (via %run), the module where the user
748 # code ran is deleted. Now that this object is a true module (needed
748 # code ran is deleted. Now that this object is a true module (needed
749 # so docetst and other tools work correctly), the Python module
749 # so docetst and other tools work correctly), the Python module
750 # teardown mechanism runs over it, and sets to None every variable
750 # teardown mechanism runs over it, and sets to None every variable
751 # present in that module. Top-level references to objects from the
751 # present in that module. Top-level references to objects from the
752 # script survive, because the user_ns is updated with them. However,
752 # script survive, because the user_ns is updated with them. However,
753 # calling functions defined in the script that use other things from
753 # calling functions defined in the script that use other things from
754 # the script will fail, because the function's closure had references
754 # the script will fail, because the function's closure had references
755 # to the original objects, which are now all None. So we must protect
755 # to the original objects, which are now all None. So we must protect
756 # these modules from deletion by keeping a cache.
756 # these modules from deletion by keeping a cache.
757 #
757 #
758 # To avoid keeping stale modules around (we only need the one from the
758 # To avoid keeping stale modules around (we only need the one from the
759 # last run), we use a dict keyed with the full path to the script, so
759 # last run), we use a dict keyed with the full path to the script, so
760 # only the last version of the module is held in the cache. Note,
760 # only the last version of the module is held in the cache. Note,
761 # however, that we must cache the module *namespace contents* (their
761 # however, that we must cache the module *namespace contents* (their
762 # __dict__). Because if we try to cache the actual modules, old ones
762 # __dict__). Because if we try to cache the actual modules, old ones
763 # (uncached) could be destroyed while still holding references (such as
763 # (uncached) could be destroyed while still holding references (such as
764 # those held by GUI objects that tend to be long-lived)>
764 # those held by GUI objects that tend to be long-lived)>
765 #
765 #
766 # The %reset command will flush this cache. See the cache_main_mod()
766 # The %reset command will flush this cache. See the cache_main_mod()
767 # and clear_main_mod_cache() methods for details on use.
767 # and clear_main_mod_cache() methods for details on use.
768
768
769 # This is the cache used for 'main' namespaces
769 # This is the cache used for 'main' namespaces
770 self._main_ns_cache = {}
770 self._main_ns_cache = {}
771 # And this is the single instance of FakeModule whose __dict__ we keep
771 # And this is the single instance of FakeModule whose __dict__ we keep
772 # copying and clearing for reuse on each %run
772 # copying and clearing for reuse on each %run
773 self._user_main_module = FakeModule()
773 self._user_main_module = FakeModule()
774
774
775 # A table holding all the namespaces IPython deals with, so that
775 # A table holding all the namespaces IPython deals with, so that
776 # introspection facilities can search easily.
776 # introspection facilities can search easily.
777 self.ns_table = {'user':user_ns,
777 self.ns_table = {'user':user_ns,
778 'user_global':user_global_ns,
778 'user_global':user_global_ns,
779 'internal':self.internal_ns,
779 'internal':self.internal_ns,
780 'builtin':__builtin__.__dict__
780 'builtin':__builtin__.__dict__
781 }
781 }
782
782
783 # Similarly, track all namespaces where references can be held and that
783 # Similarly, track all namespaces where references can be held and that
784 # we can safely clear (so it can NOT include builtin). This one can be
784 # we can safely clear (so it can NOT include builtin). This one can be
785 # a simple list.
785 # a simple list.
786 self.ns_refs_table = [ user_ns, user_global_ns, self.user_ns_hidden,
786 self.ns_refs_table = [ user_ns, user_global_ns, self.user_ns_hidden,
787 self.internal_ns, self._main_ns_cache ]
787 self.internal_ns, self._main_ns_cache ]
788
788
789 def make_user_namespaces(self, user_ns=None, user_global_ns=None):
789 def make_user_namespaces(self, user_ns=None, user_global_ns=None):
790 """Return a valid local and global user interactive namespaces.
790 """Return a valid local and global user interactive namespaces.
791
791
792 This builds a dict with the minimal information needed to operate as a
792 This builds a dict with the minimal information needed to operate as a
793 valid IPython user namespace, which you can pass to the various
793 valid IPython user namespace, which you can pass to the various
794 embedding classes in ipython. The default implementation returns the
794 embedding classes in ipython. The default implementation returns the
795 same dict for both the locals and the globals to allow functions to
795 same dict for both the locals and the globals to allow functions to
796 refer to variables in the namespace. Customized implementations can
796 refer to variables in the namespace. Customized implementations can
797 return different dicts. The locals dictionary can actually be anything
797 return different dicts. The locals dictionary can actually be anything
798 following the basic mapping protocol of a dict, but the globals dict
798 following the basic mapping protocol of a dict, but the globals dict
799 must be a true dict, not even a subclass. It is recommended that any
799 must be a true dict, not even a subclass. It is recommended that any
800 custom object for the locals namespace synchronize with the globals
800 custom object for the locals namespace synchronize with the globals
801 dict somehow.
801 dict somehow.
802
802
803 Raises TypeError if the provided globals namespace is not a true dict.
803 Raises TypeError if the provided globals namespace is not a true dict.
804
804
805 Parameters
805 Parameters
806 ----------
806 ----------
807 user_ns : dict-like, optional
807 user_ns : dict-like, optional
808 The current user namespace. The items in this namespace should
808 The current user namespace. The items in this namespace should
809 be included in the output. If None, an appropriate blank
809 be included in the output. If None, an appropriate blank
810 namespace should be created.
810 namespace should be created.
811 user_global_ns : dict, optional
811 user_global_ns : dict, optional
812 The current user global namespace. The items in this namespace
812 The current user global namespace. The items in this namespace
813 should be included in the output. If None, an appropriate
813 should be included in the output. If None, an appropriate
814 blank namespace should be created.
814 blank namespace should be created.
815
815
816 Returns
816 Returns
817 -------
817 -------
818 A pair of dictionary-like object to be used as the local namespace
818 A pair of dictionary-like object to be used as the local namespace
819 of the interpreter and a dict to be used as the global namespace.
819 of the interpreter and a dict to be used as the global namespace.
820 """
820 """
821
821
822
822
823 # We must ensure that __builtin__ (without the final 's') is always
823 # We must ensure that __builtin__ (without the final 's') is always
824 # available and pointing to the __builtin__ *module*. For more details:
824 # available and pointing to the __builtin__ *module*. For more details:
825 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
825 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
826
826
827 if user_ns is None:
827 if user_ns is None:
828 # Set __name__ to __main__ to better match the behavior of the
828 # Set __name__ to __main__ to better match the behavior of the
829 # normal interpreter.
829 # normal interpreter.
830 user_ns = {'__name__' :'__main__',
830 user_ns = {'__name__' :'__main__',
831 '__builtin__' : __builtin__,
831 '__builtin__' : __builtin__,
832 '__builtins__' : __builtin__,
832 '__builtins__' : __builtin__,
833 }
833 }
834 else:
834 else:
835 user_ns.setdefault('__name__','__main__')
835 user_ns.setdefault('__name__','__main__')
836 user_ns.setdefault('__builtin__',__builtin__)
836 user_ns.setdefault('__builtin__',__builtin__)
837 user_ns.setdefault('__builtins__',__builtin__)
837 user_ns.setdefault('__builtins__',__builtin__)
838
838
839 if user_global_ns is None:
839 if user_global_ns is None:
840 user_global_ns = user_ns
840 user_global_ns = user_ns
841 if type(user_global_ns) is not dict:
841 if type(user_global_ns) is not dict:
842 raise TypeError("user_global_ns must be a true dict; got %r"
842 raise TypeError("user_global_ns must be a true dict; got %r"
843 % type(user_global_ns))
843 % type(user_global_ns))
844
844
845 return user_ns, user_global_ns
845 return user_ns, user_global_ns
846
846
847 def init_sys_modules(self):
847 def init_sys_modules(self):
848 # We need to insert into sys.modules something that looks like a
848 # We need to insert into sys.modules something that looks like a
849 # module but which accesses the IPython namespace, for shelve and
849 # module but which accesses the IPython namespace, for shelve and
850 # pickle to work interactively. Normally they rely on getting
850 # pickle to work interactively. Normally they rely on getting
851 # everything out of __main__, but for embedding purposes each IPython
851 # everything out of __main__, but for embedding purposes each IPython
852 # instance has its own private namespace, so we can't go shoving
852 # instance has its own private namespace, so we can't go shoving
853 # everything into __main__.
853 # everything into __main__.
854
854
855 # note, however, that we should only do this for non-embedded
855 # note, however, that we should only do this for non-embedded
856 # ipythons, which really mimic the __main__.__dict__ with their own
856 # ipythons, which really mimic the __main__.__dict__ with their own
857 # namespace. Embedded instances, on the other hand, should not do
857 # namespace. Embedded instances, on the other hand, should not do
858 # this because they need to manage the user local/global namespaces
858 # this because they need to manage the user local/global namespaces
859 # only, but they live within a 'normal' __main__ (meaning, they
859 # only, but they live within a 'normal' __main__ (meaning, they
860 # shouldn't overtake the execution environment of the script they're
860 # shouldn't overtake the execution environment of the script they're
861 # embedded in).
861 # embedded in).
862
862
863 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
863 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
864
864
865 try:
865 try:
866 main_name = self.user_ns['__name__']
866 main_name = self.user_ns['__name__']
867 except KeyError:
867 except KeyError:
868 raise KeyError('user_ns dictionary MUST have a "__name__" key')
868 raise KeyError('user_ns dictionary MUST have a "__name__" key')
869 else:
869 else:
870 sys.modules[main_name] = FakeModule(self.user_ns)
870 sys.modules[main_name] = FakeModule(self.user_ns)
871
871
872 def init_user_ns(self):
872 def init_user_ns(self):
873 """Initialize all user-visible namespaces to their minimum defaults.
873 """Initialize all user-visible namespaces to their minimum defaults.
874
874
875 Certain history lists are also initialized here, as they effectively
875 Certain history lists are also initialized here, as they effectively
876 act as user namespaces.
876 act as user namespaces.
877
877
878 Notes
878 Notes
879 -----
879 -----
880 All data structures here are only filled in, they are NOT reset by this
880 All data structures here are only filled in, they are NOT reset by this
881 method. If they were not empty before, data will simply be added to
881 method. If they were not empty before, data will simply be added to
882 therm.
882 therm.
883 """
883 """
884 # This function works in two parts: first we put a few things in
884 # This function works in two parts: first we put a few things in
885 # user_ns, and we sync that contents into user_ns_hidden so that these
885 # user_ns, and we sync that contents into user_ns_hidden so that these
886 # initial variables aren't shown by %who. After the sync, we add the
886 # initial variables aren't shown by %who. After the sync, we add the
887 # rest of what we *do* want the user to see with %who even on a new
887 # rest of what we *do* want the user to see with %who even on a new
888 # session (probably nothing, so theye really only see their own stuff)
888 # session (probably nothing, so theye really only see their own stuff)
889
889
890 # The user dict must *always* have a __builtin__ reference to the
890 # The user dict must *always* have a __builtin__ reference to the
891 # Python standard __builtin__ namespace, which must be imported.
891 # Python standard __builtin__ namespace, which must be imported.
892 # This is so that certain operations in prompt evaluation can be
892 # This is so that certain operations in prompt evaluation can be
893 # reliably executed with builtins. Note that we can NOT use
893 # reliably executed with builtins. Note that we can NOT use
894 # __builtins__ (note the 's'), because that can either be a dict or a
894 # __builtins__ (note the 's'), because that can either be a dict or a
895 # module, and can even mutate at runtime, depending on the context
895 # module, and can even mutate at runtime, depending on the context
896 # (Python makes no guarantees on it). In contrast, __builtin__ is
896 # (Python makes no guarantees on it). In contrast, __builtin__ is
897 # always a module object, though it must be explicitly imported.
897 # always a module object, though it must be explicitly imported.
898
898
899 # For more details:
899 # For more details:
900 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
900 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
901 ns = dict(__builtin__ = __builtin__)
901 ns = dict(__builtin__ = __builtin__)
902
902
903 # Put 'help' in the user namespace
903 # Put 'help' in the user namespace
904 try:
904 try:
905 from site import _Helper
905 from site import _Helper
906 ns['help'] = _Helper()
906 ns['help'] = _Helper()
907 except ImportError:
907 except ImportError:
908 warn('help() not available - check site.py')
908 warn('help() not available - check site.py')
909
909
910 # make global variables for user access to the histories
910 # make global variables for user access to the histories
911 ns['_ih'] = self.input_hist
911 ns['_ih'] = self.input_hist
912 ns['_oh'] = self.output_hist
912 ns['_oh'] = self.output_hist
913 ns['_dh'] = self.dir_hist
913 ns['_dh'] = self.dir_hist
914
914
915 ns['_sh'] = shadowns
915 ns['_sh'] = shadowns
916
916
917 # user aliases to input and output histories. These shouldn't show up
917 # user aliases to input and output histories. These shouldn't show up
918 # in %who, as they can have very large reprs.
918 # in %who, as they can have very large reprs.
919 ns['In'] = self.input_hist
919 ns['In'] = self.input_hist
920 ns['Out'] = self.output_hist
920 ns['Out'] = self.output_hist
921
921
922 # Store myself as the public api!!!
922 # Store myself as the public api!!!
923 ns['get_ipython'] = self.get_ipython
923 ns['get_ipython'] = self.get_ipython
924
924
925 # Sync what we've added so far to user_ns_hidden so these aren't seen
925 # Sync what we've added so far to user_ns_hidden so these aren't seen
926 # by %who
926 # by %who
927 self.user_ns_hidden.update(ns)
927 self.user_ns_hidden.update(ns)
928
928
929 # Anything put into ns now would show up in %who. Think twice before
929 # Anything put into ns now would show up in %who. Think twice before
930 # putting anything here, as we really want %who to show the user their
930 # putting anything here, as we really want %who to show the user their
931 # stuff, not our variables.
931 # stuff, not our variables.
932
932
933 # Finally, update the real user's namespace
933 # Finally, update the real user's namespace
934 self.user_ns.update(ns)
934 self.user_ns.update(ns)
935
935
936
936
937 def reset(self):
937 def reset(self):
938 """Clear all internal namespaces.
938 """Clear all internal namespaces.
939
939
940 Note that this is much more aggressive than %reset, since it clears
940 Note that this is much more aggressive than %reset, since it clears
941 fully all namespaces, as well as all input/output lists.
941 fully all namespaces, as well as all input/output lists.
942 """
942 """
943 for ns in self.ns_refs_table:
943 for ns in self.ns_refs_table:
944 ns.clear()
944 ns.clear()
945
945
946 self.alias_manager.clear_aliases()
946 self.alias_manager.clear_aliases()
947
947
948 # Clear input and output histories
948 # Clear input and output histories
949 self.input_hist[:] = []
949 self.input_hist[:] = []
950 self.input_hist_raw[:] = []
950 self.input_hist_raw[:] = []
951 self.output_hist.clear()
951 self.output_hist.clear()
952
952
953 # Restore the user namespaces to minimal usability
953 # Restore the user namespaces to minimal usability
954 self.init_user_ns()
954 self.init_user_ns()
955
955
956 # Restore the default and user aliases
956 # Restore the default and user aliases
957 self.alias_manager.init_aliases()
957 self.alias_manager.init_aliases()
958
958
959 def reset_selective(self, regex=None):
959 def reset_selective(self, regex=None):
960 """Clear selective variables from internal namespaces based on a specified regular expression.
960 """Clear selective variables from internal namespaces based on a specified regular expression.
961
961
962 Parameters
962 Parameters
963 ----------
963 ----------
964 regex : string or compiled pattern, optional
964 regex : string or compiled pattern, optional
965 A regular expression pattern that will be used in searching variable names in the users
965 A regular expression pattern that will be used in searching variable names in the users
966 namespaces.
966 namespaces.
967 """
967 """
968 if regex is not None:
968 if regex is not None:
969 try:
969 try:
970 m = re.compile(regex)
970 m = re.compile(regex)
971 except TypeError:
971 except TypeError:
972 raise TypeError('regex must be a string or compiled pattern')
972 raise TypeError('regex must be a string or compiled pattern')
973 # Search for keys in each namespace that match the given regex
973 # Search for keys in each namespace that match the given regex
974 # If a match is found, delete the key/value pair.
974 # If a match is found, delete the key/value pair.
975 for ns in self.ns_refs_table:
975 for ns in self.ns_refs_table:
976 for var in ns:
976 for var in ns:
977 if m.search(var):
977 if m.search(var):
978 del ns[var]
978 del ns[var]
979
979
980 def push(self, variables, interactive=True):
980 def push(self, variables, interactive=True):
981 """Inject a group of variables into the IPython user namespace.
981 """Inject a group of variables into the IPython user namespace.
982
982
983 Parameters
983 Parameters
984 ----------
984 ----------
985 variables : dict, str or list/tuple of str
985 variables : dict, str or list/tuple of str
986 The variables to inject into the user's namespace. If a dict,
986 The variables to inject into the user's namespace. If a dict,
987 a simple update is done. If a str, the string is assumed to
987 a simple update is done. If a str, the string is assumed to
988 have variable names separated by spaces. A list/tuple of str
988 have variable names separated by spaces. A list/tuple of str
989 can also be used to give the variable names. If just the variable
989 can also be used to give the variable names. If just the variable
990 names are give (list/tuple/str) then the variable values looked
990 names are give (list/tuple/str) then the variable values looked
991 up in the callers frame.
991 up in the callers frame.
992 interactive : bool
992 interactive : bool
993 If True (default), the variables will be listed with the ``who``
993 If True (default), the variables will be listed with the ``who``
994 magic.
994 magic.
995 """
995 """
996 vdict = None
996 vdict = None
997
997
998 # We need a dict of name/value pairs to do namespace updates.
998 # We need a dict of name/value pairs to do namespace updates.
999 if isinstance(variables, dict):
999 if isinstance(variables, dict):
1000 vdict = variables
1000 vdict = variables
1001 elif isinstance(variables, (basestring, list, tuple)):
1001 elif isinstance(variables, (basestring, list, tuple)):
1002 if isinstance(variables, basestring):
1002 if isinstance(variables, basestring):
1003 vlist = variables.split()
1003 vlist = variables.split()
1004 else:
1004 else:
1005 vlist = variables
1005 vlist = variables
1006 vdict = {}
1006 vdict = {}
1007 cf = sys._getframe(1)
1007 cf = sys._getframe(1)
1008 for name in vlist:
1008 for name in vlist:
1009 try:
1009 try:
1010 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1010 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1011 except:
1011 except:
1012 print ('Could not get variable %s from %s' %
1012 print ('Could not get variable %s from %s' %
1013 (name,cf.f_code.co_name))
1013 (name,cf.f_code.co_name))
1014 else:
1014 else:
1015 raise ValueError('variables must be a dict/str/list/tuple')
1015 raise ValueError('variables must be a dict/str/list/tuple')
1016
1016
1017 # Propagate variables to user namespace
1017 # Propagate variables to user namespace
1018 self.user_ns.update(vdict)
1018 self.user_ns.update(vdict)
1019
1019
1020 # And configure interactive visibility
1020 # And configure interactive visibility
1021 config_ns = self.user_ns_hidden
1021 config_ns = self.user_ns_hidden
1022 if interactive:
1022 if interactive:
1023 for name, val in vdict.iteritems():
1023 for name, val in vdict.iteritems():
1024 config_ns.pop(name, None)
1024 config_ns.pop(name, None)
1025 else:
1025 else:
1026 for name,val in vdict.iteritems():
1026 for name,val in vdict.iteritems():
1027 config_ns[name] = val
1027 config_ns[name] = val
1028
1028
1029 #-------------------------------------------------------------------------
1029 #-------------------------------------------------------------------------
1030 # Things related to history management
1030 # Things related to history management
1031 #-------------------------------------------------------------------------
1031 #-------------------------------------------------------------------------
1032
1032
1033 def init_history(self):
1033 def init_history(self):
1034 # List of input with multi-line handling.
1034 # List of input with multi-line handling.
1035 self.input_hist = InputList()
1035 self.input_hist = InputList()
1036 # This one will hold the 'raw' input history, without any
1036 # This one will hold the 'raw' input history, without any
1037 # pre-processing. This will allow users to retrieve the input just as
1037 # pre-processing. This will allow users to retrieve the input just as
1038 # it was exactly typed in by the user, with %hist -r.
1038 # it was exactly typed in by the user, with %hist -r.
1039 self.input_hist_raw = InputList()
1039 self.input_hist_raw = InputList()
1040
1040
1041 # list of visited directories
1041 # list of visited directories
1042 try:
1042 try:
1043 self.dir_hist = [os.getcwd()]
1043 self.dir_hist = [os.getcwd()]
1044 except OSError:
1044 except OSError:
1045 self.dir_hist = []
1045 self.dir_hist = []
1046
1046
1047 # dict of output history
1047 # dict of output history
1048 self.output_hist = {}
1048 self.output_hist = {}
1049
1049
1050 # Now the history file
1050 # Now the history file
1051 if self.profile:
1051 if self.profile:
1052 histfname = 'history-%s' % self.profile
1052 histfname = 'history-%s' % self.profile
1053 else:
1053 else:
1054 histfname = 'history'
1054 histfname = 'history'
1055 self.histfile = os.path.join(self.ipython_dir, histfname)
1055 self.histfile = os.path.join(self.ipython_dir, histfname)
1056
1056
1057 # Fill the history zero entry, user counter starts at 1
1057 # Fill the history zero entry, user counter starts at 1
1058 self.input_hist.append('\n')
1058 self.input_hist.append('\n')
1059 self.input_hist_raw.append('\n')
1059 self.input_hist_raw.append('\n')
1060
1060
1061 def init_shadow_hist(self):
1061 def init_shadow_hist(self):
1062 try:
1062 try:
1063 self.db = pickleshare.PickleShareDB(self.ipython_dir + "/db")
1063 self.db = pickleshare.PickleShareDB(self.ipython_dir + "/db")
1064 except exceptions.UnicodeDecodeError:
1064 except exceptions.UnicodeDecodeError:
1065 print "Your ipython_dir can't be decoded to unicode!"
1065 print "Your ipython_dir can't be decoded to unicode!"
1066 print "Please set HOME environment variable to something that"
1066 print "Please set HOME environment variable to something that"
1067 print r"only has ASCII characters, e.g. c:\home"
1067 print r"only has ASCII characters, e.g. c:\home"
1068 print "Now it is", self.ipython_dir
1068 print "Now it is", self.ipython_dir
1069 sys.exit()
1069 sys.exit()
1070 self.shadowhist = ipcorehist.ShadowHist(self.db)
1070 self.shadowhist = ipcorehist.ShadowHist(self.db)
1071
1071
1072 def savehist(self):
1072 def savehist(self):
1073 """Save input history to a file (via readline library)."""
1073 """Save input history to a file (via readline library)."""
1074
1074
1075 try:
1075 try:
1076 self.readline.write_history_file(self.histfile)
1076 self.readline.write_history_file(self.histfile)
1077 except:
1077 except:
1078 print 'Unable to save IPython command history to file: ' + \
1078 print 'Unable to save IPython command history to file: ' + \
1079 `self.histfile`
1079 `self.histfile`
1080
1080
1081 def reloadhist(self):
1081 def reloadhist(self):
1082 """Reload the input history from disk file."""
1082 """Reload the input history from disk file."""
1083
1083
1084 try:
1084 try:
1085 self.readline.clear_history()
1085 self.readline.clear_history()
1086 self.readline.read_history_file(self.shell.histfile)
1086 self.readline.read_history_file(self.shell.histfile)
1087 except AttributeError:
1087 except AttributeError:
1088 pass
1088 pass
1089
1089
1090 def history_saving_wrapper(self, func):
1090 def history_saving_wrapper(self, func):
1091 """ Wrap func for readline history saving
1091 """ Wrap func for readline history saving
1092
1092
1093 Convert func into callable that saves & restores
1093 Convert func into callable that saves & restores
1094 history around the call """
1094 history around the call """
1095
1095
1096 if self.has_readline:
1096 if self.has_readline:
1097 from IPython.utils import rlineimpl as readline
1097 from IPython.utils import rlineimpl as readline
1098 else:
1098 else:
1099 return func
1099 return func
1100
1100
1101 def wrapper():
1101 def wrapper():
1102 self.savehist()
1102 self.savehist()
1103 try:
1103 try:
1104 func()
1104 func()
1105 finally:
1105 finally:
1106 readline.read_history_file(self.histfile)
1106 readline.read_history_file(self.histfile)
1107 return wrapper
1107 return wrapper
1108
1108
1109 def get_history(self, index=None, raw=False, output=True):
1109 def get_history(self, index=None, raw=False, output=True):
1110 """Get the history list.
1110 """Get the history list.
1111
1111
1112 Get the input and output history.
1112 Get the input and output history.
1113
1113
1114 Parameters
1114 Parameters
1115 ----------
1115 ----------
1116 index : n or (n1, n2) or None
1116 index : n or (n1, n2) or None
1117 If n, then the last entries. If a tuple, then all in
1117 If n, then the last entries. If a tuple, then all in
1118 range(n1, n2). If None, then all entries. Raises IndexError if
1118 range(n1, n2). If None, then all entries. Raises IndexError if
1119 the format of index is incorrect.
1119 the format of index is incorrect.
1120 raw : bool
1120 raw : bool
1121 If True, return the raw input.
1121 If True, return the raw input.
1122 output : bool
1122 output : bool
1123 If True, then return the output as well.
1123 If True, then return the output as well.
1124
1124
1125 Returns
1125 Returns
1126 -------
1126 -------
1127 If output is True, then return a dict of tuples, keyed by the prompt
1127 If output is True, then return a dict of tuples, keyed by the prompt
1128 numbers and with values of (input, output). If output is False, then
1128 numbers and with values of (input, output). If output is False, then
1129 a dict, keyed by the prompt number with the values of input. Raises
1129 a dict, keyed by the prompt number with the values of input. Raises
1130 IndexError if no history is found.
1130 IndexError if no history is found.
1131 """
1131 """
1132 if raw:
1132 if raw:
1133 input_hist = self.input_hist_raw
1133 input_hist = self.input_hist_raw
1134 else:
1134 else:
1135 input_hist = self.input_hist
1135 input_hist = self.input_hist
1136 if output:
1136 if output:
1137 output_hist = self.user_ns['Out']
1137 output_hist = self.user_ns['Out']
1138 n = len(input_hist)
1138 n = len(input_hist)
1139 if index is None:
1139 if index is None:
1140 start=0; stop=n
1140 start=0; stop=n
1141 elif isinstance(index, int):
1141 elif isinstance(index, int):
1142 start=n-index; stop=n
1142 start=n-index; stop=n
1143 elif isinstance(index, tuple) and len(index) == 2:
1143 elif isinstance(index, tuple) and len(index) == 2:
1144 start=index[0]; stop=index[1]
1144 start=index[0]; stop=index[1]
1145 else:
1145 else:
1146 raise IndexError('Not a valid index for the input history: %r' % index)
1146 raise IndexError('Not a valid index for the input history: %r' % index)
1147 hist = {}
1147 hist = {}
1148 for i in range(start, stop):
1148 for i in range(start, stop):
1149 if output:
1149 if output:
1150 hist[i] = (input_hist[i], output_hist.get(i))
1150 hist[i] = (input_hist[i], output_hist.get(i))
1151 else:
1151 else:
1152 hist[i] = input_hist[i]
1152 hist[i] = input_hist[i]
1153 if len(hist)==0:
1153 if len(hist)==0:
1154 raise IndexError('No history for range of indices: %r' % index)
1154 raise IndexError('No history for range of indices: %r' % index)
1155 return hist
1155 return hist
1156
1156
1157 #-------------------------------------------------------------------------
1157 #-------------------------------------------------------------------------
1158 # Things related to exception handling and tracebacks (not debugging)
1158 # Things related to exception handling and tracebacks (not debugging)
1159 #-------------------------------------------------------------------------
1159 #-------------------------------------------------------------------------
1160
1160
1161 def init_traceback_handlers(self, custom_exceptions):
1161 def init_traceback_handlers(self, custom_exceptions):
1162 # Syntax error handler.
1162 # Syntax error handler.
1163 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor')
1163 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor')
1164
1164
1165 # The interactive one is initialized with an offset, meaning we always
1165 # The interactive one is initialized with an offset, meaning we always
1166 # want to remove the topmost item in the traceback, which is our own
1166 # want to remove the topmost item in the traceback, which is our own
1167 # internal code. Valid modes: ['Plain','Context','Verbose']
1167 # internal code. Valid modes: ['Plain','Context','Verbose']
1168 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1168 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1169 color_scheme='NoColor',
1169 color_scheme='NoColor',
1170 tb_offset = 1)
1170 tb_offset = 1)
1171
1171
1172 # The instance will store a pointer to the system-wide exception hook,
1172 # The instance will store a pointer to the system-wide exception hook,
1173 # so that runtime code (such as magics) can access it. This is because
1173 # so that runtime code (such as magics) can access it. This is because
1174 # during the read-eval loop, it may get temporarily overwritten.
1174 # during the read-eval loop, it may get temporarily overwritten.
1175 self.sys_excepthook = sys.excepthook
1175 self.sys_excepthook = sys.excepthook
1176
1176
1177 # and add any custom exception handlers the user may have specified
1177 # and add any custom exception handlers the user may have specified
1178 self.set_custom_exc(*custom_exceptions)
1178 self.set_custom_exc(*custom_exceptions)
1179
1179
1180 # Set the exception mode
1180 # Set the exception mode
1181 self.InteractiveTB.set_mode(mode=self.xmode)
1181 self.InteractiveTB.set_mode(mode=self.xmode)
1182
1182
1183 def set_custom_exc(self, exc_tuple, handler):
1183 def set_custom_exc(self, exc_tuple, handler):
1184 """set_custom_exc(exc_tuple,handler)
1184 """set_custom_exc(exc_tuple,handler)
1185
1185
1186 Set a custom exception handler, which will be called if any of the
1186 Set a custom exception handler, which will be called if any of the
1187 exceptions in exc_tuple occur in the mainloop (specifically, in the
1187 exceptions in exc_tuple occur in the mainloop (specifically, in the
1188 runcode() method.
1188 runcode() method.
1189
1189
1190 Inputs:
1190 Inputs:
1191
1191
1192 - exc_tuple: a *tuple* of valid exceptions to call the defined
1192 - exc_tuple: a *tuple* of valid exceptions to call the defined
1193 handler for. It is very important that you use a tuple, and NOT A
1193 handler for. It is very important that you use a tuple, and NOT A
1194 LIST here, because of the way Python's except statement works. If
1194 LIST here, because of the way Python's except statement works. If
1195 you only want to trap a single exception, use a singleton tuple:
1195 you only want to trap a single exception, use a singleton tuple:
1196
1196
1197 exc_tuple == (MyCustomException,)
1197 exc_tuple == (MyCustomException,)
1198
1198
1199 - handler: this must be defined as a function with the following
1199 - handler: this must be defined as a function with the following
1200 basic interface::
1200 basic interface::
1201
1201
1202 def my_handler(self, etype, value, tb, tb_offset=None)
1202 def my_handler(self, etype, value, tb, tb_offset=None)
1203 ...
1203 ...
1204 # The return value must be
1204 # The return value must be
1205 return structured_traceback
1205 return structured_traceback
1206
1206
1207 This will be made into an instance method (via new.instancemethod)
1207 This will be made into an instance method (via new.instancemethod)
1208 of IPython itself, and it will be called if any of the exceptions
1208 of IPython itself, and it will be called if any of the exceptions
1209 listed in the exc_tuple are caught. If the handler is None, an
1209 listed in the exc_tuple are caught. If the handler is None, an
1210 internal basic one is used, which just prints basic info.
1210 internal basic one is used, which just prints basic info.
1211
1211
1212 WARNING: by putting in your own exception handler into IPython's main
1212 WARNING: by putting in your own exception handler into IPython's main
1213 execution loop, you run a very good chance of nasty crashes. This
1213 execution loop, you run a very good chance of nasty crashes. This
1214 facility should only be used if you really know what you are doing."""
1214 facility should only be used if you really know what you are doing."""
1215
1215
1216 assert type(exc_tuple)==type(()) , \
1216 assert type(exc_tuple)==type(()) , \
1217 "The custom exceptions must be given AS A TUPLE."
1217 "The custom exceptions must be given AS A TUPLE."
1218
1218
1219 def dummy_handler(self,etype,value,tb):
1219 def dummy_handler(self,etype,value,tb):
1220 print '*** Simple custom exception handler ***'
1220 print '*** Simple custom exception handler ***'
1221 print 'Exception type :',etype
1221 print 'Exception type :',etype
1222 print 'Exception value:',value
1222 print 'Exception value:',value
1223 print 'Traceback :',tb
1223 print 'Traceback :',tb
1224 print 'Source code :','\n'.join(self.buffer)
1224 print 'Source code :','\n'.join(self.buffer)
1225
1225
1226 if handler is None: handler = dummy_handler
1226 if handler is None: handler = dummy_handler
1227
1227
1228 self.CustomTB = new.instancemethod(handler,self,self.__class__)
1228 self.CustomTB = new.instancemethod(handler,self,self.__class__)
1229 self.custom_exceptions = exc_tuple
1229 self.custom_exceptions = exc_tuple
1230
1230
1231 def excepthook(self, etype, value, tb):
1231 def excepthook(self, etype, value, tb):
1232 """One more defense for GUI apps that call sys.excepthook.
1232 """One more defense for GUI apps that call sys.excepthook.
1233
1233
1234 GUI frameworks like wxPython trap exceptions and call
1234 GUI frameworks like wxPython trap exceptions and call
1235 sys.excepthook themselves. I guess this is a feature that
1235 sys.excepthook themselves. I guess this is a feature that
1236 enables them to keep running after exceptions that would
1236 enables them to keep running after exceptions that would
1237 otherwise kill their mainloop. This is a bother for IPython
1237 otherwise kill their mainloop. This is a bother for IPython
1238 which excepts to catch all of the program exceptions with a try:
1238 which excepts to catch all of the program exceptions with a try:
1239 except: statement.
1239 except: statement.
1240
1240
1241 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1241 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1242 any app directly invokes sys.excepthook, it will look to the user like
1242 any app directly invokes sys.excepthook, it will look to the user like
1243 IPython crashed. In order to work around this, we can disable the
1243 IPython crashed. In order to work around this, we can disable the
1244 CrashHandler and replace it with this excepthook instead, which prints a
1244 CrashHandler and replace it with this excepthook instead, which prints a
1245 regular traceback using our InteractiveTB. In this fashion, apps which
1245 regular traceback using our InteractiveTB. In this fashion, apps which
1246 call sys.excepthook will generate a regular-looking exception from
1246 call sys.excepthook will generate a regular-looking exception from
1247 IPython, and the CrashHandler will only be triggered by real IPython
1247 IPython, and the CrashHandler will only be triggered by real IPython
1248 crashes.
1248 crashes.
1249
1249
1250 This hook should be used sparingly, only in places which are not likely
1250 This hook should be used sparingly, only in places which are not likely
1251 to be true IPython errors.
1251 to be true IPython errors.
1252 """
1252 """
1253 self.showtraceback((etype,value,tb),tb_offset=0)
1253 self.showtraceback((etype,value,tb),tb_offset=0)
1254
1254
1255 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None,
1255 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None,
1256 exception_only=False):
1256 exception_only=False):
1257 """Display the exception that just occurred.
1257 """Display the exception that just occurred.
1258
1258
1259 If nothing is known about the exception, this is the method which
1259 If nothing is known about the exception, this is the method which
1260 should be used throughout the code for presenting user tracebacks,
1260 should be used throughout the code for presenting user tracebacks,
1261 rather than directly invoking the InteractiveTB object.
1261 rather than directly invoking the InteractiveTB object.
1262
1262
1263 A specific showsyntaxerror() also exists, but this method can take
1263 A specific showsyntaxerror() also exists, but this method can take
1264 care of calling it if needed, so unless you are explicitly catching a
1264 care of calling it if needed, so unless you are explicitly catching a
1265 SyntaxError exception, don't try to analyze the stack manually and
1265 SyntaxError exception, don't try to analyze the stack manually and
1266 simply call this method."""
1266 simply call this method."""
1267
1267
1268 try:
1268 try:
1269 if exc_tuple is None:
1269 if exc_tuple is None:
1270 etype, value, tb = sys.exc_info()
1270 etype, value, tb = sys.exc_info()
1271 else:
1271 else:
1272 etype, value, tb = exc_tuple
1272 etype, value, tb = exc_tuple
1273
1273
1274 if etype is None:
1274 if etype is None:
1275 if hasattr(sys, 'last_type'):
1275 if hasattr(sys, 'last_type'):
1276 etype, value, tb = sys.last_type, sys.last_value, \
1276 etype, value, tb = sys.last_type, sys.last_value, \
1277 sys.last_traceback
1277 sys.last_traceback
1278 else:
1278 else:
1279 self.write_err('No traceback available to show.\n')
1279 self.write_err('No traceback available to show.\n')
1280 return
1280 return
1281
1281
1282 if etype is SyntaxError:
1282 if etype is SyntaxError:
1283 # Though this won't be called by syntax errors in the input
1283 # Though this won't be called by syntax errors in the input
1284 # line, there may be SyntaxError cases whith imported code.
1284 # line, there may be SyntaxError cases whith imported code.
1285 self.showsyntaxerror(filename)
1285 self.showsyntaxerror(filename)
1286 elif etype is UsageError:
1286 elif etype is UsageError:
1287 print "UsageError:", value
1287 print "UsageError:", value
1288 else:
1288 else:
1289 # WARNING: these variables are somewhat deprecated and not
1289 # WARNING: these variables are somewhat deprecated and not
1290 # necessarily safe to use in a threaded environment, but tools
1290 # necessarily safe to use in a threaded environment, but tools
1291 # like pdb depend on their existence, so let's set them. If we
1291 # like pdb depend on their existence, so let's set them. If we
1292 # find problems in the field, we'll need to revisit their use.
1292 # find problems in the field, we'll need to revisit their use.
1293 sys.last_type = etype
1293 sys.last_type = etype
1294 sys.last_value = value
1294 sys.last_value = value
1295 sys.last_traceback = tb
1295 sys.last_traceback = tb
1296
1296
1297 if etype in self.custom_exceptions:
1297 if etype in self.custom_exceptions:
1298 # FIXME: Old custom traceback objects may just return a
1298 # FIXME: Old custom traceback objects may just return a
1299 # string, in that case we just put it into a list
1299 # string, in that case we just put it into a list
1300 stb = self.CustomTB(etype, value, tb, tb_offset)
1300 stb = self.CustomTB(etype, value, tb, tb_offset)
1301 if isinstance(ctb, basestring):
1301 if isinstance(ctb, basestring):
1302 stb = [stb]
1302 stb = [stb]
1303 else:
1303 else:
1304 if exception_only:
1304 if exception_only:
1305 stb = ['An exception has occurred, use %tb to see '
1305 stb = ['An exception has occurred, use %tb to see '
1306 'the full traceback.\n']
1306 'the full traceback.\n']
1307 stb.extend(self.InteractiveTB.get_exception_only(etype,
1307 stb.extend(self.InteractiveTB.get_exception_only(etype,
1308 value))
1308 value))
1309 else:
1309 else:
1310 stb = self.InteractiveTB.structured_traceback(etype,
1310 stb = self.InteractiveTB.structured_traceback(etype,
1311 value, tb, tb_offset=tb_offset)
1311 value, tb, tb_offset=tb_offset)
1312 # FIXME: the pdb calling should be done by us, not by
1312 # FIXME: the pdb calling should be done by us, not by
1313 # the code computing the traceback.
1313 # the code computing the traceback.
1314 if self.InteractiveTB.call_pdb:
1314 if self.InteractiveTB.call_pdb:
1315 # pdb mucks up readline, fix it back
1315 # pdb mucks up readline, fix it back
1316 self.set_completer()
1316 self.set_completer()
1317
1317
1318 # Actually show the traceback
1318 # Actually show the traceback
1319 self._showtraceback(etype, value, stb)
1319 self._showtraceback(etype, value, stb)
1320
1320
1321 except KeyboardInterrupt:
1321 except KeyboardInterrupt:
1322 self.write_err("\nKeyboardInterrupt\n")
1322 self.write_err("\nKeyboardInterrupt\n")
1323
1323
1324 def _showtraceback(self, etype, evalue, stb):
1324 def _showtraceback(self, etype, evalue, stb):
1325 """Actually show a traceback.
1325 """Actually show a traceback.
1326
1326
1327 Subclasses may override this method to put the traceback on a different
1327 Subclasses may override this method to put the traceback on a different
1328 place, like a side channel.
1328 place, like a side channel.
1329 """
1329 """
1330 # FIXME: this should use the proper write channels, but our test suite
1330 # FIXME: this should use the proper write channels, but our test suite
1331 # relies on it coming out of stdout...
1331 # relies on it coming out of stdout...
1332 print >> sys.stdout, self.InteractiveTB.stb2text(stb)
1332 print >> sys.stdout, self.InteractiveTB.stb2text(stb)
1333
1333
1334 def showsyntaxerror(self, filename=None):
1334 def showsyntaxerror(self, filename=None):
1335 """Display the syntax error that just occurred.
1335 """Display the syntax error that just occurred.
1336
1336
1337 This doesn't display a stack trace because there isn't one.
1337 This doesn't display a stack trace because there isn't one.
1338
1338
1339 If a filename is given, it is stuffed in the exception instead
1339 If a filename is given, it is stuffed in the exception instead
1340 of what was there before (because Python's parser always uses
1340 of what was there before (because Python's parser always uses
1341 "<string>" when reading from a string).
1341 "<string>" when reading from a string).
1342 """
1342 """
1343 etype, value, last_traceback = sys.exc_info()
1343 etype, value, last_traceback = sys.exc_info()
1344
1344
1345 # See note about these variables in showtraceback() above
1345 # See note about these variables in showtraceback() above
1346 sys.last_type = etype
1346 sys.last_type = etype
1347 sys.last_value = value
1347 sys.last_value = value
1348 sys.last_traceback = last_traceback
1348 sys.last_traceback = last_traceback
1349
1349
1350 if filename and etype is SyntaxError:
1350 if filename and etype is SyntaxError:
1351 # Work hard to stuff the correct filename in the exception
1351 # Work hard to stuff the correct filename in the exception
1352 try:
1352 try:
1353 msg, (dummy_filename, lineno, offset, line) = value
1353 msg, (dummy_filename, lineno, offset, line) = value
1354 except:
1354 except:
1355 # Not the format we expect; leave it alone
1355 # Not the format we expect; leave it alone
1356 pass
1356 pass
1357 else:
1357 else:
1358 # Stuff in the right filename
1358 # Stuff in the right filename
1359 try:
1359 try:
1360 # Assume SyntaxError is a class exception
1360 # Assume SyntaxError is a class exception
1361 value = SyntaxError(msg, (filename, lineno, offset, line))
1361 value = SyntaxError(msg, (filename, lineno, offset, line))
1362 except:
1362 except:
1363 # If that failed, assume SyntaxError is a string
1363 # If that failed, assume SyntaxError is a string
1364 value = msg, (filename, lineno, offset, line)
1364 value = msg, (filename, lineno, offset, line)
1365 stb = self.SyntaxTB.structured_traceback(etype, value, [])
1365 stb = self.SyntaxTB.structured_traceback(etype, value, [])
1366 self._showtraceback(etype, value, stb)
1366 self._showtraceback(etype, value, stb)
1367
1367
1368 #-------------------------------------------------------------------------
1368 #-------------------------------------------------------------------------
1369 # Things related to tab completion
1369 # Things related to tab completion
1370 #-------------------------------------------------------------------------
1370 #-------------------------------------------------------------------------
1371
1371
1372 def complete(self, text, line=None, cursor_pos=None):
1372 def complete(self, text, line=None, cursor_pos=None):
1373 """Return a sorted list of all possible completions on text.
1373 """Return the completed text and a list of completions.
1374
1374
1375 Parameters
1375 Parameters
1376 ----------
1376 ----------
1377
1377
1378 text : string
1378 text : string
1379 A string of text to be completed on.
1379 A string of text to be completed on. It can be given as empty and
1380 instead a line/position pair are given. In this case, the
1381 completer itself will split the line like readline does.
1380
1382
1381 line : string, optional
1383 line : string, optional
1382 The complete line that text is part of.
1384 The complete line that text is part of.
1383
1385
1384 cursor_pos : int, optional
1386 cursor_pos : int, optional
1385 The position of the cursor on the input line.
1387 The position of the cursor on the input line.
1386
1388
1389 Returns
1390 -------
1391 text : string
1392 The actual text that was completed.
1393
1394 matches : list
1395 A sorted list with all possible completions.
1396
1387 The optional arguments allow the completion to take more context into
1397 The optional arguments allow the completion to take more context into
1388 account, and are part of the low-level completion API.
1398 account, and are part of the low-level completion API.
1389
1399
1390 This is a wrapper around the completion mechanism, similar to what
1400 This is a wrapper around the completion mechanism, similar to what
1391 readline does at the command line when the TAB key is hit. By
1401 readline does at the command line when the TAB key is hit. By
1392 exposing it as a method, it can be used by other non-readline
1402 exposing it as a method, it can be used by other non-readline
1393 environments (such as GUIs) for text completion.
1403 environments (such as GUIs) for text completion.
1394
1404
1395 Simple usage example:
1405 Simple usage example:
1396
1406
1397 In [7]: x = 'hello'
1407 In [1]: x = 'hello'
1398
1399 In [8]: x
1400 Out[8]: 'hello'
1401
1402 In [9]: print x
1403 hello
1404
1408
1405 In [10]: _ip.complete('x.l')
1409 In [2]: _ip.complete('x.l')
1406 Out[10]: ['x.ljust', 'x.lower', 'x.lstrip']
1410 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
1407 """
1411 """
1408
1412
1409 # Inject names into __builtin__ so we can complete on the added names.
1413 # Inject names into __builtin__ so we can complete on the added names.
1410 with self.builtin_trap:
1414 with self.builtin_trap:
1411 return self.Completer.complete(text,line_buffer=text)
1415 return self.Completer.complete(text, line, cursor_pos)
1412
1416
1413 def set_custom_completer(self,completer,pos=0):
1417 def set_custom_completer(self, completer, pos=0):
1414 """Adds a new custom completer function.
1418 """Adds a new custom completer function.
1415
1419
1416 The position argument (defaults to 0) is the index in the completers
1420 The position argument (defaults to 0) is the index in the completers
1417 list where you want the completer to be inserted."""
1421 list where you want the completer to be inserted."""
1418
1422
1419 newcomp = new.instancemethod(completer,self.Completer,
1423 newcomp = new.instancemethod(completer,self.Completer,
1420 self.Completer.__class__)
1424 self.Completer.__class__)
1421 self.Completer.matchers.insert(pos,newcomp)
1425 self.Completer.matchers.insert(pos,newcomp)
1422
1426
1423 def set_completer(self):
1427 def set_completer(self):
1424 """Reset readline's completer to be our own."""
1428 """Reset readline's completer to be our own."""
1425 self.readline.set_completer(self.Completer.rlcomplete)
1429 self.readline.set_completer(self.Completer.rlcomplete)
1426
1430
1427 def set_completer_frame(self, frame=None):
1431 def set_completer_frame(self, frame=None):
1428 """Set the frame of the completer."""
1432 """Set the frame of the completer."""
1429 if frame:
1433 if frame:
1430 self.Completer.namespace = frame.f_locals
1434 self.Completer.namespace = frame.f_locals
1431 self.Completer.global_namespace = frame.f_globals
1435 self.Completer.global_namespace = frame.f_globals
1432 else:
1436 else:
1433 self.Completer.namespace = self.user_ns
1437 self.Completer.namespace = self.user_ns
1434 self.Completer.global_namespace = self.user_global_ns
1438 self.Completer.global_namespace = self.user_global_ns
1435
1439
1436 #-------------------------------------------------------------------------
1440 #-------------------------------------------------------------------------
1437 # Things related to readline
1441 # Things related to readline
1438 #-------------------------------------------------------------------------
1442 #-------------------------------------------------------------------------
1439
1443
1440 def init_readline(self):
1444 def init_readline(self):
1441 """Command history completion/saving/reloading."""
1445 """Command history completion/saving/reloading."""
1442
1446
1443 if self.readline_use:
1447 if self.readline_use:
1444 import IPython.utils.rlineimpl as readline
1448 import IPython.utils.rlineimpl as readline
1445
1449
1446 self.rl_next_input = None
1450 self.rl_next_input = None
1447 self.rl_do_indent = False
1451 self.rl_do_indent = False
1448
1452
1449 if not self.readline_use or not readline.have_readline:
1453 if not self.readline_use or not readline.have_readline:
1450 self.has_readline = False
1454 self.has_readline = False
1451 self.readline = None
1455 self.readline = None
1452 # Set a number of methods that depend on readline to be no-op
1456 # Set a number of methods that depend on readline to be no-op
1453 self.savehist = no_op
1457 self.savehist = no_op
1454 self.reloadhist = no_op
1458 self.reloadhist = no_op
1455 self.set_completer = no_op
1459 self.set_completer = no_op
1456 self.set_custom_completer = no_op
1460 self.set_custom_completer = no_op
1457 self.set_completer_frame = no_op
1461 self.set_completer_frame = no_op
1458 warn('Readline services not available or not loaded.')
1462 warn('Readline services not available or not loaded.')
1459 else:
1463 else:
1460 self.has_readline = True
1464 self.has_readline = True
1461 self.readline = readline
1465 self.readline = readline
1462 sys.modules['readline'] = readline
1466 sys.modules['readline'] = readline
1463 import atexit
1467 import atexit
1464 from IPython.core.completer import IPCompleter
1468 from IPython.core.completer import IPCompleter
1465 self.Completer = IPCompleter(self,
1469 self.Completer = IPCompleter(self,
1466 self.user_ns,
1470 self.user_ns,
1467 self.user_global_ns,
1471 self.user_global_ns,
1468 self.readline_omit__names,
1472 self.readline_omit__names,
1469 self.alias_manager.alias_table)
1473 self.alias_manager.alias_table)
1470 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1474 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1471 self.strdispatchers['complete_command'] = sdisp
1475 self.strdispatchers['complete_command'] = sdisp
1472 self.Completer.custom_completers = sdisp
1476 self.Completer.custom_completers = sdisp
1473 # Platform-specific configuration
1477 # Platform-specific configuration
1474 if os.name == 'nt':
1478 if os.name == 'nt':
1475 self.readline_startup_hook = readline.set_pre_input_hook
1479 self.readline_startup_hook = readline.set_pre_input_hook
1476 else:
1480 else:
1477 self.readline_startup_hook = readline.set_startup_hook
1481 self.readline_startup_hook = readline.set_startup_hook
1478
1482
1479 # Load user's initrc file (readline config)
1483 # Load user's initrc file (readline config)
1480 # Or if libedit is used, load editrc.
1484 # Or if libedit is used, load editrc.
1481 inputrc_name = os.environ.get('INPUTRC')
1485 inputrc_name = os.environ.get('INPUTRC')
1482 if inputrc_name is None:
1486 if inputrc_name is None:
1483 home_dir = get_home_dir()
1487 home_dir = get_home_dir()
1484 if home_dir is not None:
1488 if home_dir is not None:
1485 inputrc_name = '.inputrc'
1489 inputrc_name = '.inputrc'
1486 if readline.uses_libedit:
1490 if readline.uses_libedit:
1487 inputrc_name = '.editrc'
1491 inputrc_name = '.editrc'
1488 inputrc_name = os.path.join(home_dir, inputrc_name)
1492 inputrc_name = os.path.join(home_dir, inputrc_name)
1489 if os.path.isfile(inputrc_name):
1493 if os.path.isfile(inputrc_name):
1490 try:
1494 try:
1491 readline.read_init_file(inputrc_name)
1495 readline.read_init_file(inputrc_name)
1492 except:
1496 except:
1493 warn('Problems reading readline initialization file <%s>'
1497 warn('Problems reading readline initialization file <%s>'
1494 % inputrc_name)
1498 % inputrc_name)
1495
1499
1496 # save this in sys so embedded copies can restore it properly
1500 # save this in sys so embedded copies can restore it properly
1497 sys.ipcompleter = self.Completer.rlcomplete
1501 sys.ipcompleter = self.Completer.rlcomplete
1498 self.set_completer()
1502 self.set_completer()
1499
1503
1500 # Configure readline according to user's prefs
1504 # Configure readline according to user's prefs
1501 # This is only done if GNU readline is being used. If libedit
1505 # This is only done if GNU readline is being used. If libedit
1502 # is being used (as on Leopard) the readline config is
1506 # is being used (as on Leopard) the readline config is
1503 # not run as the syntax for libedit is different.
1507 # not run as the syntax for libedit is different.
1504 if not readline.uses_libedit:
1508 if not readline.uses_libedit:
1505 for rlcommand in self.readline_parse_and_bind:
1509 for rlcommand in self.readline_parse_and_bind:
1506 #print "loading rl:",rlcommand # dbg
1510 #print "loading rl:",rlcommand # dbg
1507 readline.parse_and_bind(rlcommand)
1511 readline.parse_and_bind(rlcommand)
1508
1512
1509 # Remove some chars from the delimiters list. If we encounter
1513 # Remove some chars from the delimiters list. If we encounter
1510 # unicode chars, discard them.
1514 # unicode chars, discard them.
1511 delims = readline.get_completer_delims().encode("ascii", "ignore")
1515 delims = readline.get_completer_delims().encode("ascii", "ignore")
1512 delims = delims.translate(string._idmap,
1516 delims = delims.translate(string._idmap,
1513 self.readline_remove_delims)
1517 self.readline_remove_delims)
1514 readline.set_completer_delims(delims)
1518 readline.set_completer_delims(delims)
1515 # otherwise we end up with a monster history after a while:
1519 # otherwise we end up with a monster history after a while:
1516 readline.set_history_length(1000)
1520 readline.set_history_length(1000)
1517 try:
1521 try:
1518 #print '*** Reading readline history' # dbg
1522 #print '*** Reading readline history' # dbg
1519 readline.read_history_file(self.histfile)
1523 readline.read_history_file(self.histfile)
1520 except IOError:
1524 except IOError:
1521 pass # It doesn't exist yet.
1525 pass # It doesn't exist yet.
1522
1526
1523 atexit.register(self.atexit_operations)
1527 atexit.register(self.atexit_operations)
1524 del atexit
1528 del atexit
1525
1529
1526 # Configure auto-indent for all platforms
1530 # Configure auto-indent for all platforms
1527 self.set_autoindent(self.autoindent)
1531 self.set_autoindent(self.autoindent)
1528
1532
1529 def set_next_input(self, s):
1533 def set_next_input(self, s):
1530 """ Sets the 'default' input string for the next command line.
1534 """ Sets the 'default' input string for the next command line.
1531
1535
1532 Requires readline.
1536 Requires readline.
1533
1537
1534 Example:
1538 Example:
1535
1539
1536 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1540 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1537 [D:\ipython]|2> Hello Word_ # cursor is here
1541 [D:\ipython]|2> Hello Word_ # cursor is here
1538 """
1542 """
1539
1543
1540 self.rl_next_input = s
1544 self.rl_next_input = s
1541
1545
1542 # Maybe move this to the terminal subclass?
1546 # Maybe move this to the terminal subclass?
1543 def pre_readline(self):
1547 def pre_readline(self):
1544 """readline hook to be used at the start of each line.
1548 """readline hook to be used at the start of each line.
1545
1549
1546 Currently it handles auto-indent only."""
1550 Currently it handles auto-indent only."""
1547
1551
1548 if self.rl_do_indent:
1552 if self.rl_do_indent:
1549 self.readline.insert_text(self._indent_current_str())
1553 self.readline.insert_text(self._indent_current_str())
1550 if self.rl_next_input is not None:
1554 if self.rl_next_input is not None:
1551 self.readline.insert_text(self.rl_next_input)
1555 self.readline.insert_text(self.rl_next_input)
1552 self.rl_next_input = None
1556 self.rl_next_input = None
1553
1557
1554 def _indent_current_str(self):
1558 def _indent_current_str(self):
1555 """return the current level of indentation as a string"""
1559 """return the current level of indentation as a string"""
1556 return self.indent_current_nsp * ' '
1560 return self.indent_current_nsp * ' '
1557
1561
1558 #-------------------------------------------------------------------------
1562 #-------------------------------------------------------------------------
1559 # Things related to magics
1563 # Things related to magics
1560 #-------------------------------------------------------------------------
1564 #-------------------------------------------------------------------------
1561
1565
1562 def init_magics(self):
1566 def init_magics(self):
1563 # FIXME: Move the color initialization to the DisplayHook, which
1567 # FIXME: Move the color initialization to the DisplayHook, which
1564 # should be split into a prompt manager and displayhook. We probably
1568 # should be split into a prompt manager and displayhook. We probably
1565 # even need a centralize colors management object.
1569 # even need a centralize colors management object.
1566 self.magic_colors(self.colors)
1570 self.magic_colors(self.colors)
1567 # History was moved to a separate module
1571 # History was moved to a separate module
1568 from . import history
1572 from . import history
1569 history.init_ipython(self)
1573 history.init_ipython(self)
1570
1574
1571 def magic(self,arg_s):
1575 def magic(self,arg_s):
1572 """Call a magic function by name.
1576 """Call a magic function by name.
1573
1577
1574 Input: a string containing the name of the magic function to call and any
1578 Input: a string containing the name of the magic function to call and any
1575 additional arguments to be passed to the magic.
1579 additional arguments to be passed to the magic.
1576
1580
1577 magic('name -opt foo bar') is equivalent to typing at the ipython
1581 magic('name -opt foo bar') is equivalent to typing at the ipython
1578 prompt:
1582 prompt:
1579
1583
1580 In[1]: %name -opt foo bar
1584 In[1]: %name -opt foo bar
1581
1585
1582 To call a magic without arguments, simply use magic('name').
1586 To call a magic without arguments, simply use magic('name').
1583
1587
1584 This provides a proper Python function to call IPython's magics in any
1588 This provides a proper Python function to call IPython's magics in any
1585 valid Python code you can type at the interpreter, including loops and
1589 valid Python code you can type at the interpreter, including loops and
1586 compound statements.
1590 compound statements.
1587 """
1591 """
1588 args = arg_s.split(' ',1)
1592 args = arg_s.split(' ',1)
1589 magic_name = args[0]
1593 magic_name = args[0]
1590 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
1594 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
1591
1595
1592 try:
1596 try:
1593 magic_args = args[1]
1597 magic_args = args[1]
1594 except IndexError:
1598 except IndexError:
1595 magic_args = ''
1599 magic_args = ''
1596 fn = getattr(self,'magic_'+magic_name,None)
1600 fn = getattr(self,'magic_'+magic_name,None)
1597 if fn is None:
1601 if fn is None:
1598 error("Magic function `%s` not found." % magic_name)
1602 error("Magic function `%s` not found." % magic_name)
1599 else:
1603 else:
1600 magic_args = self.var_expand(magic_args,1)
1604 magic_args = self.var_expand(magic_args,1)
1601 with nested(self.builtin_trap,):
1605 with nested(self.builtin_trap,):
1602 result = fn(magic_args)
1606 result = fn(magic_args)
1603 return result
1607 return result
1604
1608
1605 def define_magic(self, magicname, func):
1609 def define_magic(self, magicname, func):
1606 """Expose own function as magic function for ipython
1610 """Expose own function as magic function for ipython
1607
1611
1608 def foo_impl(self,parameter_s=''):
1612 def foo_impl(self,parameter_s=''):
1609 'My very own magic!. (Use docstrings, IPython reads them).'
1613 'My very own magic!. (Use docstrings, IPython reads them).'
1610 print 'Magic function. Passed parameter is between < >:'
1614 print 'Magic function. Passed parameter is between < >:'
1611 print '<%s>' % parameter_s
1615 print '<%s>' % parameter_s
1612 print 'The self object is:',self
1616 print 'The self object is:',self
1613
1617
1614 self.define_magic('foo',foo_impl)
1618 self.define_magic('foo',foo_impl)
1615 """
1619 """
1616
1620
1617 import new
1621 import new
1618 im = new.instancemethod(func,self, self.__class__)
1622 im = new.instancemethod(func,self, self.__class__)
1619 old = getattr(self, "magic_" + magicname, None)
1623 old = getattr(self, "magic_" + magicname, None)
1620 setattr(self, "magic_" + magicname, im)
1624 setattr(self, "magic_" + magicname, im)
1621 return old
1625 return old
1622
1626
1623 #-------------------------------------------------------------------------
1627 #-------------------------------------------------------------------------
1624 # Things related to macros
1628 # Things related to macros
1625 #-------------------------------------------------------------------------
1629 #-------------------------------------------------------------------------
1626
1630
1627 def define_macro(self, name, themacro):
1631 def define_macro(self, name, themacro):
1628 """Define a new macro
1632 """Define a new macro
1629
1633
1630 Parameters
1634 Parameters
1631 ----------
1635 ----------
1632 name : str
1636 name : str
1633 The name of the macro.
1637 The name of the macro.
1634 themacro : str or Macro
1638 themacro : str or Macro
1635 The action to do upon invoking the macro. If a string, a new
1639 The action to do upon invoking the macro. If a string, a new
1636 Macro object is created by passing the string to it.
1640 Macro object is created by passing the string to it.
1637 """
1641 """
1638
1642
1639 from IPython.core import macro
1643 from IPython.core import macro
1640
1644
1641 if isinstance(themacro, basestring):
1645 if isinstance(themacro, basestring):
1642 themacro = macro.Macro(themacro)
1646 themacro = macro.Macro(themacro)
1643 if not isinstance(themacro, macro.Macro):
1647 if not isinstance(themacro, macro.Macro):
1644 raise ValueError('A macro must be a string or a Macro instance.')
1648 raise ValueError('A macro must be a string or a Macro instance.')
1645 self.user_ns[name] = themacro
1649 self.user_ns[name] = themacro
1646
1650
1647 #-------------------------------------------------------------------------
1651 #-------------------------------------------------------------------------
1648 # Things related to the running of system commands
1652 # Things related to the running of system commands
1649 #-------------------------------------------------------------------------
1653 #-------------------------------------------------------------------------
1650
1654
1651 def system(self, cmd):
1655 def system(self, cmd):
1652 """Make a system call, using IPython."""
1656 """Make a system call, using IPython."""
1653 return self.hooks.shell_hook(self.var_expand(cmd, depth=2))
1657 return self.hooks.shell_hook(self.var_expand(cmd, depth=2))
1654
1658
1655 #-------------------------------------------------------------------------
1659 #-------------------------------------------------------------------------
1656 # Things related to aliases
1660 # Things related to aliases
1657 #-------------------------------------------------------------------------
1661 #-------------------------------------------------------------------------
1658
1662
1659 def init_alias(self):
1663 def init_alias(self):
1660 self.alias_manager = AliasManager(shell=self, config=self.config)
1664 self.alias_manager = AliasManager(shell=self, config=self.config)
1661 self.ns_table['alias'] = self.alias_manager.alias_table,
1665 self.ns_table['alias'] = self.alias_manager.alias_table,
1662
1666
1663 #-------------------------------------------------------------------------
1667 #-------------------------------------------------------------------------
1664 # Things related to extensions and plugins
1668 # Things related to extensions and plugins
1665 #-------------------------------------------------------------------------
1669 #-------------------------------------------------------------------------
1666
1670
1667 def init_extension_manager(self):
1671 def init_extension_manager(self):
1668 self.extension_manager = ExtensionManager(shell=self, config=self.config)
1672 self.extension_manager = ExtensionManager(shell=self, config=self.config)
1669
1673
1670 def init_plugin_manager(self):
1674 def init_plugin_manager(self):
1671 self.plugin_manager = PluginManager(config=self.config)
1675 self.plugin_manager = PluginManager(config=self.config)
1672
1676
1673 #-------------------------------------------------------------------------
1677 #-------------------------------------------------------------------------
1674 # Things related to payloads
1678 # Things related to payloads
1675 #-------------------------------------------------------------------------
1679 #-------------------------------------------------------------------------
1676
1680
1677 def init_payload(self):
1681 def init_payload(self):
1678 self.payload_manager = PayloadManager(config=self.config)
1682 self.payload_manager = PayloadManager(config=self.config)
1679
1683
1680 #-------------------------------------------------------------------------
1684 #-------------------------------------------------------------------------
1681 # Things related to the prefilter
1685 # Things related to the prefilter
1682 #-------------------------------------------------------------------------
1686 #-------------------------------------------------------------------------
1683
1687
1684 def init_prefilter(self):
1688 def init_prefilter(self):
1685 self.prefilter_manager = PrefilterManager(shell=self, config=self.config)
1689 self.prefilter_manager = PrefilterManager(shell=self, config=self.config)
1686 # Ultimately this will be refactored in the new interpreter code, but
1690 # Ultimately this will be refactored in the new interpreter code, but
1687 # for now, we should expose the main prefilter method (there's legacy
1691 # for now, we should expose the main prefilter method (there's legacy
1688 # code out there that may rely on this).
1692 # code out there that may rely on this).
1689 self.prefilter = self.prefilter_manager.prefilter_lines
1693 self.prefilter = self.prefilter_manager.prefilter_lines
1690
1694
1691 #-------------------------------------------------------------------------
1695 #-------------------------------------------------------------------------
1692 # Things related to the running of code
1696 # Things related to the running of code
1693 #-------------------------------------------------------------------------
1697 #-------------------------------------------------------------------------
1694
1698
1695 def ex(self, cmd):
1699 def ex(self, cmd):
1696 """Execute a normal python statement in user namespace."""
1700 """Execute a normal python statement in user namespace."""
1697 with nested(self.builtin_trap,):
1701 with nested(self.builtin_trap,):
1698 exec cmd in self.user_global_ns, self.user_ns
1702 exec cmd in self.user_global_ns, self.user_ns
1699
1703
1700 def ev(self, expr):
1704 def ev(self, expr):
1701 """Evaluate python expression expr in user namespace.
1705 """Evaluate python expression expr in user namespace.
1702
1706
1703 Returns the result of evaluation
1707 Returns the result of evaluation
1704 """
1708 """
1705 with nested(self.builtin_trap,):
1709 with nested(self.builtin_trap,):
1706 return eval(expr, self.user_global_ns, self.user_ns)
1710 return eval(expr, self.user_global_ns, self.user_ns)
1707
1711
1708 def safe_execfile(self, fname, *where, **kw):
1712 def safe_execfile(self, fname, *where, **kw):
1709 """A safe version of the builtin execfile().
1713 """A safe version of the builtin execfile().
1710
1714
1711 This version will never throw an exception, but instead print
1715 This version will never throw an exception, but instead print
1712 helpful error messages to the screen. This only works on pure
1716 helpful error messages to the screen. This only works on pure
1713 Python files with the .py extension.
1717 Python files with the .py extension.
1714
1718
1715 Parameters
1719 Parameters
1716 ----------
1720 ----------
1717 fname : string
1721 fname : string
1718 The name of the file to be executed.
1722 The name of the file to be executed.
1719 where : tuple
1723 where : tuple
1720 One or two namespaces, passed to execfile() as (globals,locals).
1724 One or two namespaces, passed to execfile() as (globals,locals).
1721 If only one is given, it is passed as both.
1725 If only one is given, it is passed as both.
1722 exit_ignore : bool (False)
1726 exit_ignore : bool (False)
1723 If True, then silence SystemExit for non-zero status (it is always
1727 If True, then silence SystemExit for non-zero status (it is always
1724 silenced for zero status, as it is so common).
1728 silenced for zero status, as it is so common).
1725 """
1729 """
1726 kw.setdefault('exit_ignore', False)
1730 kw.setdefault('exit_ignore', False)
1727
1731
1728 fname = os.path.abspath(os.path.expanduser(fname))
1732 fname = os.path.abspath(os.path.expanduser(fname))
1729
1733
1730 # Make sure we have a .py file
1734 # Make sure we have a .py file
1731 if not fname.endswith('.py'):
1735 if not fname.endswith('.py'):
1732 warn('File must end with .py to be run using execfile: <%s>' % fname)
1736 warn('File must end with .py to be run using execfile: <%s>' % fname)
1733
1737
1734 # Make sure we can open the file
1738 # Make sure we can open the file
1735 try:
1739 try:
1736 with open(fname) as thefile:
1740 with open(fname) as thefile:
1737 pass
1741 pass
1738 except:
1742 except:
1739 warn('Could not open file <%s> for safe execution.' % fname)
1743 warn('Could not open file <%s> for safe execution.' % fname)
1740 return
1744 return
1741
1745
1742 # Find things also in current directory. This is needed to mimic the
1746 # Find things also in current directory. This is needed to mimic the
1743 # behavior of running a script from the system command line, where
1747 # behavior of running a script from the system command line, where
1744 # Python inserts the script's directory into sys.path
1748 # Python inserts the script's directory into sys.path
1745 dname = os.path.dirname(fname)
1749 dname = os.path.dirname(fname)
1746
1750
1747 with prepended_to_syspath(dname):
1751 with prepended_to_syspath(dname):
1748 try:
1752 try:
1749 execfile(fname,*where)
1753 execfile(fname,*where)
1750 except SystemExit, status:
1754 except SystemExit, status:
1751 # If the call was made with 0 or None exit status (sys.exit(0)
1755 # If the call was made with 0 or None exit status (sys.exit(0)
1752 # or sys.exit() ), don't bother showing a traceback, as both of
1756 # or sys.exit() ), don't bother showing a traceback, as both of
1753 # these are considered normal by the OS:
1757 # these are considered normal by the OS:
1754 # > python -c'import sys;sys.exit(0)'; echo $?
1758 # > python -c'import sys;sys.exit(0)'; echo $?
1755 # 0
1759 # 0
1756 # > python -c'import sys;sys.exit()'; echo $?
1760 # > python -c'import sys;sys.exit()'; echo $?
1757 # 0
1761 # 0
1758 # For other exit status, we show the exception unless
1762 # For other exit status, we show the exception unless
1759 # explicitly silenced, but only in short form.
1763 # explicitly silenced, but only in short form.
1760 if status.code not in (0, None) and not kw['exit_ignore']:
1764 if status.code not in (0, None) and not kw['exit_ignore']:
1761 self.showtraceback(exception_only=True)
1765 self.showtraceback(exception_only=True)
1762 except:
1766 except:
1763 self.showtraceback()
1767 self.showtraceback()
1764
1768
1765 def safe_execfile_ipy(self, fname):
1769 def safe_execfile_ipy(self, fname):
1766 """Like safe_execfile, but for .ipy files with IPython syntax.
1770 """Like safe_execfile, but for .ipy files with IPython syntax.
1767
1771
1768 Parameters
1772 Parameters
1769 ----------
1773 ----------
1770 fname : str
1774 fname : str
1771 The name of the file to execute. The filename must have a
1775 The name of the file to execute. The filename must have a
1772 .ipy extension.
1776 .ipy extension.
1773 """
1777 """
1774 fname = os.path.abspath(os.path.expanduser(fname))
1778 fname = os.path.abspath(os.path.expanduser(fname))
1775
1779
1776 # Make sure we have a .py file
1780 # Make sure we have a .py file
1777 if not fname.endswith('.ipy'):
1781 if not fname.endswith('.ipy'):
1778 warn('File must end with .py to be run using execfile: <%s>' % fname)
1782 warn('File must end with .py to be run using execfile: <%s>' % fname)
1779
1783
1780 # Make sure we can open the file
1784 # Make sure we can open the file
1781 try:
1785 try:
1782 with open(fname) as thefile:
1786 with open(fname) as thefile:
1783 pass
1787 pass
1784 except:
1788 except:
1785 warn('Could not open file <%s> for safe execution.' % fname)
1789 warn('Could not open file <%s> for safe execution.' % fname)
1786 return
1790 return
1787
1791
1788 # Find things also in current directory. This is needed to mimic the
1792 # Find things also in current directory. This is needed to mimic the
1789 # behavior of running a script from the system command line, where
1793 # behavior of running a script from the system command line, where
1790 # Python inserts the script's directory into sys.path
1794 # Python inserts the script's directory into sys.path
1791 dname = os.path.dirname(fname)
1795 dname = os.path.dirname(fname)
1792
1796
1793 with prepended_to_syspath(dname):
1797 with prepended_to_syspath(dname):
1794 try:
1798 try:
1795 with open(fname) as thefile:
1799 with open(fname) as thefile:
1796 script = thefile.read()
1800 script = thefile.read()
1797 # self.runlines currently captures all exceptions
1801 # self.runlines currently captures all exceptions
1798 # raise in user code. It would be nice if there were
1802 # raise in user code. It would be nice if there were
1799 # versions of runlines, execfile that did raise, so
1803 # versions of runlines, execfile that did raise, so
1800 # we could catch the errors.
1804 # we could catch the errors.
1801 self.runlines(script, clean=True)
1805 self.runlines(script, clean=True)
1802 except:
1806 except:
1803 self.showtraceback()
1807 self.showtraceback()
1804 warn('Unknown failure executing file: <%s>' % fname)
1808 warn('Unknown failure executing file: <%s>' % fname)
1805
1809
1806 def runlines(self, lines, clean=False):
1810 def runlines(self, lines, clean=False):
1807 """Run a string of one or more lines of source.
1811 """Run a string of one or more lines of source.
1808
1812
1809 This method is capable of running a string containing multiple source
1813 This method is capable of running a string containing multiple source
1810 lines, as if they had been entered at the IPython prompt. Since it
1814 lines, as if they had been entered at the IPython prompt. Since it
1811 exposes IPython's processing machinery, the given strings can contain
1815 exposes IPython's processing machinery, the given strings can contain
1812 magic calls (%magic), special shell access (!cmd), etc.
1816 magic calls (%magic), special shell access (!cmd), etc.
1813 """
1817 """
1814
1818
1815 if isinstance(lines, (list, tuple)):
1819 if isinstance(lines, (list, tuple)):
1816 lines = '\n'.join(lines)
1820 lines = '\n'.join(lines)
1817
1821
1818 if clean:
1822 if clean:
1819 lines = self._cleanup_ipy_script(lines)
1823 lines = self._cleanup_ipy_script(lines)
1820
1824
1821 # We must start with a clean buffer, in case this is run from an
1825 # We must start with a clean buffer, in case this is run from an
1822 # interactive IPython session (via a magic, for example).
1826 # interactive IPython session (via a magic, for example).
1823 self.resetbuffer()
1827 self.resetbuffer()
1824 lines = lines.splitlines()
1828 lines = lines.splitlines()
1825 more = 0
1829 more = 0
1826
1830
1827 with nested(self.builtin_trap, self.display_trap):
1831 with nested(self.builtin_trap, self.display_trap):
1828 for line in lines:
1832 for line in lines:
1829 # skip blank lines so we don't mess up the prompt counter, but do
1833 # skip blank lines so we don't mess up the prompt counter, but do
1830 # NOT skip even a blank line if we are in a code block (more is
1834 # NOT skip even a blank line if we are in a code block (more is
1831 # true)
1835 # true)
1832
1836
1833 if line or more:
1837 if line or more:
1834 # push to raw history, so hist line numbers stay in sync
1838 # push to raw history, so hist line numbers stay in sync
1835 self.input_hist_raw.append("# " + line + "\n")
1839 self.input_hist_raw.append("# " + line + "\n")
1836 prefiltered = self.prefilter_manager.prefilter_lines(line,more)
1840 prefiltered = self.prefilter_manager.prefilter_lines(line,more)
1837 more = self.push_line(prefiltered)
1841 more = self.push_line(prefiltered)
1838 # IPython's runsource returns None if there was an error
1842 # IPython's runsource returns None if there was an error
1839 # compiling the code. This allows us to stop processing right
1843 # compiling the code. This allows us to stop processing right
1840 # away, so the user gets the error message at the right place.
1844 # away, so the user gets the error message at the right place.
1841 if more is None:
1845 if more is None:
1842 break
1846 break
1843 else:
1847 else:
1844 self.input_hist_raw.append("\n")
1848 self.input_hist_raw.append("\n")
1845 # final newline in case the input didn't have it, so that the code
1849 # final newline in case the input didn't have it, so that the code
1846 # actually does get executed
1850 # actually does get executed
1847 if more:
1851 if more:
1848 self.push_line('\n')
1852 self.push_line('\n')
1849
1853
1850 def runsource(self, source, filename='<input>', symbol='single'):
1854 def runsource(self, source, filename='<input>', symbol='single'):
1851 """Compile and run some source in the interpreter.
1855 """Compile and run some source in the interpreter.
1852
1856
1853 Arguments are as for compile_command().
1857 Arguments are as for compile_command().
1854
1858
1855 One several things can happen:
1859 One several things can happen:
1856
1860
1857 1) The input is incorrect; compile_command() raised an
1861 1) The input is incorrect; compile_command() raised an
1858 exception (SyntaxError or OverflowError). A syntax traceback
1862 exception (SyntaxError or OverflowError). A syntax traceback
1859 will be printed by calling the showsyntaxerror() method.
1863 will be printed by calling the showsyntaxerror() method.
1860
1864
1861 2) The input is incomplete, and more input is required;
1865 2) The input is incomplete, and more input is required;
1862 compile_command() returned None. Nothing happens.
1866 compile_command() returned None. Nothing happens.
1863
1867
1864 3) The input is complete; compile_command() returned a code
1868 3) The input is complete; compile_command() returned a code
1865 object. The code is executed by calling self.runcode() (which
1869 object. The code is executed by calling self.runcode() (which
1866 also handles run-time exceptions, except for SystemExit).
1870 also handles run-time exceptions, except for SystemExit).
1867
1871
1868 The return value is:
1872 The return value is:
1869
1873
1870 - True in case 2
1874 - True in case 2
1871
1875
1872 - False in the other cases, unless an exception is raised, where
1876 - False in the other cases, unless an exception is raised, where
1873 None is returned instead. This can be used by external callers to
1877 None is returned instead. This can be used by external callers to
1874 know whether to continue feeding input or not.
1878 know whether to continue feeding input or not.
1875
1879
1876 The return value can be used to decide whether to use sys.ps1 or
1880 The return value can be used to decide whether to use sys.ps1 or
1877 sys.ps2 to prompt the next line."""
1881 sys.ps2 to prompt the next line."""
1878
1882
1879 # if the source code has leading blanks, add 'if 1:\n' to it
1883 # if the source code has leading blanks, add 'if 1:\n' to it
1880 # this allows execution of indented pasted code. It is tempting
1884 # this allows execution of indented pasted code. It is tempting
1881 # to add '\n' at the end of source to run commands like ' a=1'
1885 # to add '\n' at the end of source to run commands like ' a=1'
1882 # directly, but this fails for more complicated scenarios
1886 # directly, but this fails for more complicated scenarios
1883 source=source.encode(self.stdin_encoding)
1887 source=source.encode(self.stdin_encoding)
1884 if source[:1] in [' ', '\t']:
1888 if source[:1] in [' ', '\t']:
1885 source = 'if 1:\n%s' % source
1889 source = 'if 1:\n%s' % source
1886
1890
1887 try:
1891 try:
1888 code = self.compile(source,filename,symbol)
1892 code = self.compile(source,filename,symbol)
1889 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
1893 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
1890 # Case 1
1894 # Case 1
1891 self.showsyntaxerror(filename)
1895 self.showsyntaxerror(filename)
1892 return None
1896 return None
1893
1897
1894 if code is None:
1898 if code is None:
1895 # Case 2
1899 # Case 2
1896 return True
1900 return True
1897
1901
1898 # Case 3
1902 # Case 3
1899 # We store the code object so that threaded shells and
1903 # We store the code object so that threaded shells and
1900 # custom exception handlers can access all this info if needed.
1904 # custom exception handlers can access all this info if needed.
1901 # The source corresponding to this can be obtained from the
1905 # The source corresponding to this can be obtained from the
1902 # buffer attribute as '\n'.join(self.buffer).
1906 # buffer attribute as '\n'.join(self.buffer).
1903 self.code_to_run = code
1907 self.code_to_run = code
1904 # now actually execute the code object
1908 # now actually execute the code object
1905 if self.runcode(code) == 0:
1909 if self.runcode(code) == 0:
1906 return False
1910 return False
1907 else:
1911 else:
1908 return None
1912 return None
1909
1913
1910 def runcode(self,code_obj):
1914 def runcode(self,code_obj):
1911 """Execute a code object.
1915 """Execute a code object.
1912
1916
1913 When an exception occurs, self.showtraceback() is called to display a
1917 When an exception occurs, self.showtraceback() is called to display a
1914 traceback.
1918 traceback.
1915
1919
1916 Return value: a flag indicating whether the code to be run completed
1920 Return value: a flag indicating whether the code to be run completed
1917 successfully:
1921 successfully:
1918
1922
1919 - 0: successful execution.
1923 - 0: successful execution.
1920 - 1: an error occurred.
1924 - 1: an error occurred.
1921 """
1925 """
1922
1926
1923 # Set our own excepthook in case the user code tries to call it
1927 # Set our own excepthook in case the user code tries to call it
1924 # directly, so that the IPython crash handler doesn't get triggered
1928 # directly, so that the IPython crash handler doesn't get triggered
1925 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
1929 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
1926
1930
1927 # we save the original sys.excepthook in the instance, in case config
1931 # we save the original sys.excepthook in the instance, in case config
1928 # code (such as magics) needs access to it.
1932 # code (such as magics) needs access to it.
1929 self.sys_excepthook = old_excepthook
1933 self.sys_excepthook = old_excepthook
1930 outflag = 1 # happens in more places, so it's easier as default
1934 outflag = 1 # happens in more places, so it's easier as default
1931 try:
1935 try:
1932 try:
1936 try:
1933 self.hooks.pre_runcode_hook()
1937 self.hooks.pre_runcode_hook()
1934 #rprint('Running code') # dbg
1938 #rprint('Running code') # dbg
1935 exec code_obj in self.user_global_ns, self.user_ns
1939 exec code_obj in self.user_global_ns, self.user_ns
1936 finally:
1940 finally:
1937 # Reset our crash handler in place
1941 # Reset our crash handler in place
1938 sys.excepthook = old_excepthook
1942 sys.excepthook = old_excepthook
1939 except SystemExit:
1943 except SystemExit:
1940 self.resetbuffer()
1944 self.resetbuffer()
1941 self.showtraceback(exception_only=True)
1945 self.showtraceback(exception_only=True)
1942 warn("To exit: use any of 'exit', 'quit', %Exit or Ctrl-D.", level=1)
1946 warn("To exit: use any of 'exit', 'quit', %Exit or Ctrl-D.", level=1)
1943 except self.custom_exceptions:
1947 except self.custom_exceptions:
1944 etype,value,tb = sys.exc_info()
1948 etype,value,tb = sys.exc_info()
1945 self.CustomTB(etype,value,tb)
1949 self.CustomTB(etype,value,tb)
1946 except:
1950 except:
1947 self.showtraceback()
1951 self.showtraceback()
1948 else:
1952 else:
1949 outflag = 0
1953 outflag = 0
1950 if softspace(sys.stdout, 0):
1954 if softspace(sys.stdout, 0):
1951 print
1955 print
1952 # Flush out code object which has been run (and source)
1956 # Flush out code object which has been run (and source)
1953 self.code_to_run = None
1957 self.code_to_run = None
1954 return outflag
1958 return outflag
1955
1959
1956 def push_line(self, line):
1960 def push_line(self, line):
1957 """Push a line to the interpreter.
1961 """Push a line to the interpreter.
1958
1962
1959 The line should not have a trailing newline; it may have
1963 The line should not have a trailing newline; it may have
1960 internal newlines. The line is appended to a buffer and the
1964 internal newlines. The line is appended to a buffer and the
1961 interpreter's runsource() method is called with the
1965 interpreter's runsource() method is called with the
1962 concatenated contents of the buffer as source. If this
1966 concatenated contents of the buffer as source. If this
1963 indicates that the command was executed or invalid, the buffer
1967 indicates that the command was executed or invalid, the buffer
1964 is reset; otherwise, the command is incomplete, and the buffer
1968 is reset; otherwise, the command is incomplete, and the buffer
1965 is left as it was after the line was appended. The return
1969 is left as it was after the line was appended. The return
1966 value is 1 if more input is required, 0 if the line was dealt
1970 value is 1 if more input is required, 0 if the line was dealt
1967 with in some way (this is the same as runsource()).
1971 with in some way (this is the same as runsource()).
1968 """
1972 """
1969
1973
1970 # autoindent management should be done here, and not in the
1974 # autoindent management should be done here, and not in the
1971 # interactive loop, since that one is only seen by keyboard input. We
1975 # interactive loop, since that one is only seen by keyboard input. We
1972 # need this done correctly even for code run via runlines (which uses
1976 # need this done correctly even for code run via runlines (which uses
1973 # push).
1977 # push).
1974
1978
1975 #print 'push line: <%s>' % line # dbg
1979 #print 'push line: <%s>' % line # dbg
1976 for subline in line.splitlines():
1980 for subline in line.splitlines():
1977 self._autoindent_update(subline)
1981 self._autoindent_update(subline)
1978 self.buffer.append(line)
1982 self.buffer.append(line)
1979 more = self.runsource('\n'.join(self.buffer), self.filename)
1983 more = self.runsource('\n'.join(self.buffer), self.filename)
1980 if not more:
1984 if not more:
1981 self.resetbuffer()
1985 self.resetbuffer()
1982 return more
1986 return more
1983
1987
1984 def resetbuffer(self):
1988 def resetbuffer(self):
1985 """Reset the input buffer."""
1989 """Reset the input buffer."""
1986 self.buffer[:] = []
1990 self.buffer[:] = []
1987
1991
1988 def _is_secondary_block_start(self, s):
1992 def _is_secondary_block_start(self, s):
1989 if not s.endswith(':'):
1993 if not s.endswith(':'):
1990 return False
1994 return False
1991 if (s.startswith('elif') or
1995 if (s.startswith('elif') or
1992 s.startswith('else') or
1996 s.startswith('else') or
1993 s.startswith('except') or
1997 s.startswith('except') or
1994 s.startswith('finally')):
1998 s.startswith('finally')):
1995 return True
1999 return True
1996
2000
1997 def _cleanup_ipy_script(self, script):
2001 def _cleanup_ipy_script(self, script):
1998 """Make a script safe for self.runlines()
2002 """Make a script safe for self.runlines()
1999
2003
2000 Currently, IPython is lines based, with blocks being detected by
2004 Currently, IPython is lines based, with blocks being detected by
2001 empty lines. This is a problem for block based scripts that may
2005 empty lines. This is a problem for block based scripts that may
2002 not have empty lines after blocks. This script adds those empty
2006 not have empty lines after blocks. This script adds those empty
2003 lines to make scripts safe for running in the current line based
2007 lines to make scripts safe for running in the current line based
2004 IPython.
2008 IPython.
2005 """
2009 """
2006 res = []
2010 res = []
2007 lines = script.splitlines()
2011 lines = script.splitlines()
2008 level = 0
2012 level = 0
2009
2013
2010 for l in lines:
2014 for l in lines:
2011 lstripped = l.lstrip()
2015 lstripped = l.lstrip()
2012 stripped = l.strip()
2016 stripped = l.strip()
2013 if not stripped:
2017 if not stripped:
2014 continue
2018 continue
2015 newlevel = len(l) - len(lstripped)
2019 newlevel = len(l) - len(lstripped)
2016 if level > 0 and newlevel == 0 and \
2020 if level > 0 and newlevel == 0 and \
2017 not self._is_secondary_block_start(stripped):
2021 not self._is_secondary_block_start(stripped):
2018 # add empty line
2022 # add empty line
2019 res.append('')
2023 res.append('')
2020 res.append(l)
2024 res.append(l)
2021 level = newlevel
2025 level = newlevel
2022
2026
2023 return '\n'.join(res) + '\n'
2027 return '\n'.join(res) + '\n'
2024
2028
2025 def _autoindent_update(self,line):
2029 def _autoindent_update(self,line):
2026 """Keep track of the indent level."""
2030 """Keep track of the indent level."""
2027
2031
2028 #debugx('line')
2032 #debugx('line')
2029 #debugx('self.indent_current_nsp')
2033 #debugx('self.indent_current_nsp')
2030 if self.autoindent:
2034 if self.autoindent:
2031 if line:
2035 if line:
2032 inisp = num_ini_spaces(line)
2036 inisp = num_ini_spaces(line)
2033 if inisp < self.indent_current_nsp:
2037 if inisp < self.indent_current_nsp:
2034 self.indent_current_nsp = inisp
2038 self.indent_current_nsp = inisp
2035
2039
2036 if line[-1] == ':':
2040 if line[-1] == ':':
2037 self.indent_current_nsp += 4
2041 self.indent_current_nsp += 4
2038 elif dedent_re.match(line):
2042 elif dedent_re.match(line):
2039 self.indent_current_nsp -= 4
2043 self.indent_current_nsp -= 4
2040 else:
2044 else:
2041 self.indent_current_nsp = 0
2045 self.indent_current_nsp = 0
2042
2046
2043 #-------------------------------------------------------------------------
2047 #-------------------------------------------------------------------------
2044 # Things related to GUI support and pylab
2048 # Things related to GUI support and pylab
2045 #-------------------------------------------------------------------------
2049 #-------------------------------------------------------------------------
2046
2050
2047 def enable_pylab(self, gui=None):
2051 def enable_pylab(self, gui=None):
2048 raise NotImplementedError('Implement enable_pylab in a subclass')
2052 raise NotImplementedError('Implement enable_pylab in a subclass')
2049
2053
2050 #-------------------------------------------------------------------------
2054 #-------------------------------------------------------------------------
2051 # Utilities
2055 # Utilities
2052 #-------------------------------------------------------------------------
2056 #-------------------------------------------------------------------------
2053
2057
2054 def getoutput(self, cmd):
2058 def getoutput(self, cmd):
2055 return getoutput(self.var_expand(cmd,depth=2),
2059 return getoutput(self.var_expand(cmd,depth=2),
2056 header=self.system_header,
2060 header=self.system_header,
2057 verbose=self.system_verbose)
2061 verbose=self.system_verbose)
2058
2062
2059 def getoutputerror(self, cmd):
2063 def getoutputerror(self, cmd):
2060 return getoutputerror(self.var_expand(cmd,depth=2),
2064 return getoutputerror(self.var_expand(cmd,depth=2),
2061 header=self.system_header,
2065 header=self.system_header,
2062 verbose=self.system_verbose)
2066 verbose=self.system_verbose)
2063
2067
2064 def var_expand(self,cmd,depth=0):
2068 def var_expand(self,cmd,depth=0):
2065 """Expand python variables in a string.
2069 """Expand python variables in a string.
2066
2070
2067 The depth argument indicates how many frames above the caller should
2071 The depth argument indicates how many frames above the caller should
2068 be walked to look for the local namespace where to expand variables.
2072 be walked to look for the local namespace where to expand variables.
2069
2073
2070 The global namespace for expansion is always the user's interactive
2074 The global namespace for expansion is always the user's interactive
2071 namespace.
2075 namespace.
2072 """
2076 """
2073
2077
2074 return str(ItplNS(cmd,
2078 return str(ItplNS(cmd,
2075 self.user_ns, # globals
2079 self.user_ns, # globals
2076 # Skip our own frame in searching for locals:
2080 # Skip our own frame in searching for locals:
2077 sys._getframe(depth+1).f_locals # locals
2081 sys._getframe(depth+1).f_locals # locals
2078 ))
2082 ))
2079
2083
2080 def mktempfile(self,data=None):
2084 def mktempfile(self,data=None):
2081 """Make a new tempfile and return its filename.
2085 """Make a new tempfile and return its filename.
2082
2086
2083 This makes a call to tempfile.mktemp, but it registers the created
2087 This makes a call to tempfile.mktemp, but it registers the created
2084 filename internally so ipython cleans it up at exit time.
2088 filename internally so ipython cleans it up at exit time.
2085
2089
2086 Optional inputs:
2090 Optional inputs:
2087
2091
2088 - data(None): if data is given, it gets written out to the temp file
2092 - data(None): if data is given, it gets written out to the temp file
2089 immediately, and the file is closed again."""
2093 immediately, and the file is closed again."""
2090
2094
2091 filename = tempfile.mktemp('.py','ipython_edit_')
2095 filename = tempfile.mktemp('.py','ipython_edit_')
2092 self.tempfiles.append(filename)
2096 self.tempfiles.append(filename)
2093
2097
2094 if data:
2098 if data:
2095 tmp_file = open(filename,'w')
2099 tmp_file = open(filename,'w')
2096 tmp_file.write(data)
2100 tmp_file.write(data)
2097 tmp_file.close()
2101 tmp_file.close()
2098 return filename
2102 return filename
2099
2103
2100 # TODO: This should be removed when Term is refactored.
2104 # TODO: This should be removed when Term is refactored.
2101 def write(self,data):
2105 def write(self,data):
2102 """Write a string to the default output"""
2106 """Write a string to the default output"""
2103 io.Term.cout.write(data)
2107 io.Term.cout.write(data)
2104
2108
2105 # TODO: This should be removed when Term is refactored.
2109 # TODO: This should be removed when Term is refactored.
2106 def write_err(self,data):
2110 def write_err(self,data):
2107 """Write a string to the default error output"""
2111 """Write a string to the default error output"""
2108 io.Term.cerr.write(data)
2112 io.Term.cerr.write(data)
2109
2113
2110 def ask_yes_no(self,prompt,default=True):
2114 def ask_yes_no(self,prompt,default=True):
2111 if self.quiet:
2115 if self.quiet:
2112 return True
2116 return True
2113 return ask_yes_no(prompt,default)
2117 return ask_yes_no(prompt,default)
2114
2118
2115 #-------------------------------------------------------------------------
2119 #-------------------------------------------------------------------------
2116 # Things related to IPython exiting
2120 # Things related to IPython exiting
2117 #-------------------------------------------------------------------------
2121 #-------------------------------------------------------------------------
2118
2122
2119 def atexit_operations(self):
2123 def atexit_operations(self):
2120 """This will be executed at the time of exit.
2124 """This will be executed at the time of exit.
2121
2125
2122 Saving of persistent data should be performed here.
2126 Saving of persistent data should be performed here.
2123 """
2127 """
2124 self.savehist()
2128 self.savehist()
2125
2129
2126 # Cleanup all tempfiles left around
2130 # Cleanup all tempfiles left around
2127 for tfile in self.tempfiles:
2131 for tfile in self.tempfiles:
2128 try:
2132 try:
2129 os.unlink(tfile)
2133 os.unlink(tfile)
2130 except OSError:
2134 except OSError:
2131 pass
2135 pass
2132
2136
2133 # Clear all user namespaces to release all references cleanly.
2137 # Clear all user namespaces to release all references cleanly.
2134 self.reset()
2138 self.reset()
2135
2139
2136 # Run user hooks
2140 # Run user hooks
2137 self.hooks.shutdown_hook()
2141 self.hooks.shutdown_hook()
2138
2142
2139 def cleanup(self):
2143 def cleanup(self):
2140 self.restore_sys_module_state()
2144 self.restore_sys_module_state()
2141
2145
2142
2146
2143 class InteractiveShellABC(object):
2147 class InteractiveShellABC(object):
2144 """An abstract base class for InteractiveShell."""
2148 """An abstract base class for InteractiveShell."""
2145 __metaclass__ = abc.ABCMeta
2149 __metaclass__ = abc.ABCMeta
2146
2150
2147 InteractiveShellABC.register(InteractiveShell)
2151 InteractiveShellABC.register(InteractiveShell)
@@ -1,35 +1,83 b''
1 """Tests for the IPython tab-completion machinery.
1 """Tests for the IPython tab-completion machinery.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Module imports
4 # Module imports
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6
6
7 # stdlib
7 # stdlib
8 import sys
8 import sys
9 import unittest
9
10
10 # third party
11 # third party
11 import nose.tools as nt
12 import nose.tools as nt
12
13
13 # our own packages
14 # our own packages
14 from IPython.core import completer
15 from IPython.core import completer
15
16
16 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
17 # Test functions
18 # Test functions
18 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
19 def test_protect_filename():
20 def test_protect_filename():
20 pairs = [ ('abc','abc'),
21 pairs = [ ('abc','abc'),
21 (' abc',r'\ abc'),
22 (' abc',r'\ abc'),
22 ('a bc',r'a\ bc'),
23 ('a bc',r'a\ bc'),
23 ('a bc',r'a\ \ bc'),
24 ('a bc',r'a\ \ bc'),
24 (' bc',r'\ \ bc'),
25 (' bc',r'\ \ bc'),
25 ]
26 ]
26 # On posix, we also protect parens
27 # On posix, we also protect parens
27 if sys.platform != 'win32':
28 if sys.platform != 'win32':
28 pairs.extend( [('a(bc',r'a\(bc'),
29 pairs.extend( [('a(bc',r'a\(bc'),
29 ('a)bc',r'a\)bc'),
30 ('a)bc',r'a\)bc'),
30 ('a( )bc',r'a\(\ \)bc'),
31 ('a( )bc',r'a\(\ \)bc'),
31 ] )
32 ] )
32 # run the actual tests
33 # run the actual tests
33 for s1, s2 in pairs:
34 for s1, s2 in pairs:
34 s1p = completer.protect_filename(s1)
35 s1p = completer.protect_filename(s1)
35 nt.assert_equals(s1p, s2)
36 nt.assert_equals(s1p, s2)
37
38
39 def check_line_split(splitter, test_specs):
40 for part1, part2, split in test_specs:
41 cursor_pos = len(part1)
42 line = part1+part2
43 out = splitter.split_line(line, cursor_pos)
44 nt.assert_equal(out, split)
45
46
47 def test_line_split():
48 """Basice line splitter test with default specs."""
49 sp = completer.CompletionSplitter()
50 # The format of the test specs is: part1, part2, expected answer. Parts 1
51 # and 2 are joined into the 'line' sent to the splitter, as if the cursor
52 # was at the end of part1. So an empty part2 represents someone hitting
53 # tab at the end of the line, the most common case.
54 t = [('run some/scrip', '', 'some/scrip'),
55 ('run scripts/er', 'ror.py foo', 'scripts/er'),
56 ('echo $HOM', '', 'HOM'),
57 ('print sys.pa', '', 'sys.pa'),
58 ('print(sys.pa', '', 'sys.pa'),
59 ("execfile('scripts/er", '', 'scripts/er'),
60 ('a[x.', '', 'x.'),
61 ('a[x.', 'y', 'x.'),
62 ('cd "some_file/', '', 'some_file/'),
63 ]
64 check_line_split(sp, t)
65
66
67 class CompletionSplitterTestCase(unittest.TestCase):
68 def setUp(self):
69 self.sp = completer.CompletionSplitter()
70
71 def test_delim_setting(self):
72 self.sp.set_delims(' ')
73 nt.assert_equal(self.sp.get_delims(), ' ')
74 nt.assert_equal(self.sp._delim_expr, '[\ ]')
75
76 def test_spaces(self):
77 """Test with only spaces as split chars."""
78 self.sp.delims = ' '
79 t = [('foo', '', 'foo'),
80 ('run foo', '', 'foo'),
81 ('run foo', 'bar', 'foo'),
82 ]
83 check_line_split(self.sp, t)
@@ -1,1282 +1,1289 b''
1 # Standard library imports
1 # Standard library imports
2 import re
2 import re
3 import sys
3 import sys
4 from textwrap import dedent
4 from textwrap import dedent
5
5
6 # System library imports
6 # System library imports
7 from PyQt4 import QtCore, QtGui
7 from PyQt4 import QtCore, QtGui
8
8
9 # Local imports
9 # Local imports
10 from ansi_code_processor import QtAnsiCodeProcessor
10 from ansi_code_processor import QtAnsiCodeProcessor
11 from completion_widget import CompletionWidget
11 from completion_widget import CompletionWidget
12
12
13
13
14 class ConsoleWidget(QtGui.QWidget):
14 class ConsoleWidget(QtGui.QWidget):
15 """ An abstract base class for console-type widgets. This class has
15 """ An abstract base class for console-type widgets. This class has
16 functionality for:
16 functionality for:
17
17
18 * Maintaining a prompt and editing region
18 * Maintaining a prompt and editing region
19 * Providing the traditional Unix-style console keyboard shortcuts
19 * Providing the traditional Unix-style console keyboard shortcuts
20 * Performing tab completion
20 * Performing tab completion
21 * Paging text
21 * Paging text
22 * Handling ANSI escape codes
22 * Handling ANSI escape codes
23
23
24 ConsoleWidget also provides a number of utility methods that will be
24 ConsoleWidget also provides a number of utility methods that will be
25 convenient to implementors of a console-style widget.
25 convenient to implementors of a console-style widget.
26 """
26 """
27
27
28 # Whether to process ANSI escape codes.
28 # Whether to process ANSI escape codes.
29 ansi_codes = True
29 ansi_codes = True
30
30
31 # The maximum number of lines of text before truncation.
31 # The maximum number of lines of text before truncation.
32 buffer_size = 500
32 buffer_size = 500
33
33
34 # Whether to use a list widget or plain text output for tab completion.
34 # Whether to use a list widget or plain text output for tab completion.
35 gui_completion = True
35 gui_completion = True
36
36
37 # Whether to override ShortcutEvents for the keybindings defined by this
37 # Whether to override ShortcutEvents for the keybindings defined by this
38 # widget (Ctrl+n, Ctrl+a, etc). Enable this if you want this widget to take
38 # widget (Ctrl+n, Ctrl+a, etc). Enable this if you want this widget to take
39 # priority (when it has focus) over, e.g., window-level menu shortcuts.
39 # priority (when it has focus) over, e.g., window-level menu shortcuts.
40 override_shortcuts = False
40 override_shortcuts = False
41
41
42 # Signals that indicate ConsoleWidget state.
42 # Signals that indicate ConsoleWidget state.
43 copy_available = QtCore.pyqtSignal(bool)
43 copy_available = QtCore.pyqtSignal(bool)
44 redo_available = QtCore.pyqtSignal(bool)
44 redo_available = QtCore.pyqtSignal(bool)
45 undo_available = QtCore.pyqtSignal(bool)
45 undo_available = QtCore.pyqtSignal(bool)
46
46
47 # Signal emitted when paging is needed and the paging style has been
47 # Signal emitted when paging is needed and the paging style has been
48 # specified as 'custom'.
48 # specified as 'custom'.
49 custom_page_requested = QtCore.pyqtSignal(object)
49 custom_page_requested = QtCore.pyqtSignal(object)
50
50
51 # Protected class variables.
51 # Protected class variables.
52 _ctrl_down_remap = { QtCore.Qt.Key_B : QtCore.Qt.Key_Left,
52 _ctrl_down_remap = { QtCore.Qt.Key_B : QtCore.Qt.Key_Left,
53 QtCore.Qt.Key_F : QtCore.Qt.Key_Right,
53 QtCore.Qt.Key_F : QtCore.Qt.Key_Right,
54 QtCore.Qt.Key_A : QtCore.Qt.Key_Home,
54 QtCore.Qt.Key_A : QtCore.Qt.Key_Home,
55 QtCore.Qt.Key_E : QtCore.Qt.Key_End,
55 QtCore.Qt.Key_E : QtCore.Qt.Key_End,
56 QtCore.Qt.Key_P : QtCore.Qt.Key_Up,
56 QtCore.Qt.Key_P : QtCore.Qt.Key_Up,
57 QtCore.Qt.Key_N : QtCore.Qt.Key_Down,
57 QtCore.Qt.Key_N : QtCore.Qt.Key_Down,
58 QtCore.Qt.Key_D : QtCore.Qt.Key_Delete, }
58 QtCore.Qt.Key_D : QtCore.Qt.Key_Delete, }
59 _shortcuts = set(_ctrl_down_remap.keys() +
59 _shortcuts = set(_ctrl_down_remap.keys() +
60 [ QtCore.Qt.Key_C, QtCore.Qt.Key_V ])
60 [ QtCore.Qt.Key_C, QtCore.Qt.Key_V ])
61
61
62 #---------------------------------------------------------------------------
62 #---------------------------------------------------------------------------
63 # 'QObject' interface
63 # 'QObject' interface
64 #---------------------------------------------------------------------------
64 #---------------------------------------------------------------------------
65
65
66 def __init__(self, kind='plain', paging='inside', parent=None):
66 def __init__(self, kind='plain', paging='inside', parent=None):
67 """ Create a ConsoleWidget.
67 """ Create a ConsoleWidget.
68
68
69 Parameters
69 Parameters
70 ----------
70 ----------
71 kind : str, optional [default 'plain']
71 kind : str, optional [default 'plain']
72 The type of underlying text widget to use. Valid values are 'plain',
72 The type of underlying text widget to use. Valid values are 'plain',
73 which specifies a QPlainTextEdit, and 'rich', which specifies a
73 which specifies a QPlainTextEdit, and 'rich', which specifies a
74 QTextEdit.
74 QTextEdit.
75
75
76 paging : str, optional [default 'inside']
76 paging : str, optional [default 'inside']
77 The type of paging to use. Valid values are:
77 The type of paging to use. Valid values are:
78 'inside' : The widget pages like a traditional terminal pager.
78 'inside' : The widget pages like a traditional terminal pager.
79 'hsplit' : When paging is requested, the widget is split
79 'hsplit' : When paging is requested, the widget is split
80 horizontally. The top pane contains the console,
80 horizontally. The top pane contains the console,
81 and the bottom pane contains the paged text.
81 and the bottom pane contains the paged text.
82 'vsplit' : Similar to 'hsplit', except that a vertical splitter
82 'vsplit' : Similar to 'hsplit', except that a vertical splitter
83 used.
83 used.
84 'custom' : No action is taken by the widget beyond emitting a
84 'custom' : No action is taken by the widget beyond emitting a
85 'custom_page_requested(str)' signal.
85 'custom_page_requested(str)' signal.
86 'none' : The text is written directly to the console.
86 'none' : The text is written directly to the console.
87
87
88 parent : QWidget, optional [default None]
88 parent : QWidget, optional [default None]
89 The parent for this widget.
89 The parent for this widget.
90 """
90 """
91 super(ConsoleWidget, self).__init__(parent)
91 super(ConsoleWidget, self).__init__(parent)
92
92
93 # Create the layout and underlying text widget.
93 # Create the layout and underlying text widget.
94 layout = QtGui.QStackedLayout(self)
94 layout = QtGui.QStackedLayout(self)
95 layout.setMargin(0)
95 layout.setMargin(0)
96 self._control = self._create_control(kind)
96 self._control = self._create_control(kind)
97 self._page_control = None
97 self._page_control = None
98 self._splitter = None
98 self._splitter = None
99 if paging in ('hsplit', 'vsplit'):
99 if paging in ('hsplit', 'vsplit'):
100 self._splitter = QtGui.QSplitter()
100 self._splitter = QtGui.QSplitter()
101 if paging == 'hsplit':
101 if paging == 'hsplit':
102 self._splitter.setOrientation(QtCore.Qt.Horizontal)
102 self._splitter.setOrientation(QtCore.Qt.Horizontal)
103 else:
103 else:
104 self._splitter.setOrientation(QtCore.Qt.Vertical)
104 self._splitter.setOrientation(QtCore.Qt.Vertical)
105 self._splitter.addWidget(self._control)
105 self._splitter.addWidget(self._control)
106 layout.addWidget(self._splitter)
106 layout.addWidget(self._splitter)
107 else:
107 else:
108 layout.addWidget(self._control)
108 layout.addWidget(self._control)
109
109
110 # Create the paging widget, if necessary.
110 # Create the paging widget, if necessary.
111 self._page_style = paging
111 self._page_style = paging
112 if paging in ('inside', 'hsplit', 'vsplit'):
112 if paging in ('inside', 'hsplit', 'vsplit'):
113 self._page_control = self._create_page_control()
113 self._page_control = self._create_page_control()
114 if self._splitter:
114 if self._splitter:
115 self._page_control.hide()
115 self._page_control.hide()
116 self._splitter.addWidget(self._page_control)
116 self._splitter.addWidget(self._page_control)
117 else:
117 else:
118 layout.addWidget(self._page_control)
118 layout.addWidget(self._page_control)
119 elif paging not in ('custom', 'none'):
119 elif paging not in ('custom', 'none'):
120 raise ValueError('Paging style %s unknown.' % repr(paging))
120 raise ValueError('Paging style %s unknown.' % repr(paging))
121
121
122 # Initialize protected variables. Some variables contain useful state
122 # Initialize protected variables. Some variables contain useful state
123 # information for subclasses; they should be considered read-only.
123 # information for subclasses; they should be considered read-only.
124 self._ansi_processor = QtAnsiCodeProcessor()
124 self._ansi_processor = QtAnsiCodeProcessor()
125 self._completion_widget = CompletionWidget(self._control)
125 self._completion_widget = CompletionWidget(self._control)
126 self._continuation_prompt = '> '
126 self._continuation_prompt = '> '
127 self._continuation_prompt_html = None
127 self._continuation_prompt_html = None
128 self._executing = False
128 self._executing = False
129 self._prompt = ''
129 self._prompt = ''
130 self._prompt_html = None
130 self._prompt_html = None
131 self._prompt_pos = 0
131 self._prompt_pos = 0
132 self._reading = False
132 self._reading = False
133 self._reading_callback = None
133 self._reading_callback = None
134 self._tab_width = 8
134 self._tab_width = 8
135
135
136 # Set a monospaced font.
136 # Set a monospaced font.
137 self.reset_font()
137 self.reset_font()
138
138
139 def eventFilter(self, obj, event):
139 def eventFilter(self, obj, event):
140 """ Reimplemented to ensure a console-like behavior in the underlying
140 """ Reimplemented to ensure a console-like behavior in the underlying
141 text widget.
141 text widget.
142 """
142 """
143 # Re-map keys for all filtered widgets.
143 # Re-map keys for all filtered widgets.
144 etype = event.type()
144 etype = event.type()
145 if etype == QtCore.QEvent.KeyPress and \
145 if etype == QtCore.QEvent.KeyPress and \
146 self._control_key_down(event.modifiers()) and \
146 self._control_key_down(event.modifiers()) and \
147 event.key() in self._ctrl_down_remap:
147 event.key() in self._ctrl_down_remap:
148 new_event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress,
148 new_event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress,
149 self._ctrl_down_remap[event.key()],
149 self._ctrl_down_remap[event.key()],
150 QtCore.Qt.NoModifier)
150 QtCore.Qt.NoModifier)
151 QtGui.qApp.sendEvent(obj, new_event)
151 QtGui.qApp.sendEvent(obj, new_event)
152 return True
152 return True
153
153
154 # Override shortucts for all filtered widgets. Note that on Mac OS it is
154 # Override shortucts for all filtered widgets. Note that on Mac OS it is
155 # always unnecessary to override shortcuts, hence the check below (users
155 # always unnecessary to override shortcuts, hence the check below (users
156 # should just use the Control key instead of the Command key).
156 # should just use the Control key instead of the Command key).
157 elif etype == QtCore.QEvent.ShortcutOverride and \
157 elif etype == QtCore.QEvent.ShortcutOverride and \
158 sys.platform != 'darwin' and \
158 sys.platform != 'darwin' and \
159 self._control_key_down(event.modifiers()) and \
159 self._control_key_down(event.modifiers()) and \
160 event.key() in self._shortcuts:
160 event.key() in self._shortcuts:
161 event.accept()
161 event.accept()
162 return False
162 return False
163
163
164 elif obj == self._control:
164 elif obj == self._control:
165 # Disable moving text by drag and drop.
165 # Disable moving text by drag and drop.
166 if etype == QtCore.QEvent.DragMove:
166 if etype == QtCore.QEvent.DragMove:
167 return True
167 return True
168
168
169 elif etype == QtCore.QEvent.KeyPress:
169 elif etype == QtCore.QEvent.KeyPress:
170 return self._event_filter_console_keypress(event)
170 return self._event_filter_console_keypress(event)
171
171
172 elif obj == self._page_control:
172 elif obj == self._page_control:
173 if etype == QtCore.QEvent.KeyPress:
173 if etype == QtCore.QEvent.KeyPress:
174 return self._event_filter_page_keypress(event)
174 return self._event_filter_page_keypress(event)
175
175
176 return super(ConsoleWidget, self).eventFilter(obj, event)
176 return super(ConsoleWidget, self).eventFilter(obj, event)
177
177
178 #---------------------------------------------------------------------------
178 #---------------------------------------------------------------------------
179 # 'QWidget' interface
179 # 'QWidget' interface
180 #---------------------------------------------------------------------------
180 #---------------------------------------------------------------------------
181
181
182 def sizeHint(self):
182 def sizeHint(self):
183 """ Reimplemented to suggest a size that is 80 characters wide and
183 """ Reimplemented to suggest a size that is 80 characters wide and
184 25 lines high.
184 25 lines high.
185 """
185 """
186 style = self.style()
186 style = self.style()
187 opt = QtGui.QStyleOptionHeader()
187 opt = QtGui.QStyleOptionHeader()
188 font_metrics = QtGui.QFontMetrics(self.font)
188 font_metrics = QtGui.QFontMetrics(self.font)
189 splitwidth = style.pixelMetric(QtGui.QStyle.PM_SplitterWidth, opt, self)
189 splitwidth = style.pixelMetric(QtGui.QStyle.PM_SplitterWidth, opt, self)
190
190
191 width = font_metrics.width(' ') * 80
191 width = font_metrics.width(' ') * 80
192 width += style.pixelMetric(QtGui.QStyle.PM_ScrollBarExtent, opt, self)
192 width += style.pixelMetric(QtGui.QStyle.PM_ScrollBarExtent, opt, self)
193 if self._page_style == 'hsplit':
193 if self._page_style == 'hsplit':
194 width = width * 2 + splitwidth
194 width = width * 2 + splitwidth
195
195
196 height = font_metrics.height() * 25
196 height = font_metrics.height() * 25
197 if self._page_style == 'vsplit':
197 if self._page_style == 'vsplit':
198 height = height * 2 + splitwidth
198 height = height * 2 + splitwidth
199
199
200 return QtCore.QSize(width, height)
200 return QtCore.QSize(width, height)
201
201
202 #---------------------------------------------------------------------------
202 #---------------------------------------------------------------------------
203 # 'ConsoleWidget' public interface
203 # 'ConsoleWidget' public interface
204 #---------------------------------------------------------------------------
204 #---------------------------------------------------------------------------
205
205
206 def can_paste(self):
206 def can_paste(self):
207 """ Returns whether text can be pasted from the clipboard.
207 """ Returns whether text can be pasted from the clipboard.
208 """
208 """
209 # Accept only text that can be ASCII encoded.
209 # Accept only text that can be ASCII encoded.
210 if self._control.textInteractionFlags() & QtCore.Qt.TextEditable:
210 if self._control.textInteractionFlags() & QtCore.Qt.TextEditable:
211 text = QtGui.QApplication.clipboard().text()
211 text = QtGui.QApplication.clipboard().text()
212 if not text.isEmpty():
212 if not text.isEmpty():
213 try:
213 try:
214 str(text)
214 str(text)
215 return True
215 return True
216 except UnicodeEncodeError:
216 except UnicodeEncodeError:
217 pass
217 pass
218 return False
218 return False
219
219
220 def clear(self, keep_input=True):
220 def clear(self, keep_input=True):
221 """ Clear the console, then write a new prompt. If 'keep_input' is set,
221 """ Clear the console, then write a new prompt. If 'keep_input' is set,
222 restores the old input buffer when the new prompt is written.
222 restores the old input buffer when the new prompt is written.
223 """
223 """
224 if keep_input:
224 if keep_input:
225 input_buffer = self.input_buffer
225 input_buffer = self.input_buffer
226 self._control.clear()
226 self._control.clear()
227 self._show_prompt()
227 self._show_prompt()
228 if keep_input:
228 if keep_input:
229 self.input_buffer = input_buffer
229 self.input_buffer = input_buffer
230
230
231 def copy(self):
231 def copy(self):
232 """ Copy the current selected text to the clipboard.
232 """ Copy the current selected text to the clipboard.
233 """
233 """
234 self._control.copy()
234 self._control.copy()
235
235
236 def execute(self, source=None, hidden=False, interactive=False):
236 def execute(self, source=None, hidden=False, interactive=False):
237 """ Executes source or the input buffer, possibly prompting for more
237 """ Executes source or the input buffer, possibly prompting for more
238 input.
238 input.
239
239
240 Parameters:
240 Parameters:
241 -----------
241 -----------
242 source : str, optional
242 source : str, optional
243
243
244 The source to execute. If not specified, the input buffer will be
244 The source to execute. If not specified, the input buffer will be
245 used. If specified and 'hidden' is False, the input buffer will be
245 used. If specified and 'hidden' is False, the input buffer will be
246 replaced with the source before execution.
246 replaced with the source before execution.
247
247
248 hidden : bool, optional (default False)
248 hidden : bool, optional (default False)
249
249
250 If set, no output will be shown and the prompt will not be modified.
250 If set, no output will be shown and the prompt will not be modified.
251 In other words, it will be completely invisible to the user that
251 In other words, it will be completely invisible to the user that
252 an execution has occurred.
252 an execution has occurred.
253
253
254 interactive : bool, optional (default False)
254 interactive : bool, optional (default False)
255
255
256 Whether the console is to treat the source as having been manually
256 Whether the console is to treat the source as having been manually
257 entered by the user. The effect of this parameter depends on the
257 entered by the user. The effect of this parameter depends on the
258 subclass implementation.
258 subclass implementation.
259
259
260 Raises:
260 Raises:
261 -------
261 -------
262 RuntimeError
262 RuntimeError
263 If incomplete input is given and 'hidden' is True. In this case,
263 If incomplete input is given and 'hidden' is True. In this case,
264 it is not possible to prompt for more input.
264 it is not possible to prompt for more input.
265
265
266 Returns:
266 Returns:
267 --------
267 --------
268 A boolean indicating whether the source was executed.
268 A boolean indicating whether the source was executed.
269 """
269 """
270 if not hidden:
270 if not hidden:
271 if source is not None:
271 if source is not None:
272 self.input_buffer = source
272 self.input_buffer = source
273
273
274 self._append_plain_text('\n')
274 self._append_plain_text('\n')
275 self._executing_input_buffer = self.input_buffer
275 self._executing_input_buffer = self.input_buffer
276 self._executing = True
276 self._executing = True
277 self._prompt_finished()
277 self._prompt_finished()
278
278
279 real_source = self.input_buffer if source is None else source
279 real_source = self.input_buffer if source is None else source
280 complete = self._is_complete(real_source, interactive)
280 complete = self._is_complete(real_source, interactive)
281 if complete:
281 if complete:
282 if not hidden:
282 if not hidden:
283 # The maximum block count is only in effect during execution.
283 # The maximum block count is only in effect during execution.
284 # This ensures that _prompt_pos does not become invalid due to
284 # This ensures that _prompt_pos does not become invalid due to
285 # text truncation.
285 # text truncation.
286 self._control.document().setMaximumBlockCount(self.buffer_size)
286 self._control.document().setMaximumBlockCount(self.buffer_size)
287 self._execute(real_source, hidden)
287 self._execute(real_source, hidden)
288 elif hidden:
288 elif hidden:
289 raise RuntimeError('Incomplete noninteractive input: "%s"' % source)
289 raise RuntimeError('Incomplete noninteractive input: "%s"' % source)
290 else:
290 else:
291 self._show_continuation_prompt()
291 self._show_continuation_prompt()
292
292
293 return complete
293 return complete
294
294
295 def _get_input_buffer(self):
295 def _get_input_buffer(self):
296 """ The text that the user has entered entered at the current prompt.
296 """ The text that the user has entered entered at the current prompt.
297 """
297 """
298 # If we're executing, the input buffer may not even exist anymore due to
298 # If we're executing, the input buffer may not even exist anymore due to
299 # the limit imposed by 'buffer_size'. Therefore, we store it.
299 # the limit imposed by 'buffer_size'. Therefore, we store it.
300 if self._executing:
300 if self._executing:
301 return self._executing_input_buffer
301 return self._executing_input_buffer
302
302
303 cursor = self._get_end_cursor()
303 cursor = self._get_end_cursor()
304 cursor.setPosition(self._prompt_pos, QtGui.QTextCursor.KeepAnchor)
304 cursor.setPosition(self._prompt_pos, QtGui.QTextCursor.KeepAnchor)
305 input_buffer = str(cursor.selection().toPlainText())
305 input_buffer = str(cursor.selection().toPlainText())
306
306
307 # Strip out continuation prompts.
307 # Strip out continuation prompts.
308 return input_buffer.replace('\n' + self._continuation_prompt, '\n')
308 return input_buffer.replace('\n' + self._continuation_prompt, '\n')
309
309
310 def _set_input_buffer(self, string):
310 def _set_input_buffer(self, string):
311 """ Replaces the text in the input buffer with 'string'.
311 """ Replaces the text in the input buffer with 'string'.
312 """
312 """
313 # For now, it is an error to modify the input buffer during execution.
313 # For now, it is an error to modify the input buffer during execution.
314 if self._executing:
314 if self._executing:
315 raise RuntimeError("Cannot change input buffer during execution.")
315 raise RuntimeError("Cannot change input buffer during execution.")
316
316
317 # Remove old text.
317 # Remove old text.
318 cursor = self._get_end_cursor()
318 cursor = self._get_end_cursor()
319 cursor.beginEditBlock()
319 cursor.beginEditBlock()
320 cursor.setPosition(self._prompt_pos, QtGui.QTextCursor.KeepAnchor)
320 cursor.setPosition(self._prompt_pos, QtGui.QTextCursor.KeepAnchor)
321 cursor.removeSelectedText()
321 cursor.removeSelectedText()
322
322
323 # Insert new text with continuation prompts.
323 # Insert new text with continuation prompts.
324 lines = string.splitlines(True)
324 lines = string.splitlines(True)
325 if lines:
325 if lines:
326 self._append_plain_text(lines[0])
326 self._append_plain_text(lines[0])
327 for i in xrange(1, len(lines)):
327 for i in xrange(1, len(lines)):
328 if self._continuation_prompt_html is None:
328 if self._continuation_prompt_html is None:
329 self._append_plain_text(self._continuation_prompt)
329 self._append_plain_text(self._continuation_prompt)
330 else:
330 else:
331 self._append_html(self._continuation_prompt_html)
331 self._append_html(self._continuation_prompt_html)
332 self._append_plain_text(lines[i])
332 self._append_plain_text(lines[i])
333 cursor.endEditBlock()
333 cursor.endEditBlock()
334 self._control.moveCursor(QtGui.QTextCursor.End)
334 self._control.moveCursor(QtGui.QTextCursor.End)
335
335
336 input_buffer = property(_get_input_buffer, _set_input_buffer)
336 input_buffer = property(_get_input_buffer, _set_input_buffer)
337
337
338 def _get_font(self):
338 def _get_font(self):
339 """ The base font being used by the ConsoleWidget.
339 """ The base font being used by the ConsoleWidget.
340 """
340 """
341 return self._control.document().defaultFont()
341 return self._control.document().defaultFont()
342
342
343 def _set_font(self, font):
343 def _set_font(self, font):
344 """ Sets the base font for the ConsoleWidget to the specified QFont.
344 """ Sets the base font for the ConsoleWidget to the specified QFont.
345 """
345 """
346 font_metrics = QtGui.QFontMetrics(font)
346 font_metrics = QtGui.QFontMetrics(font)
347 self._control.setTabStopWidth(self.tab_width * font_metrics.width(' '))
347 self._control.setTabStopWidth(self.tab_width * font_metrics.width(' '))
348
348
349 self._completion_widget.setFont(font)
349 self._completion_widget.setFont(font)
350 self._control.document().setDefaultFont(font)
350 self._control.document().setDefaultFont(font)
351 if self._page_control:
351 if self._page_control:
352 self._page_control.document().setDefaultFont(font)
352 self._page_control.document().setDefaultFont(font)
353
353
354 font = property(_get_font, _set_font)
354 font = property(_get_font, _set_font)
355
355
356 def paste(self):
356 def paste(self):
357 """ Paste the contents of the clipboard into the input region.
357 """ Paste the contents of the clipboard into the input region.
358 """
358 """
359 if self._control.textInteractionFlags() & QtCore.Qt.TextEditable:
359 if self._control.textInteractionFlags() & QtCore.Qt.TextEditable:
360 try:
360 try:
361 text = str(QtGui.QApplication.clipboard().text())
361 text = str(QtGui.QApplication.clipboard().text())
362 except UnicodeEncodeError:
362 except UnicodeEncodeError:
363 pass
363 pass
364 else:
364 else:
365 self._insert_plain_text_into_buffer(dedent(text))
365 self._insert_plain_text_into_buffer(dedent(text))
366
366
367 def print_(self, printer):
367 def print_(self, printer):
368 """ Print the contents of the ConsoleWidget to the specified QPrinter.
368 """ Print the contents of the ConsoleWidget to the specified QPrinter.
369 """
369 """
370 self._control.print_(printer)
370 self._control.print_(printer)
371
371
372 def redo(self):
372 def redo(self):
373 """ Redo the last operation. If there is no operation to redo, nothing
373 """ Redo the last operation. If there is no operation to redo, nothing
374 happens.
374 happens.
375 """
375 """
376 self._control.redo()
376 self._control.redo()
377
377
378 def reset_font(self):
378 def reset_font(self):
379 """ Sets the font to the default fixed-width font for this platform.
379 """ Sets the font to the default fixed-width font for this platform.
380 """
380 """
381 # FIXME: font family and size should be configurable by the user.
382
381 if sys.platform == 'win32':
383 if sys.platform == 'win32':
384 # Fixme: we should test whether Consolas is available and use it
385 # first if it is. Consolas ships by default from Vista onwards,
386 # it's *vastly* more readable and prettier than Courier, and is
387 # often installed even on XP systems. So we should first check for
388 # it, and only fallback to Courier if absolutely necessary.
382 name = 'Courier'
389 name = 'Courier'
383 elif sys.platform == 'darwin':
390 elif sys.platform == 'darwin':
384 name = 'Monaco'
391 name = 'Monaco'
385 else:
392 else:
386 name = 'Monospace'
393 name = 'Monospace'
387 font = QtGui.QFont(name, QtGui.qApp.font().pointSize())
394 font = QtGui.QFont(name, QtGui.qApp.font().pointSize())
388 font.setStyleHint(QtGui.QFont.TypeWriter)
395 font.setStyleHint(QtGui.QFont.TypeWriter)
389 self._set_font(font)
396 self._set_font(font)
390
397
391 def select_all(self):
398 def select_all(self):
392 """ Selects all the text in the buffer.
399 """ Selects all the text in the buffer.
393 """
400 """
394 self._control.selectAll()
401 self._control.selectAll()
395
402
396 def _get_tab_width(self):
403 def _get_tab_width(self):
397 """ The width (in terms of space characters) for tab characters.
404 """ The width (in terms of space characters) for tab characters.
398 """
405 """
399 return self._tab_width
406 return self._tab_width
400
407
401 def _set_tab_width(self, tab_width):
408 def _set_tab_width(self, tab_width):
402 """ Sets the width (in terms of space characters) for tab characters.
409 """ Sets the width (in terms of space characters) for tab characters.
403 """
410 """
404 font_metrics = QtGui.QFontMetrics(self.font)
411 font_metrics = QtGui.QFontMetrics(self.font)
405 self._control.setTabStopWidth(tab_width * font_metrics.width(' '))
412 self._control.setTabStopWidth(tab_width * font_metrics.width(' '))
406
413
407 self._tab_width = tab_width
414 self._tab_width = tab_width
408
415
409 tab_width = property(_get_tab_width, _set_tab_width)
416 tab_width = property(_get_tab_width, _set_tab_width)
410
417
411 def undo(self):
418 def undo(self):
412 """ Undo the last operation. If there is no operation to undo, nothing
419 """ Undo the last operation. If there is no operation to undo, nothing
413 happens.
420 happens.
414 """
421 """
415 self._control.undo()
422 self._control.undo()
416
423
417 #---------------------------------------------------------------------------
424 #---------------------------------------------------------------------------
418 # 'ConsoleWidget' abstract interface
425 # 'ConsoleWidget' abstract interface
419 #---------------------------------------------------------------------------
426 #---------------------------------------------------------------------------
420
427
421 def _is_complete(self, source, interactive):
428 def _is_complete(self, source, interactive):
422 """ Returns whether 'source' can be executed. When triggered by an
429 """ Returns whether 'source' can be executed. When triggered by an
423 Enter/Return key press, 'interactive' is True; otherwise, it is
430 Enter/Return key press, 'interactive' is True; otherwise, it is
424 False.
431 False.
425 """
432 """
426 raise NotImplementedError
433 raise NotImplementedError
427
434
428 def _execute(self, source, hidden):
435 def _execute(self, source, hidden):
429 """ Execute 'source'. If 'hidden', do not show any output.
436 """ Execute 'source'. If 'hidden', do not show any output.
430 """
437 """
431 raise NotImplementedError
438 raise NotImplementedError
432
439
433 def _prompt_started_hook(self):
440 def _prompt_started_hook(self):
434 """ Called immediately after a new prompt is displayed.
441 """ Called immediately after a new prompt is displayed.
435 """
442 """
436 pass
443 pass
437
444
438 def _prompt_finished_hook(self):
445 def _prompt_finished_hook(self):
439 """ Called immediately after a prompt is finished, i.e. when some input
446 """ Called immediately after a prompt is finished, i.e. when some input
440 will be processed and a new prompt displayed.
447 will be processed and a new prompt displayed.
441 """
448 """
442 pass
449 pass
443
450
444 def _up_pressed(self):
451 def _up_pressed(self):
445 """ Called when the up key is pressed. Returns whether to continue
452 """ Called when the up key is pressed. Returns whether to continue
446 processing the event.
453 processing the event.
447 """
454 """
448 return True
455 return True
449
456
450 def _down_pressed(self):
457 def _down_pressed(self):
451 """ Called when the down key is pressed. Returns whether to continue
458 """ Called when the down key is pressed. Returns whether to continue
452 processing the event.
459 processing the event.
453 """
460 """
454 return True
461 return True
455
462
456 def _tab_pressed(self):
463 def _tab_pressed(self):
457 """ Called when the tab key is pressed. Returns whether to continue
464 """ Called when the tab key is pressed. Returns whether to continue
458 processing the event.
465 processing the event.
459 """
466 """
460 return False
467 return False
461
468
462 #--------------------------------------------------------------------------
469 #--------------------------------------------------------------------------
463 # 'ConsoleWidget' protected interface
470 # 'ConsoleWidget' protected interface
464 #--------------------------------------------------------------------------
471 #--------------------------------------------------------------------------
465
472
466 def _append_html(self, html):
473 def _append_html(self, html):
467 """ Appends html at the end of the console buffer.
474 """ Appends html at the end of the console buffer.
468 """
475 """
469 cursor = self._get_end_cursor()
476 cursor = self._get_end_cursor()
470 self._insert_html(cursor, html)
477 self._insert_html(cursor, html)
471
478
472 def _append_html_fetching_plain_text(self, html):
479 def _append_html_fetching_plain_text(self, html):
473 """ Appends 'html', then returns the plain text version of it.
480 """ Appends 'html', then returns the plain text version of it.
474 """
481 """
475 cursor = self._get_end_cursor()
482 cursor = self._get_end_cursor()
476 return self._insert_html_fetching_plain_text(cursor, html)
483 return self._insert_html_fetching_plain_text(cursor, html)
477
484
478 def _append_plain_text(self, text):
485 def _append_plain_text(self, text):
479 """ Appends plain text at the end of the console buffer, processing
486 """ Appends plain text at the end of the console buffer, processing
480 ANSI codes if enabled.
487 ANSI codes if enabled.
481 """
488 """
482 cursor = self._get_end_cursor()
489 cursor = self._get_end_cursor()
483 self._insert_plain_text(cursor, text)
490 self._insert_plain_text(cursor, text)
484
491
485 def _append_plain_text_keeping_prompt(self, text):
492 def _append_plain_text_keeping_prompt(self, text):
486 """ Writes 'text' after the current prompt, then restores the old prompt
493 """ Writes 'text' after the current prompt, then restores the old prompt
487 with its old input buffer.
494 with its old input buffer.
488 """
495 """
489 input_buffer = self.input_buffer
496 input_buffer = self.input_buffer
490 self._append_plain_text('\n')
497 self._append_plain_text('\n')
491 self._prompt_finished()
498 self._prompt_finished()
492
499
493 self._append_plain_text(text)
500 self._append_plain_text(text)
494 self._show_prompt()
501 self._show_prompt()
495 self.input_buffer = input_buffer
502 self.input_buffer = input_buffer
496
503
497 def _complete_with_items(self, cursor, items):
504 def _complete_with_items(self, cursor, items):
498 """ Performs completion with 'items' at the specified cursor location.
505 """ Performs completion with 'items' at the specified cursor location.
499 """
506 """
500 if len(items) == 1:
507 if len(items) == 1:
501 cursor.setPosition(self._control.textCursor().position(),
508 cursor.setPosition(self._control.textCursor().position(),
502 QtGui.QTextCursor.KeepAnchor)
509 QtGui.QTextCursor.KeepAnchor)
503 cursor.insertText(items[0])
510 cursor.insertText(items[0])
504 elif len(items) > 1:
511 elif len(items) > 1:
505 if self.gui_completion:
512 if self.gui_completion:
506 self._completion_widget.show_items(cursor, items)
513 self._completion_widget.show_items(cursor, items)
507 else:
514 else:
508 text = self._format_as_columns(items)
515 text = self._format_as_columns(items)
509 self._append_plain_text_keeping_prompt(text)
516 self._append_plain_text_keeping_prompt(text)
510
517
511 def _control_key_down(self, modifiers):
518 def _control_key_down(self, modifiers):
512 """ Given a KeyboardModifiers flags object, return whether the Control
519 """ Given a KeyboardModifiers flags object, return whether the Control
513 key is down (on Mac OS, treat the Command key as a synonym for
520 key is down (on Mac OS, treat the Command key as a synonym for
514 Control).
521 Control).
515 """
522 """
516 down = bool(modifiers & QtCore.Qt.ControlModifier)
523 down = bool(modifiers & QtCore.Qt.ControlModifier)
517
524
518 # Note: on Mac OS, ControlModifier corresponds to the Command key while
525 # Note: on Mac OS, ControlModifier corresponds to the Command key while
519 # MetaModifier corresponds to the Control key.
526 # MetaModifier corresponds to the Control key.
520 if sys.platform == 'darwin':
527 if sys.platform == 'darwin':
521 down = down ^ bool(modifiers & QtCore.Qt.MetaModifier)
528 down = down ^ bool(modifiers & QtCore.Qt.MetaModifier)
522
529
523 return down
530 return down
524
531
525 def _create_control(self, kind):
532 def _create_control(self, kind):
526 """ Creates and connects the underlying text widget.
533 """ Creates and connects the underlying text widget.
527 """
534 """
528 if kind == 'plain':
535 if kind == 'plain':
529 control = QtGui.QPlainTextEdit()
536 control = QtGui.QPlainTextEdit()
530 elif kind == 'rich':
537 elif kind == 'rich':
531 control = QtGui.QTextEdit()
538 control = QtGui.QTextEdit()
532 control.setAcceptRichText(False)
539 control.setAcceptRichText(False)
533 else:
540 else:
534 raise ValueError("Kind %s unknown." % repr(kind))
541 raise ValueError("Kind %s unknown." % repr(kind))
535 control.installEventFilter(self)
542 control.installEventFilter(self)
536 control.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
543 control.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
537 control.customContextMenuRequested.connect(self._show_context_menu)
544 control.customContextMenuRequested.connect(self._show_context_menu)
538 control.copyAvailable.connect(self.copy_available)
545 control.copyAvailable.connect(self.copy_available)
539 control.redoAvailable.connect(self.redo_available)
546 control.redoAvailable.connect(self.redo_available)
540 control.undoAvailable.connect(self.undo_available)
547 control.undoAvailable.connect(self.undo_available)
541 control.setReadOnly(True)
548 control.setReadOnly(True)
542 control.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
549 control.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
543 return control
550 return control
544
551
545 def _create_page_control(self):
552 def _create_page_control(self):
546 """ Creates and connects the underlying paging widget.
553 """ Creates and connects the underlying paging widget.
547 """
554 """
548 control = QtGui.QPlainTextEdit()
555 control = QtGui.QPlainTextEdit()
549 control.installEventFilter(self)
556 control.installEventFilter(self)
550 control.setReadOnly(True)
557 control.setReadOnly(True)
551 control.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
558 control.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
552 return control
559 return control
553
560
554 def _event_filter_console_keypress(self, event):
561 def _event_filter_console_keypress(self, event):
555 """ Filter key events for the underlying text widget to create a
562 """ Filter key events for the underlying text widget to create a
556 console-like interface.
563 console-like interface.
557 """
564 """
558 intercepted = False
565 intercepted = False
559 cursor = self._control.textCursor()
566 cursor = self._control.textCursor()
560 position = cursor.position()
567 position = cursor.position()
561 key = event.key()
568 key = event.key()
562 ctrl_down = self._control_key_down(event.modifiers())
569 ctrl_down = self._control_key_down(event.modifiers())
563 alt_down = event.modifiers() & QtCore.Qt.AltModifier
570 alt_down = event.modifiers() & QtCore.Qt.AltModifier
564 shift_down = event.modifiers() & QtCore.Qt.ShiftModifier
571 shift_down = event.modifiers() & QtCore.Qt.ShiftModifier
565
572
566 if event.matches(QtGui.QKeySequence.Paste):
573 if event.matches(QtGui.QKeySequence.Paste):
567 # Call our paste instead of the underlying text widget's.
574 # Call our paste instead of the underlying text widget's.
568 self.paste()
575 self.paste()
569 intercepted = True
576 intercepted = True
570
577
571 elif ctrl_down:
578 elif ctrl_down:
572 if key == QtCore.Qt.Key_K:
579 if key == QtCore.Qt.Key_K:
573 if self._in_buffer(position):
580 if self._in_buffer(position):
574 cursor.movePosition(QtGui.QTextCursor.EndOfLine,
581 cursor.movePosition(QtGui.QTextCursor.EndOfLine,
575 QtGui.QTextCursor.KeepAnchor)
582 QtGui.QTextCursor.KeepAnchor)
576 cursor.removeSelectedText()
583 cursor.removeSelectedText()
577 intercepted = True
584 intercepted = True
578
585
579 elif key == QtCore.Qt.Key_X:
586 elif key == QtCore.Qt.Key_X:
580 intercepted = True
587 intercepted = True
581
588
582 elif key == QtCore.Qt.Key_Y:
589 elif key == QtCore.Qt.Key_Y:
583 self.paste()
590 self.paste()
584 intercepted = True
591 intercepted = True
585
592
586 elif alt_down:
593 elif alt_down:
587 if key == QtCore.Qt.Key_B:
594 if key == QtCore.Qt.Key_B:
588 self._set_cursor(self._get_word_start_cursor(position))
595 self._set_cursor(self._get_word_start_cursor(position))
589 intercepted = True
596 intercepted = True
590
597
591 elif key == QtCore.Qt.Key_F:
598 elif key == QtCore.Qt.Key_F:
592 self._set_cursor(self._get_word_end_cursor(position))
599 self._set_cursor(self._get_word_end_cursor(position))
593 intercepted = True
600 intercepted = True
594
601
595 elif key == QtCore.Qt.Key_Backspace:
602 elif key == QtCore.Qt.Key_Backspace:
596 cursor = self._get_word_start_cursor(position)
603 cursor = self._get_word_start_cursor(position)
597 cursor.setPosition(position, QtGui.QTextCursor.KeepAnchor)
604 cursor.setPosition(position, QtGui.QTextCursor.KeepAnchor)
598 cursor.removeSelectedText()
605 cursor.removeSelectedText()
599 intercepted = True
606 intercepted = True
600
607
601 elif key == QtCore.Qt.Key_D:
608 elif key == QtCore.Qt.Key_D:
602 cursor = self._get_word_end_cursor(position)
609 cursor = self._get_word_end_cursor(position)
603 cursor.setPosition(position, QtGui.QTextCursor.KeepAnchor)
610 cursor.setPosition(position, QtGui.QTextCursor.KeepAnchor)
604 cursor.removeSelectedText()
611 cursor.removeSelectedText()
605 intercepted = True
612 intercepted = True
606
613
607 else:
614 else:
608 if key in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter):
615 if key in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter):
609 if self._reading:
616 if self._reading:
610 self._append_plain_text('\n')
617 self._append_plain_text('\n')
611 self._reading = False
618 self._reading = False
612 if self._reading_callback:
619 if self._reading_callback:
613 self._reading_callback()
620 self._reading_callback()
614 elif not self._executing:
621 elif not self._executing:
615 self.execute(interactive=True)
622 self.execute(interactive=True)
616 intercepted = True
623 intercepted = True
617
624
618 elif key == QtCore.Qt.Key_Up:
625 elif key == QtCore.Qt.Key_Up:
619 if self._reading or not self._up_pressed():
626 if self._reading or not self._up_pressed():
620 intercepted = True
627 intercepted = True
621 else:
628 else:
622 prompt_line = self._get_prompt_cursor().blockNumber()
629 prompt_line = self._get_prompt_cursor().blockNumber()
623 intercepted = cursor.blockNumber() <= prompt_line
630 intercepted = cursor.blockNumber() <= prompt_line
624
631
625 elif key == QtCore.Qt.Key_Down:
632 elif key == QtCore.Qt.Key_Down:
626 if self._reading or not self._down_pressed():
633 if self._reading or not self._down_pressed():
627 intercepted = True
634 intercepted = True
628 else:
635 else:
629 end_line = self._get_end_cursor().blockNumber()
636 end_line = self._get_end_cursor().blockNumber()
630 intercepted = cursor.blockNumber() == end_line
637 intercepted = cursor.blockNumber() == end_line
631
638
632 elif key == QtCore.Qt.Key_Tab:
639 elif key == QtCore.Qt.Key_Tab:
633 if not self._reading:
640 if not self._reading:
634 intercepted = not self._tab_pressed()
641 intercepted = not self._tab_pressed()
635
642
636 elif key == QtCore.Qt.Key_Left:
643 elif key == QtCore.Qt.Key_Left:
637 intercepted = not self._in_buffer(position - 1)
644 intercepted = not self._in_buffer(position - 1)
638
645
639 elif key == QtCore.Qt.Key_Home:
646 elif key == QtCore.Qt.Key_Home:
640 cursor.movePosition(QtGui.QTextCursor.StartOfBlock)
647 cursor.movePosition(QtGui.QTextCursor.StartOfBlock)
641 start_line = cursor.blockNumber()
648 start_line = cursor.blockNumber()
642 if start_line == self._get_prompt_cursor().blockNumber():
649 if start_line == self._get_prompt_cursor().blockNumber():
643 start_pos = self._prompt_pos
650 start_pos = self._prompt_pos
644 else:
651 else:
645 start_pos = cursor.position()
652 start_pos = cursor.position()
646 start_pos += len(self._continuation_prompt)
653 start_pos += len(self._continuation_prompt)
647 if shift_down and self._in_buffer(position):
654 if shift_down and self._in_buffer(position):
648 self._set_selection(position, start_pos)
655 self._set_selection(position, start_pos)
649 else:
656 else:
650 self._set_position(start_pos)
657 self._set_position(start_pos)
651 intercepted = True
658 intercepted = True
652
659
653 elif key == QtCore.Qt.Key_Backspace:
660 elif key == QtCore.Qt.Key_Backspace:
654
661
655 # Line deletion (remove continuation prompt)
662 # Line deletion (remove continuation prompt)
656 len_prompt = len(self._continuation_prompt)
663 len_prompt = len(self._continuation_prompt)
657 if not self._reading and \
664 if not self._reading and \
658 cursor.columnNumber() == len_prompt and \
665 cursor.columnNumber() == len_prompt and \
659 position != self._prompt_pos:
666 position != self._prompt_pos:
660 cursor.movePosition(QtGui.QTextCursor.StartOfBlock,
667 cursor.movePosition(QtGui.QTextCursor.StartOfBlock,
661 QtGui.QTextCursor.KeepAnchor)
668 QtGui.QTextCursor.KeepAnchor)
662 cursor.removeSelectedText()
669 cursor.removeSelectedText()
663 cursor.deletePreviousChar()
670 cursor.deletePreviousChar()
664 intercepted = True
671 intercepted = True
665
672
666 # Regular backwards deletion
673 # Regular backwards deletion
667 else:
674 else:
668 anchor = cursor.anchor()
675 anchor = cursor.anchor()
669 if anchor == position:
676 if anchor == position:
670 intercepted = not self._in_buffer(position - 1)
677 intercepted = not self._in_buffer(position - 1)
671 else:
678 else:
672 intercepted = not self._in_buffer(min(anchor, position))
679 intercepted = not self._in_buffer(min(anchor, position))
673
680
674 elif key == QtCore.Qt.Key_Delete:
681 elif key == QtCore.Qt.Key_Delete:
675 anchor = cursor.anchor()
682 anchor = cursor.anchor()
676 intercepted = not self._in_buffer(min(anchor, position))
683 intercepted = not self._in_buffer(min(anchor, position))
677
684
678 # Don't move the cursor if control is down to allow copy-paste using
685 # Don't move the cursor if control is down to allow copy-paste using
679 # the keyboard in any part of the buffer.
686 # the keyboard in any part of the buffer.
680 if not ctrl_down:
687 if not ctrl_down:
681 self._keep_cursor_in_buffer()
688 self._keep_cursor_in_buffer()
682
689
683 return intercepted
690 return intercepted
684
691
685 def _event_filter_page_keypress(self, event):
692 def _event_filter_page_keypress(self, event):
686 """ Filter key events for the paging widget to create console-like
693 """ Filter key events for the paging widget to create console-like
687 interface.
694 interface.
688 """
695 """
689 key = event.key()
696 key = event.key()
690
697
691 if key in (QtCore.Qt.Key_Q, QtCore.Qt.Key_Escape):
698 if key in (QtCore.Qt.Key_Q, QtCore.Qt.Key_Escape):
692 if self._splitter:
699 if self._splitter:
693 self._page_control.hide()
700 self._page_control.hide()
694 else:
701 else:
695 self.layout().setCurrentWidget(self._control)
702 self.layout().setCurrentWidget(self._control)
696 return True
703 return True
697
704
698 elif key in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return):
705 elif key in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return):
699 new_event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress,
706 new_event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress,
700 QtCore.Qt.Key_Down,
707 QtCore.Qt.Key_Down,
701 QtCore.Qt.NoModifier)
708 QtCore.Qt.NoModifier)
702 QtGui.qApp.sendEvent(self._page_control, new_event)
709 QtGui.qApp.sendEvent(self._page_control, new_event)
703 return True
710 return True
704
711
705 return False
712 return False
706
713
707 def _format_as_columns(self, items, separator=' '):
714 def _format_as_columns(self, items, separator=' '):
708 """ Transform a list of strings into a single string with columns.
715 """ Transform a list of strings into a single string with columns.
709
716
710 Parameters
717 Parameters
711 ----------
718 ----------
712 items : sequence of strings
719 items : sequence of strings
713 The strings to process.
720 The strings to process.
714
721
715 separator : str, optional [default is two spaces]
722 separator : str, optional [default is two spaces]
716 The string that separates columns.
723 The string that separates columns.
717
724
718 Returns
725 Returns
719 -------
726 -------
720 The formatted string.
727 The formatted string.
721 """
728 """
722 # Note: this code is adapted from columnize 0.3.2.
729 # Note: this code is adapted from columnize 0.3.2.
723 # See http://code.google.com/p/pycolumnize/
730 # See http://code.google.com/p/pycolumnize/
724
731
725 width = self._control.viewport().width()
732 width = self._control.viewport().width()
726 char_width = QtGui.QFontMetrics(self.font).width(' ')
733 char_width = QtGui.QFontMetrics(self.font).width(' ')
727 displaywidth = max(5, width / char_width)
734 displaywidth = max(5, width / char_width)
728
735
729 # Some degenerate cases.
736 # Some degenerate cases.
730 size = len(items)
737 size = len(items)
731 if size == 0:
738 if size == 0:
732 return '\n'
739 return '\n'
733 elif size == 1:
740 elif size == 1:
734 return '%s\n' % str(items[0])
741 return '%s\n' % str(items[0])
735
742
736 # Try every row count from 1 upwards
743 # Try every row count from 1 upwards
737 array_index = lambda nrows, row, col: nrows*col + row
744 array_index = lambda nrows, row, col: nrows*col + row
738 for nrows in range(1, size):
745 for nrows in range(1, size):
739 ncols = (size + nrows - 1) // nrows
746 ncols = (size + nrows - 1) // nrows
740 colwidths = []
747 colwidths = []
741 totwidth = -len(separator)
748 totwidth = -len(separator)
742 for col in range(ncols):
749 for col in range(ncols):
743 # Get max column width for this column
750 # Get max column width for this column
744 colwidth = 0
751 colwidth = 0
745 for row in range(nrows):
752 for row in range(nrows):
746 i = array_index(nrows, row, col)
753 i = array_index(nrows, row, col)
747 if i >= size: break
754 if i >= size: break
748 x = items[i]
755 x = items[i]
749 colwidth = max(colwidth, len(x))
756 colwidth = max(colwidth, len(x))
750 colwidths.append(colwidth)
757 colwidths.append(colwidth)
751 totwidth += colwidth + len(separator)
758 totwidth += colwidth + len(separator)
752 if totwidth > displaywidth:
759 if totwidth > displaywidth:
753 break
760 break
754 if totwidth <= displaywidth:
761 if totwidth <= displaywidth:
755 break
762 break
756
763
757 # The smallest number of rows computed and the max widths for each
764 # The smallest number of rows computed and the max widths for each
758 # column has been obtained. Now we just have to format each of the rows.
765 # column has been obtained. Now we just have to format each of the rows.
759 string = ''
766 string = ''
760 for row in range(nrows):
767 for row in range(nrows):
761 texts = []
768 texts = []
762 for col in range(ncols):
769 for col in range(ncols):
763 i = row + nrows*col
770 i = row + nrows*col
764 if i >= size:
771 if i >= size:
765 texts.append('')
772 texts.append('')
766 else:
773 else:
767 texts.append(items[i])
774 texts.append(items[i])
768 while texts and not texts[-1]:
775 while texts and not texts[-1]:
769 del texts[-1]
776 del texts[-1]
770 for col in range(len(texts)):
777 for col in range(len(texts)):
771 texts[col] = texts[col].ljust(colwidths[col])
778 texts[col] = texts[col].ljust(colwidths[col])
772 string += '%s\n' % str(separator.join(texts))
779 string += '%s\n' % str(separator.join(texts))
773 return string
780 return string
774
781
775 def _get_block_plain_text(self, block):
782 def _get_block_plain_text(self, block):
776 """ Given a QTextBlock, return its unformatted text.
783 """ Given a QTextBlock, return its unformatted text.
777 """
784 """
778 cursor = QtGui.QTextCursor(block)
785 cursor = QtGui.QTextCursor(block)
779 cursor.movePosition(QtGui.QTextCursor.StartOfBlock)
786 cursor.movePosition(QtGui.QTextCursor.StartOfBlock)
780 cursor.movePosition(QtGui.QTextCursor.EndOfBlock,
787 cursor.movePosition(QtGui.QTextCursor.EndOfBlock,
781 QtGui.QTextCursor.KeepAnchor)
788 QtGui.QTextCursor.KeepAnchor)
782 return str(cursor.selection().toPlainText())
789 return str(cursor.selection().toPlainText())
783
790
784 def _get_cursor(self):
791 def _get_cursor(self):
785 """ Convenience method that returns a cursor for the current position.
792 """ Convenience method that returns a cursor for the current position.
786 """
793 """
787 return self._control.textCursor()
794 return self._control.textCursor()
788
795
789 def _get_end_cursor(self):
796 def _get_end_cursor(self):
790 """ Convenience method that returns a cursor for the last character.
797 """ Convenience method that returns a cursor for the last character.
791 """
798 """
792 cursor = self._control.textCursor()
799 cursor = self._control.textCursor()
793 cursor.movePosition(QtGui.QTextCursor.End)
800 cursor.movePosition(QtGui.QTextCursor.End)
794 return cursor
801 return cursor
795
802
796 def _get_input_buffer_cursor_column(self):
803 def _get_input_buffer_cursor_column(self):
797 """ Returns the column of the cursor in the input buffer, excluding the
804 """ Returns the column of the cursor in the input buffer, excluding the
798 contribution by the prompt, or -1 if there is no such column.
805 contribution by the prompt, or -1 if there is no such column.
799 """
806 """
800 prompt = self._get_input_buffer_cursor_prompt()
807 prompt = self._get_input_buffer_cursor_prompt()
801 if prompt is None:
808 if prompt is None:
802 return -1
809 return -1
803 else:
810 else:
804 cursor = self._control.textCursor()
811 cursor = self._control.textCursor()
805 return cursor.columnNumber() - len(prompt)
812 return cursor.columnNumber() - len(prompt)
806
813
807 def _get_input_buffer_cursor_line(self):
814 def _get_input_buffer_cursor_line(self):
808 """ Returns line of the input buffer that contains the cursor, or None
815 """ Returns line of the input buffer that contains the cursor, or None
809 if there is no such line.
816 if there is no such line.
810 """
817 """
811 prompt = self._get_input_buffer_cursor_prompt()
818 prompt = self._get_input_buffer_cursor_prompt()
812 if prompt is None:
819 if prompt is None:
813 return None
820 return None
814 else:
821 else:
815 cursor = self._control.textCursor()
822 cursor = self._control.textCursor()
816 text = self._get_block_plain_text(cursor.block())
823 text = self._get_block_plain_text(cursor.block())
817 return text[len(prompt):]
824 return text[len(prompt):]
818
825
819 def _get_input_buffer_cursor_prompt(self):
826 def _get_input_buffer_cursor_prompt(self):
820 """ Returns the (plain text) prompt for line of the input buffer that
827 """ Returns the (plain text) prompt for line of the input buffer that
821 contains the cursor, or None if there is no such line.
828 contains the cursor, or None if there is no such line.
822 """
829 """
823 if self._executing:
830 if self._executing:
824 return None
831 return None
825 cursor = self._control.textCursor()
832 cursor = self._control.textCursor()
826 if cursor.position() >= self._prompt_pos:
833 if cursor.position() >= self._prompt_pos:
827 if cursor.blockNumber() == self._get_prompt_cursor().blockNumber():
834 if cursor.blockNumber() == self._get_prompt_cursor().blockNumber():
828 return self._prompt
835 return self._prompt
829 else:
836 else:
830 return self._continuation_prompt
837 return self._continuation_prompt
831 else:
838 else:
832 return None
839 return None
833
840
834 def _get_prompt_cursor(self):
841 def _get_prompt_cursor(self):
835 """ Convenience method that returns a cursor for the prompt position.
842 """ Convenience method that returns a cursor for the prompt position.
836 """
843 """
837 cursor = self._control.textCursor()
844 cursor = self._control.textCursor()
838 cursor.setPosition(self._prompt_pos)
845 cursor.setPosition(self._prompt_pos)
839 return cursor
846 return cursor
840
847
841 def _get_selection_cursor(self, start, end):
848 def _get_selection_cursor(self, start, end):
842 """ Convenience method that returns a cursor with text selected between
849 """ Convenience method that returns a cursor with text selected between
843 the positions 'start' and 'end'.
850 the positions 'start' and 'end'.
844 """
851 """
845 cursor = self._control.textCursor()
852 cursor = self._control.textCursor()
846 cursor.setPosition(start)
853 cursor.setPosition(start)
847 cursor.setPosition(end, QtGui.QTextCursor.KeepAnchor)
854 cursor.setPosition(end, QtGui.QTextCursor.KeepAnchor)
848 return cursor
855 return cursor
849
856
850 def _get_word_start_cursor(self, position):
857 def _get_word_start_cursor(self, position):
851 """ Find the start of the word to the left the given position. If a
858 """ Find the start of the word to the left the given position. If a
852 sequence of non-word characters precedes the first word, skip over
859 sequence of non-word characters precedes the first word, skip over
853 them. (This emulates the behavior of bash, emacs, etc.)
860 them. (This emulates the behavior of bash, emacs, etc.)
854 """
861 """
855 document = self._control.document()
862 document = self._control.document()
856 position -= 1
863 position -= 1
857 while position >= self._prompt_pos and \
864 while position >= self._prompt_pos and \
858 not document.characterAt(position).isLetterOrNumber():
865 not document.characterAt(position).isLetterOrNumber():
859 position -= 1
866 position -= 1
860 while position >= self._prompt_pos and \
867 while position >= self._prompt_pos and \
861 document.characterAt(position).isLetterOrNumber():
868 document.characterAt(position).isLetterOrNumber():
862 position -= 1
869 position -= 1
863 cursor = self._control.textCursor()
870 cursor = self._control.textCursor()
864 cursor.setPosition(position + 1)
871 cursor.setPosition(position + 1)
865 return cursor
872 return cursor
866
873
867 def _get_word_end_cursor(self, position):
874 def _get_word_end_cursor(self, position):
868 """ Find the end of the word to the right the given position. If a
875 """ Find the end of the word to the right the given position. If a
869 sequence of non-word characters precedes the first word, skip over
876 sequence of non-word characters precedes the first word, skip over
870 them. (This emulates the behavior of bash, emacs, etc.)
877 them. (This emulates the behavior of bash, emacs, etc.)
871 """
878 """
872 document = self._control.document()
879 document = self._control.document()
873 end = self._get_end_cursor().position()
880 end = self._get_end_cursor().position()
874 while position < end and \
881 while position < end and \
875 not document.characterAt(position).isLetterOrNumber():
882 not document.characterAt(position).isLetterOrNumber():
876 position += 1
883 position += 1
877 while position < end and \
884 while position < end and \
878 document.characterAt(position).isLetterOrNumber():
885 document.characterAt(position).isLetterOrNumber():
879 position += 1
886 position += 1
880 cursor = self._control.textCursor()
887 cursor = self._control.textCursor()
881 cursor.setPosition(position)
888 cursor.setPosition(position)
882 return cursor
889 return cursor
883
890
884 def _insert_html(self, cursor, html):
891 def _insert_html(self, cursor, html):
885 """ Inserts HTML using the specified cursor in such a way that future
892 """ Inserts HTML using the specified cursor in such a way that future
886 formatting is unaffected.
893 formatting is unaffected.
887 """
894 """
888 cursor.beginEditBlock()
895 cursor.beginEditBlock()
889 cursor.insertHtml(html)
896 cursor.insertHtml(html)
890
897
891 # After inserting HTML, the text document "remembers" it's in "html
898 # After inserting HTML, the text document "remembers" it's in "html
892 # mode", which means that subsequent calls adding plain text will result
899 # mode", which means that subsequent calls adding plain text will result
893 # in unwanted formatting, lost tab characters, etc. The following code
900 # in unwanted formatting, lost tab characters, etc. The following code
894 # hacks around this behavior, which I consider to be a bug in Qt, by
901 # hacks around this behavior, which I consider to be a bug in Qt, by
895 # (crudely) resetting the document's style state.
902 # (crudely) resetting the document's style state.
896 cursor.movePosition(QtGui.QTextCursor.Left,
903 cursor.movePosition(QtGui.QTextCursor.Left,
897 QtGui.QTextCursor.KeepAnchor)
904 QtGui.QTextCursor.KeepAnchor)
898 if cursor.selection().toPlainText() == ' ':
905 if cursor.selection().toPlainText() == ' ':
899 cursor.removeSelectedText()
906 cursor.removeSelectedText()
900 else:
907 else:
901 cursor.movePosition(QtGui.QTextCursor.Right)
908 cursor.movePosition(QtGui.QTextCursor.Right)
902 cursor.insertText(' ', QtGui.QTextCharFormat())
909 cursor.insertText(' ', QtGui.QTextCharFormat())
903 cursor.endEditBlock()
910 cursor.endEditBlock()
904
911
905 def _insert_html_fetching_plain_text(self, cursor, html):
912 def _insert_html_fetching_plain_text(self, cursor, html):
906 """ Inserts HTML using the specified cursor, then returns its plain text
913 """ Inserts HTML using the specified cursor, then returns its plain text
907 version.
914 version.
908 """
915 """
909 cursor.beginEditBlock()
916 cursor.beginEditBlock()
910 cursor.removeSelectedText()
917 cursor.removeSelectedText()
911
918
912 start = cursor.position()
919 start = cursor.position()
913 self._insert_html(cursor, html)
920 self._insert_html(cursor, html)
914 end = cursor.position()
921 end = cursor.position()
915 cursor.setPosition(start, QtGui.QTextCursor.KeepAnchor)
922 cursor.setPosition(start, QtGui.QTextCursor.KeepAnchor)
916 text = str(cursor.selection().toPlainText())
923 text = str(cursor.selection().toPlainText())
917
924
918 cursor.setPosition(end)
925 cursor.setPosition(end)
919 cursor.endEditBlock()
926 cursor.endEditBlock()
920 return text
927 return text
921
928
922 def _insert_plain_text(self, cursor, text):
929 def _insert_plain_text(self, cursor, text):
923 """ Inserts plain text using the specified cursor, processing ANSI codes
930 """ Inserts plain text using the specified cursor, processing ANSI codes
924 if enabled.
931 if enabled.
925 """
932 """
926 cursor.beginEditBlock()
933 cursor.beginEditBlock()
927 if self.ansi_codes:
934 if self.ansi_codes:
928 for substring in self._ansi_processor.split_string(text):
935 for substring in self._ansi_processor.split_string(text):
929 for action in self._ansi_processor.actions:
936 for action in self._ansi_processor.actions:
930 if action.kind == 'erase' and action.area == 'screen':
937 if action.kind == 'erase' and action.area == 'screen':
931 cursor.select(QtGui.QTextCursor.Document)
938 cursor.select(QtGui.QTextCursor.Document)
932 cursor.removeSelectedText()
939 cursor.removeSelectedText()
933 format = self._ansi_processor.get_format()
940 format = self._ansi_processor.get_format()
934 cursor.insertText(substring, format)
941 cursor.insertText(substring, format)
935 else:
942 else:
936 cursor.insertText(text)
943 cursor.insertText(text)
937 cursor.endEditBlock()
944 cursor.endEditBlock()
938
945
939 def _insert_plain_text_into_buffer(self, text):
946 def _insert_plain_text_into_buffer(self, text):
940 """ Inserts text into the input buffer at the current cursor position,
947 """ Inserts text into the input buffer at the current cursor position,
941 ensuring that continuation prompts are inserted as necessary.
948 ensuring that continuation prompts are inserted as necessary.
942 """
949 """
943 lines = str(text).splitlines(True)
950 lines = str(text).splitlines(True)
944 if lines:
951 if lines:
945 self._keep_cursor_in_buffer()
952 self._keep_cursor_in_buffer()
946 cursor = self._control.textCursor()
953 cursor = self._control.textCursor()
947 cursor.beginEditBlock()
954 cursor.beginEditBlock()
948 cursor.insertText(lines[0])
955 cursor.insertText(lines[0])
949 for line in lines[1:]:
956 for line in lines[1:]:
950 if self._continuation_prompt_html is None:
957 if self._continuation_prompt_html is None:
951 cursor.insertText(self._continuation_prompt)
958 cursor.insertText(self._continuation_prompt)
952 else:
959 else:
953 self._continuation_prompt = \
960 self._continuation_prompt = \
954 self._insert_html_fetching_plain_text(
961 self._insert_html_fetching_plain_text(
955 cursor, self._continuation_prompt_html)
962 cursor, self._continuation_prompt_html)
956 cursor.insertText(line)
963 cursor.insertText(line)
957 cursor.endEditBlock()
964 cursor.endEditBlock()
958 self._control.setTextCursor(cursor)
965 self._control.setTextCursor(cursor)
959
966
960 def _in_buffer(self, position=None):
967 def _in_buffer(self, position=None):
961 """ Returns whether the current cursor (or, if specified, a position) is
968 """ Returns whether the current cursor (or, if specified, a position) is
962 inside the editing region.
969 inside the editing region.
963 """
970 """
964 cursor = self._control.textCursor()
971 cursor = self._control.textCursor()
965 if position is None:
972 if position is None:
966 position = cursor.position()
973 position = cursor.position()
967 else:
974 else:
968 cursor.setPosition(position)
975 cursor.setPosition(position)
969 line = cursor.blockNumber()
976 line = cursor.blockNumber()
970 prompt_line = self._get_prompt_cursor().blockNumber()
977 prompt_line = self._get_prompt_cursor().blockNumber()
971 if line == prompt_line:
978 if line == prompt_line:
972 return position >= self._prompt_pos
979 return position >= self._prompt_pos
973 elif line > prompt_line:
980 elif line > prompt_line:
974 cursor.movePosition(QtGui.QTextCursor.StartOfBlock)
981 cursor.movePosition(QtGui.QTextCursor.StartOfBlock)
975 prompt_pos = cursor.position() + len(self._continuation_prompt)
982 prompt_pos = cursor.position() + len(self._continuation_prompt)
976 return position >= prompt_pos
983 return position >= prompt_pos
977 return False
984 return False
978
985
979 def _keep_cursor_in_buffer(self):
986 def _keep_cursor_in_buffer(self):
980 """ Ensures that the cursor is inside the editing region. Returns
987 """ Ensures that the cursor is inside the editing region. Returns
981 whether the cursor was moved.
988 whether the cursor was moved.
982 """
989 """
983 moved = not self._in_buffer()
990 moved = not self._in_buffer()
984 if moved:
991 if moved:
985 cursor = self._control.textCursor()
992 cursor = self._control.textCursor()
986 cursor.movePosition(QtGui.QTextCursor.End)
993 cursor.movePosition(QtGui.QTextCursor.End)
987 self._control.setTextCursor(cursor)
994 self._control.setTextCursor(cursor)
988 return moved
995 return moved
989
996
990 def _page(self, text):
997 def _page(self, text):
991 """ Displays text using the pager if it exceeds the height of the
998 """ Displays text using the pager if it exceeds the height of the
992 visible area.
999 visible area.
993 """
1000 """
994 if self._page_style == 'none':
1001 if self._page_style == 'none':
995 self._append_plain_text(text)
1002 self._append_plain_text(text)
996 else:
1003 else:
997 line_height = QtGui.QFontMetrics(self.font).height()
1004 line_height = QtGui.QFontMetrics(self.font).height()
998 minlines = self._control.viewport().height() / line_height
1005 minlines = self._control.viewport().height() / line_height
999 if re.match("(?:[^\n]*\n){%i}" % minlines, text):
1006 if re.match("(?:[^\n]*\n){%i}" % minlines, text):
1000 if self._page_style == 'custom':
1007 if self._page_style == 'custom':
1001 self.custom_page_requested.emit(text)
1008 self.custom_page_requested.emit(text)
1002 else:
1009 else:
1003 self._page_control.clear()
1010 self._page_control.clear()
1004 cursor = self._page_control.textCursor()
1011 cursor = self._page_control.textCursor()
1005 self._insert_plain_text(cursor, text)
1012 self._insert_plain_text(cursor, text)
1006 self._page_control.moveCursor(QtGui.QTextCursor.Start)
1013 self._page_control.moveCursor(QtGui.QTextCursor.Start)
1007
1014
1008 self._page_control.viewport().resize(self._control.size())
1015 self._page_control.viewport().resize(self._control.size())
1009 if self._splitter:
1016 if self._splitter:
1010 self._page_control.show()
1017 self._page_control.show()
1011 self._page_control.setFocus()
1018 self._page_control.setFocus()
1012 else:
1019 else:
1013 self.layout().setCurrentWidget(self._page_control)
1020 self.layout().setCurrentWidget(self._page_control)
1014 else:
1021 else:
1015 self._append_plain_text(text)
1022 self._append_plain_text(text)
1016
1023
1017 def _prompt_started(self):
1024 def _prompt_started(self):
1018 """ Called immediately after a new prompt is displayed.
1025 """ Called immediately after a new prompt is displayed.
1019 """
1026 """
1020 # Temporarily disable the maximum block count to permit undo/redo and
1027 # Temporarily disable the maximum block count to permit undo/redo and
1021 # to ensure that the prompt position does not change due to truncation.
1028 # to ensure that the prompt position does not change due to truncation.
1022 self._control.document().setMaximumBlockCount(0)
1029 self._control.document().setMaximumBlockCount(0)
1023 self._control.setUndoRedoEnabled(True)
1030 self._control.setUndoRedoEnabled(True)
1024
1031
1025 self._control.setReadOnly(False)
1032 self._control.setReadOnly(False)
1026 self._control.moveCursor(QtGui.QTextCursor.End)
1033 self._control.moveCursor(QtGui.QTextCursor.End)
1027
1034
1028 self._executing = False
1035 self._executing = False
1029 self._prompt_started_hook()
1036 self._prompt_started_hook()
1030
1037
1031 def _prompt_finished(self):
1038 def _prompt_finished(self):
1032 """ Called immediately after a prompt is finished, i.e. when some input
1039 """ Called immediately after a prompt is finished, i.e. when some input
1033 will be processed and a new prompt displayed.
1040 will be processed and a new prompt displayed.
1034 """
1041 """
1035 self._control.setUndoRedoEnabled(False)
1042 self._control.setUndoRedoEnabled(False)
1036 self._control.setReadOnly(True)
1043 self._control.setReadOnly(True)
1037 self._prompt_finished_hook()
1044 self._prompt_finished_hook()
1038
1045
1039 def _readline(self, prompt='', callback=None):
1046 def _readline(self, prompt='', callback=None):
1040 """ Reads one line of input from the user.
1047 """ Reads one line of input from the user.
1041
1048
1042 Parameters
1049 Parameters
1043 ----------
1050 ----------
1044 prompt : str, optional
1051 prompt : str, optional
1045 The prompt to print before reading the line.
1052 The prompt to print before reading the line.
1046
1053
1047 callback : callable, optional
1054 callback : callable, optional
1048 A callback to execute with the read line. If not specified, input is
1055 A callback to execute with the read line. If not specified, input is
1049 read *synchronously* and this method does not return until it has
1056 read *synchronously* and this method does not return until it has
1050 been read.
1057 been read.
1051
1058
1052 Returns
1059 Returns
1053 -------
1060 -------
1054 If a callback is specified, returns nothing. Otherwise, returns the
1061 If a callback is specified, returns nothing. Otherwise, returns the
1055 input string with the trailing newline stripped.
1062 input string with the trailing newline stripped.
1056 """
1063 """
1057 if self._reading:
1064 if self._reading:
1058 raise RuntimeError('Cannot read a line. Widget is already reading.')
1065 raise RuntimeError('Cannot read a line. Widget is already reading.')
1059
1066
1060 if not callback and not self.isVisible():
1067 if not callback and not self.isVisible():
1061 # If the user cannot see the widget, this function cannot return.
1068 # If the user cannot see the widget, this function cannot return.
1062 raise RuntimeError('Cannot synchronously read a line if the widget'
1069 raise RuntimeError('Cannot synchronously read a line if the widget'
1063 'is not visible!')
1070 'is not visible!')
1064
1071
1065 self._reading = True
1072 self._reading = True
1066 self._show_prompt(prompt, newline=False)
1073 self._show_prompt(prompt, newline=False)
1067
1074
1068 if callback is None:
1075 if callback is None:
1069 self._reading_callback = None
1076 self._reading_callback = None
1070 while self._reading:
1077 while self._reading:
1071 QtCore.QCoreApplication.processEvents()
1078 QtCore.QCoreApplication.processEvents()
1072 return self.input_buffer.rstrip('\n')
1079 return self.input_buffer.rstrip('\n')
1073
1080
1074 else:
1081 else:
1075 self._reading_callback = lambda: \
1082 self._reading_callback = lambda: \
1076 callback(self.input_buffer.rstrip('\n'))
1083 callback(self.input_buffer.rstrip('\n'))
1077
1084
1078 def _set_continuation_prompt(self, prompt, html=False):
1085 def _set_continuation_prompt(self, prompt, html=False):
1079 """ Sets the continuation prompt.
1086 """ Sets the continuation prompt.
1080
1087
1081 Parameters
1088 Parameters
1082 ----------
1089 ----------
1083 prompt : str
1090 prompt : str
1084 The prompt to show when more input is needed.
1091 The prompt to show when more input is needed.
1085
1092
1086 html : bool, optional (default False)
1093 html : bool, optional (default False)
1087 If set, the prompt will be inserted as formatted HTML. Otherwise,
1094 If set, the prompt will be inserted as formatted HTML. Otherwise,
1088 the prompt will be treated as plain text, though ANSI color codes
1095 the prompt will be treated as plain text, though ANSI color codes
1089 will be handled.
1096 will be handled.
1090 """
1097 """
1091 if html:
1098 if html:
1092 self._continuation_prompt_html = prompt
1099 self._continuation_prompt_html = prompt
1093 else:
1100 else:
1094 self._continuation_prompt = prompt
1101 self._continuation_prompt = prompt
1095 self._continuation_prompt_html = None
1102 self._continuation_prompt_html = None
1096
1103
1097 def _set_cursor(self, cursor):
1104 def _set_cursor(self, cursor):
1098 """ Convenience method to set the current cursor.
1105 """ Convenience method to set the current cursor.
1099 """
1106 """
1100 self._control.setTextCursor(cursor)
1107 self._control.setTextCursor(cursor)
1101
1108
1102 def _set_position(self, position):
1109 def _set_position(self, position):
1103 """ Convenience method to set the position of the cursor.
1110 """ Convenience method to set the position of the cursor.
1104 """
1111 """
1105 cursor = self._control.textCursor()
1112 cursor = self._control.textCursor()
1106 cursor.setPosition(position)
1113 cursor.setPosition(position)
1107 self._control.setTextCursor(cursor)
1114 self._control.setTextCursor(cursor)
1108
1115
1109 def _set_selection(self, start, end):
1116 def _set_selection(self, start, end):
1110 """ Convenience method to set the current selected text.
1117 """ Convenience method to set the current selected text.
1111 """
1118 """
1112 self._control.setTextCursor(self._get_selection_cursor(start, end))
1119 self._control.setTextCursor(self._get_selection_cursor(start, end))
1113
1120
1114 def _show_context_menu(self, pos):
1121 def _show_context_menu(self, pos):
1115 """ Shows a context menu at the given QPoint (in widget coordinates).
1122 """ Shows a context menu at the given QPoint (in widget coordinates).
1116 """
1123 """
1117 menu = QtGui.QMenu()
1124 menu = QtGui.QMenu()
1118
1125
1119 copy_action = menu.addAction('Copy', self.copy)
1126 copy_action = menu.addAction('Copy', self.copy)
1120 copy_action.setEnabled(self._get_cursor().hasSelection())
1127 copy_action.setEnabled(self._get_cursor().hasSelection())
1121 copy_action.setShortcut(QtGui.QKeySequence.Copy)
1128 copy_action.setShortcut(QtGui.QKeySequence.Copy)
1122
1129
1123 paste_action = menu.addAction('Paste', self.paste)
1130 paste_action = menu.addAction('Paste', self.paste)
1124 paste_action.setEnabled(self.can_paste())
1131 paste_action.setEnabled(self.can_paste())
1125 paste_action.setShortcut(QtGui.QKeySequence.Paste)
1132 paste_action.setShortcut(QtGui.QKeySequence.Paste)
1126
1133
1127 menu.addSeparator()
1134 menu.addSeparator()
1128 menu.addAction('Select All', self.select_all)
1135 menu.addAction('Select All', self.select_all)
1129
1136
1130 menu.exec_(self._control.mapToGlobal(pos))
1137 menu.exec_(self._control.mapToGlobal(pos))
1131
1138
1132 def _show_prompt(self, prompt=None, html=False, newline=True):
1139 def _show_prompt(self, prompt=None, html=False, newline=True):
1133 """ Writes a new prompt at the end of the buffer.
1140 """ Writes a new prompt at the end of the buffer.
1134
1141
1135 Parameters
1142 Parameters
1136 ----------
1143 ----------
1137 prompt : str, optional
1144 prompt : str, optional
1138 The prompt to show. If not specified, the previous prompt is used.
1145 The prompt to show. If not specified, the previous prompt is used.
1139
1146
1140 html : bool, optional (default False)
1147 html : bool, optional (default False)
1141 Only relevant when a prompt is specified. If set, the prompt will
1148 Only relevant when a prompt is specified. If set, the prompt will
1142 be inserted as formatted HTML. Otherwise, the prompt will be treated
1149 be inserted as formatted HTML. Otherwise, the prompt will be treated
1143 as plain text, though ANSI color codes will be handled.
1150 as plain text, though ANSI color codes will be handled.
1144
1151
1145 newline : bool, optional (default True)
1152 newline : bool, optional (default True)
1146 If set, a new line will be written before showing the prompt if
1153 If set, a new line will be written before showing the prompt if
1147 there is not already a newline at the end of the buffer.
1154 there is not already a newline at the end of the buffer.
1148 """
1155 """
1149 # Insert a preliminary newline, if necessary.
1156 # Insert a preliminary newline, if necessary.
1150 if newline:
1157 if newline:
1151 cursor = self._get_end_cursor()
1158 cursor = self._get_end_cursor()
1152 if cursor.position() > 0:
1159 if cursor.position() > 0:
1153 cursor.movePosition(QtGui.QTextCursor.Left,
1160 cursor.movePosition(QtGui.QTextCursor.Left,
1154 QtGui.QTextCursor.KeepAnchor)
1161 QtGui.QTextCursor.KeepAnchor)
1155 if str(cursor.selection().toPlainText()) != '\n':
1162 if str(cursor.selection().toPlainText()) != '\n':
1156 self._append_plain_text('\n')
1163 self._append_plain_text('\n')
1157
1164
1158 # Write the prompt.
1165 # Write the prompt.
1159 if prompt is None:
1166 if prompt is None:
1160 if self._prompt_html is None:
1167 if self._prompt_html is None:
1161 self._append_plain_text(self._prompt)
1168 self._append_plain_text(self._prompt)
1162 else:
1169 else:
1163 self._append_html(self._prompt_html)
1170 self._append_html(self._prompt_html)
1164 else:
1171 else:
1165 if html:
1172 if html:
1166 self._prompt = self._append_html_fetching_plain_text(prompt)
1173 self._prompt = self._append_html_fetching_plain_text(prompt)
1167 self._prompt_html = prompt
1174 self._prompt_html = prompt
1168 else:
1175 else:
1169 self._append_plain_text(prompt)
1176 self._append_plain_text(prompt)
1170 self._prompt = prompt
1177 self._prompt = prompt
1171 self._prompt_html = None
1178 self._prompt_html = None
1172
1179
1173 self._prompt_pos = self._get_end_cursor().position()
1180 self._prompt_pos = self._get_end_cursor().position()
1174 self._prompt_started()
1181 self._prompt_started()
1175
1182
1176 def _show_continuation_prompt(self):
1183 def _show_continuation_prompt(self):
1177 """ Writes a new continuation prompt at the end of the buffer.
1184 """ Writes a new continuation prompt at the end of the buffer.
1178 """
1185 """
1179 if self._continuation_prompt_html is None:
1186 if self._continuation_prompt_html is None:
1180 self._append_plain_text(self._continuation_prompt)
1187 self._append_plain_text(self._continuation_prompt)
1181 else:
1188 else:
1182 self._continuation_prompt = self._append_html_fetching_plain_text(
1189 self._continuation_prompt = self._append_html_fetching_plain_text(
1183 self._continuation_prompt_html)
1190 self._continuation_prompt_html)
1184
1191
1185 self._prompt_started()
1192 self._prompt_started()
1186
1193
1187
1194
1188 class HistoryConsoleWidget(ConsoleWidget):
1195 class HistoryConsoleWidget(ConsoleWidget):
1189 """ A ConsoleWidget that keeps a history of the commands that have been
1196 """ A ConsoleWidget that keeps a history of the commands that have been
1190 executed.
1197 executed.
1191 """
1198 """
1192
1199
1193 #---------------------------------------------------------------------------
1200 #---------------------------------------------------------------------------
1194 # 'object' interface
1201 # 'object' interface
1195 #---------------------------------------------------------------------------
1202 #---------------------------------------------------------------------------
1196
1203
1197 def __init__(self, *args, **kw):
1204 def __init__(self, *args, **kw):
1198 super(HistoryConsoleWidget, self).__init__(*args, **kw)
1205 super(HistoryConsoleWidget, self).__init__(*args, **kw)
1199 self._history = []
1206 self._history = []
1200 self._history_index = 0
1207 self._history_index = 0
1201
1208
1202 #---------------------------------------------------------------------------
1209 #---------------------------------------------------------------------------
1203 # 'ConsoleWidget' public interface
1210 # 'ConsoleWidget' public interface
1204 #---------------------------------------------------------------------------
1211 #---------------------------------------------------------------------------
1205
1212
1206 def execute(self, source=None, hidden=False, interactive=False):
1213 def execute(self, source=None, hidden=False, interactive=False):
1207 """ Reimplemented to the store history.
1214 """ Reimplemented to the store history.
1208 """
1215 """
1209 if not hidden:
1216 if not hidden:
1210 history = self.input_buffer if source is None else source
1217 history = self.input_buffer if source is None else source
1211
1218
1212 executed = super(HistoryConsoleWidget, self).execute(
1219 executed = super(HistoryConsoleWidget, self).execute(
1213 source, hidden, interactive)
1220 source, hidden, interactive)
1214
1221
1215 if executed and not hidden:
1222 if executed and not hidden:
1216 self._history.append(history.rstrip())
1223 self._history.append(history.rstrip())
1217 self._history_index = len(self._history)
1224 self._history_index = len(self._history)
1218
1225
1219 return executed
1226 return executed
1220
1227
1221 #---------------------------------------------------------------------------
1228 #---------------------------------------------------------------------------
1222 # 'ConsoleWidget' abstract interface
1229 # 'ConsoleWidget' abstract interface
1223 #---------------------------------------------------------------------------
1230 #---------------------------------------------------------------------------
1224
1231
1225 def _up_pressed(self):
1232 def _up_pressed(self):
1226 """ Called when the up key is pressed. Returns whether to continue
1233 """ Called when the up key is pressed. Returns whether to continue
1227 processing the event.
1234 processing the event.
1228 """
1235 """
1229 prompt_cursor = self._get_prompt_cursor()
1236 prompt_cursor = self._get_prompt_cursor()
1230 if self._get_cursor().blockNumber() == prompt_cursor.blockNumber():
1237 if self._get_cursor().blockNumber() == prompt_cursor.blockNumber():
1231 self.history_previous()
1238 self.history_previous()
1232
1239
1233 # Go to the first line of prompt for seemless history scrolling.
1240 # Go to the first line of prompt for seemless history scrolling.
1234 cursor = self._get_prompt_cursor()
1241 cursor = self._get_prompt_cursor()
1235 cursor.movePosition(QtGui.QTextCursor.EndOfLine)
1242 cursor.movePosition(QtGui.QTextCursor.EndOfLine)
1236 self._set_cursor(cursor)
1243 self._set_cursor(cursor)
1237
1244
1238 return False
1245 return False
1239 return True
1246 return True
1240
1247
1241 def _down_pressed(self):
1248 def _down_pressed(self):
1242 """ Called when the down key is pressed. Returns whether to continue
1249 """ Called when the down key is pressed. Returns whether to continue
1243 processing the event.
1250 processing the event.
1244 """
1251 """
1245 end_cursor = self._get_end_cursor()
1252 end_cursor = self._get_end_cursor()
1246 if self._get_cursor().blockNumber() == end_cursor.blockNumber():
1253 if self._get_cursor().blockNumber() == end_cursor.blockNumber():
1247 self.history_next()
1254 self.history_next()
1248 return False
1255 return False
1249 return True
1256 return True
1250
1257
1251 #---------------------------------------------------------------------------
1258 #---------------------------------------------------------------------------
1252 # 'HistoryConsoleWidget' public interface
1259 # 'HistoryConsoleWidget' public interface
1253 #---------------------------------------------------------------------------
1260 #---------------------------------------------------------------------------
1254
1261
1255 def history_previous(self):
1262 def history_previous(self):
1256 """ If possible, set the input buffer to the previous item in the
1263 """ If possible, set the input buffer to the previous item in the
1257 history.
1264 history.
1258 """
1265 """
1259 if self._history_index > 0:
1266 if self._history_index > 0:
1260 self._history_index -= 1
1267 self._history_index -= 1
1261 self.input_buffer = self._history[self._history_index]
1268 self.input_buffer = self._history[self._history_index]
1262
1269
1263 def history_next(self):
1270 def history_next(self):
1264 """ Set the input buffer to the next item in the history, or a blank
1271 """ Set the input buffer to the next item in the history, or a blank
1265 line if there is no subsequent item.
1272 line if there is no subsequent item.
1266 """
1273 """
1267 if self._history_index < len(self._history):
1274 if self._history_index < len(self._history):
1268 self._history_index += 1
1275 self._history_index += 1
1269 if self._history_index < len(self._history):
1276 if self._history_index < len(self._history):
1270 self.input_buffer = self._history[self._history_index]
1277 self.input_buffer = self._history[self._history_index]
1271 else:
1278 else:
1272 self.input_buffer = ''
1279 self.input_buffer = ''
1273
1280
1274 #---------------------------------------------------------------------------
1281 #---------------------------------------------------------------------------
1275 # 'HistoryConsoleWidget' protected interface
1282 # 'HistoryConsoleWidget' protected interface
1276 #---------------------------------------------------------------------------
1283 #---------------------------------------------------------------------------
1277
1284
1278 def _set_history(self, history):
1285 def _set_history(self, history):
1279 """ Replace the current history with a sequence of history items.
1286 """ Replace the current history with a sequence of history items.
1280 """
1287 """
1281 self._history = list(history)
1288 self._history = list(history)
1282 self._history_index = len(self._history)
1289 self._history_index = len(self._history)
@@ -1,423 +1,434 b''
1 # Standard library imports
1 # Standard library imports
2 import signal
2 import signal
3 import sys
3 import sys
4
4
5 # System library imports
5 # System library imports
6 from pygments.lexers import PythonLexer
6 from pygments.lexers import PythonLexer
7 from PyQt4 import QtCore, QtGui
7 from PyQt4 import QtCore, QtGui
8 import zmq
8 import zmq
9
9
10 # Local imports
10 # Local imports
11 from IPython.core.inputsplitter import InputSplitter
11 from IPython.core.inputsplitter import InputSplitter
12 from IPython.frontend.qt.base_frontend_mixin import BaseFrontendMixin
12 from IPython.frontend.qt.base_frontend_mixin import BaseFrontendMixin
13 from call_tip_widget import CallTipWidget
13 from call_tip_widget import CallTipWidget
14 from completion_lexer import CompletionLexer
14 from completion_lexer import CompletionLexer
15 from console_widget import HistoryConsoleWidget
15 from console_widget import HistoryConsoleWidget
16 from pygments_highlighter import PygmentsHighlighter
16 from pygments_highlighter import PygmentsHighlighter
17
17
18
18
19 class FrontendHighlighter(PygmentsHighlighter):
19 class FrontendHighlighter(PygmentsHighlighter):
20 """ A PygmentsHighlighter that can be turned on and off and that ignores
20 """ A PygmentsHighlighter that can be turned on and off and that ignores
21 prompts.
21 prompts.
22 """
22 """
23
23
24 def __init__(self, frontend):
24 def __init__(self, frontend):
25 super(FrontendHighlighter, self).__init__(frontend._control.document())
25 super(FrontendHighlighter, self).__init__(frontend._control.document())
26 self._current_offset = 0
26 self._current_offset = 0
27 self._frontend = frontend
27 self._frontend = frontend
28 self.highlighting_on = False
28 self.highlighting_on = False
29
29
30 def highlightBlock(self, qstring):
30 def highlightBlock(self, qstring):
31 """ Highlight a block of text. Reimplemented to highlight selectively.
31 """ Highlight a block of text. Reimplemented to highlight selectively.
32 """
32 """
33 if not self.highlighting_on:
33 if not self.highlighting_on:
34 return
34 return
35
35
36 # The input to this function is unicode string that may contain
36 # The input to this function is unicode string that may contain
37 # paragraph break characters, non-breaking spaces, etc. Here we acquire
37 # paragraph break characters, non-breaking spaces, etc. Here we acquire
38 # the string as plain text so we can compare it.
38 # the string as plain text so we can compare it.
39 current_block = self.currentBlock()
39 current_block = self.currentBlock()
40 string = self._frontend._get_block_plain_text(current_block)
40 string = self._frontend._get_block_plain_text(current_block)
41
41
42 # Decide whether to check for the regular or continuation prompt.
42 # Decide whether to check for the regular or continuation prompt.
43 if current_block.contains(self._frontend._prompt_pos):
43 if current_block.contains(self._frontend._prompt_pos):
44 prompt = self._frontend._prompt
44 prompt = self._frontend._prompt
45 else:
45 else:
46 prompt = self._frontend._continuation_prompt
46 prompt = self._frontend._continuation_prompt
47
47
48 # Don't highlight the part of the string that contains the prompt.
48 # Don't highlight the part of the string that contains the prompt.
49 if string.startswith(prompt):
49 if string.startswith(prompt):
50 self._current_offset = len(prompt)
50 self._current_offset = len(prompt)
51 qstring.remove(0, len(prompt))
51 qstring.remove(0, len(prompt))
52 else:
52 else:
53 self._current_offset = 0
53 self._current_offset = 0
54
54
55 PygmentsHighlighter.highlightBlock(self, qstring)
55 PygmentsHighlighter.highlightBlock(self, qstring)
56
56
57 def rehighlightBlock(self, block):
57 def rehighlightBlock(self, block):
58 """ Reimplemented to temporarily enable highlighting if disabled.
58 """ Reimplemented to temporarily enable highlighting if disabled.
59 """
59 """
60 old = self.highlighting_on
60 old = self.highlighting_on
61 self.highlighting_on = True
61 self.highlighting_on = True
62 super(FrontendHighlighter, self).rehighlightBlock(block)
62 super(FrontendHighlighter, self).rehighlightBlock(block)
63 self.highlighting_on = old
63 self.highlighting_on = old
64
64
65 def setFormat(self, start, count, format):
65 def setFormat(self, start, count, format):
66 """ Reimplemented to highlight selectively.
66 """ Reimplemented to highlight selectively.
67 """
67 """
68 start += self._current_offset
68 start += self._current_offset
69 PygmentsHighlighter.setFormat(self, start, count, format)
69 PygmentsHighlighter.setFormat(self, start, count, format)
70
70
71
71
72 class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):
72 class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):
73 """ A Qt frontend for a generic Python kernel.
73 """ A Qt frontend for a generic Python kernel.
74 """
74 """
75
75
76 # An option and corresponding signal for overriding the default kernel
76 # An option and corresponding signal for overriding the default kernel
77 # interrupt behavior.
77 # interrupt behavior.
78 custom_interrupt = False
78 custom_interrupt = False
79 custom_interrupt_requested = QtCore.pyqtSignal()
79 custom_interrupt_requested = QtCore.pyqtSignal()
80
80
81 # An option and corresponding signal for overriding the default kernel
81 # An option and corresponding signal for overriding the default kernel
82 # restart behavior.
82 # restart behavior.
83 custom_restart = False
83 custom_restart = False
84 custom_restart_requested = QtCore.pyqtSignal()
84 custom_restart_requested = QtCore.pyqtSignal()
85
85
86 # Emitted when an 'execute_reply' has been received from the kernel and
86 # Emitted when an 'execute_reply' has been received from the kernel and
87 # processed by the FrontendWidget.
87 # processed by the FrontendWidget.
88 executed = QtCore.pyqtSignal(object)
88 executed = QtCore.pyqtSignal(object)
89
89
90 # Protected class variables.
90 # Protected class variables.
91 _highlighter_class = FrontendHighlighter
91 _highlighter_class = FrontendHighlighter
92 _input_splitter_class = InputSplitter
92 _input_splitter_class = InputSplitter
93
93
94 #---------------------------------------------------------------------------
94 #---------------------------------------------------------------------------
95 # 'object' interface
95 # 'object' interface
96 #---------------------------------------------------------------------------
96 #---------------------------------------------------------------------------
97
97
98 def __init__(self, *args, **kw):
98 def __init__(self, *args, **kw):
99 super(FrontendWidget, self).__init__(*args, **kw)
99 super(FrontendWidget, self).__init__(*args, **kw)
100
100
101 # FrontendWidget protected variables.
101 # FrontendWidget protected variables.
102 self._call_tip_widget = CallTipWidget(self._control)
102 self._call_tip_widget = CallTipWidget(self._control)
103 self._completion_lexer = CompletionLexer(PythonLexer())
103 self._completion_lexer = CompletionLexer(PythonLexer())
104 self._hidden = False
104 self._hidden = False
105 self._highlighter = self._highlighter_class(self)
105 self._highlighter = self._highlighter_class(self)
106 self._input_splitter = self._input_splitter_class(input_mode='replace')
106 self._input_splitter = self._input_splitter_class(input_mode='replace')
107 self._kernel_manager = None
107 self._kernel_manager = None
108
108
109 # Configure the ConsoleWidget.
109 # Configure the ConsoleWidget.
110 self.tab_width = 4
110 self.tab_width = 4
111 self._set_continuation_prompt('... ')
111 self._set_continuation_prompt('... ')
112
112
113 # Connect signal handlers.
113 # Connect signal handlers.
114 document = self._control.document()
114 document = self._control.document()
115 document.contentsChange.connect(self._document_contents_change)
115 document.contentsChange.connect(self._document_contents_change)
116
116
117 #---------------------------------------------------------------------------
117 #---------------------------------------------------------------------------
118 # 'ConsoleWidget' abstract interface
118 # 'ConsoleWidget' abstract interface
119 #---------------------------------------------------------------------------
119 #---------------------------------------------------------------------------
120
120
121 def _is_complete(self, source, interactive):
121 def _is_complete(self, source, interactive):
122 """ Returns whether 'source' can be completely processed and a new
122 """ Returns whether 'source' can be completely processed and a new
123 prompt created. When triggered by an Enter/Return key press,
123 prompt created. When triggered by an Enter/Return key press,
124 'interactive' is True; otherwise, it is False.
124 'interactive' is True; otherwise, it is False.
125 """
125 """
126 complete = self._input_splitter.push(source.expandtabs(4))
126 complete = self._input_splitter.push(source.expandtabs(4))
127 if interactive:
127 if interactive:
128 complete = not self._input_splitter.push_accepts_more()
128 complete = not self._input_splitter.push_accepts_more()
129 return complete
129 return complete
130
130
131 def _execute(self, source, hidden):
131 def _execute(self, source, hidden):
132 """ Execute 'source'. If 'hidden', do not show any output.
132 """ Execute 'source'. If 'hidden', do not show any output.
133 """
133 """
134 self.kernel_manager.xreq_channel.execute(source, hidden)
134 self.kernel_manager.xreq_channel.execute(source, hidden)
135 self._hidden = hidden
135 self._hidden = hidden
136
136
137 def _prompt_started_hook(self):
137 def _prompt_started_hook(self):
138 """ Called immediately after a new prompt is displayed.
138 """ Called immediately after a new prompt is displayed.
139 """
139 """
140 if not self._reading:
140 if not self._reading:
141 self._highlighter.highlighting_on = True
141 self._highlighter.highlighting_on = True
142
142
143 def _prompt_finished_hook(self):
143 def _prompt_finished_hook(self):
144 """ Called immediately after a prompt is finished, i.e. when some input
144 """ Called immediately after a prompt is finished, i.e. when some input
145 will be processed and a new prompt displayed.
145 will be processed and a new prompt displayed.
146 """
146 """
147 if not self._reading:
147 if not self._reading:
148 self._highlighter.highlighting_on = False
148 self._highlighter.highlighting_on = False
149
149
150 def _tab_pressed(self):
150 def _tab_pressed(self):
151 """ Called when the tab key is pressed. Returns whether to continue
151 """ Called when the tab key is pressed. Returns whether to continue
152 processing the event.
152 processing the event.
153 """
153 """
154 # Perform tab completion if:
154 # Perform tab completion if:
155 # 1) The cursor is in the input buffer.
155 # 1) The cursor is in the input buffer.
156 # 2) There is a non-whitespace character before the cursor.
156 # 2) There is a non-whitespace character before the cursor.
157 text = self._get_input_buffer_cursor_line()
157 text = self._get_input_buffer_cursor_line()
158 if text is None:
158 if text is None:
159 return False
159 return False
160 complete = bool(text[:self._get_input_buffer_cursor_column()].strip())
160 complete = bool(text[:self._get_input_buffer_cursor_column()].strip())
161 if complete:
161 if complete:
162 self._complete()
162 self._complete()
163 return not complete
163 return not complete
164
164
165 #---------------------------------------------------------------------------
165 #---------------------------------------------------------------------------
166 # 'ConsoleWidget' protected interface
166 # 'ConsoleWidget' protected interface
167 #---------------------------------------------------------------------------
167 #---------------------------------------------------------------------------
168
168
169 def _event_filter_console_keypress(self, event):
169 def _event_filter_console_keypress(self, event):
170 """ Reimplemented to allow execution interruption.
170 """ Reimplemented to allow execution interruption.
171 """
171 """
172 key = event.key()
172 key = event.key()
173 if self._executing and self._control_key_down(event.modifiers()):
173 if self._executing and self._control_key_down(event.modifiers()):
174 if key == QtCore.Qt.Key_C:
174 if key == QtCore.Qt.Key_C:
175 self._kernel_interrupt()
175 self._kernel_interrupt()
176 return True
176 return True
177 elif key == QtCore.Qt.Key_Period:
177 elif key == QtCore.Qt.Key_Period:
178 self._kernel_restart()
178 self._kernel_restart()
179 return True
179 return True
180 return super(FrontendWidget, self)._event_filter_console_keypress(event)
180 return super(FrontendWidget, self)._event_filter_console_keypress(event)
181
181
182 def _show_continuation_prompt(self):
182 def _show_continuation_prompt(self):
183 """ Reimplemented for auto-indentation.
183 """ Reimplemented for auto-indentation.
184 """
184 """
185 super(FrontendWidget, self)._show_continuation_prompt()
185 super(FrontendWidget, self)._show_continuation_prompt()
186 spaces = self._input_splitter.indent_spaces
186 spaces = self._input_splitter.indent_spaces
187 self._append_plain_text('\t' * (spaces / self.tab_width))
187 self._append_plain_text('\t' * (spaces / self.tab_width))
188 self._append_plain_text(' ' * (spaces % self.tab_width))
188 self._append_plain_text(' ' * (spaces % self.tab_width))
189
189
190 #---------------------------------------------------------------------------
190 #---------------------------------------------------------------------------
191 # 'BaseFrontendMixin' abstract interface
191 # 'BaseFrontendMixin' abstract interface
192 #---------------------------------------------------------------------------
192 #---------------------------------------------------------------------------
193
193
194 def _handle_complete_reply(self, rep):
194 def _handle_complete_reply(self, rep):
195 """ Handle replies for tab completion.
195 """ Handle replies for tab completion.
196 """
196 """
197 cursor = self._get_cursor()
197 cursor = self._get_cursor()
198 if rep['parent_header']['msg_id'] == self._complete_id and \
198 if rep['parent_header']['msg_id'] == self._complete_id and \
199 cursor.position() == self._complete_pos:
199 cursor.position() == self._complete_pos:
200 text = '.'.join(self._get_context())
200 # The completer tells us what text was actually used for the
201 # matching, so we must move that many characters left to apply the
202 # completions.
203 text = rep['content']['matched_text']
201 cursor.movePosition(QtGui.QTextCursor.Left, n=len(text))
204 cursor.movePosition(QtGui.QTextCursor.Left, n=len(text))
202 self._complete_with_items(cursor, rep['content']['matches'])
205 self._complete_with_items(cursor, rep['content']['matches'])
203
206
204 def _handle_execute_reply(self, msg):
207 def _handle_execute_reply(self, msg):
205 """ Handles replies for code execution.
208 """ Handles replies for code execution.
206 """
209 """
207 if not self._hidden:
210 if not self._hidden:
208 # Make sure that all output from the SUB channel has been processed
211 # Make sure that all output from the SUB channel has been processed
209 # before writing a new prompt.
212 # before writing a new prompt.
210 self.kernel_manager.sub_channel.flush()
213 self.kernel_manager.sub_channel.flush()
211
214
212 content = msg['content']
215 content = msg['content']
213 status = content['status']
216 status = content['status']
214 if status == 'ok':
217 if status == 'ok':
215 self._process_execute_ok(msg)
218 self._process_execute_ok(msg)
216 elif status == 'error':
219 elif status == 'error':
217 self._process_execute_error(msg)
220 self._process_execute_error(msg)
218 elif status == 'abort':
221 elif status == 'abort':
219 self._process_execute_abort(msg)
222 self._process_execute_abort(msg)
220
223
221 self._show_interpreter_prompt_for_reply(msg)
224 self._show_interpreter_prompt_for_reply(msg)
222 self.executed.emit(msg)
225 self.executed.emit(msg)
223
226
224 def _handle_input_request(self, msg):
227 def _handle_input_request(self, msg):
225 """ Handle requests for raw_input.
228 """ Handle requests for raw_input.
226 """
229 """
227 if self._hidden:
230 if self._hidden:
228 raise RuntimeError('Request for raw input during hidden execution.')
231 raise RuntimeError('Request for raw input during hidden execution.')
229
232
230 # Make sure that all output from the SUB channel has been processed
233 # Make sure that all output from the SUB channel has been processed
231 # before entering readline mode.
234 # before entering readline mode.
232 self.kernel_manager.sub_channel.flush()
235 self.kernel_manager.sub_channel.flush()
233
236
234 def callback(line):
237 def callback(line):
235 self.kernel_manager.rep_channel.input(line)
238 self.kernel_manager.rep_channel.input(line)
236 self._readline(msg['content']['prompt'], callback=callback)
239 self._readline(msg['content']['prompt'], callback=callback)
237
240
238 def _handle_object_info_reply(self, rep):
241 def _handle_object_info_reply(self, rep):
239 """ Handle replies for call tips.
242 """ Handle replies for call tips.
240 """
243 """
241 cursor = self._get_cursor()
244 cursor = self._get_cursor()
242 if rep['parent_header']['msg_id'] == self._call_tip_id and \
245 if rep['parent_header']['msg_id'] == self._call_tip_id and \
243 cursor.position() == self._call_tip_pos:
246 cursor.position() == self._call_tip_pos:
244 doc = rep['content']['docstring']
247 doc = rep['content']['docstring']
245 if doc:
248 if doc:
246 self._call_tip_widget.show_docstring(doc)
249 self._call_tip_widget.show_docstring(doc)
247
250
248 def _handle_pyout(self, msg):
251 def _handle_pyout(self, msg):
249 """ Handle display hook output.
252 """ Handle display hook output.
250 """
253 """
251 if not self._hidden and self._is_from_this_session(msg):
254 if not self._hidden and self._is_from_this_session(msg):
252 self._append_plain_text(msg['content']['data'] + '\n')
255 self._append_plain_text(msg['content']['data'] + '\n')
253
256
254 def _handle_stream(self, msg):
257 def _handle_stream(self, msg):
255 """ Handle stdout, stderr, and stdin.
258 """ Handle stdout, stderr, and stdin.
256 """
259 """
257 if not self._hidden and self._is_from_this_session(msg):
260 if not self._hidden and self._is_from_this_session(msg):
258 self._append_plain_text(msg['content']['data'])
261 self._append_plain_text(msg['content']['data'])
259 self._control.moveCursor(QtGui.QTextCursor.End)
262 self._control.moveCursor(QtGui.QTextCursor.End)
260
263
261 def _started_channels(self):
264 def _started_channels(self):
262 """ Called when the KernelManager channels have started listening or
265 """ Called when the KernelManager channels have started listening or
263 when the frontend is assigned an already listening KernelManager.
266 when the frontend is assigned an already listening KernelManager.
264 """
267 """
265 self._control.clear()
268 self._control.clear()
266 self._append_plain_text(self._get_banner())
269 self._append_plain_text(self._get_banner())
267 self._show_interpreter_prompt()
270 self._show_interpreter_prompt()
268
271
269 def _stopped_channels(self):
272 def _stopped_channels(self):
270 """ Called when the KernelManager channels have stopped listening or
273 """ Called when the KernelManager channels have stopped listening or
271 when a listening KernelManager is removed from the frontend.
274 when a listening KernelManager is removed from the frontend.
272 """
275 """
273 self._executing = self._reading = False
276 self._executing = self._reading = False
274 self._highlighter.highlighting_on = False
277 self._highlighter.highlighting_on = False
275
278
276 #---------------------------------------------------------------------------
279 #---------------------------------------------------------------------------
277 # 'FrontendWidget' interface
280 # 'FrontendWidget' interface
278 #---------------------------------------------------------------------------
281 #---------------------------------------------------------------------------
279
282
280 def execute_file(self, path, hidden=False):
283 def execute_file(self, path, hidden=False):
281 """ Attempts to execute file with 'path'. If 'hidden', no output is
284 """ Attempts to execute file with 'path'. If 'hidden', no output is
282 shown.
285 shown.
283 """
286 """
284 self.execute('execfile("%s")' % path, hidden=hidden)
287 self.execute('execfile("%s")' % path, hidden=hidden)
285
288
286 #---------------------------------------------------------------------------
289 #---------------------------------------------------------------------------
287 # 'FrontendWidget' protected interface
290 # 'FrontendWidget' protected interface
288 #---------------------------------------------------------------------------
291 #---------------------------------------------------------------------------
289
292
290 def _call_tip(self):
293 def _call_tip(self):
291 """ Shows a call tip, if appropriate, at the current cursor location.
294 """ Shows a call tip, if appropriate, at the current cursor location.
292 """
295 """
293 # Decide if it makes sense to show a call tip
296 # Decide if it makes sense to show a call tip
294 cursor = self._get_cursor()
297 cursor = self._get_cursor()
295 cursor.movePosition(QtGui.QTextCursor.Left)
298 cursor.movePosition(QtGui.QTextCursor.Left)
296 document = self._control.document()
299 document = self._control.document()
297 if document.characterAt(cursor.position()).toAscii() != '(':
300 if document.characterAt(cursor.position()).toAscii() != '(':
298 return False
301 return False
299 context = self._get_context(cursor)
302 context = self._get_context(cursor)
300 if not context:
303 if not context:
301 return False
304 return False
302
305
303 # Send the metadata request to the kernel
306 # Send the metadata request to the kernel
304 name = '.'.join(context)
307 name = '.'.join(context)
305 self._call_tip_id = self.kernel_manager.xreq_channel.object_info(name)
308 self._call_tip_id = self.kernel_manager.xreq_channel.object_info(name)
306 self._call_tip_pos = self._get_cursor().position()
309 self._call_tip_pos = self._get_cursor().position()
307 return True
310 return True
308
311
309 def _complete(self):
312 def _complete(self):
310 """ Performs completion at the current cursor location.
313 """ Performs completion at the current cursor location.
311 """
314 """
312 # Decide if it makes sense to do completion
315 # Decide if it makes sense to do completion
313 context = self._get_context()
316
314 if not context:
317 # We should return only if the line is empty. Otherwise, let the
318 # kernel split the line up.
319 line = self._get_input_buffer_cursor_line()
320 if not line:
315 return False
321 return False
316
322
323 # We let the kernel split the input line, so we *always* send an empty
324 # text field. Readline-based frontends do get a real text field which
325 # they can use.
326 text = ''
327
317 # Send the completion request to the kernel
328 # Send the completion request to the kernel
318 self._complete_id = self.kernel_manager.xreq_channel.complete(
329 self._complete_id = self.kernel_manager.xreq_channel.complete(
319 '.'.join(context), # text
330 text, # text
320 self._get_input_buffer_cursor_line(), # line
331 line, # line
321 self._get_input_buffer_cursor_column(), # cursor_pos
332 self._get_input_buffer_cursor_column(), # cursor_pos
322 self.input_buffer) # block
333 self.input_buffer) # block
323 self._complete_pos = self._get_cursor().position()
334 self._complete_pos = self._get_cursor().position()
324 return True
335 return True
325
336
326 def _get_banner(self):
337 def _get_banner(self):
327 """ Gets a banner to display at the beginning of a session.
338 """ Gets a banner to display at the beginning of a session.
328 """
339 """
329 banner = 'Python %s on %s\nType "help", "copyright", "credits" or ' \
340 banner = 'Python %s on %s\nType "help", "copyright", "credits" or ' \
330 '"license" for more information.'
341 '"license" for more information.'
331 return banner % (sys.version, sys.platform)
342 return banner % (sys.version, sys.platform)
332
343
333 def _get_context(self, cursor=None):
344 def _get_context(self, cursor=None):
334 """ Gets the context at the current cursor location.
345 """ Gets the context at the current cursor location.
335 """
346 """
336 if cursor is None:
347 if cursor is None:
337 cursor = self._get_cursor()
348 cursor = self._get_cursor()
338 cursor.movePosition(QtGui.QTextCursor.StartOfBlock,
349 cursor.movePosition(QtGui.QTextCursor.StartOfBlock,
339 QtGui.QTextCursor.KeepAnchor)
350 QtGui.QTextCursor.KeepAnchor)
340 text = str(cursor.selection().toPlainText())
351 text = str(cursor.selection().toPlainText())
341 return self._completion_lexer.get_context(text)
352 return self._completion_lexer.get_context(text)
342
353
343 def _kernel_interrupt(self):
354 def _kernel_interrupt(self):
344 """ Attempts to interrupt the running kernel.
355 """ Attempts to interrupt the running kernel.
345 """
356 """
346 if self.custom_interrupt:
357 if self.custom_interrupt:
347 self.custom_interrupt_requested.emit()
358 self.custom_interrupt_requested.emit()
348 elif self.kernel_manager.has_kernel:
359 elif self.kernel_manager.has_kernel:
349 self.kernel_manager.signal_kernel(signal.SIGINT)
360 self.kernel_manager.signal_kernel(signal.SIGINT)
350 else:
361 else:
351 self._append_plain_text('Kernel process is either remote or '
362 self._append_plain_text('Kernel process is either remote or '
352 'unspecified. Cannot interrupt.\n')
363 'unspecified. Cannot interrupt.\n')
353
364
354 def _kernel_restart(self):
365 def _kernel_restart(self):
355 """ Attempts to restart the running kernel.
366 """ Attempts to restart the running kernel.
356 """
367 """
357 if self.custom_restart:
368 if self.custom_restart:
358 self.custom_restart_requested.emit()
369 self.custom_restart_requested.emit()
359 elif self.kernel_manager.has_kernel:
370 elif self.kernel_manager.has_kernel:
360 try:
371 try:
361 self.kernel_manager.restart_kernel()
372 self.kernel_manager.restart_kernel()
362 except RuntimeError:
373 except RuntimeError:
363 message = 'Kernel started externally. Cannot restart.\n'
374 message = 'Kernel started externally. Cannot restart.\n'
364 self._append_plain_text(message)
375 self._append_plain_text(message)
365 else:
376 else:
366 self._stopped_channels()
377 self._stopped_channels()
367 self._append_plain_text('Kernel restarting...\n')
378 self._append_plain_text('Kernel restarting...\n')
368 self._show_interpreter_prompt()
379 self._show_interpreter_prompt()
369 else:
380 else:
370 self._append_plain_text('Kernel process is either remote or '
381 self._append_plain_text('Kernel process is either remote or '
371 'unspecified. Cannot restart.\n')
382 'unspecified. Cannot restart.\n')
372
383
373 def _process_execute_abort(self, msg):
384 def _process_execute_abort(self, msg):
374 """ Process a reply for an aborted execution request.
385 """ Process a reply for an aborted execution request.
375 """
386 """
376 self._append_plain_text("ERROR: execution aborted\n")
387 self._append_plain_text("ERROR: execution aborted\n")
377
388
378 def _process_execute_error(self, msg):
389 def _process_execute_error(self, msg):
379 """ Process a reply for an execution request that resulted in an error.
390 """ Process a reply for an execution request that resulted in an error.
380 """
391 """
381 content = msg['content']
392 content = msg['content']
382 traceback = ''.join(content['traceback'])
393 traceback = ''.join(content['traceback'])
383 self._append_plain_text(traceback)
394 self._append_plain_text(traceback)
384
395
385 def _process_execute_ok(self, msg):
396 def _process_execute_ok(self, msg):
386 """ Process a reply for a successful execution equest.
397 """ Process a reply for a successful execution equest.
387 """
398 """
388 payload = msg['content']['payload']
399 payload = msg['content']['payload']
389 for item in payload:
400 for item in payload:
390 if not self._process_execute_payload(item):
401 if not self._process_execute_payload(item):
391 warning = 'Received unknown payload of type %s\n'
402 warning = 'Received unknown payload of type %s\n'
392 self._append_plain_text(warning % repr(item['source']))
403 self._append_plain_text(warning % repr(item['source']))
393
404
394 def _process_execute_payload(self, item):
405 def _process_execute_payload(self, item):
395 """ Process a single payload item from the list of payload items in an
406 """ Process a single payload item from the list of payload items in an
396 execution reply. Returns whether the payload was handled.
407 execution reply. Returns whether the payload was handled.
397 """
408 """
398 # The basic FrontendWidget doesn't handle payloads, as they are a
409 # The basic FrontendWidget doesn't handle payloads, as they are a
399 # mechanism for going beyond the standard Python interpreter model.
410 # mechanism for going beyond the standard Python interpreter model.
400 return False
411 return False
401
412
402 def _show_interpreter_prompt(self):
413 def _show_interpreter_prompt(self):
403 """ Shows a prompt for the interpreter.
414 """ Shows a prompt for the interpreter.
404 """
415 """
405 self._show_prompt('>>> ')
416 self._show_prompt('>>> ')
406
417
407 def _show_interpreter_prompt_for_reply(self, msg):
418 def _show_interpreter_prompt_for_reply(self, msg):
408 """ Shows a prompt for the interpreter given an 'execute_reply' message.
419 """ Shows a prompt for the interpreter given an 'execute_reply' message.
409 """
420 """
410 self._show_interpreter_prompt()
421 self._show_interpreter_prompt()
411
422
412 #------ Signal handlers ----------------------------------------------------
423 #------ Signal handlers ----------------------------------------------------
413
424
414 def _document_contents_change(self, position, removed, added):
425 def _document_contents_change(self, position, removed, added):
415 """ Called whenever the document's content changes. Display a call tip
426 """ Called whenever the document's content changes. Display a call tip
416 if appropriate.
427 if appropriate.
417 """
428 """
418 # Calculate where the cursor should be *after* the change:
429 # Calculate where the cursor should be *after* the change:
419 position += added
430 position += added
420
431
421 document = self._control.document()
432 document = self._control.document()
422 if position == self._get_cursor().position():
433 if position == self._get_cursor().position():
423 self._call_tip()
434 self._call_tip()
@@ -1,286 +1,294 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 IO related utilities.
3 IO related utilities.
4 """
4 """
5
5
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2008-2009 The IPython Development Team
7 # Copyright (C) 2008-2009 The IPython Development Team
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 from __future__ import print_function
12
13
13 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
14 # Imports
15 # Imports
15 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
16 import sys
17 import sys
17 import tempfile
18 import tempfile
18
19
19 from IPython.external.Itpl import itpl, printpl
20 from IPython.external.Itpl import itpl, printpl
20
21
21 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
22 # Code
23 # Code
23 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
24
25
25
26
26 class IOStream:
27 class IOStream:
27
28
28 def __init__(self,stream,fallback):
29 def __init__(self,stream,fallback):
29 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
30 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
30 stream = fallback
31 stream = fallback
31 self.stream = stream
32 self.stream = stream
32 self._swrite = stream.write
33 self._swrite = stream.write
33 self.flush = stream.flush
34 self.flush = stream.flush
34
35
35 def write(self,data):
36 def write(self,data):
36 try:
37 try:
37 self._swrite(data)
38 self._swrite(data)
38 except:
39 except:
39 try:
40 try:
40 # print handles some unicode issues which may trip a plain
41 # print handles some unicode issues which may trip a plain
41 # write() call. Attempt to emulate write() by using a
42 # write() call. Emulate write() by using an empty end
42 # trailing comma
43 # argument.
43 print >> self.stream, data,
44 print(data, end='', file=self.stream)
44 except:
45 except:
45 # if we get here, something is seriously broken.
46 # if we get here, something is seriously broken.
46 print >> sys.stderr, \
47 print('ERROR - failed to write data to stream:', self.stream,
47 'ERROR - failed to write data to stream:', self.stream
48 file=sys.stderr)
48
49
49 # This class used to have a writeln method, but regular files and streams
50 # This class used to have a writeln method, but regular files and streams
50 # in Python don't have this method. We need to keep this completely
51 # in Python don't have this method. We need to keep this completely
51 # compatible so we removed it.
52 # compatible so we removed it.
52
53
53 def close(self):
54 def close(self):
54 pass
55 pass
55
56
56
57
57 class IOTerm:
58 class IOTerm:
58 """ Term holds the file or file-like objects for handling I/O operations.
59 """ Term holds the file or file-like objects for handling I/O operations.
59
60
60 These are normally just sys.stdin, sys.stdout and sys.stderr but for
61 These are normally just sys.stdin, sys.stdout and sys.stderr but for
61 Windows they can can replaced to allow editing the strings before they are
62 Windows they can can replaced to allow editing the strings before they are
62 displayed."""
63 displayed."""
63
64
64 # In the future, having IPython channel all its I/O operations through
65 # In the future, having IPython channel all its I/O operations through
65 # this class will make it easier to embed it into other environments which
66 # this class will make it easier to embed it into other environments which
66 # are not a normal terminal (such as a GUI-based shell)
67 # are not a normal terminal (such as a GUI-based shell)
67 def __init__(self, cin=None, cout=None, cerr=None):
68 def __init__(self, cin=None, cout=None, cerr=None):
68 self.cin = IOStream(cin, sys.stdin)
69 self.cin = IOStream(cin, sys.stdin)
69 self.cout = IOStream(cout, sys.stdout)
70 self.cout = IOStream(cout, sys.stdout)
70 self.cerr = IOStream(cerr, sys.stderr)
71 self.cerr = IOStream(cerr, sys.stderr)
71
72
72
73
73 class Tee(object):
74 class Tee(object):
74 """A class to duplicate an output stream to stdout/err.
75 """A class to duplicate an output stream to stdout/err.
75
76
76 This works in a manner very similar to the Unix 'tee' command.
77 This works in a manner very similar to the Unix 'tee' command.
77
78
78 When the object is closed or deleted, it closes the original file given to
79 When the object is closed or deleted, it closes the original file given to
79 it for duplication.
80 it for duplication.
80 """
81 """
81 # Inspired by:
82 # Inspired by:
82 # http://mail.python.org/pipermail/python-list/2007-May/442737.html
83 # http://mail.python.org/pipermail/python-list/2007-May/442737.html
83
84
84 def __init__(self, file_or_name, mode=None, channel='stdout'):
85 def __init__(self, file_or_name, mode=None, channel='stdout'):
85 """Construct a new Tee object.
86 """Construct a new Tee object.
86
87
87 Parameters
88 Parameters
88 ----------
89 ----------
89 file_or_name : filename or open filehandle (writable)
90 file_or_name : filename or open filehandle (writable)
90 File that will be duplicated
91 File that will be duplicated
91
92
92 mode : optional, valid mode for open().
93 mode : optional, valid mode for open().
93 If a filename was give, open with this mode.
94 If a filename was give, open with this mode.
94
95
95 channel : str, one of ['stdout', 'stderr']
96 channel : str, one of ['stdout', 'stderr']
96 """
97 """
97 if channel not in ['stdout', 'stderr']:
98 if channel not in ['stdout', 'stderr']:
98 raise ValueError('Invalid channel spec %s' % channel)
99 raise ValueError('Invalid channel spec %s' % channel)
99
100
100 if hasattr(file, 'write') and hasattr(file, 'seek'):
101 if hasattr(file, 'write') and hasattr(file, 'seek'):
101 self.file = file_or_name
102 self.file = file_or_name
102 else:
103 else:
103 self.file = open(file_or_name, mode)
104 self.file = open(file_or_name, mode)
104 self.channel = channel
105 self.channel = channel
105 self.ostream = getattr(sys, channel)
106 self.ostream = getattr(sys, channel)
106 setattr(sys, channel, self)
107 setattr(sys, channel, self)
107 self._closed = False
108 self._closed = False
108
109
109 def close(self):
110 def close(self):
110 """Close the file and restore the channel."""
111 """Close the file and restore the channel."""
111 self.flush()
112 self.flush()
112 setattr(sys, self.channel, self.ostream)
113 setattr(sys, self.channel, self.ostream)
113 self.file.close()
114 self.file.close()
114 self._closed = True
115 self._closed = True
115
116
116 def write(self, data):
117 def write(self, data):
117 """Write data to both channels."""
118 """Write data to both channels."""
118 self.file.write(data)
119 self.file.write(data)
119 self.ostream.write(data)
120 self.ostream.write(data)
120 self.ostream.flush()
121 self.ostream.flush()
121
122
122 def flush(self):
123 def flush(self):
123 """Flush both channels."""
124 """Flush both channels."""
124 self.file.flush()
125 self.file.flush()
125 self.ostream.flush()
126 self.ostream.flush()
126
127
127 def __del__(self):
128 def __del__(self):
128 if not self._closed:
129 if not self._closed:
129 self.close()
130 self.close()
130
131
131
132
132 def file_read(filename):
133 def file_read(filename):
133 """Read a file and close it. Returns the file source."""
134 """Read a file and close it. Returns the file source."""
134 fobj = open(filename,'r');
135 fobj = open(filename,'r');
135 source = fobj.read();
136 source = fobj.read();
136 fobj.close()
137 fobj.close()
137 return source
138 return source
138
139
139
140
140 def file_readlines(filename):
141 def file_readlines(filename):
141 """Read a file and close it. Returns the file source using readlines()."""
142 """Read a file and close it. Returns the file source using readlines()."""
142 fobj = open(filename,'r');
143 fobj = open(filename,'r');
143 lines = fobj.readlines();
144 lines = fobj.readlines();
144 fobj.close()
145 fobj.close()
145 return lines
146 return lines
146
147
147
148
148 def raw_input_multi(header='', ps1='==> ', ps2='..> ',terminate_str = '.'):
149 def raw_input_multi(header='', ps1='==> ', ps2='..> ',terminate_str = '.'):
149 """Take multiple lines of input.
150 """Take multiple lines of input.
150
151
151 A list with each line of input as a separate element is returned when a
152 A list with each line of input as a separate element is returned when a
152 termination string is entered (defaults to a single '.'). Input can also
153 termination string is entered (defaults to a single '.'). Input can also
153 terminate via EOF (^D in Unix, ^Z-RET in Windows).
154 terminate via EOF (^D in Unix, ^Z-RET in Windows).
154
155
155 Lines of input which end in \\ are joined into single entries (and a
156 Lines of input which end in \\ are joined into single entries (and a
156 secondary continuation prompt is issued as long as the user terminates
157 secondary continuation prompt is issued as long as the user terminates
157 lines with \\). This allows entering very long strings which are still
158 lines with \\). This allows entering very long strings which are still
158 meant to be treated as single entities.
159 meant to be treated as single entities.
159 """
160 """
160
161
161 try:
162 try:
162 if header:
163 if header:
163 header += '\n'
164 header += '\n'
164 lines = [raw_input(header + ps1)]
165 lines = [raw_input(header + ps1)]
165 except EOFError:
166 except EOFError:
166 return []
167 return []
167 terminate = [terminate_str]
168 terminate = [terminate_str]
168 try:
169 try:
169 while lines[-1:] != terminate:
170 while lines[-1:] != terminate:
170 new_line = raw_input(ps1)
171 new_line = raw_input(ps1)
171 while new_line.endswith('\\'):
172 while new_line.endswith('\\'):
172 new_line = new_line[:-1] + raw_input(ps2)
173 new_line = new_line[:-1] + raw_input(ps2)
173 lines.append(new_line)
174 lines.append(new_line)
174
175
175 return lines[:-1] # don't return the termination command
176 return lines[:-1] # don't return the termination command
176 except EOFError:
177 except EOFError:
177 print
178 print
178 return lines
179 return lines
179
180
180
181
181 def raw_input_ext(prompt='', ps2='... '):
182 def raw_input_ext(prompt='', ps2='... '):
182 """Similar to raw_input(), but accepts extended lines if input ends with \\."""
183 """Similar to raw_input(), but accepts extended lines if input ends with \\."""
183
184
184 line = raw_input(prompt)
185 line = raw_input(prompt)
185 while line.endswith('\\'):
186 while line.endswith('\\'):
186 line = line[:-1] + raw_input(ps2)
187 line = line[:-1] + raw_input(ps2)
187 return line
188 return line
188
189
189
190
190 def ask_yes_no(prompt,default=None):
191 def ask_yes_no(prompt,default=None):
191 """Asks a question and returns a boolean (y/n) answer.
192 """Asks a question and returns a boolean (y/n) answer.
192
193
193 If default is given (one of 'y','n'), it is used if the user input is
194 If default is given (one of 'y','n'), it is used if the user input is
194 empty. Otherwise the question is repeated until an answer is given.
195 empty. Otherwise the question is repeated until an answer is given.
195
196
196 An EOF is treated as the default answer. If there is no default, an
197 An EOF is treated as the default answer. If there is no default, an
197 exception is raised to prevent infinite loops.
198 exception is raised to prevent infinite loops.
198
199
199 Valid answers are: y/yes/n/no (match is not case sensitive)."""
200 Valid answers are: y/yes/n/no (match is not case sensitive)."""
200
201
201 answers = {'y':True,'n':False,'yes':True,'no':False}
202 answers = {'y':True,'n':False,'yes':True,'no':False}
202 ans = None
203 ans = None
203 while ans not in answers.keys():
204 while ans not in answers.keys():
204 try:
205 try:
205 ans = raw_input(prompt+' ').lower()
206 ans = raw_input(prompt+' ').lower()
206 if not ans: # response was an empty string
207 if not ans: # response was an empty string
207 ans = default
208 ans = default
208 except KeyboardInterrupt:
209 except KeyboardInterrupt:
209 pass
210 pass
210 except EOFError:
211 except EOFError:
211 if default in answers.keys():
212 if default in answers.keys():
212 ans = default
213 ans = default
213 print
214 print
214 else:
215 else:
215 raise
216 raise
216
217
217 return answers[ans]
218 return answers[ans]
218
219
219
220
220 class NLprinter:
221 class NLprinter:
221 """Print an arbitrarily nested list, indicating index numbers.
222 """Print an arbitrarily nested list, indicating index numbers.
222
223
223 An instance of this class called nlprint is available and callable as a
224 An instance of this class called nlprint is available and callable as a
224 function.
225 function.
225
226
226 nlprint(list,indent=' ',sep=': ') -> prints indenting each level by 'indent'
227 nlprint(list,indent=' ',sep=': ') -> prints indenting each level by 'indent'
227 and using 'sep' to separate the index from the value. """
228 and using 'sep' to separate the index from the value. """
228
229
229 def __init__(self):
230 def __init__(self):
230 self.depth = 0
231 self.depth = 0
231
232
232 def __call__(self,lst,pos='',**kw):
233 def __call__(self,lst,pos='',**kw):
233 """Prints the nested list numbering levels."""
234 """Prints the nested list numbering levels."""
234 kw.setdefault('indent',' ')
235 kw.setdefault('indent',' ')
235 kw.setdefault('sep',': ')
236 kw.setdefault('sep',': ')
236 kw.setdefault('start',0)
237 kw.setdefault('start',0)
237 kw.setdefault('stop',len(lst))
238 kw.setdefault('stop',len(lst))
238 # we need to remove start and stop from kw so they don't propagate
239 # we need to remove start and stop from kw so they don't propagate
239 # into a recursive call for a nested list.
240 # into a recursive call for a nested list.
240 start = kw['start']; del kw['start']
241 start = kw['start']; del kw['start']
241 stop = kw['stop']; del kw['stop']
242 stop = kw['stop']; del kw['stop']
242 if self.depth == 0 and 'header' in kw.keys():
243 if self.depth == 0 and 'header' in kw.keys():
243 print kw['header']
244 print(kw['header'])
244
245
245 for idx in range(start,stop):
246 for idx in range(start,stop):
246 elem = lst[idx]
247 elem = lst[idx]
247 if type(elem)==type([]):
248 if type(elem)==type([]):
248 self.depth += 1
249 self.depth += 1
249 self.__call__(elem,itpl('$pos$idx,'),**kw)
250 self.__call__(elem,itpl('$pos$idx,'),**kw)
250 self.depth -= 1
251 self.depth -= 1
251 else:
252 else:
252 printpl(kw['indent']*self.depth+'$pos$idx$kw["sep"]$elem')
253 printpl(kw['indent']*self.depth+'$pos$idx$kw["sep"]$elem')
253
254
254 nlprint = NLprinter()
255 nlprint = NLprinter()
255
256
256
257
257 def temp_pyfile(src, ext='.py'):
258 def temp_pyfile(src, ext='.py'):
258 """Make a temporary python file, return filename and filehandle.
259 """Make a temporary python file, return filename and filehandle.
259
260
260 Parameters
261 Parameters
261 ----------
262 ----------
262 src : string or list of strings (no need for ending newlines if list)
263 src : string or list of strings (no need for ending newlines if list)
263 Source code to be written to the file.
264 Source code to be written to the file.
264
265
265 ext : optional, string
266 ext : optional, string
266 Extension for the generated file.
267 Extension for the generated file.
267
268
268 Returns
269 Returns
269 -------
270 -------
270 (filename, open filehandle)
271 (filename, open filehandle)
271 It is the caller's responsibility to close the open file and unlink it.
272 It is the caller's responsibility to close the open file and unlink it.
272 """
273 """
273 fname = tempfile.mkstemp(ext)[1]
274 fname = tempfile.mkstemp(ext)[1]
274 f = open(fname,'w')
275 f = open(fname,'w')
275 f.write(src)
276 f.write(src)
276 f.flush()
277 f.flush()
277 return fname, f
278 return fname, f
278
279
279
280
280 def rprint(*info):
281 def rprint(*args, **kw):
282 """Raw print to sys.__stdout__"""
283
284 print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
285 file=sys.__stdout__)
286 sys.__stdout__.flush()
287
288
289 def rprinte(*args, **kw):
281 """Raw print to sys.__stderr__"""
290 """Raw print to sys.__stderr__"""
282
291
283 for item in info:
292 print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
284 print >> sys.__stderr__, item,
293 file=sys.__stderr__)
285 print >> sys.__stderr__
286 sys.__stderr__.flush()
294 sys.__stderr__.flush()
@@ -1,399 +1,400 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 """A simple interactive kernel that talks to a frontend over 0MQ.
2 """A simple interactive kernel that talks to a frontend over 0MQ.
3
3
4 Things to do:
4 Things to do:
5
5
6 * Implement `set_parent` logic. Right before doing exec, the Kernel should
6 * Implement `set_parent` logic. Right before doing exec, the Kernel should
7 call set_parent on all the PUB objects with the message about to be executed.
7 call set_parent on all the PUB objects with the message about to be executed.
8 * Implement random port and security key logic.
8 * Implement random port and security key logic.
9 * Implement control messages.
9 * Implement control messages.
10 * Implement event loop and poll version.
10 * Implement event loop and poll version.
11 """
11 """
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 from __future__ import print_function
16
17
17 # Standard library imports.
18 # Standard library imports.
18 import __builtin__
19 import __builtin__
19 import sys
20 import sys
20 import time
21 import time
21 import traceback
22 import traceback
22
23
23 # System library imports.
24 # System library imports.
24 import zmq
25 import zmq
25
26
26 # Local imports.
27 # Local imports.
27 from IPython.config.configurable import Configurable
28 from IPython.config.configurable import Configurable
29 from IPython.utils import io
28 from IPython.utils.traitlets import Instance
30 from IPython.utils.traitlets import Instance
29 from completer import KernelCompleter
31 from completer import KernelCompleter
30 from entry_point import base_launch_kernel, make_argument_parser, make_kernel, \
32 from entry_point import base_launch_kernel, make_argument_parser, make_kernel, \
31 start_kernel
33 start_kernel
32 from iostream import OutStream
34 from iostream import OutStream
33 from session import Session, Message
35 from session import Session, Message
34 from zmqshell import ZMQInteractiveShell
36 from zmqshell import ZMQInteractiveShell
35
37
36 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
37 # Main kernel class
39 # Main kernel class
38 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
39
41
40 class Kernel(Configurable):
42 class Kernel(Configurable):
41
43
42 #---------------------------------------------------------------------------
44 #---------------------------------------------------------------------------
43 # Kernel interface
45 # Kernel interface
44 #---------------------------------------------------------------------------
46 #---------------------------------------------------------------------------
45
47
46 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
48 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
47 session = Instance(Session)
49 session = Instance(Session)
48 reply_socket = Instance('zmq.Socket')
50 reply_socket = Instance('zmq.Socket')
49 pub_socket = Instance('zmq.Socket')
51 pub_socket = Instance('zmq.Socket')
50 req_socket = Instance('zmq.Socket')
52 req_socket = Instance('zmq.Socket')
51
53
52 # Maps user-friendly backend names to matplotlib backend identifiers.
54 # Maps user-friendly backend names to matplotlib backend identifiers.
53 _pylab_map = { 'tk': 'TkAgg',
55 _pylab_map = { 'tk': 'TkAgg',
54 'gtk': 'GTKAgg',
56 'gtk': 'GTKAgg',
55 'wx': 'WXAgg',
57 'wx': 'WXAgg',
56 'qt': 'Qt4Agg', # qt3 not supported
58 'qt': 'Qt4Agg', # qt3 not supported
57 'qt4': 'Qt4Agg',
59 'qt4': 'Qt4Agg',
58 'payload-svg' : \
60 'payload-svg' : \
59 'module://IPython.zmq.pylab.backend_payload_svg' }
61 'module://IPython.zmq.pylab.backend_payload_svg' }
60
62
61 def __init__(self, **kwargs):
63 def __init__(self, **kwargs):
62 super(Kernel, self).__init__(**kwargs)
64 super(Kernel, self).__init__(**kwargs)
63
65
64 # Initialize the InteractiveShell subclass
66 # Initialize the InteractiveShell subclass
65 self.shell = ZMQInteractiveShell.instance()
67 self.shell = ZMQInteractiveShell.instance()
66 self.shell.displayhook.session = self.session
68 self.shell.displayhook.session = self.session
67 self.shell.displayhook.pub_socket = self.pub_socket
69 self.shell.displayhook.pub_socket = self.pub_socket
68
70
69 # TMP - hack while developing
71 # TMP - hack while developing
70 self.shell._reply_content = None
72 self.shell._reply_content = None
71
73
72 # Build dict of handlers for message types
74 # Build dict of handlers for message types
73 msg_types = [ 'execute_request', 'complete_request',
75 msg_types = [ 'execute_request', 'complete_request',
74 'object_info_request', 'prompt_request',
76 'object_info_request', 'prompt_request',
75 'history_request' ]
77 'history_request' ]
76 self.handlers = {}
78 self.handlers = {}
77 for msg_type in msg_types:
79 for msg_type in msg_types:
78 self.handlers[msg_type] = getattr(self, msg_type)
80 self.handlers[msg_type] = getattr(self, msg_type)
79
81
80 def activate_pylab(self, backend=None, import_all=True):
82 def activate_pylab(self, backend=None, import_all=True):
81 """ Activates pylab in this kernel's namespace.
83 """ Activates pylab in this kernel's namespace.
82
84
83 Parameters:
85 Parameters:
84 -----------
86 -----------
85 backend : str, optional
87 backend : str, optional
86 A valid backend name.
88 A valid backend name.
87
89
88 import_all : bool, optional
90 import_all : bool, optional
89 If true, an 'import *' is done from numpy and pylab.
91 If true, an 'import *' is done from numpy and pylab.
90 """
92 """
91 # FIXME: This is adapted from IPython.lib.pylabtools.pylab_activate.
93 # FIXME: This is adapted from IPython.lib.pylabtools.pylab_activate.
92 # Common functionality should be refactored.
94 # Common functionality should be refactored.
93
95
94 # We must set the desired backend before importing pylab.
96 # We must set the desired backend before importing pylab.
95 import matplotlib
97 import matplotlib
96 if backend:
98 if backend:
97 backend_id = self._pylab_map[backend]
99 backend_id = self._pylab_map[backend]
98 if backend_id.startswith('module://'):
100 if backend_id.startswith('module://'):
99 # Work around bug in matplotlib: matplotlib.use converts the
101 # Work around bug in matplotlib: matplotlib.use converts the
100 # backend_id to lowercase even if a module name is specified!
102 # backend_id to lowercase even if a module name is specified!
101 matplotlib.rcParams['backend'] = backend_id
103 matplotlib.rcParams['backend'] = backend_id
102 else:
104 else:
103 matplotlib.use(backend_id)
105 matplotlib.use(backend_id)
104
106
105 # Import numpy as np/pyplot as plt are conventions we're trying to
107 # Import numpy as np/pyplot as plt are conventions we're trying to
106 # somewhat standardize on. Making them available to users by default
108 # somewhat standardize on. Making them available to users by default
107 # will greatly help this.
109 # will greatly help this.
108 exec ("import numpy\n"
110 exec ("import numpy\n"
109 "import matplotlib\n"
111 "import matplotlib\n"
110 "from matplotlib import pylab, mlab, pyplot\n"
112 "from matplotlib import pylab, mlab, pyplot\n"
111 "np = numpy\n"
113 "np = numpy\n"
112 "plt = pyplot\n"
114 "plt = pyplot\n"
113 ) in self.shell.user_ns
115 ) in self.shell.user_ns
114
116
115 if import_all:
117 if import_all:
116 exec("from matplotlib.pylab import *\n"
118 exec("from matplotlib.pylab import *\n"
117 "from numpy import *\n") in self.shell.user_ns
119 "from numpy import *\n") in self.shell.user_ns
118
120
119 matplotlib.interactive(True)
121 matplotlib.interactive(True)
120
122
121 def start(self):
123 def start(self):
122 """ Start the kernel main loop.
124 """ Start the kernel main loop.
123 """
125 """
124 while True:
126 while True:
125 ident = self.reply_socket.recv()
127 ident = self.reply_socket.recv()
126 assert self.reply_socket.rcvmore(), "Missing message part."
128 assert self.reply_socket.rcvmore(), "Missing message part."
127 msg = self.reply_socket.recv_json()
129 msg = self.reply_socket.recv_json()
128 omsg = Message(msg)
130 omsg = Message(msg)
129 print>>sys.__stdout__
131 io.rprint('\n', omsg)
130 print>>sys.__stdout__, omsg
131 handler = self.handlers.get(omsg.msg_type, None)
132 handler = self.handlers.get(omsg.msg_type, None)
132 if handler is None:
133 if handler is None:
133 print >> sys.__stderr__, "UNKNOWN MESSAGE TYPE:", omsg
134 io.rprinte("UNKNOWN MESSAGE TYPE:", omsg)
134 else:
135 else:
135 handler(ident, omsg)
136 handler(ident, omsg)
136
137
137 #---------------------------------------------------------------------------
138 #---------------------------------------------------------------------------
138 # Kernel request handlers
139 # Kernel request handlers
139 #---------------------------------------------------------------------------
140 #---------------------------------------------------------------------------
140
141
141 def execute_request(self, ident, parent):
142 def execute_request(self, ident, parent):
142 try:
143 try:
143 code = parent[u'content'][u'code']
144 code = parent[u'content'][u'code']
144 except:
145 except:
145 print>>sys.__stderr__, "Got bad msg: "
146 io.rprinte("Got bad msg: ")
146 print>>sys.__stderr__, Message(parent)
147 io.rprinte(Message(parent))
147 return
148 return
148 pyin_msg = self.session.msg(u'pyin',{u'code':code}, parent=parent)
149 pyin_msg = self.session.msg(u'pyin',{u'code':code}, parent=parent)
149 self.pub_socket.send_json(pyin_msg)
150 self.pub_socket.send_json(pyin_msg)
150
151
151 try:
152 try:
152 # Replace raw_input. Note that is not sufficient to replace
153 # Replace raw_input. Note that is not sufficient to replace
153 # raw_input in the user namespace.
154 # raw_input in the user namespace.
154 raw_input = lambda prompt='': self._raw_input(prompt, ident, parent)
155 raw_input = lambda prompt='': self._raw_input(prompt, ident, parent)
155 __builtin__.raw_input = raw_input
156 __builtin__.raw_input = raw_input
156
157
157 # Set the parent message of the display hook and out streams.
158 # Set the parent message of the display hook and out streams.
158 self.shell.displayhook.set_parent(parent)
159 self.shell.displayhook.set_parent(parent)
159 sys.stdout.set_parent(parent)
160 sys.stdout.set_parent(parent)
160 sys.stderr.set_parent(parent)
161 sys.stderr.set_parent(parent)
161
162
162 # FIXME: runlines calls the exception handler itself. We should
163 # FIXME: runlines calls the exception handler itself. We should
163 # clean this up.
164 # clean this up.
164 self.shell._reply_content = None
165 self.shell._reply_content = None
165 self.shell.runlines(code)
166 self.shell.runlines(code)
166 except:
167 except:
167 # FIXME: this code right now isn't being used yet by default,
168 # FIXME: this code right now isn't being used yet by default,
168 # because the runlines() call above directly fires off exception
169 # because the runlines() call above directly fires off exception
169 # reporting. This code, therefore, is only active in the scenario
170 # reporting. This code, therefore, is only active in the scenario
170 # where runlines itself has an unhandled exception. We need to
171 # where runlines itself has an unhandled exception. We need to
171 # uniformize this, for all exception construction to come from a
172 # uniformize this, for all exception construction to come from a
172 # single location in the codbase.
173 # single location in the codbase.
173 etype, evalue, tb = sys.exc_info()
174 etype, evalue, tb = sys.exc_info()
174 tb_list = traceback.format_exception(etype, evalue, tb)
175 tb_list = traceback.format_exception(etype, evalue, tb)
175 reply_content = self.shell._showtraceback(etype, evalue, tb_list)
176 reply_content = self.shell._showtraceback(etype, evalue, tb_list)
176 else:
177 else:
177 payload = self.shell.payload_manager.read_payload()
178 payload = self.shell.payload_manager.read_payload()
178 # Be agressive about clearing the payload because we don't want
179 # Be agressive about clearing the payload because we don't want
179 # it to sit in memory until the next execute_request comes in.
180 # it to sit in memory until the next execute_request comes in.
180 self.shell.payload_manager.clear_payload()
181 self.shell.payload_manager.clear_payload()
181 reply_content = { 'status' : 'ok', 'payload' : payload }
182 reply_content = { 'status' : 'ok', 'payload' : payload }
182
183
183 # Compute the prompt information
184 # Compute the prompt information
184 prompt_number = self.shell.displayhook.prompt_count
185 prompt_number = self.shell.displayhook.prompt_count
185 reply_content['prompt_number'] = prompt_number
186 reply_content['prompt_number'] = prompt_number
186 prompt_string = self.shell.displayhook.prompt1.peek_next_prompt()
187 prompt_string = self.shell.displayhook.prompt1.peek_next_prompt()
187 next_prompt = {'prompt_string' : prompt_string,
188 next_prompt = {'prompt_string' : prompt_string,
188 'prompt_number' : prompt_number+1,
189 'prompt_number' : prompt_number+1,
189 'input_sep' : self.shell.displayhook.input_sep}
190 'input_sep' : self.shell.displayhook.input_sep}
190 reply_content['next_prompt'] = next_prompt
191 reply_content['next_prompt'] = next_prompt
191
192
192 # TMP - fish exception info out of shell, possibly left there by
193 # TMP - fish exception info out of shell, possibly left there by
193 # runlines
194 # runlines
194 if self.shell._reply_content is not None:
195 if self.shell._reply_content is not None:
195 reply_content.update(self.shell._reply_content)
196 reply_content.update(self.shell._reply_content)
196
197
197 # Flush output before sending the reply.
198 # Flush output before sending the reply.
198 sys.stderr.flush()
199 sys.stderr.flush()
199 sys.stdout.flush()
200 sys.stdout.flush()
200
201
201 # Send the reply.
202 # Send the reply.
202 reply_msg = self.session.msg(u'execute_reply', reply_content, parent)
203 reply_msg = self.session.msg(u'execute_reply', reply_content, parent)
203 print>>sys.__stdout__, Message(reply_msg)
204 io.rprint(Message(reply_msg))
204 self.reply_socket.send(ident, zmq.SNDMORE)
205 self.reply_socket.send(ident, zmq.SNDMORE)
205 self.reply_socket.send_json(reply_msg)
206 self.reply_socket.send_json(reply_msg)
206 if reply_msg['content']['status'] == u'error':
207 if reply_msg['content']['status'] == u'error':
207 self._abort_queue()
208 self._abort_queue()
208
209
209 def complete_request(self, ident, parent):
210 def complete_request(self, ident, parent):
210 matches = {'matches' : self._complete(parent),
211 txt, matches = self._complete(parent)
212 matches = {'matches' : matches,
213 'matched_text' : txt,
211 'status' : 'ok'}
214 'status' : 'ok'}
212 completion_msg = self.session.send(self.reply_socket, 'complete_reply',
215 completion_msg = self.session.send(self.reply_socket, 'complete_reply',
213 matches, parent, ident)
216 matches, parent, ident)
214 print >> sys.__stdout__, completion_msg
217 io.rprint(completion_msg)
215
218
216 def object_info_request(self, ident, parent):
219 def object_info_request(self, ident, parent):
217 context = parent['content']['oname'].split('.')
220 context = parent['content']['oname'].split('.')
218 object_info = self._object_info(context)
221 object_info = self._object_info(context)
219 msg = self.session.send(self.reply_socket, 'object_info_reply',
222 msg = self.session.send(self.reply_socket, 'object_info_reply',
220 object_info, parent, ident)
223 object_info, parent, ident)
221 print >> sys.__stdout__, msg
224 io.rprint(msg)
222
225
223 def prompt_request(self, ident, parent):
226 def prompt_request(self, ident, parent):
224 prompt_number = self.shell.displayhook.prompt_count
227 prompt_number = self.shell.displayhook.prompt_count
225 prompt_string = self.shell.displayhook.prompt1.peek_next_prompt()
228 prompt_string = self.shell.displayhook.prompt1.peek_next_prompt()
226 content = {'prompt_string' : prompt_string,
229 content = {'prompt_string' : prompt_string,
227 'prompt_number' : prompt_number+1,
230 'prompt_number' : prompt_number+1,
228 'input_sep' : self.shell.displayhook.input_sep}
231 'input_sep' : self.shell.displayhook.input_sep}
229 msg = self.session.send(self.reply_socket, 'prompt_reply',
232 msg = self.session.send(self.reply_socket, 'prompt_reply',
230 content, parent, ident)
233 content, parent, ident)
231 print >> sys.__stdout__, msg
234 io.rprint(msg)
232
235
233 def history_request(self, ident, parent):
236 def history_request(self, ident, parent):
234 output = parent['content']['output']
237 output = parent['content']['output']
235 index = parent['content']['index']
238 index = parent['content']['index']
236 raw = parent['content']['raw']
239 raw = parent['content']['raw']
237 hist = self.shell.get_history(index=index, raw=raw, output=output)
240 hist = self.shell.get_history(index=index, raw=raw, output=output)
238 content = {'history' : hist}
241 content = {'history' : hist}
239 msg = self.session.send(self.reply_socket, 'history_reply',
242 msg = self.session.send(self.reply_socket, 'history_reply',
240 content, parent, ident)
243 content, parent, ident)
241 print >> sys.__stdout__, msg
244 io.rprint(msg)
242
245
243 #---------------------------------------------------------------------------
246 #---------------------------------------------------------------------------
244 # Protected interface
247 # Protected interface
245 #---------------------------------------------------------------------------
248 #---------------------------------------------------------------------------
246
249
247 def _abort_queue(self):
250 def _abort_queue(self):
248 while True:
251 while True:
249 try:
252 try:
250 ident = self.reply_socket.recv(zmq.NOBLOCK)
253 ident = self.reply_socket.recv(zmq.NOBLOCK)
251 except zmq.ZMQError, e:
254 except zmq.ZMQError, e:
252 if e.errno == zmq.EAGAIN:
255 if e.errno == zmq.EAGAIN:
253 break
256 break
254 else:
257 else:
255 assert self.reply_socket.rcvmore(), "Unexpected missing message part."
258 assert self.reply_socket.rcvmore(), "Unexpected missing message part."
256 msg = self.reply_socket.recv_json()
259 msg = self.reply_socket.recv_json()
257 print>>sys.__stdout__, "Aborting:"
260 io.rprint("Aborting:\n", Message(msg))
258 print>>sys.__stdout__, Message(msg)
259 msg_type = msg['msg_type']
261 msg_type = msg['msg_type']
260 reply_type = msg_type.split('_')[0] + '_reply'
262 reply_type = msg_type.split('_')[0] + '_reply'
261 reply_msg = self.session.msg(reply_type, {'status' : 'aborted'}, msg)
263 reply_msg = self.session.msg(reply_type, {'status' : 'aborted'}, msg)
262 print>>sys.__stdout__, Message(reply_msg)
264 io.rprint(Message(reply_msg))
263 self.reply_socket.send(ident,zmq.SNDMORE)
265 self.reply_socket.send(ident,zmq.SNDMORE)
264 self.reply_socket.send_json(reply_msg)
266 self.reply_socket.send_json(reply_msg)
265 # We need to wait a bit for requests to come in. This can probably
267 # We need to wait a bit for requests to come in. This can probably
266 # be set shorter for true asynchronous clients.
268 # be set shorter for true asynchronous clients.
267 time.sleep(0.1)
269 time.sleep(0.1)
268
270
269 def _raw_input(self, prompt, ident, parent):
271 def _raw_input(self, prompt, ident, parent):
270 # Flush output before making the request.
272 # Flush output before making the request.
271 sys.stderr.flush()
273 sys.stderr.flush()
272 sys.stdout.flush()
274 sys.stdout.flush()
273
275
274 # Send the input request.
276 # Send the input request.
275 content = dict(prompt=prompt)
277 content = dict(prompt=prompt)
276 msg = self.session.msg(u'input_request', content, parent)
278 msg = self.session.msg(u'input_request', content, parent)
277 self.req_socket.send_json(msg)
279 self.req_socket.send_json(msg)
278
280
279 # Await a response.
281 # Await a response.
280 reply = self.req_socket.recv_json()
282 reply = self.req_socket.recv_json()
281 try:
283 try:
282 value = reply['content']['value']
284 value = reply['content']['value']
283 except:
285 except:
284 print>>sys.__stderr__, "Got bad raw_input reply: "
286 io.rprinte("Got bad raw_input reply: ")
285 print>>sys.__stderr__, Message(parent)
287 io.rprinte(Message(parent))
286 value = ''
288 value = ''
287 return value
289 return value
288
290
289 def _complete(self, msg):
291 def _complete(self, msg):
290 #from IPython.utils.io import rprint # dbg
291 #rprint('\n\n**MSG**\n\n', msg) # dbg
292 #import traceback; rprint(''.join(traceback.format_stack())) # dbg
293 c = msg['content']
292 c = msg['content']
294 try:
293 try:
295 cpos = int(c['cursor_pos'])
294 cpos = int(c['cursor_pos'])
296 except:
295 except:
297 # If we don't get something that we can convert to an integer, at
296 # If we don't get something that we can convert to an integer, at
298 # leasat attempt the completion guessing the cursor is at the end
297 # least attempt the completion guessing the cursor is at the end of
299 # of the text
298 # the text, if there's any, and otherwise of the line
300 cpos = len(c['text'])
299 cpos = len(c['text'])
300 if cpos==0:
301 cpos = len(c['line'])
301 return self.shell.complete(c['text'], c['line'], cpos)
302 return self.shell.complete(c['text'], c['line'], cpos)
302
303
303 def _object_info(self, context):
304 def _object_info(self, context):
304 symbol, leftover = self._symbol_from_context(context)
305 symbol, leftover = self._symbol_from_context(context)
305 if symbol is not None and not leftover:
306 if symbol is not None and not leftover:
306 doc = getattr(symbol, '__doc__', '')
307 doc = getattr(symbol, '__doc__', '')
307 else:
308 else:
308 doc = ''
309 doc = ''
309 object_info = dict(docstring = doc)
310 object_info = dict(docstring = doc)
310 return object_info
311 return object_info
311
312
312 def _symbol_from_context(self, context):
313 def _symbol_from_context(self, context):
313 if not context:
314 if not context:
314 return None, context
315 return None, context
315
316
316 base_symbol_string = context[0]
317 base_symbol_string = context[0]
317 symbol = self.shell.user_ns.get(base_symbol_string, None)
318 symbol = self.shell.user_ns.get(base_symbol_string, None)
318 if symbol is None:
319 if symbol is None:
319 symbol = __builtin__.__dict__.get(base_symbol_string, None)
320 symbol = __builtin__.__dict__.get(base_symbol_string, None)
320 if symbol is None:
321 if symbol is None:
321 return None, context
322 return None, context
322
323
323 context = context[1:]
324 context = context[1:]
324 for i, name in enumerate(context):
325 for i, name in enumerate(context):
325 new_symbol = getattr(symbol, name, None)
326 new_symbol = getattr(symbol, name, None)
326 if new_symbol is None:
327 if new_symbol is None:
327 return symbol, context[i:]
328 return symbol, context[i:]
328 else:
329 else:
329 symbol = new_symbol
330 symbol = new_symbol
330
331
331 return symbol, []
332 return symbol, []
332
333
333 #-----------------------------------------------------------------------------
334 #-----------------------------------------------------------------------------
334 # Kernel main and launch functions
335 # Kernel main and launch functions
335 #-----------------------------------------------------------------------------
336 #-----------------------------------------------------------------------------
336
337
337 def launch_kernel(xrep_port=0, pub_port=0, req_port=0, independent=False,
338 def launch_kernel(xrep_port=0, pub_port=0, req_port=0, independent=False,
338 pylab=False):
339 pylab=False):
339 """ Launches a localhost kernel, binding to the specified ports.
340 """ Launches a localhost kernel, binding to the specified ports.
340
341
341 Parameters
342 Parameters
342 ----------
343 ----------
343 xrep_port : int, optional
344 xrep_port : int, optional
344 The port to use for XREP channel.
345 The port to use for XREP channel.
345
346
346 pub_port : int, optional
347 pub_port : int, optional
347 The port to use for the SUB channel.
348 The port to use for the SUB channel.
348
349
349 req_port : int, optional
350 req_port : int, optional
350 The port to use for the REQ (raw input) channel.
351 The port to use for the REQ (raw input) channel.
351
352
352 independent : bool, optional (default False)
353 independent : bool, optional (default False)
353 If set, the kernel process is guaranteed to survive if this process
354 If set, the kernel process is guaranteed to survive if this process
354 dies. If not set, an effort is made to ensure that the kernel is killed
355 dies. If not set, an effort is made to ensure that the kernel is killed
355 when this process dies. Note that in this case it is still good practice
356 when this process dies. Note that in this case it is still good practice
356 to kill kernels manually before exiting.
357 to kill kernels manually before exiting.
357
358
358 pylab : bool or string, optional (default False)
359 pylab : bool or string, optional (default False)
359 If not False, the kernel will be launched with pylab enabled. If a
360 If not False, the kernel will be launched with pylab enabled. If a
360 string is passed, matplotlib will use the specified backend. Otherwise,
361 string is passed, matplotlib will use the specified backend. Otherwise,
361 matplotlib's default backend will be used.
362 matplotlib's default backend will be used.
362
363
363 Returns
364 Returns
364 -------
365 -------
365 A tuple of form:
366 A tuple of form:
366 (kernel_process, xrep_port, pub_port, req_port)
367 (kernel_process, xrep_port, pub_port, req_port)
367 where kernel_process is a Popen object and the ports are integers.
368 where kernel_process is a Popen object and the ports are integers.
368 """
369 """
369 extra_arguments = []
370 extra_arguments = []
370 if pylab:
371 if pylab:
371 extra_arguments.append('--pylab')
372 extra_arguments.append('--pylab')
372 if isinstance(pylab, basestring):
373 if isinstance(pylab, basestring):
373 extra_arguments.append(pylab)
374 extra_arguments.append(pylab)
374 return base_launch_kernel('from IPython.zmq.ipkernel import main; main()',
375 return base_launch_kernel('from IPython.zmq.ipkernel import main; main()',
375 xrep_port, pub_port, req_port, independent,
376 xrep_port, pub_port, req_port, independent,
376 extra_arguments)
377 extra_arguments)
377
378
378 def main():
379 def main():
379 """ The IPython kernel main entry point.
380 """ The IPython kernel main entry point.
380 """
381 """
381 parser = make_argument_parser()
382 parser = make_argument_parser()
382 parser.add_argument('--pylab', type=str, metavar='GUI', nargs='?',
383 parser.add_argument('--pylab', type=str, metavar='GUI', nargs='?',
383 const='auto', help = \
384 const='auto', help = \
384 "Pre-load matplotlib and numpy for interactive use. If GUI is not \
385 "Pre-load matplotlib and numpy for interactive use. If GUI is not \
385 given, the GUI backend is matplotlib's, otherwise use one of: \
386 given, the GUI backend is matplotlib's, otherwise use one of: \
386 ['tk', 'gtk', 'qt', 'wx', 'payload-svg'].")
387 ['tk', 'gtk', 'qt', 'wx', 'payload-svg'].")
387 namespace = parser.parse_args()
388 namespace = parser.parse_args()
388
389
389 kernel = make_kernel(namespace, Kernel, OutStream)
390 kernel = make_kernel(namespace, Kernel, OutStream)
390 if namespace.pylab:
391 if namespace.pylab:
391 if namespace.pylab == 'auto':
392 if namespace.pylab == 'auto':
392 kernel.activate_pylab()
393 kernel.activate_pylab()
393 else:
394 else:
394 kernel.activate_pylab(namespace.pylab)
395 kernel.activate_pylab(namespace.pylab)
395
396
396 start_kernel(namespace, kernel)
397 start_kernel(namespace, kernel)
397
398
398 if __name__ == '__main__':
399 if __name__ == '__main__':
399 main()
400 main()
General Comments 0
You need to be logged in to leave comments. Login now